diff --git a/db/build.xml b/db/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b6d09936b012c84d09f9dd451186f61ab1f61d53
--- /dev/null
+++ b/db/build.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0"?>
+
+<project name="setupDB" basedir="." default="all">
+
+	<target name="dropHSQLTables" if="useHSQL">
+		<echo message="Drop tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}" onerror="continue">
+			<classpath>
+				<fileset dir="${spring.root}/lib">
+					<include name="hsqldb/hsqldb.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/dropTables.txt" />
+		</sql>
+	</target>
+
+	<target name="createHSQLTables" if="useHSQL">
+		<echo message="Create tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}" onerror="continue">
+			<classpath>
+				<fileset dir="${spring.root}/lib">
+					<include name="hsqldb/hsqldb.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/hsqldb/initDB.txt" />
+		</sql>
+	</target>
+
+	<target name="dropMYSQLTables" if="useMYSQL">
+		<echo message="Dropping tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}" onerror="continue">
+			<classpath>
+				<fileset dir="${db.dir}/mysql">
+					<include name="mysql*.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/dropTables.txt" />
+		</sql>
+	</target>
+
+	<target name="createMYSQLTables" if="useMYSQL">
+		<echo message="Creating tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}" onerror="continue">
+			<classpath>
+				<fileset dir="${db.dir}/mysql">
+					<include name="mysql*.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/mysql/initDB.txt" />
+		</sql>
+	</target>
+
+	<target name="emptyTables">
+		<echo message="Emptying tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}">
+			<classpath>
+				<fileset dir="${spring.root}/lib">
+					<include name="hsqldb/hsqldb.jar" />
+				</fileset>
+				<fileset dir="${db.dir}/mysql">
+					<include name="mysql*.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/emptyDB.txt" />
+		</sql>
+	</target>
+
+	<target name="populateTables">
+		<echo message="Populating tables using: ${db.driver} ${db.url}" />
+		<sql driver="${db.driver}" url="${db.url}" userid="${db.user}" password="${db.pw}">
+			<classpath>
+				<fileset dir="${spring.root}/lib">
+					<include name="hsqldb/hsqldb.jar" />
+				</fileset>
+				<fileset dir="${db.dir}/mysql">
+					<include name="mysql*.jar" />
+				</fileset>
+			</classpath>
+			<transaction src="${db.dir}/populateDB.txt" />
+		</sql>
+	</target>
+
+	<target name="all" depends="dropHSQLTables,createHSQLTables,dropMYSQLTables,createMYSQLTables,emptyTables,populateTables" />
+
+</project>
\ No newline at end of file
diff --git a/db/dropTables.txt b/db/dropTables.txt
new file mode 100644
index 0000000000000000000000000000000000000000..90ae6329f90859d5945753ba28441d489b0384f7
--- /dev/null
+++ b/db/dropTables.txt
@@ -0,0 +1,7 @@
+DROP TABLE visits;
+DROP TABLE pets;
+DROP TABLE owners;
+DROP TABLE types;
+DROP TABLE vet_specialties;
+DROP TABLE specialties;
+DROP TABLE vets;
diff --git a/db/emptyDB.txt b/db/emptyDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..d5dd8728c0eea31ff1187e82abec8a3c3d077ea1
--- /dev/null
+++ b/db/emptyDB.txt
@@ -0,0 +1,7 @@
+DELETE FROM vets;
+DELETE FROM specialties;
+DELETE FROM vet_specialties;
+DELETE FROM types;
+DELETE FROM owners;
+DELETE FROM pets;
+DELETE FROM visits;
diff --git a/db/mysql/createDB.txt b/db/mysql/createDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5b4b3859e9aedc6bc4fac16fc3e82297eccb7da0
--- /dev/null
+++ b/db/mysql/createDB.txt
@@ -0,0 +1,3 @@
+CREATE DATABASE petclinic;
+
+GRANT ALL PRIVILEGES ON petclinic.* TO pc@localhost IDENTIFIED BY 'pc';
\ No newline at end of file
diff --git a/db/mysql/dropDB.txt b/db/mysql/dropDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e1209da0e5eb48f7aaef810f0a2bb7b8a9fc12fc
--- /dev/null
+++ b/db/mysql/dropDB.txt
@@ -0,0 +1 @@
+DROP DATABASE petclinic;
diff --git a/db/mysql/initDB.txt b/db/mysql/initDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0007ee3a3396b50887b9bd4a202c45857cb85e29
--- /dev/null
+++ b/db/mysql/initDB.txt
@@ -0,0 +1,58 @@
+USE petclinic;
+
+CREATE TABLE vets (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  first_name VARCHAR(30),
+  last_name VARCHAR(30),
+  INDEX(last_name)
+) engine=InnoDB;
+
+CREATE TABLE specialties (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  name VARCHAR(80),
+  INDEX(name)
+) engine=InnoDB;
+
+CREATE TABLE vet_specialties (
+  vet_id INT(4) UNSIGNED NOT NULL,
+  specialty_id INT(4) UNSIGNED NOT NULL
+) engine=InnoDB;
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_vets FOREIGN KEY (vet_id) REFERENCES vets(id);
+ALTER TABLE vet_specialties ADD CONSTRAINT fk_vet_specialties_specialties FOREIGN KEY (specialty_id) REFERENCES specialties(id);
+
+CREATE TABLE types (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  name VARCHAR(80),
+  INDEX(name)
+) engine=InnoDB;
+
+CREATE TABLE owners (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  first_name VARCHAR(30),
+  last_name VARCHAR(30),
+  address VARCHAR(255),
+  city VARCHAR(80),
+  telephone VARCHAR(20),
+  INDEX(last_name)
+) engine=InnoDB;
+
+CREATE TABLE pets (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  name VARCHAR(30),
+  birth_date DATE,
+  type_id INT(4) UNSIGNED NOT NULL,
+  owner_id INT(4) UNSIGNED NOT NULL,
+  INDEX(name)
+) engine=InnoDB;
+ALTER TABLE pets ADD CONSTRAINT fk_pets_owners FOREIGN KEY (owner_id) REFERENCES owners(id);
+ALTER TABLE pets ADD CONSTRAINT fk_pets_types FOREIGN KEY (type_id) REFERENCES types(id);
+CREATE INDEX pets_name ON pets(name);
+
+CREATE TABLE visits (
+  id INT(4) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+  pet_id INT(4) UNSIGNED NOT NULL,
+  visit_date DATE,
+  description VARCHAR(255),
+  INDEX(pet_id)
+) engine=InnoDB;
+ALTER TABLE visits ADD CONSTRAINT fk_visits_pets FOREIGN KEY (pet_id) REFERENCES pets(id);
diff --git a/db/mysql/petclinic_db_setup_mysql.txt b/db/mysql/petclinic_db_setup_mysql.txt
new file mode 100644
index 0000000000000000000000000000000000000000..66727e190aa96fb238d9ccd099ea2327789a69f9
--- /dev/null
+++ b/db/mysql/petclinic_db_setup_mysql.txt
@@ -0,0 +1,22 @@
+================================================================================
+===        Spring PetClinic sample application - MySQL Configuration         ===
+================================================================================
+
+@author Sam Brannen
+
+--------------------------------------------------------------------------------
+
+1) Download and install the MySQL database (e.g., MySQL Community Server 5.1.x),
+   which can be found here: http://dev.mysql.com/downloads/
+
+2) Download Connector/J, the MySQL JDBC driver (e.g., Connector/J 5.1.x), which
+   can be found here: http://dev.mysql.com/downloads/connector/j/
+   Copy the Connector/J JAR file (e.g., mysql-connector-java-5.1.5-bin.jar) into
+   the db/mysql directory.
+
+3) Create the PetClinic database and user by executing the "db/mysql/createDB.txt"
+   script.
+
+4) Open "src/main/resources/jdbc.properties"; comment out all properties in the
+   "HSQL Settings" section; uncomment all properties in the "MySQL Settings"
+   section.
\ No newline at end of file
diff --git a/db/mysql/petclinic_tomcat_mysql.xml b/db/mysql/petclinic_tomcat_mysql.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d1c5a3b04e3ba2d597e8369d3f57ed0058095eb5
--- /dev/null
+++ b/db/mysql/petclinic_tomcat_mysql.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Context path="/petclinic" docBase="petclinic" debug="4" reloadable="true">
+  <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_petclinic_log." suffix=".txt" timestamp="true"/>
+
+  <!-- Define a database connection pool for MYSQL -->
+  <Resource name="jdbc/petclinicMYSQL" auth="Container" type="javax.sql.DataSource"/>
+  <ResourceParams name="jdbc/petclinicMYSQL">
+    <parameter>
+      <name>factory</name>
+      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+    </parameter>
+    
+    <parameter>
+      <name>driverClassName</name>
+      <value>org.gjt.mm.mysql.Driver</value>
+    </parameter>
+    <!--
+          The JDBC connection url for connecting to your MySQL dB.
+          The autoReconnect=true argument to the url makes sure that the
+          mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
+          connection.  mysqld by default closes idle connections after 8 hours.
+    -->
+    <parameter>
+      <name>url</name>
+      <value>jdbc:mysql://localhost:3306/petclinic?autoReconnect=true</value>
+    </parameter>
+    <parameter>
+      <name>username</name>
+      <value>pc</value>
+    </parameter>
+    <parameter>
+      <name>password</name>
+      <value>pc</value>
+    </parameter>
+    
+    <parameter>
+      <name>maxActive</name>
+      <value>50</value>
+    </parameter>
+    <parameter>
+      <name>maxIdle</name>
+      <value>10</value>
+    </parameter>
+    <parameter>
+      <name>maxWait</name>
+      <value>10000</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandoned</name>
+      <value>true</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandonedTimeout</name>
+      <value>60</value>
+    </parameter>
+    <parameter>
+      <name>logAbandoned</name>
+      <value>true</value>
+    </parameter>
+  </ResourceParams>
+
+  
+</Context>
diff --git a/db/petclinic_tomcat_all.xml b/db/petclinic_tomcat_all.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed45c5cd339ba2ebb863aefda5a047ca54788698
--- /dev/null
+++ b/db/petclinic_tomcat_all.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Context path="/petclinic" docBase="petclinic" debug="4" reloadable="true">
+  <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_petclinic_log." suffix=".txt" timestamp="true"/>
+
+  <!-- Define a database connection pool for HSQL -->
+  <!-- NOTE: make sure that a copy of hsqldb.jar is in the TOMCAT common/lib directory -->
+  <Resource name="jdbc/petclinicHSQL" auth="Container" type="javax.sql.DataSource"/>
+  <ResourceParams name="jdbc/petclinicHSQL">
+    <parameter>
+      <name>factory</name>
+      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+    </parameter>
+    
+    <parameter>
+      <name>driverClassName</name>
+      <value>org.hsqldb.jdbcDriver</value>
+    </parameter>
+    <parameter>
+      <name>url</name>
+      <value>jdbc:hsqldb:hsql://localhost:9001</value>
+    </parameter>
+    <parameter>
+      <name>username</name>
+      <value>sa</value>
+    </parameter>
+    
+    <parameter>
+      <name>maxActive</name>
+      <value>50</value>
+    </parameter>
+    <parameter>
+      <name>maxIdle</name>
+      <value>10</value>
+    </parameter>
+    <parameter>
+      <name>maxWait</name>
+      <value>10000</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandoned</name>
+      <value>true</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandonedTimeout</name>
+      <value>60</value>
+    </parameter>
+    <parameter>
+      <name>logAbandoned</name>
+      <value>true</value>
+    </parameter>
+  </ResourceParams>
+
+  <!-- Define a database connection pool for MYSQL -->
+  <Resource name="jdbc/petclinicMYSQL" auth="Container" type="javax.sql.DataSource"/>
+  <ResourceParams name="jdbc/petclinicMYSQL">
+    <parameter>
+      <name>factory</name>
+      <value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
+    </parameter>
+    
+    <parameter>
+      <name>driverClassName</name>
+      <value>org.gjt.mm.mysql.Driver</value>
+    </parameter>
+    <!--
+          The JDBC connection url for connecting to your MySQL dB.
+          The autoReconnect=true argument to the url makes sure that the
+          mm.mysql JDBC Driver will automatically reconnect if mysqld closed the
+          connection.  mysqld by default closes idle connections after 8 hours.
+    -->
+    <parameter>
+      <name>url</name>
+      <value>jdbc:mysql://localhost:3306/petclinic?autoReconnect=true</value>
+    </parameter>
+    <parameter>
+      <name>username</name>
+      <value>pc</value>
+    </parameter>
+    <parameter>
+      <name>password</name>
+      <value>pc</value>
+    </parameter>
+    
+    <parameter>
+      <name>maxActive</name>
+      <value>50</value>
+    </parameter>
+    <parameter>
+      <name>maxIdle</name>
+      <value>10</value>
+    </parameter>
+    <parameter>
+      <name>maxWait</name>
+      <value>10000</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandoned</name>
+      <value>true</value>
+    </parameter>
+    <parameter>
+      <name>removeAbandonedTimeout</name>
+      <value>60</value>
+    </parameter>
+    <parameter>
+      <name>logAbandoned</name>
+      <value>true</value>
+    </parameter>
+  </ResourceParams>
+
+  
+</Context>
diff --git a/db/populateDB.txt b/db/populateDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1bf0c4a6edb05ac0f8bb2382d19367d8b15e85cf
--- /dev/null
+++ b/db/populateDB.txt
@@ -0,0 +1,53 @@
+INSERT INTO vets VALUES (1, 'James', 'Carter');
+INSERT INTO vets VALUES (2, 'Helen', 'Leary');
+INSERT INTO vets VALUES (3, 'Linda', 'Douglas');
+INSERT INTO vets VALUES (4, 'Rafael', 'Ortega');
+INSERT INTO vets VALUES (5, 'Henry', 'Stevens');
+INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins');
+
+INSERT INTO specialties VALUES (1, 'radiology');
+INSERT INTO specialties VALUES (2, 'surgery');
+INSERT INTO specialties VALUES (3, 'dentistry');
+
+INSERT INTO vet_specialties VALUES (2, 1);
+INSERT INTO vet_specialties VALUES (3, 2);
+INSERT INTO vet_specialties VALUES (3, 3);
+INSERT INTO vet_specialties VALUES (4, 2);
+INSERT INTO vet_specialties VALUES (5, 1);
+
+INSERT INTO types VALUES (1, 'cat');
+INSERT INTO types VALUES (2, 'dog');
+INSERT INTO types VALUES (3, 'lizard');
+INSERT INTO types VALUES (4, 'snake');
+INSERT INTO types VALUES (5, 'bird');
+INSERT INTO types VALUES (6, 'hamster');
+
+INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
+INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
+INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
+INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
+INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
+INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
+INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
+INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
+INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
+INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
+
+INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1);
+INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2);
+INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3);
+INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3);
+INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4);
+INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5);
+INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6);
+INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6);
+INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7);
+INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8);
+INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9);
+INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10);
+INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10);
+
+INSERT INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot');
+INSERT INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot');
+INSERT INTO visits VALUES (3, 8, '1996-06-04', 'neutered');
+INSERT INTO visits VALUES (4, 7, '1996-09-04', 'spayed');
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9b79897e2e09978ce9abeb5d9319dd632547abe
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,233 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>org.springframework.samples</groupId>
+	<artifactId>org.springframework.samples.petclinic</artifactId>
+	<name>petclinic-classic</name>
+	<packaging>war</packaging>
+	<version>1.0.0-SNAPSHOT</version>
+	<properties>
+		<spring.version>3.0.0.RC2</spring.version>
+		<slf4j.version>1.5.6</slf4j.version>
+	</properties>
+	<dependencies>
+		<dependency>
+			<groupId>com.oracle.toplink.essentials</groupId>
+			<artifactId>com.springsource.oracle.toplink.essentials</artifactId>
+			<version>2.0.0.b41-beta2</version>
+		</dependency>
+		<dependency>
+			<groupId>com.sun.syndication</groupId>
+			<artifactId>com.springsource.com.sun.syndication</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.persistence</groupId>
+			<artifactId>com.springsource.javax.persistence</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>com.springsource.javax.servlet</artifactId>
+			<version>2.5.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>com.springsource.javax.servlet.jsp</artifactId>
+			<version>2.1.0</version>
+			<scope>provided</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.servlet</groupId>
+			<artifactId>com.springsource.javax.servlet.jsp.jstl</artifactId>
+			<version>1.2.0</version>
+		</dependency>
+		<dependency>
+			<groupId>javax.xml.bind</groupId>
+			<artifactId>com.springsource.javax.xml.bind</artifactId>
+			<version>2.1.7</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>com.springsource.org.apache.commons.dbcp</artifactId>
+			<version>1.2.2.osgi</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.log4j</groupId>
+			<artifactId>com.springsource.org.apache.log4j</artifactId>
+			<version>1.2.15</version>
+		</dependency>		
+		<dependency>
+			<groupId>org.apache.openjpa</groupId>
+			<artifactId>com.springsource.org.apache.openjpa</artifactId>
+			<version>1.1.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.taglibs</groupId>
+			<artifactId>com.springsource.org.apache.taglibs.standard</artifactId>
+			<version>1.1.2</version>
+		</dependency>		
+		<dependency>
+			<groupId>org.aspectj</groupId>
+			<artifactId>com.springsource.org.aspectj.weaver</artifactId>
+			<version>1.6.3.RELEASE</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>com.springsource.org.hibernate</artifactId>
+			<version>3.3.1.GA</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>com.springsource.org.hibernate.ejb</artifactId>
+			<version>3.4.0.GA</version>
+		</dependency>
+		<dependency>
+			<groupId>org.hsqldb</groupId>
+			<artifactId>com.springsource.org.hsqldb</artifactId>
+			<version>1.8.0.9</version>
+		</dependency>
+		<dependency>
+			<groupId>org.jdom</groupId>
+			<artifactId>com.springsource.org.jdom</artifactId>
+			<version>1.0.0</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>org.springframework.asm</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>org.springframework.orm</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>org.springframework.oxm</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>org.springframework.web.servlet</artifactId>
+			<version>${spring.version}</version>
+		</dependency>
+		<!-- Test dependencies -->
+		<dependency>
+			<groupId>org.junit</groupId>
+			<artifactId>com.springsource.org.junit</artifactId>
+			<version>4.5.0</version>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>org.springframework.test</artifactId>
+			<version>${spring.version}</version>
+            <scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>javax.transaction</groupId>
+			<artifactId>com.springsource.javax.transaction</artifactId>
+			<version>1.1.0</version>
+            <scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.hibernate</groupId>
+			<artifactId>com.springsource.org.hibernate.annotations</artifactId>
+			<version>3.4.0.GA</version>
+			<scope>test</scope>
+		</dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>com.springsource.slf4j.api</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>com.springsource.slf4j.log4j</artifactId>
+            <version>${slf4j.version}</version>
+            <scope>provided</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>log4j</groupId>
+                    <artifactId>log4j</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.log4j</groupId>
+                    <artifactId>com.springsource.org.apache.log4j</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+	</dependencies>
+	<repositories>
+		<repository>
+			<id>com.springsource.repository.bundles.release</id>
+			<name>SpringSource Enterprise Bundle Repository - SpringSource Releases</name>
+			<url>http://repository.springsource.com/maven/bundles/release</url>
+		</repository>
+		<repository>
+			<id>com.springsource.repository.bundles.milestone</id>
+			<name>SpringSource Enterprise Bundle Repository - SpringSource Milestones</name>
+			<url>http://repository.springsource.com/maven/bundles/milestone</url>
+		</repository>
+		<repository>
+			<id>com.springsource.repository.bundles.external</id>
+			<name>SpringSource Enterprise Bundle Repository - External Releases</name>
+			<url>http://repository.springsource.com/maven/bundles/external</url>
+		</repository>
+		<repository>
+			<id>com.springsource.repository.bundles.snapshot</id>
+			<name>SpringSource Enterprise Bundle Repository - Snapshot Releases</name>
+			<url>http://repository.springsource.com/maven/bundles/snapshot</url>
+		</repository>
+        <repository>
+            <id>spring-release</id>
+            <name>Spring Portfolio Release Repository</name>
+            <url>http://maven.springframework.org/release</url>
+        </repository>
+        <repository>
+            <id>spring-external</id>
+            <name>Spring Portfolio External Repository</name>
+            <url>http://maven.springframework.org/external</url>
+        </repository>
+        <repository>
+            <id>spring-milestone</id>
+            <name>Spring Portfolio Milestone Repository</name>
+            <url>http://maven.springframework.org/milestone</url>
+        </repository>
+	</repositories>
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-compiler-plugin</artifactId>
+				<configuration>
+					<source>1.5</source>
+					<target>1.5</target>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-dependency-plugin</artifactId>
+				<executions>
+					<execution>
+						<id>install</id>
+						<phase>install</phase>
+						<goals>
+							<goal>sources</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+		</plugins>
+	</build>
+</project>
\ No newline at end of file
diff --git a/readme.txt b/readme.txt
index aee19b7ffee3809815d379f75d6452d0de611ec2..ae1fb2511bc74353ff05a861875e6289132ce043 100644
--- a/readme.txt
+++ b/readme.txt
@@ -44,22 +44,20 @@ pooling.
 === Build and Deployment
 ==========================================================================
 
-The Spring PetClinic sample application is built using Spring Build, which
-is a custom build solution based on Ant and Ivy for dependency management.
-For deployment, the web application needs to be built with Apache Ant 1.6
-or higher. When the project is first built, Spring Build will use Ivy to
-automatically download all required dependencies. Thus the initial build
+The Spring PetClinic sample application is built using Maven.
+When the project is first built, Maven will automatically download all required
+dependencies (if these haven't been downloaded before). Thus the initial build
 may take a few minutes depending on the speed of your Internet connection,
 but subsequent builds will be much faster.
 
 Available build commands:
 
-- ant clean        --> cleans the project
-- ant clean test   --> cleans the project and runs all tests
-- ant clean jar    --> cleans the project and builds the WAR
+- mvn clean         --> cleans the project
+- mvn clean test    --> cleans the project and runs all tests
+- mvn clean package --> cleans the project and builds the WAR
 
-After building the project with "ant clean jar", you will find the
-resulting WAR file in the "target/artifacts" directory. By default, an
+After building the project with "mvn clean package", you will find the
+resulting WAR file in the "target/" directory. By default, an
 embedded HSQLDB instance in configured. No other steps are necessary to
 get the data source up and running: you can simply deploy the built WAR
 file directly to your Servlet container.
diff --git a/src/main/java/org/springframework/samples/petclinic/BaseEntity.java b/src/main/java/org/springframework/samples/petclinic/BaseEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb68af4fc01f870b25db873e05091890b96fca29
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/BaseEntity.java
@@ -0,0 +1,27 @@
+package org.springframework.samples.petclinic;
+
+/**
+ * Simple JavaBean domain object with an id property.
+ * Used as a base class for objects needing this property.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ */
+public class BaseEntity {
+
+	private Integer id;
+	
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public boolean isNew() {
+		return (this.id == null);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Clinic.java b/src/main/java/org/springframework/samples/petclinic/Clinic.java
new file mode 100644
index 0000000000000000000000000000000000000000..e48e8507b352c7bc757d1853217bd947ea5e12fb
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Clinic.java
@@ -0,0 +1,82 @@
+package org.springframework.samples.petclinic;
+
+import java.util.Collection;
+
+import org.springframework.dao.DataAccessException;
+
+/**
+ * The high-level PetClinic business interface.
+ *
+ * <p>This is basically a data access object.
+ * PetClinic doesn't have a dedicated business facade.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ */
+public interface Clinic {
+
+	/**
+	 * Retrieve all <code>Vet</code>s from the data store.
+	 * @return a <code>Collection</code> of <code>Vet</code>s
+	 */
+	Collection<Vet> getVets() throws DataAccessException;
+
+	/**
+	 * Retrieve all <code>PetType</code>s from the data store.
+	 * @return a <code>Collection</code> of <code>PetType</code>s
+	 */
+	Collection<PetType> getPetTypes() throws DataAccessException;
+
+	/**
+	 * Retrieve <code>Owner</code>s from the data store by last name,
+	 * returning all owners whose last name <i>starts</i> with the given name.
+	 * @param lastName Value to search for
+	 * @return a <code>Collection</code> of matching <code>Owner</code>s
+	 * (or an empty <code>Collection</code> if none found)
+	 */
+	Collection<Owner> findOwners(String lastName) throws DataAccessException;
+
+	/**
+	 * Retrieve an <code>Owner</code> from the data store by id.
+	 * @param id the id to search for
+	 * @return the <code>Owner</code> if found
+	 * @throws org.springframework.dao.DataRetrievalFailureException if not found
+	 */
+	Owner loadOwner(int id) throws DataAccessException;
+
+	/**
+	 * Retrieve a <code>Pet</code> from the data store by id.
+	 * @param id the id to search for
+	 * @return the <code>Pet</code> if found
+	 * @throws org.springframework.dao.DataRetrievalFailureException if not found
+	 */
+	Pet loadPet(int id) throws DataAccessException;
+
+	/**
+	 * Save an <code>Owner</code> to the data store, either inserting or updating it.
+	 * @param owner the <code>Owner</code> to save
+	 * @see BaseEntity#isNew
+	 */
+	void storeOwner(Owner owner) throws DataAccessException;
+
+	/**
+	 * Save a <code>Pet</code> to the data store, either inserting or updating it.
+	 * @param pet the <code>Pet</code> to save
+	 * @see BaseEntity#isNew
+	 */
+	void storePet(Pet pet) throws DataAccessException;
+
+	/**
+	 * Save a <code>Visit</code> to the data store, either inserting or updating it.
+	 * @param visit the <code>Visit</code> to save
+	 * @see BaseEntity#isNew
+	 */
+	void storeVisit(Visit visit) throws DataAccessException;
+
+	/**
+	 * Deletes a <code>Pet</code> from the data store.
+	 */
+	void deletePet(int id) throws DataAccessException;
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/NamedEntity.java b/src/main/java/org/springframework/samples/petclinic/NamedEntity.java
new file mode 100644
index 0000000000000000000000000000000000000000..40c5931d86d1ac03f157ced1e63a189274820567
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/NamedEntity.java
@@ -0,0 +1,28 @@
+package org.springframework.samples.petclinic;
+
+/**
+ * Simple JavaBean domain object adds a name property to <code>BaseEntity</code>.
+ * Used as a base class for objects needing these properties.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ */
+public class NamedEntity extends BaseEntity {
+
+	private String name;
+	
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return this.name;
+	}
+
+	@Override
+	public String toString() {
+		return this.getName();
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Owner.java b/src/main/java/org/springframework/samples/petclinic/Owner.java
new file mode 100644
index 0000000000000000000000000000000000000000..75ea3bc064c570ff96f17b7fc8de77bfd64d3342
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Owner.java
@@ -0,0 +1,127 @@
+package org.springframework.samples.petclinic;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+import org.springframework.core.style.ToStringCreator;
+
+/**
+ * Simple JavaBean domain object representing an owner.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ */
+public class Owner extends Person {
+
+	private String address;
+
+	private String city;
+
+	private String telephone;
+
+	private Set<Pet> pets;
+
+
+	public String getAddress() {
+		return this.address;
+	}
+
+	public void setAddress(String address) {
+		this.address = address;
+	}
+
+	public String getCity() {
+		return this.city;
+	}
+
+	public void setCity(String city) {
+		this.city = city;
+	}
+
+	public String getTelephone() {
+		return this.telephone;
+	}
+
+	public void setTelephone(String telephone) {
+		this.telephone = telephone;
+	}
+
+	protected void setPetsInternal(Set<Pet> pets) {
+		this.pets = pets;
+	}
+
+	protected Set<Pet> getPetsInternal() {
+		if (this.pets == null) {
+			this.pets = new HashSet<Pet>();
+		}
+		return this.pets;
+	}
+
+	public List<Pet> getPets() {
+		List<Pet> sortedPets = new ArrayList<Pet>(getPetsInternal());
+		PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
+		return Collections.unmodifiableList(sortedPets);
+	}
+
+	public void addPet(Pet pet) {
+		getPetsInternal().add(pet);
+		pet.setOwner(this);
+	}
+
+	/**
+	 * Return the Pet with the given name, or null if none found for this Owner.
+	 *
+	 * @param name to test
+	 * @return true if pet name is already in use
+	 */
+	public Pet getPet(String name) {
+		return getPet(name, false);
+	}
+
+	/**
+	 * Return the Pet with the given name, or null if none found for this Owner.
+	 *
+	 * @param name to test
+	 * @return true if pet name is already in use
+	 */
+	public Pet getPet(String name, boolean ignoreNew) {
+		name = name.toLowerCase();
+		for (Pet pet : getPetsInternal()) {
+			if (!ignoreNew || !pet.isNew()) {
+				String compName = pet.getName();
+				compName = compName.toLowerCase();
+				if (compName.equals(name)) {
+					return pet;
+				}
+			}
+		}
+		return null;
+	}
+
+	@Override
+	public String toString() {
+		return new ToStringCreator(this)
+
+		.append("id", this.getId())
+
+		.append("new", this.isNew())
+
+		.append("lastName", this.getLastName())
+
+		.append("firstName", this.getFirstName())
+
+		.append("address", this.address)
+
+		.append("city", this.city)
+
+		.append("telephone", this.telephone)
+
+		.toString();
+	}
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Person.java b/src/main/java/org/springframework/samples/petclinic/Person.java
new file mode 100644
index 0000000000000000000000000000000000000000..da7974a7de77a6e64815952f8466c6cbf51bcb1e
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Person.java
@@ -0,0 +1,32 @@
+package org.springframework.samples.petclinic;
+
+/**
+ * Simple JavaBean domain object representing an person.
+ *
+ * @author Ken Krebs
+ */
+public class Person extends BaseEntity {
+
+	private String firstName;
+
+	private String lastName;
+
+	public String getFirstName() {
+		return this.firstName;
+	}
+
+	public void setFirstName(String firstName) {
+		this.firstName = firstName;
+	}
+
+	public String getLastName() {
+		return this.lastName;
+	}
+
+	public void setLastName(String lastName) {
+		this.lastName = lastName;
+	}
+
+
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Pet.java b/src/main/java/org/springframework/samples/petclinic/Pet.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5294b5ca9f3385ae9f4aea883abb48dd2e7402a
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Pet.java
@@ -0,0 +1,77 @@
+package org.springframework.samples.petclinic;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+
+/**
+ * Simple JavaBean business object representing a pet.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ */
+public class Pet extends NamedEntity {
+
+	private Date birthDate;
+
+	private PetType type;
+
+	private Owner owner;
+
+	private Set<Visit> visits;
+
+
+	public void setBirthDate(Date birthDate) {
+		this.birthDate = birthDate;
+	}
+
+	public Date getBirthDate() {
+		return this.birthDate;
+	}
+
+	public void setType(PetType type) {
+		this.type = type;
+	}
+
+	public PetType getType() {
+		return this.type;
+	}
+
+	protected void setOwner(Owner owner) {
+		this.owner = owner;
+	}
+
+	public Owner getOwner() {
+		return this.owner;
+	}
+
+	protected void setVisitsInternal(Set<Visit> visits) {
+		this.visits = visits;
+	}
+
+	protected Set<Visit> getVisitsInternal() {
+		if (this.visits == null) {
+			this.visits = new HashSet<Visit>();
+		}
+		return this.visits;
+	}
+
+	public List<Visit> getVisits() {
+		List<Visit> sortedVisits = new ArrayList<Visit>(getVisitsInternal());
+		PropertyComparator.sort(sortedVisits, new MutableSortDefinition("date", false, false));
+		return Collections.unmodifiableList(sortedVisits);
+	}
+
+	public void addVisit(Visit visit) {
+		getVisitsInternal().add(visit);
+		visit.setPet(this);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/PetType.java b/src/main/java/org/springframework/samples/petclinic/PetType.java
new file mode 100644
index 0000000000000000000000000000000000000000..aaadc5c44d099c5d8c3726bbe411a2b335aab2bc
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/PetType.java
@@ -0,0 +1,8 @@
+package org.springframework.samples.petclinic;
+
+/**
+ * @author Juergen Hoeller
+ */
+public class PetType extends NamedEntity {
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Specialty.java b/src/main/java/org/springframework/samples/petclinic/Specialty.java
new file mode 100644
index 0000000000000000000000000000000000000000..d19ccaba96e42d5f15360f8d2cb4984373c717a3
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Specialty.java
@@ -0,0 +1,10 @@
+package org.springframework.samples.petclinic;
+
+/**
+ * Models a {@link Vet Vet's} specialty (for example, dentistry).
+ * 
+ * @author Juergen Hoeller
+ */
+public class Specialty extends NamedEntity {
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Vet.java b/src/main/java/org/springframework/samples/petclinic/Vet.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c7c8da0b1c32e46cd84a7a8311ba457148dcd89
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Vet.java
@@ -0,0 +1,52 @@
+package org.springframework.samples.petclinic;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import javax.xml.bind.annotation.XmlElement;
+
+import org.springframework.beans.support.MutableSortDefinition;
+import org.springframework.beans.support.PropertyComparator;
+
+/**
+ * Simple JavaBean domain object representing a veterinarian.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ * @author Arjen Poutsma
+ */
+public class Vet extends Person {
+
+	private Set<Specialty> specialties;
+
+
+	protected void setSpecialtiesInternal(Set<Specialty> specialties) {
+		this.specialties = specialties;
+	}
+
+	protected Set<Specialty> getSpecialtiesInternal() {
+		if (this.specialties == null) {
+			this.specialties = new HashSet<Specialty>();
+		}
+		return this.specialties;
+	}
+
+	@XmlElement
+	public List<Specialty> getSpecialties() {
+		List<Specialty> sortedSpecs = new ArrayList<Specialty>(getSpecialtiesInternal());
+		PropertyComparator.sort(sortedSpecs, new MutableSortDefinition("name", true, true));
+		return Collections.unmodifiableList(sortedSpecs);
+	}
+
+	public int getNrOfSpecialties() {
+		return getSpecialtiesInternal().size();
+	}
+
+	public void addSpecialty(Specialty specialty) {
+		getSpecialtiesInternal().add(specialty);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Vets.java b/src/main/java/org/springframework/samples/petclinic/Vets.java
new file mode 100644
index 0000000000000000000000000000000000000000..2e3b25e270a436efc43b2a68a3a93d988764ca84
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Vets.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Simple JavaBean domain object representing a list of veterinarians. Mostly here to be used for the 'vets'
+ * {@link org.springframework.web.servlet.view.xml.MarshallingView}.
+ *
+ * @author Arjen Poutsma
+ */
+@XmlRootElement
+public class Vets {
+
+	private List<Vet> vets;
+
+	@XmlElement
+	public List<Vet> getVetList() {
+		if (vets == null) {
+			vets = new ArrayList<Vet>();
+		}
+		return vets;
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/Visit.java b/src/main/java/org/springframework/samples/petclinic/Visit.java
new file mode 100644
index 0000000000000000000000000000000000000000..c42bdcee5e5d3c9bdbdf4c140bf9b45d4683ad1f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/Visit.java
@@ -0,0 +1,70 @@
+package org.springframework.samples.petclinic;
+
+import java.util.Date;
+
+/**
+ * Simple JavaBean domain object representing a visit.
+ *
+ * @author Ken Krebs
+ */
+public class Visit extends BaseEntity {
+
+	/** Holds value of property date. */
+	private Date date;
+
+	/** Holds value of property description. */
+	private String description;
+
+	/** Holds value of property pet. */
+	private Pet pet;
+
+
+	/** Creates a new instance of Visit for the current date */
+	public Visit() {
+		this.date = new Date();
+	}
+
+
+	/** Getter for property date.
+	 * @return Value of property date.
+	 */
+	public Date getDate() {
+		return this.date;
+	}
+
+	/** Setter for property date.
+	 * @param date New value of property date.
+	 */
+	public void setDate(Date date) {
+		this.date = date;
+	}
+
+	/** Getter for property description.
+	 * @return Value of property description.
+	 */
+	public String getDescription() {
+		return this.description;
+	}
+
+	/** Setter for property description.
+	 * @param description New value of property description.
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+
+	/** Getter for property pet.
+	 * @return Value of property pet.
+	 */
+	public Pet getPet() {
+		return this.pet;
+	}
+
+	/** Setter for property pet.
+	 * @param pet New value of property pet.
+	 */
+	public void setPet(Pet pet) {
+		this.pet = pet;
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..26d32359fc445e43d6fe7282048a1b2c23a396c1
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/aspects/AbstractTraceAspect.java
@@ -0,0 +1,31 @@
+package org.springframework.samples.petclinic.aspects;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+
+/**
+ * Aspect to illustrate Spring-driven load-time weaving.
+ *
+ * @author Ramnivas Laddad
+ * @since 2.5
+ */
+@Aspect
+public abstract class AbstractTraceAspect {
+
+	private static final Log logger = LogFactory.getLog(AbstractTraceAspect.class);
+	
+	@Pointcut
+	public abstract void traced();
+	
+	@Before("traced()")
+	public void trace(JoinPoint.StaticPart jpsp) {
+		if (logger.isTraceEnabled()) {
+			logger.trace("Entering " + jpsp.getSignature().toLongString());
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..2de4cb41d0a15d94aa0c4b8f39a3accd30ba5558
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/aspects/CallMonitoringAspect.java
@@ -0,0 +1,81 @@
+package org.springframework.samples.petclinic.aspects;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+
+import org.springframework.jmx.export.annotation.ManagedAttribute;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.util.StopWatch;
+
+/**
+ * Simple AspectJ aspect that monitors call count and call invocation time.
+ * Implements the CallMonitor management interface.
+ *
+ * @author Rob Harrop
+ * @author Juergen Hoeller
+ * @since 2.5
+ */
+@ManagedResource("petclinic:type=CallMonitor")
+@Aspect
+public class CallMonitoringAspect {
+
+	private boolean isEnabled = true;
+
+	private int callCount = 0;
+
+	private long accumulatedCallTime = 0;
+
+
+	@ManagedAttribute
+	public void setEnabled(boolean enabled) {
+		isEnabled = enabled;
+	}
+
+	@ManagedAttribute
+	public boolean isEnabled() {
+		return isEnabled;
+	}
+
+	@ManagedOperation
+	public void reset() {
+		this.callCount = 0;
+		this.accumulatedCallTime = 0;
+	}
+
+	@ManagedAttribute
+	public int getCallCount() {
+		return callCount;
+	}
+
+	@ManagedAttribute
+	public long getCallTime() {
+		return (this.callCount > 0 ? this.accumulatedCallTime / this.callCount : 0);
+	}
+
+
+	@Around("within(@org.springframework.stereotype.Service *)")
+	public Object invoke(ProceedingJoinPoint joinPoint) throws Throwable {
+		if (this.isEnabled) {
+			StopWatch sw = new StopWatch(joinPoint.toShortString());
+
+			sw.start("invoke");
+			try {
+				return joinPoint.proceed();
+			}
+			finally {
+				sw.stop();
+				synchronized (this) {
+					this.callCount++;
+					this.accumulatedCallTime += sw.getTotalTimeMillis();
+				}
+			}
+		}
+
+		else {
+			return joinPoint.proceed();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java b/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java
new file mode 100644
index 0000000000000000000000000000000000000000..e326abfb755ef1e45b3d84b3f827cf042194f7e8
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/aspects/UsageLogAspect.java
@@ -0,0 +1,48 @@
+package org.springframework.samples.petclinic.aspects;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+
+/**
+ * Sample AspectJ annotation-style aspect that saves
+ * every owner name requested to the clinic.
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @since 2.0
+ */
+@Aspect
+public class UsageLogAspect {
+
+	private int historySize = 100;
+
+	// Of course saving all names is not suitable for
+	// production use, but this is a simple example.
+	private List<String> namesRequested = new ArrayList<String>(this.historySize);
+
+
+	public synchronized void setHistorySize(int historySize) {
+		this.historySize = historySize;
+		this.namesRequested = new ArrayList<String>(historySize);
+	}
+
+	@Before("execution(* *.findOwners(String)) && args(name)")
+	public synchronized void logNameRequest(String name) {
+		// Not the most efficient implementation,
+		// but we're aiming to illustrate the power of
+		// @AspectJ AOP, not write perfect code here :-)
+		if (this.namesRequested.size() > this.historySize) {
+			this.namesRequested.remove(0);
+		}
+		this.namesRequested.add(name);
+	}
+
+	public synchronized List<String> getNamesRequested() {
+		return Collections.unmodifiableList(this.namesRequested);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java b/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java
new file mode 100644
index 0000000000000000000000000000000000000000..0454161e65fa0274952230973204e7d547178044
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/config/DbcpDataSourceFactory.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2002-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.samples.petclinic.config;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringWriter;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.core.io.Resource;
+
+/**
+ * A factory that creates a data source fit for use in a system environment. Creates a DBCP simple data source 
+ * from the provided connection properties.
+ *
+ * This factory returns a fully-initialized DataSource implementation. When the DataSource is returned, callers are
+ * guaranteed that the database schema and data will have been loaded by that time.
+ *
+ * Is a FactoryBean, for exposing the fully-initialized DataSource as a Spring bean. See {@link #getObject()}.
+ *
+ * @author Chris Beams
+ * @author Scott Andrews
+ */
+public class DbcpDataSourceFactory implements FactoryBean<DataSource>, DisposableBean {
+
+	// configurable properties
+
+	private String driverClassName;
+
+	private String url;
+
+	private String username;
+
+	private String password;
+
+	private boolean populate;
+
+	private Resource schemaLocation;
+
+	private Resource dataLocation;
+
+	private Resource dropLocation;
+
+	/**
+	 * The object created by this factory.
+	 */
+	private BasicDataSource dataSource;
+
+	public void setDriverClassName(String driverClassName) {
+		this.driverClassName = driverClassName;
+	}
+
+	/**
+	 * The data source connection URL
+	 */
+	public void setUrl(String url) {
+		this.url = url;
+	}
+
+	/**
+	 * The data source username
+	 */
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	/**
+	 *The data source password
+	 */
+	public void setPassword(String password) {
+		this.password = password;
+	}
+
+	/**
+	 * Indicates that the data base should be populated from the schema and data locations
+	 */
+	public void setPopulate(boolean populate) {
+		this.populate = populate;
+	}
+
+	/**
+	 * Sets the location of the file containing the schema DDL to export to the database.
+	 * @param schemaLocation the location of the database schema DDL
+	 */
+	public void setSchemaLocation(Resource schemaLocation) {
+		this.schemaLocation = schemaLocation;
+	}
+
+	/**
+	 * Sets the location of the file containing the data to load into the database.
+	 * @param testDataLocation the location of the data file
+	 */
+	public void setDataLocation(Resource testDataLocation) {
+		this.dataLocation = testDataLocation;
+	}
+
+	/**
+	 * Sets the location of the file containing the drop scripts for the database.
+	 * @param testDataLocation the location of the data file
+	 */
+	public void setDropLocation(Resource testDropLocation) {
+		this.dropLocation = testDropLocation;
+	}
+
+	// implementing FactoryBean
+
+	// this method is called by Spring to expose the DataSource as a bean
+	public DataSource getObject() throws Exception {
+		if (dataSource == null) {
+			initDataSource();
+		}
+		return dataSource;
+	}
+
+	public Class<DataSource> getObjectType() {
+		return DataSource.class;
+	}
+
+	public boolean isSingleton() {
+		return true;
+	}
+
+	// implementing DisposableBean
+
+	public void destroy() throws Exception {
+		dataSource.close();
+	}
+
+	// internal helper methods
+
+	// encapsulates the steps involved in initializing the data source: creating it, and populating it
+	private void initDataSource() {
+		// create the database source first
+		this.dataSource = createDataSource();
+
+		if (this.populate) {
+			// now populate the database by loading the schema and data
+			populateDataSource();
+		}
+	}
+
+	private BasicDataSource createDataSource() {
+		BasicDataSource dataSource = new BasicDataSource();
+		dataSource.setDriverClassName(this.driverClassName);
+		dataSource.setUrl(this.url);
+		dataSource.setUsername(this.username);
+		dataSource.setPassword(this.password);
+		return dataSource;
+	}
+
+	private void populateDataSource() {
+		DatabasePopulator populator = new DatabasePopulator(dataSource);
+		if (dropLocation != null) {
+			try {
+				populator.populate(this.dropLocation);
+			} 
+			catch (Exception e) {
+			   	// ignore
+			}
+		}
+		populator.populate(this.schemaLocation);
+		populator.populate(this.dataLocation);
+	}
+
+	/**
+	 * Populates a in memory data source with data.
+	 */
+	private class DatabasePopulator {
+
+		private DataSource dataSource;
+
+		/**
+		 * Creates a new database populator.
+		 * @param dataSource the data source that will be populated.
+		 */
+		public DatabasePopulator(DataSource dataSource) {
+			this.dataSource = dataSource;
+		}
+
+		/**
+		 * Populate the database executing the statements in the provided resource against the database
+		 * @param sqlFile spring resource containing SQL to run against the db
+		 */
+		public void populate(Resource sqlFile) {
+			Connection connection = null;
+			try {
+				connection = dataSource.getConnection();
+				try {
+					String sql = parseSqlIn(sqlFile);
+					executeSql(sql, connection);
+				} catch (IOException e) {
+					throw new RuntimeException("I/O exception occurred accessing the database schema file", e);
+				} catch (SQLException e) {
+					throw new RuntimeException("SQL exception occurred exporting database schema", e);
+				}
+			} catch (SQLException e) {
+				throw new RuntimeException("SQL exception occurred acquiring connection", e);
+			} finally {
+				if (connection != null) {
+					try {
+						connection.close();
+					} catch (SQLException e) {
+					}
+				}
+			}
+		}
+
+		// utility method to read a .sql txt input stream
+		private String parseSqlIn(Resource resource) throws IOException {
+			InputStream is = null;
+			try {
+				is = resource.getInputStream();
+				BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+
+				StringWriter sw = new StringWriter();
+				BufferedWriter writer = new BufferedWriter(sw);
+
+				for (int c=reader.read(); c != -1; c=reader.read()) {
+					writer.write(c);
+				}
+				writer.flush();
+				return sw.toString();
+
+			} finally {
+				if (is != null) {
+					is.close();
+				}
+			}
+		}
+
+		// utility method to run the parsed sql
+		private void executeSql(String sql, Connection connection) throws SQLException {
+			Statement statement = connection.createStatement();
+			statement.execute(sql);
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java b/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java
new file mode 100644
index 0000000000000000000000000000000000000000..4116385628173b1e9e167390b87460cfea492981
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/hibernate/HibernateClinic.java
@@ -0,0 +1,98 @@
+package org.springframework.samples.petclinic.hibernate;
+
+import java.util.Collection;
+
+import org.hibernate.SessionFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.Vet;
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * Hibernate implementation of the Clinic interface.
+ *
+ * <p>The mappings are defined in "petclinic.hbm.xml", located in the root of the
+ * class path.
+ *
+ * <p>Note that transactions are declared with annotations and that some methods
+ * contain "readOnly = true" which is an optimization that is particularly
+ * valuable when using Hibernate (to suppress unnecessary flush attempts for
+ * read-only operations).
+ *
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ * @author Mark Fisher
+ * @since 19.10.2003
+ */
+@Repository
+@Transactional
+public class HibernateClinic implements Clinic {
+
+	private SessionFactory sessionFactory;
+	
+	@Autowired
+	public HibernateClinic(SessionFactory sessionFactory) {
+		this.sessionFactory = sessionFactory;
+	}
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<Vet> getVets() {
+		return sessionFactory.getCurrentSession().createQuery("from Vet vet order by vet.lastName, vet.firstName").list();
+	}
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<PetType> getPetTypes() {
+		return sessionFactory.getCurrentSession().createQuery("from PetType type order by type.name").list();
+	}
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<Owner> findOwners(String lastName) {
+		return sessionFactory.getCurrentSession().createQuery("from Owner owner where owner.lastName like :lastName")
+				.setString("lastName", lastName + "%").list();
+	}
+
+	@Transactional(readOnly = true)
+	public Owner loadOwner(int id) {
+		return (Owner) sessionFactory.getCurrentSession().load(Owner.class, id);
+	}
+
+	@Transactional(readOnly = true)
+	public Pet loadPet(int id) {
+		return (Pet) sessionFactory.getCurrentSession().load(Pet.class, id);
+	}
+
+	public void storeOwner(Owner owner) {
+		// Note: Hibernate3's merge operation does not reassociate the object
+		// with the current Hibernate Session. Instead, it will always copy the
+		// state over to a registered representation of the entity. In case of a
+		// new entity, it will register a copy as well, but will not update the
+		// id of the passed-in object. To still update the ids of the original
+		// objects too, we need to register Spring's
+		// IdTransferringMergeEventListener on our SessionFactory.
+		sessionFactory.getCurrentSession().merge(owner);
+	}
+
+	public void storePet(Pet pet) {
+		sessionFactory.getCurrentSession().merge(pet);
+	}
+
+	public void storeVisit(Visit visit) {
+		sessionFactory.getCurrentSession().merge(visit);
+	}
+
+	public void deletePet(int id) throws DataAccessException {
+		Pet pet = loadPet(id);
+		sessionFactory.getCurrentSession().delete(pet);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java b/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..e39ebac4735c0d4e82b4d14074b2b19fe9c551fd
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/hibernate/package-info.java
@@ -0,0 +1,9 @@
+
+/**
+ *
+ * The classes in this package represent the Hibernate implementation
+ * of PetClinic's persistence layer.
+ *
+ */
+package org.springframework.samples.petclinic.hibernate;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java b/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java
new file mode 100644
index 0000000000000000000000000000000000000000..963ffdfe0332731705a806d57074514e53ae4bb3
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jdbc/JdbcPet.java
@@ -0,0 +1,35 @@
+package org.springframework.samples.petclinic.jdbc;
+
+import org.springframework.samples.petclinic.Pet;
+
+/**
+ * Subclass of Pet that carries temporary id properties which
+ * are only relevant for a JDBC implmentation of the Clinic.
+ *
+ * @author Juergen Hoeller
+ * @see SimpleJdbcClinic
+ */
+class JdbcPet extends Pet {
+
+	private int typeId;
+
+	private int ownerId;
+
+
+	public void setTypeId(int typeId) {
+		this.typeId = typeId;
+	}
+
+	public int getTypeId() {
+		return this.typeId;
+	}
+
+	public void setOwnerId(int ownerId) {
+		this.ownerId = ownerId;
+	}
+
+	public int getOwnerId() {
+		return this.ownerId;
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java
new file mode 100644
index 0000000000000000000000000000000000000000..587acecb9516802dd890dbe2942dd8a69715744c
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinic.java
@@ -0,0 +1,342 @@
+package org.springframework.samples.petclinic.jdbc;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.EmptyResultDataAccessException;
+import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
+import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
+import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+import org.springframework.jmx.export.annotation.ManagedOperation;
+import org.springframework.jmx.export.annotation.ManagedResource;
+import org.springframework.orm.ObjectRetrievalFailureException;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.Specialty;
+import org.springframework.samples.petclinic.Vet;
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.samples.petclinic.util.EntityUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+/**
+ * A simple JDBC-based implementation of the {@link Clinic} interface.
+ *
+ * <p>This class uses Java 5 language features and the {@link SimpleJdbcTemplate}
+ * plus {@link SimpleJdbcInsert}. It also takes advantage of classes like
+ * {@link BeanPropertySqlParameterSource} and
+ * {@link ParameterizedBeanPropertyRowMapper} which provide automatic mapping
+ * between JavaBean properties and JDBC parameters or query results.
+ *
+ * <p>SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base
+ * class for JDBC implementations of the Clinic interface for Spring 2.0.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ * @author Rob Harrop
+ * @author Sam Brannen
+ * @author Thomas Risberg
+ * @author Mark Fisher
+ */
+@Service
+@ManagedResource("petclinic:type=Clinic")
+public class SimpleJdbcClinic implements Clinic, SimpleJdbcClinicMBean {
+
+	private final Log logger = LogFactory.getLog(getClass());
+
+	private SimpleJdbcTemplate simpleJdbcTemplate;
+
+	private SimpleJdbcInsert insertOwner;
+	private SimpleJdbcInsert insertPet;
+	private SimpleJdbcInsert insertVisit;
+
+	private final List<Vet> vets = new ArrayList<Vet>();
+
+
+	@Autowired
+	public void init(DataSource dataSource) {
+		this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
+
+		this.insertOwner = new SimpleJdbcInsert(dataSource)
+			.withTableName("owners")
+			.usingGeneratedKeyColumns("id");
+		this.insertPet = new SimpleJdbcInsert(dataSource)
+			.withTableName("pets")
+			.usingGeneratedKeyColumns("id");
+		this.insertVisit = new SimpleJdbcInsert(dataSource)
+			.withTableName("visits")
+			.usingGeneratedKeyColumns("id");
+	}
+
+
+	/**
+	 * Refresh the cache of Vets that the Clinic is holding.
+	 * @see org.springframework.samples.petclinic.Clinic#getVets()
+	 */
+	@ManagedOperation
+	@Transactional(readOnly = true)
+	public void refreshVetsCache() throws DataAccessException {
+		synchronized (this.vets) {
+			this.logger.info("Refreshing vets cache");
+
+			// Retrieve the list of all vets.
+			this.vets.clear();
+			this.vets.addAll(this.simpleJdbcTemplate.query(
+					"SELECT id, first_name, last_name FROM vets ORDER BY last_name,first_name",
+					ParameterizedBeanPropertyRowMapper.newInstance(Vet.class)));
+
+			// Retrieve the list of all possible specialties.
+			final List<Specialty> specialties = this.simpleJdbcTemplate.query(
+					"SELECT id, name FROM specialties",
+					ParameterizedBeanPropertyRowMapper.newInstance(Specialty.class));
+
+			// Build each vet's list of specialties.
+			for (Vet vet : this.vets) {
+				final List<Integer> vetSpecialtiesIds = this.simpleJdbcTemplate.query(
+						"SELECT specialty_id FROM vet_specialties WHERE vet_id=?",
+						new ParameterizedRowMapper<Integer>() {
+							public Integer mapRow(ResultSet rs, int row) throws SQLException {
+								return Integer.valueOf(rs.getInt(1));
+							}},
+						vet.getId().intValue());
+				for (int specialtyId : vetSpecialtiesIds) {
+					Specialty specialty = EntityUtils.getById(specialties, Specialty.class, specialtyId);
+					vet.addSpecialty(specialty);
+				}
+			}
+		}
+	}
+
+
+	// START of Clinic implementation section *******************************
+
+	@Transactional(readOnly = true)
+	public Collection<Vet> getVets() throws DataAccessException {
+		synchronized (this.vets) {
+			if (this.vets.isEmpty()) {
+				refreshVetsCache();
+			}
+			return this.vets;
+		}
+	}
+
+	@Transactional(readOnly = true)
+	public Collection<PetType> getPetTypes() throws DataAccessException {
+		return this.simpleJdbcTemplate.query(
+				"SELECT id, name FROM types ORDER BY name",
+				ParameterizedBeanPropertyRowMapper.newInstance(PetType.class));
+	}
+
+	/**
+	 * Loads {@link Owner Owners} from the data store by last name, returning
+	 * all owners whose last name <i>starts</i> with the given name; also loads
+	 * the {@link Pet Pets} and {@link Visit Visits} for the corresponding
+	 * owners, if not already loaded.
+	 */
+	@Transactional(readOnly = true)
+	public Collection<Owner> findOwners(String lastName) throws DataAccessException {
+		List<Owner> owners = this.simpleJdbcTemplate.query(
+				"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE last_name like ?",
+				ParameterizedBeanPropertyRowMapper.newInstance(Owner.class),
+				lastName + "%");
+		loadOwnersPetsAndVisits(owners);
+		return owners;
+	}
+
+	/**
+	 * Loads the {@link Owner} with the supplied <code>id</code>; also loads
+	 * the {@link Pet Pets} and {@link Visit Visits} for the corresponding
+	 * owner, if not already loaded.
+	 */
+	@Transactional(readOnly = true)
+	public Owner loadOwner(int id) throws DataAccessException {
+		Owner owner;
+		try {
+			owner = this.simpleJdbcTemplate.queryForObject(
+					"SELECT id, first_name, last_name, address, city, telephone FROM owners WHERE id=?",
+					ParameterizedBeanPropertyRowMapper.newInstance(Owner.class),
+					id);
+		}
+		catch (EmptyResultDataAccessException ex) {
+			throw new ObjectRetrievalFailureException(Owner.class, new Integer(id));
+		}
+		loadPetsAndVisits(owner);
+		return owner;
+	}
+
+	@Transactional(readOnly = true)
+	public Pet loadPet(int id) throws DataAccessException {
+		JdbcPet pet;
+		try {
+			pet = this.simpleJdbcTemplate.queryForObject(
+					"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE id=?",
+					new JdbcPetRowMapper(),
+					id);
+		}
+		catch (EmptyResultDataAccessException ex) {
+			throw new ObjectRetrievalFailureException(Pet.class, new Integer(id));
+		}
+		Owner owner = loadOwner(pet.getOwnerId());
+		owner.addPet(pet);
+		pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
+		loadVisits(pet);
+		return pet;
+	}
+
+	@Transactional
+	public void storeOwner(Owner owner) throws DataAccessException {
+		if (owner.isNew()) {
+			Number newKey = this.insertOwner.executeAndReturnKey(
+					new BeanPropertySqlParameterSource(owner));
+			owner.setId(newKey.intValue());
+		}
+		else {
+			this.simpleJdbcTemplate.update(
+					"UPDATE owners SET first_name=:firstName, last_name=:lastName, address=:address, " +
+					"city=:city, telephone=:telephone WHERE id=:id",
+					new BeanPropertySqlParameterSource(owner));
+		}
+	}
+
+	@Transactional
+	public void storePet(Pet pet) throws DataAccessException {
+		if (pet.isNew()) {
+			Number newKey = this.insertPet.executeAndReturnKey(
+					createPetParameterSource(pet));
+			pet.setId(newKey.intValue());
+		}
+		else {
+			this.simpleJdbcTemplate.update(
+					"UPDATE pets SET name=:name, birth_date=:birth_date, type_id=:type_id, " +
+					"owner_id=:owner_id WHERE id=:id",
+					createPetParameterSource(pet));
+		}
+	}
+
+	@Transactional
+	public void storeVisit(Visit visit) throws DataAccessException {
+		if (visit.isNew()) {
+			Number newKey = this.insertVisit.executeAndReturnKey(
+					createVisitParameterSource(visit));
+			visit.setId(newKey.intValue());
+		}
+		else {
+			throw new UnsupportedOperationException("Visit update not supported");
+		}
+	}
+
+	public void deletePet(int id) throws DataAccessException {
+		this.simpleJdbcTemplate.update("DELETE FROM pets WHERE id=?", id);
+	}
+
+	// END of Clinic implementation section ************************************
+
+
+	/**
+	 * Creates a {@link MapSqlParameterSource} based on data values from the
+	 * supplied {@link Pet} instance.
+	 */
+	private MapSqlParameterSource createPetParameterSource(Pet pet) {
+		return new MapSqlParameterSource()
+			.addValue("id", pet.getId())
+			.addValue("name", pet.getName())
+			.addValue("birth_date", pet.getBirthDate())
+			.addValue("type_id", pet.getType().getId())
+			.addValue("owner_id", pet.getOwner().getId());
+	}
+
+	/**
+	 * Creates a {@link MapSqlParameterSource} based on data values from the
+	 * supplied {@link Visit} instance.
+	 */
+	private MapSqlParameterSource createVisitParameterSource(Visit visit) {
+		return new MapSqlParameterSource()
+			.addValue("id", visit.getId())
+			.addValue("visit_date", visit.getDate())
+			.addValue("description", visit.getDescription())
+			.addValue("pet_id", visit.getPet().getId());
+	}
+
+	/**
+	 * Loads the {@link Visit} data for the supplied {@link Pet}.
+	 */
+	private void loadVisits(JdbcPet pet) {
+		final List<Visit> visits = this.simpleJdbcTemplate.query(
+				"SELECT id, visit_date, description FROM visits WHERE pet_id=?",
+				new ParameterizedRowMapper<Visit>() {
+					public Visit mapRow(ResultSet rs, int row) throws SQLException {
+						Visit visit = new Visit();
+						visit.setId(rs.getInt("id"));
+						visit.setDate(rs.getTimestamp("visit_date"));
+						visit.setDescription(rs.getString("description"));
+						return visit;
+					}
+				},
+				pet.getId().intValue());
+		for (Visit visit : visits) {
+			pet.addVisit(visit);
+		}
+	}
+
+	/**
+	 * Loads the {@link Pet} and {@link Visit} data for the supplied
+	 * {@link Owner}.
+	 */
+	private void loadPetsAndVisits(final Owner owner) {
+		final List<JdbcPet> pets = this.simpleJdbcTemplate.query(
+				"SELECT id, name, birth_date, type_id, owner_id FROM pets WHERE owner_id=?",
+				new JdbcPetRowMapper(),
+				owner.getId().intValue());
+		for (JdbcPet pet : pets) {
+			owner.addPet(pet);
+			pet.setType(EntityUtils.getById(getPetTypes(), PetType.class, pet.getTypeId()));
+			loadVisits(pet);
+		}
+	}
+
+	/**
+	 * Loads the {@link Pet} and {@link Visit} data for the supplied
+	 * {@link List} of {@link Owner Owners}.
+	 *
+	 * @param owners the list of owners for whom the pet and visit data should be loaded
+	 * @see #loadPetsAndVisits(Owner)
+	 */
+	private void loadOwnersPetsAndVisits(List<Owner> owners) {
+		for (Owner owner : owners) {
+			loadPetsAndVisits(owner);
+		}
+	}
+
+	/**
+	 * {@link ParameterizedRowMapper} implementation mapping data from a
+	 * {@link ResultSet} to the corresponding properties of the {@link JdbcPet} class.
+	 */
+	private class JdbcPetRowMapper implements ParameterizedRowMapper<JdbcPet> {
+
+		public JdbcPet mapRow(ResultSet rs, int rownum) throws SQLException {
+			JdbcPet pet = new JdbcPet();
+			pet.setId(rs.getInt("id"));
+			pet.setName(rs.getString("name"));
+			pet.setBirthDate(rs.getDate("birth_date"));
+			pet.setTypeId(rs.getInt("type_id"));
+			pet.setOwnerId(rs.getInt("owner_id"));
+			return pet;
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java
new file mode 100644
index 0000000000000000000000000000000000000000..c9a7a78478be439d5bdb84c25c94450a1495dd28
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicMBean.java
@@ -0,0 +1,20 @@
+package org.springframework.samples.petclinic.jdbc;
+
+/**
+ * Interface that defines a cache refresh operation.
+ * To be exposed for management via JMX.
+ * 
+ * @author Rob Harrop
+ * @author Juergen Hoeller
+ * @see SimpleJdbcClinic
+ */
+public interface SimpleJdbcClinicMBean {
+
+	/**
+	 * Refresh the cache of Vets that the Clinic is holding.
+	 * @see org.springframework.samples.petclinic.Clinic#getVets()
+	 * @see SimpleJdbcClinic#refreshVetsCache()
+	 */
+	void refreshVetsCache();
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java b/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ec278b44653530cfa12a275e08c1af6f8bb05e8
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jdbc/package-info.java
@@ -0,0 +1,9 @@
+
+/**
+ *
+ * The classes in this package represent the JDBC implementation
+ * of PetClinic's persistence layer.
+ *
+ */
+package org.springframework.samples.petclinic.jdbc;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java b/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java
new file mode 100644
index 0000000000000000000000000000000000000000..92fe1e247711fc679d2771c1f98c51abcacad46b
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jpa/EntityManagerClinic.java
@@ -0,0 +1,96 @@
+package org.springframework.samples.petclinic.jpa;
+
+import java.util.Collection;
+
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.Vet;
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.dao.DataAccessException;
+
+/**
+ * JPA implementation of the Clinic interface using EntityManager.
+ *
+ * <p>The mappings are defined in "orm.xml" located in the META-INF directory.
+ *
+ * @author Mike Keith
+ * @author Rod Johnson
+ * @author Sam Brannen
+ * @since 22.4.2006
+ */
+@Repository
+@Transactional
+public class EntityManagerClinic implements Clinic {
+
+	@PersistenceContext
+	private EntityManager em;
+
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<Vet> getVets() {
+		return this.em.createQuery("SELECT vet FROM Vet vet ORDER BY vet.lastName, vet.firstName").getResultList();
+	}
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<PetType> getPetTypes() {
+		return this.em.createQuery("SELECT ptype FROM PetType ptype ORDER BY ptype.name").getResultList();
+	}
+
+	@Transactional(readOnly = true)
+	@SuppressWarnings("unchecked")
+	public Collection<Owner> findOwners(String lastName) {
+		Query query = this.em.createQuery("SELECT owner FROM Owner owner WHERE owner.lastName LIKE :lastName");
+		query.setParameter("lastName", lastName + "%");
+		return query.getResultList();
+	}
+
+	@Transactional(readOnly = true)
+	public Owner loadOwner(int id) {
+		return this.em.find(Owner.class, id);
+	}
+
+	@Transactional(readOnly = true)
+	public Pet loadPet(int id) {
+		return this.em.find(Pet.class, id);
+	}
+
+	public void storeOwner(Owner owner) {
+		// Consider returning the persistent object here, for exposing
+		// a newly assigned id using any persistence provider...
+		Owner merged = this.em.merge(owner);
+		this.em.flush();
+		owner.setId(merged.getId());
+	}
+
+	public void storePet(Pet pet) {
+		// Consider returning the persistent object here, for exposing
+		// a newly assigned id using any persistence provider...
+		Pet merged = this.em.merge(pet);
+		this.em.flush();
+		pet.setId(merged.getId());
+	}
+
+	public void storeVisit(Visit visit) {
+		// Consider returning the persistent object here, for exposing
+		// a newly assigned id using any persistence provider...
+		Visit merged = this.em.merge(visit);
+		this.em.flush();
+		visit.setId(merged.getId());
+	}
+
+	public void deletePet(int id) throws DataAccessException {
+		Pet pet = loadPet(id);
+		this.em.remove(pet);
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java b/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..8093784ec542da7114b13ef5bb8b233d877261ab
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/jpa/package-info.java
@@ -0,0 +1,9 @@
+
+/**
+ *
+ * The classes in this package represent the JPA implementation
+ * of PetClinic's persistence layer.
+ *
+ */
+package org.springframework.samples.petclinic.jpa;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/package-info.java b/src/main/java/org/springframework/samples/petclinic/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2cc3691593e623aee75ac6ac542e2b16e31bdf0
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/package-info.java
@@ -0,0 +1,8 @@
+
+/**
+ *
+ * The classes in this package represent PetClinic's business layer.
+ *
+ */
+package org.springframework.samples.petclinic;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java b/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java
new file mode 100644
index 0000000000000000000000000000000000000000..1086591decd45594794ee8188800480997cbeacf
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/toplink/EssentialsHSQLPlatformWithNativeSequence.java
@@ -0,0 +1,56 @@
+package org.springframework.samples.petclinic.toplink;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import oracle.toplink.essentials.exceptions.ValidationException;
+import oracle.toplink.essentials.platform.database.HSQLPlatform;
+import oracle.toplink.essentials.queryframework.ValueReadQuery;
+
+/**
+ * Subclass of the TopLink Essentials default HSQLPlatform class, using native
+ * HSQLDB identity columns for id generation.
+ *
+ * <p>Necessary for PetClinic's default data model, which relies on identity
+ * columns: this is uniformly used across all persistence layer implementations
+ * (JDBC, Hibernate, and JPA).
+ *
+ * @author Juergen Hoeller
+ * @author <a href="mailto:james.x.clark@oracle.com">James Clark</a>
+ * @since 1.2
+ */
+public class EssentialsHSQLPlatformWithNativeSequence extends HSQLPlatform {
+
+	private static final long serialVersionUID = -55658009691346735L;
+
+
+	public EssentialsHSQLPlatformWithNativeSequence() {
+		// setUsesNativeSequencing(true);
+	}
+
+	@Override
+	public boolean supportsNativeSequenceNumbers() {
+		return true;
+	}
+
+	@Override
+	public boolean shouldNativeSequenceAcquireValueAfterInsert() {
+		return true;
+	}
+
+	@Override
+	public ValueReadQuery buildSelectQueryForNativeSequence() {
+		return new ValueReadQuery("CALL IDENTITY()");
+	}
+
+	@Override
+	public void printFieldIdentityClause(Writer writer) throws ValidationException {
+		try {
+			writer.write(" IDENTITY");
+		}
+		catch (IOException ex) {
+			throw ValidationException.fileError(ex);
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java b/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..3bcc9add7db5061f164945fb223e0bf995996cf6
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/toplink/package-info.java
@@ -0,0 +1,10 @@
+
+/**
+ *
+ * The classes in this package provide support for using the TopLink
+ * implementation with PetClinic's EntityManagerClinic.
+ * 
+ *
+ */
+package org.springframework.samples.petclinic.toplink;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java b/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..16df5fa9a916c1d86339b1b3ae228541477036c7
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/util/EntityUtils.java
@@ -0,0 +1,41 @@
+
+package org.springframework.samples.petclinic.util;
+
+import java.util.Collection;
+
+import org.springframework.orm.ObjectRetrievalFailureException;
+import org.springframework.samples.petclinic.BaseEntity;
+
+/**
+ * Utility methods for handling entities. Separate from the BaseEntity class
+ * mainly because of dependency on the ORM-associated
+ * ObjectRetrievalFailureException.
+ *
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ * @since 29.10.2003
+ * @see org.springframework.samples.petclinic.BaseEntity
+ */
+public abstract class EntityUtils {
+
+	/**
+	 * Look up the entity of the given class with the given id in the given
+	 * collection.
+	 *
+	 * @param entities the collection to search
+	 * @param entityClass the entity class to look up
+	 * @param entityId the entity id to look up
+	 * @return the found entity
+	 * @throws ObjectRetrievalFailureException if the entity was not found
+	 */
+	public static <T extends BaseEntity> T getById(Collection<T> entities, Class<T> entityClass, int entityId)
+			throws ObjectRetrievalFailureException {
+		for (T entity : entities) {
+			if (entity.getId().intValue() == entityId && entityClass.isInstance(entity)) {
+				return entity;
+			}
+		}
+		throw new ObjectRetrievalFailureException(entityClass, new Integer(entityId));
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..04b6b7d58afd411579ef99b864db8e97e63e3921
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/validation/OwnerValidator.java
@@ -0,0 +1,43 @@
+package org.springframework.samples.petclinic.validation;
+
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.util.StringUtils;
+import org.springframework.validation.Errors;
+
+/**
+ * <code>Validator</code> for <code>Owner</code> forms.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ */
+public class OwnerValidator {
+
+	public void validate(Owner owner, Errors errors) {
+		if (!StringUtils.hasLength(owner.getFirstName())) {
+			errors.rejectValue("firstName", "required", "required");
+		}
+		if (!StringUtils.hasLength(owner.getLastName())) {
+			errors.rejectValue("lastName", "required", "required");
+		}
+		if (!StringUtils.hasLength(owner.getAddress())) {
+			errors.rejectValue("address", "required", "required");
+		}
+		if (!StringUtils.hasLength(owner.getCity())) {
+			errors.rejectValue("city", "required", "required");
+		}
+
+		String telephone = owner.getTelephone();
+		if (!StringUtils.hasLength(telephone)) {
+			errors.rejectValue("telephone", "required", "required");
+		}
+		else {
+			for (int i = 0; i < telephone.length(); ++i) {
+				if ((Character.isDigit(telephone.charAt(i))) == false) {
+					errors.rejectValue("telephone", "nonNumeric", "non-numeric");
+					break;
+				}
+			}
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ad6eb0ac03507e727ec62b9d8e26017cff4108f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/validation/PetValidator.java
@@ -0,0 +1,25 @@
+package org.springframework.samples.petclinic.validation;
+
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.util.StringUtils;
+import org.springframework.validation.Errors;
+
+/**
+ * <code>Validator</code> for <code>Pet</code> forms.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ */
+public class PetValidator {
+
+	public void validate(Pet pet, Errors errors) {
+		String name = pet.getName();
+		if (!StringUtils.hasLength(name)) {
+			errors.rejectValue("name", "required", "required");
+		}
+		else if (pet.isNew() && pet.getOwner().getPet(name, true) != null) {
+			errors.rejectValue("name", "duplicate", "already exists");
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java b/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java
new file mode 100644
index 0000000000000000000000000000000000000000..35c80bafa10f289717dc81e731bf57b33f6e701b
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/validation/VisitValidator.java
@@ -0,0 +1,21 @@
+package org.springframework.samples.petclinic.validation;
+
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.util.StringUtils;
+import org.springframework.validation.Errors;
+
+/**
+ * <code>Validator</code> for <code>Visit</code> forms.
+ *
+ * @author Ken Krebs
+ * @author Juergen Hoeller
+ */
+public class VisitValidator {
+
+	public void validate(Visit visit, Errors errors) {
+		if (!StringUtils.hasLength(visit.getDescription())) {
+			errors.rejectValue("description", "required", "required");
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/validation/package-info.java b/src/main/java/org/springframework/samples/petclinic/validation/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..7db2ee521d74f681ce92b1e15ee502db00c67179
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/validation/package-info.java
@@ -0,0 +1,9 @@
+
+/**
+ *
+ * The classes in this package represent the set of Validator objects 
+ * the Business Layer makes available to the Presentation Layer.
+ *
+ */
+package org.springframework.samples.petclinic.validation;
+
diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..cd830aff6fbe14d1f03793af926fcb72c638e007
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/AddOwnerForm.java
@@ -0,0 +1,65 @@
+
+package org.springframework.samples.petclinic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.validation.OwnerValidator;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.support.SessionStatus;
+
+/**
+ * JavaBean form controller that is used to add a new <code>Owner</code> to the
+ * system.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+@RequestMapping("/owners/new")
+@SessionAttributes(types = Owner.class)
+public class AddOwnerForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public AddOwnerForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(method = RequestMethod.GET)
+	public String setupForm(Model model) {
+		Owner owner = new Owner();
+		model.addAttribute(owner);
+		return "owners/form";
+	}
+
+	@RequestMapping(method = RequestMethod.POST)
+	public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) {
+		new OwnerValidator().validate(owner, result);
+		if (result.hasErrors()) {
+			return "owners/form";
+		}
+		else {
+			this.clinic.storeOwner(owner);
+			status.setComplete();
+			return "redirect:/owners/" + owner.getId();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..586cf3d67c5eead7b5144b9dc7f0d740e7586f34
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/AddPetForm.java
@@ -0,0 +1,77 @@
+
+package org.springframework.samples.petclinic.web;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.validation.PetValidator;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.support.SessionStatus;
+
+/**
+ * JavaBean form controller that is used to add a new <code>Pet</code> to the
+ * system.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+@RequestMapping("/owners/{ownerId}/pets/new")
+@SessionAttributes("pet")
+public class AddPetForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public AddPetForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@ModelAttribute("types")
+	public Collection<PetType> populatePetTypes() {
+		return this.clinic.getPetTypes();
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(method = RequestMethod.GET)
+	public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
+		Owner owner = this.clinic.loadOwner(ownerId);
+		Pet pet = new Pet();
+		owner.addPet(pet);
+		model.addAttribute("pet", pet);
+		return "pets/form";
+	}
+
+	@RequestMapping(method = RequestMethod.POST)
+	public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
+		new PetValidator().validate(pet, result);
+		if (result.hasErrors()) {
+			return "pets/form";
+		}
+		else {
+			this.clinic.storePet(pet);
+			status.setComplete();
+			return "redirect:/owners/" + pet.getOwner().getId();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java b/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..68368644026b9e1d1ffba76c11644325c984829f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/AddVisitForm.java
@@ -0,0 +1,69 @@
+
+package org.springframework.samples.petclinic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.samples.petclinic.validation.VisitValidator;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.support.SessionStatus;
+
+/**
+ * JavaBean form controller that is used to add a new <code>Visit</code> to the
+ * system.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+@RequestMapping("/owners/*/pets/{petId}/visits/new")
+@SessionAttributes("visit")
+public class AddVisitForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public AddVisitForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(method = RequestMethod.GET)
+	public String setupForm(@PathVariable("petId") int petId, Model model) {
+		Pet pet = this.clinic.loadPet(petId);
+		Visit visit = new Visit();
+		pet.addVisit(visit);
+		model.addAttribute("visit", visit);
+		return "pets/visitForm";
+	}
+
+	@RequestMapping(method = RequestMethod.POST)
+	public String processSubmit(@ModelAttribute("visit") Visit visit, BindingResult result, SessionStatus status) {
+		new VisitValidator().validate(visit, result);
+		if (result.hasErrors()) {
+			return "pets/visitForm";
+		}
+		else {
+			this.clinic.storeVisit(visit);
+			status.setComplete();
+			return "redirect:/owners/" + visit.getPet().getOwner().getId();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java b/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java
new file mode 100644
index 0000000000000000000000000000000000000000..2d2a8bdc15f3d4d07b394e2e823401fb0101109f
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/ClinicBindingInitializer.java
@@ -0,0 +1,37 @@
+package org.springframework.samples.petclinic.web;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.propertyeditors.CustomDateEditor;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.support.WebBindingInitializer;
+import org.springframework.web.context.request.WebRequest;
+
+/**
+ * Shared WebBindingInitializer for PetClinic's custom editors.
+ *
+ * <p>Alternatively, such init-binder code may be put into
+ * {@link org.springframework.web.bind.annotation.InitBinder}
+ * annotated methods on the controller classes themselves.
+ *
+ * @author Juergen Hoeller
+ */
+public class ClinicBindingInitializer implements WebBindingInitializer {
+
+	@Autowired
+	private Clinic clinic;
+
+	public void initBinder(WebDataBinder binder, WebRequest request) {
+		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+		dateFormat.setLenient(false);
+		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
+		binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
+		binder.registerCustomEditor(PetType.class, new PetTypeEditor(this.clinic));
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java
new file mode 100644
index 0000000000000000000000000000000000000000..e93ae8f66633fd8ec26784c0cb9a646c53c88277
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/ClinicController.java
@@ -0,0 +1,89 @@
+
+package org.springframework.samples.petclinic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Vets;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.ModelAndView;
+
+/**
+ * Annotation-driven <em>MultiActionController</em> that handles all non-form
+ * URL's.
+ *
+ * @author Juergen Hoeller
+ * @author Mark Fisher
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+public class ClinicController {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public ClinicController(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	/**
+	 * Custom handler for the welcome view.
+	 * <p>
+	 * Note that this handler relies on the RequestToViewNameTranslator to
+	 * determine the logical view name based on the request URL: "/welcome.do"
+	 * -&gt; "welcome".
+	 */
+	@RequestMapping("/")
+	public String welcomeHandler() {
+		return "welcome";
+	}
+
+	/**
+	 * Custom handler for displaying vets.
+	 *
+	 * <p>Note that this handler returns a plain {@link ModelMap} object instead of
+	 * a ModelAndView, thus leveraging convention-based model attribute names.
+	 * It relies on the RequestToViewNameTranslator to determine the logical
+	 * view name based on the request URL: "/vets.do" -&gt; "vets".
+	 *
+	 * @return a ModelMap with the model attributes for the view
+	 */
+	@RequestMapping("/vets")
+	public ModelMap vetsHandler() {
+		Vets vets = new Vets();
+		vets.getVetList().addAll(this.clinic.getVets());
+		return new ModelMap(vets);
+	}
+
+	/**
+	 * Custom handler for displaying an owner.
+	 *
+	 * @param ownerId the ID of the owner to display
+	 * @return a ModelMap with the model attributes for the view
+	 */
+	@RequestMapping("/owners/{ownerId}")
+	public ModelAndView ownerHandler(@PathVariable("ownerId") int ownerId) {
+		ModelAndView mav = new ModelAndView("owners/show");
+		mav.addObject(this.clinic.loadOwner(ownerId));
+		return mav;
+	}
+
+	/**
+	 * Custom handler for displaying an list of visits.
+	 *
+	 * @param petId the ID of the pet whose visits to display
+	 * @return a ModelMap with the model attributes for the view
+	 */
+	@RequestMapping(value="/owners/*/pets/{petId}/visits", method=RequestMethod.GET)
+	public ModelAndView visitsHandler(@PathVariable int petId) {
+		ModelAndView mav = new ModelAndView("visits");
+		mav.addObject("visits", this.clinic.loadPet(petId).getVisits());
+		return mav;
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b65de51bf69e1ab01b225422ccd1769c0a56210
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/EditOwnerForm.java
@@ -0,0 +1,65 @@
+
+package org.springframework.samples.petclinic.web;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.validation.OwnerValidator;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.support.SessionStatus;
+
+/**
+ * JavaBean Form controller that is used to edit an existing <code>Owner</code>.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+@RequestMapping("/owners/{ownerId}/edit")
+@SessionAttributes(types = Owner.class)
+public class EditOwnerForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public EditOwnerForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(method = RequestMethod.GET)
+	public String setupForm(@PathVariable("ownerId") int ownerId, Model model) {
+		Owner owner = this.clinic.loadOwner(ownerId);
+		model.addAttribute(owner);
+		return "owners/form";
+	}
+
+	@RequestMapping(method = RequestMethod.PUT)
+	public String processSubmit(@ModelAttribute Owner owner, BindingResult result, SessionStatus status) {
+		new OwnerValidator().validate(owner, result);
+		if (result.hasErrors()) {
+			return "owners/form";
+		}
+		else {
+			this.clinic.storeOwner(owner);
+			status.setComplete();
+			return "redirect:/owners/" + owner.getId();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java b/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..1a7fd6ed3c624249e47d59896cb72545724c7aa4
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/EditPetForm.java
@@ -0,0 +1,80 @@
+
+package org.springframework.samples.petclinic.web;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.validation.PetValidator;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.SessionAttributes;
+import org.springframework.web.bind.support.SessionStatus;
+
+/**
+ * JavaBean Form controller that is used to edit an existing <code>Pet</code>.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+@RequestMapping("/owners/*/pets/{petId}/edit")
+@SessionAttributes("pet")
+public class EditPetForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public EditPetForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@ModelAttribute("types")
+	public Collection<PetType> populatePetTypes() {
+		return this.clinic.getPetTypes();
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(method = RequestMethod.GET)
+	public String setupForm(@PathVariable("petId") int petId, Model model) {
+		Pet pet = this.clinic.loadPet(petId);
+		model.addAttribute("pet", pet);
+		return "pets/form";
+	}
+
+	@RequestMapping(method = { RequestMethod.PUT, RequestMethod.POST })
+	public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, SessionStatus status) {
+		new PetValidator().validate(pet, result);
+		if (result.hasErrors()) {
+			return "pets/form";
+		}
+		else {
+			this.clinic.storePet(pet);
+			status.setComplete();
+			return "redirect:/owners/" + pet.getOwner().getId();
+		}
+	}
+
+	@RequestMapping(method = RequestMethod.DELETE)
+	public String deletePet(@PathVariable int petId) {
+		Pet pet = this.clinic.loadPet(petId);
+		this.clinic.deletePet(petId);
+		return "redirect:/owners/" + pet.getOwner().getId();
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb93fabad0a44a970f14a62be79c2da92c58d56c
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/FindOwnersForm.java
@@ -0,0 +1,74 @@
+
+package org.springframework.samples.petclinic.web;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.WebDataBinder;
+import org.springframework.web.bind.annotation.InitBinder;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * JavaBean Form controller that is used to search for <code>Owner</code>s by
+ * last name.
+ * 
+ * @author Juergen Hoeller
+ * @author Ken Krebs
+ * @author Arjen Poutsma
+ */
+@Controller
+public class FindOwnersForm {
+
+	private final Clinic clinic;
+
+
+	@Autowired
+	public FindOwnersForm(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@InitBinder
+	public void setAllowedFields(WebDataBinder dataBinder) {
+		dataBinder.setDisallowedFields("id");
+	}
+
+	@RequestMapping(value = "/owners/search", method = RequestMethod.GET)
+	public String setupForm(Model model) {
+		model.addAttribute("owner", new Owner());
+		return "owners/search";
+	}
+
+	@RequestMapping(value = "/owners", method = RequestMethod.GET)
+	public String processSubmit(Owner owner, BindingResult result, Model model) {
+
+		// allow parameterless GET request for /owners to return all records
+		if (owner.getLastName() == null) {
+			owner.setLastName(""); // empty string signifies broadest possible search
+		}
+
+		// find owners by last name
+		Collection<Owner> results = this.clinic.findOwners(owner.getLastName());
+		if (results.size() < 1) {
+			// no owners found
+			result.rejectValue("lastName", "notFound", "not found");
+			return "owners/search";
+		}
+		if (results.size() > 1) {
+			// multiple owners found
+			model.addAttribute("selections", results);
+			return "owners/list";
+		}
+		else {
+			// 1 owner found
+			owner = results.iterator().next();
+			return "redirect:/owners/" + owner.getId();
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java b/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java
new file mode 100644
index 0000000000000000000000000000000000000000..812b648d7111087fe206bfa5ac3b9a0da31f3b10
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/PetTypeEditor.java
@@ -0,0 +1,30 @@
+package org.springframework.samples.petclinic.web;
+
+import java.beans.PropertyEditorSupport;
+
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.PetType;
+
+/**
+ * @author Mark Fisher
+ * @author Juergen Hoeller
+ */
+public class PetTypeEditor extends PropertyEditorSupport {
+
+	private final Clinic clinic;
+
+
+	public PetTypeEditor(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@Override
+	public void setAsText(String text) throws IllegalArgumentException {
+		for (PetType type : this.clinic.getPetTypes()) {
+			if (type.getName().equals(text)) {
+				setValue(type);
+			}
+		}
+	}
+
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java b/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java
new file mode 100644
index 0000000000000000000000000000000000000000..e9da832e4d71c29227d70fd68f49795536ac3ed7
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/VisitsAtomView.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.web;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import com.sun.syndication.feed.atom.Content;
+import com.sun.syndication.feed.atom.Entry;
+import com.sun.syndication.feed.atom.Feed;
+
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.web.servlet.view.feed.AbstractAtomFeedView;
+
+/**
+ * A view creating a Atom representation from a list of Visit objects. 
+ * 
+ * @author Alef Arendsen
+ * @author Arjen Poutsma
+ */
+public class VisitsAtomView extends AbstractAtomFeedView {
+
+	@Override
+	protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) {
+		feed.setId("tag:springsource.com");
+		feed.setTitle("Pet Clinic Visits");
+		@SuppressWarnings("unchecked")
+		List<Visit> visits = (List<Visit>) model.get("visits");
+		for (Visit visit : visits) {
+			Date date = visit.getDate();
+			if (feed.getUpdated() == null || date.compareTo(feed.getUpdated()) > 0) {
+				feed.setUpdated(date);
+			}
+		}
+	}
+
+	@Override
+	protected List<Entry> buildFeedEntries(Map<String, Object> model,
+			HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+		@SuppressWarnings("unchecked")
+		List<Visit> visits = (List<Visit>) model.get("visits");
+		List<Entry> entries = new ArrayList<Entry>(visits.size());
+
+		for (Visit visit : visits) {
+			Entry entry = new Entry();
+			String date = String.format("%1$tY-%1$tm-%1$td", visit.getDate());
+			// see http://diveintomark.org/archives/2004/05/28/howto-atom-id#other
+			entry.setId(String.format("tag:springsource.com,%s:%d", date, visit.getId()));
+			entry.setTitle(String.format("%s visit on %s", visit.getPet().getName(), date));
+			entry.setUpdated(visit.getDate());
+
+			Content summary = new Content();
+			summary.setValue(visit.getDescription());
+			entry.setSummary(summary);
+
+			entries.add(entry);
+		}
+
+		return entries;
+
+	}
+	
+}
diff --git a/src/main/java/org/springframework/samples/petclinic/web/package-info.java b/src/main/java/org/springframework/samples/petclinic/web/package-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..c909ccf7f046b781d90619e48754247afe2fed18
--- /dev/null
+++ b/src/main/java/org/springframework/samples/petclinic/web/package-info.java
@@ -0,0 +1,8 @@
+
+/**
+ *
+ * The classes in this package represent PetClinic's web presentation layer.
+ *
+ */
+package org.springframework.samples.petclinic.web;
+
diff --git a/src/main/java/overview.html b/src/main/java/overview.html
new file mode 100644
index 0000000000000000000000000000000000000000..1eb7a2e8c194f8fac74dd8a8eabc4ccbe753d8d8
--- /dev/null
+++ b/src/main/java/overview.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+<p>
+The Spring Data Binding framework, an internal library used by Spring Web Flow.
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties
new file mode 100644
index 0000000000000000000000000000000000000000..e039cdf1b6c9599c1bbf54a49de043f7425990b6
--- /dev/null
+++ b/src/main/resources/jdbc.properties
@@ -0,0 +1,63 @@
+# Properties file with JDBC and JPA settings.
+#
+# Applied by <context:property-placeholder location="jdbc.properties"/> from
+# various application context XML files (e.g., "applicationContext-*.xml").
+# Targeted at system administrators, to avoid touching the context XML files.
+
+
+#-------------------------------------------------------------------------------
+# Common Settings
+
+hibernate.generate_statistics=true
+hibernate.show_sql=true
+jpa.showSql=true
+
+
+#-------------------------------------------------------------------------------
+# HSQL Settings
+
+jdbc.driverClassName=org.hsqldb.jdbcDriver
+jdbc.url=jdbc:hsqldb:mem:petclinic
+jdbc.username=sa
+jdbc.password=
+
+# Properties that control the population of schema and data for a new data source
+jdbc.populate=true
+jdbc.schemaLocation=classpath:/META-INF/hsqldb/initDB.txt
+jdbc.dataLocation=classpath:/META-INF/hsqldb/populateDB.txt
+jdbc.dropLocation=classpath:/META-INF/hsqldb/dropTables.txt
+
+# Property that determines which Hibernate dialect to use
+# (only applied with "applicationContext-hibernate.xml")
+hibernate.dialect=org.hibernate.dialect.HSQLDialect
+
+# Property that determines which JPA DatabasePlatform to use with TopLink Essentials
+jpa.databasePlatform=org.springframework.samples.petclinic.toplink.EssentialsHSQLPlatformWithNativeSequence
+
+# Property that determines which database to use with an AbstractJpaVendorAdapter
+jpa.database=HSQL
+
+
+#-------------------------------------------------------------------------------
+# MySQL Settings
+
+#jdbc.driverClassName=com.mysql.jdbc.Driver
+#jdbc.url=jdbc:mysql://localhost:3306/petclinic
+#jdbc.username=pc
+#jdbc.password=pc
+
+# Properties that control the population of schema and data for a new data source
+#jdbc.populate=false
+#jdbc.schemaLocation=
+#jdbc.dataLocation=
+#jdbc.dropLocation=
+
+# Property that determines which Hibernate dialect to use
+# (only applied with "applicationContext-hibernate.xml")
+#hibernate.dialect=org.hibernate.dialect.MySQLDialect
+
+# Property that determines which JPA DatabasePlatform to use with TopLink Essentials
+#jpa.databasePlatform=oracle.toplink.essentials.platform.database.MySQL4Platform
+
+# Property that determines which database to use with an AbstractJpaVendorAdapter
+#jpa.database=MYSQL
diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ebee551aa88864fb8a3ae65dcd1ebe88b66ac4ba
--- /dev/null
+++ b/src/main/resources/log4j.properties
@@ -0,0 +1,18 @@
+# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
+# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
+log4j.rootLogger=INFO, stdout, logfile
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
+
+log4j.appender.logfile=org.apache.log4j.RollingFileAppender
+log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log
+log4j.appender.logfile.MaxFileSize=512KB
+# Keep three backup files.
+log4j.appender.logfile.MaxBackupIndex=3
+# Pattern to output: date priority [category] - message
+log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
+
+log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG
diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties
new file mode 100644
index 0000000000000000000000000000000000000000..173417a1014824791ee97decfc43084273fd0723
--- /dev/null
+++ b/src/main/resources/messages.properties
@@ -0,0 +1,8 @@
+welcome=Welcome
+required=is required
+notFound=has not been found
+duplicate=is already in use
+nonNumeric=must be all numeric
+duplicateFormSubmission=Duplicate form submission is not allowed
+typeMismatch.date=invalid date
+typeMismatch.birthDate=invalid date
diff --git a/src/main/resources/messages_de.properties b/src/main/resources/messages_de.properties
new file mode 100644
index 0000000000000000000000000000000000000000..124bee48b2c863f62b80367890392fb0775efcfd
--- /dev/null
+++ b/src/main/resources/messages_de.properties
@@ -0,0 +1,8 @@
+welcome=Willkommen
+required=muss angegeben werden
+notFound=wurde nicht gefunden
+duplicate=ist bereits vergeben
+nonNumeric=darf nur numerisch sein
+duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt
+typeMismatch.date=ungültiges Datum
+typeMismatch.birthDate=ungültiges Datum
diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties
new file mode 100644
index 0000000000000000000000000000000000000000..05d519bb86d059e73ce879196658c54c1e8cd7dc
--- /dev/null
+++ b/src/main/resources/messages_en.properties
@@ -0,0 +1 @@
+# This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file.
\ No newline at end of file
diff --git a/src/main/resources/petclinic.hbm.xml b/src/main/resources/petclinic.hbm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f9a993cf1212fac6075a393b3760273f085a2158
--- /dev/null
+++ b/src/main/resources/petclinic.hbm.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
+		"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+  - Mapping file for the Hibernate implementation of the Clinic interface.
+	-->
+<hibernate-mapping auto-import="true" default-lazy="false">
+
+	<class name="org.springframework.samples.petclinic.Vet" table="vets">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="firstName" column="first_name"/>
+		<property name="lastName" column="last_name"/>
+		<set name="specialtiesInternal" table="vet_specialties">
+			<key column="vet_id"/>
+			<many-to-many column="specialty_id" class="org.springframework.samples.petclinic.Specialty"/>
+		</set>
+	</class>
+
+	<class name="org.springframework.samples.petclinic.Specialty" table="specialties">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="name" column="name"/>
+	</class>
+
+	<class name="org.springframework.samples.petclinic.Owner" table="owners">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="firstName" column="first_name"/>
+		<property name="lastName" column="last_name"/>
+		<property name="address" column="address"/>
+		<property name="city" column="city"/>
+		<property name="telephone" column="telephone"/>
+		<set name="petsInternal" inverse="true" cascade="all">
+			<key column="owner_id"/>
+			<one-to-many class="org.springframework.samples.petclinic.Pet"/>
+		</set>
+	</class>
+
+	<class name="org.springframework.samples.petclinic.Pet" table="pets">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="name" column="name"/>
+		<property name="birthDate" column="birth_date" type="date"/>
+		<many-to-one name="owner" column="owner_id" class="org.springframework.samples.petclinic.Owner"/>
+		<many-to-one name="type" column="type_id" class="org.springframework.samples.petclinic.PetType"/>
+		<set name="visitsInternal" inverse="true" cascade="all">
+			<key column="pet_id"/>
+			<one-to-many class="org.springframework.samples.petclinic.Visit"/>
+		</set>
+	</class>
+
+	<class name="org.springframework.samples.petclinic.PetType" table="types">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="name" column="name"/>
+	</class>
+
+	<class name="org.springframework.samples.petclinic.Visit" table="visits">
+		<id name="id" column="id">
+			<generator class="identity"/>
+		</id>
+		<property name="date" column="visit_date" type="date"/>
+		<property name="description" column="description"/>
+		<many-to-one name="pet" column="pet_id" class="org.springframework.samples.petclinic.Pet"/>
+	</class>
+
+</hibernate-mapping>
diff --git a/src/main/webapp/META-INF/aop.xml b/src/main/webapp/META-INF/aop.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b49ffd8b19a86e9cca472aeb1f4da133e2a0ccf9
--- /dev/null
+++ b/src/main/webapp/META-INF/aop.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!-- Custom aspects for the PetClinic sample application -->
+<aspectj>
+
+	<weaver>
+		<include within="org.springframework.samples.petclinic..*"/>
+	</weaver>
+
+	<aspects>
+		<aspect name="org.springframework.samples.petclinic.aspects.UsageLogAspect"/>
+		<concrete-aspect name="org.springframework.samples.petclinic.aspects.ApplicationTraceAspect"
+				extends="org.springframework.samples.petclinic.aspects.AbstractTraceAspect">
+			<pointcut name="traced" expression="execution(* org.springframework.samples..*.*(..))"/>
+		</concrete-aspect>
+	</aspects>
+
+</aspectj>
diff --git a/src/main/webapp/META-INF/context.xml b/src/main/webapp/META-INF/context.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5deabaf701f03c27f6346e0cc375876778aefc0
--- /dev/null
+++ b/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,7 @@
+<!-- Tomcat context descriptor used for specifying a custom ClassLoader -->
+<Context path="/petclinic" reloadable="false">
+	<!-- please note that useSystemClassLoaderAsParent is available since Tomcat 5.5.20 / remove if previous versions are being used -->
+	<!--  
+	<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader" useSystemClassLoaderAsParent="false"/>
+	-->
+</Context>
diff --git a/src/main/webapp/META-INF/hsqldb/dropTables.txt b/src/main/webapp/META-INF/hsqldb/dropTables.txt
new file mode 100644
index 0000000000000000000000000000000000000000..90ae6329f90859d5945753ba28441d489b0384f7
--- /dev/null
+++ b/src/main/webapp/META-INF/hsqldb/dropTables.txt
@@ -0,0 +1,7 @@
+DROP TABLE visits;
+DROP TABLE pets;
+DROP TABLE owners;
+DROP TABLE types;
+DROP TABLE vet_specialties;
+DROP TABLE specialties;
+DROP TABLE vets;
diff --git a/src/main/webapp/META-INF/hsqldb/initDB.txt b/src/main/webapp/META-INF/hsqldb/initDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a75bfbbd86da3da4e60d6fbd5ed565837453b657
--- /dev/null
+++ b/src/main/webapp/META-INF/hsqldb/initDB.txt
@@ -0,0 +1,55 @@
+CREATE TABLE vets (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	first_name VARCHAR(30),
+	last_name VARCHAR(30)
+);
+CREATE INDEX vets_last_name ON vets(last_name);
+
+CREATE TABLE specialties (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	name VARCHAR(80)
+);
+CREATE INDEX specialties_name ON specialties(name);
+
+CREATE TABLE vet_specialties (
+	vet_id INTEGER NOT NULL,
+	specialty_id INTEGER NOT NULL
+);
+alter table vet_specialties add constraint fk_vet_specialties_vets foreign key (vet_id) references vets(id);
+alter table vet_specialties add constraint fk_vet_specialties_specialties foreign key (specialty_id) references specialties(id);
+
+CREATE TABLE types (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	name VARCHAR(80)
+);
+CREATE INDEX types_name ON types(name);
+
+CREATE TABLE owners (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	first_name VARCHAR(30),
+	last_name VARCHAR(30),
+	address VARCHAR(255),
+	city VARCHAR(80),
+	telephone VARCHAR(20)
+);
+CREATE INDEX owners_last_name ON owners(last_name);
+
+CREATE TABLE pets (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	name VARCHAR(30),
+	birth_date DATE,
+	type_id INTEGER NOT NULL,
+	owner_id INTEGER NOT NULL
+);
+alter table pets add constraint fk_pets_owners foreign key (owner_id) references owners(id);
+alter table pets add constraint fk_pets_types foreign key (type_id) references types(id);
+CREATE INDEX pets_name ON pets(name);
+
+CREATE TABLE visits (
+	id INTEGER NOT NULL IDENTITY PRIMARY KEY,
+	pet_id INTEGER NOT NULL,
+	visit_date DATE,
+	description VARCHAR(255)
+);
+alter table visits add constraint fk_visits_pets foreign key (pet_id) references pets(id);
+CREATE INDEX visits_pet_id ON visits(pet_id);
diff --git a/src/main/webapp/META-INF/hsqldb/populateDB.txt b/src/main/webapp/META-INF/hsqldb/populateDB.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1bf0c4a6edb05ac0f8bb2382d19367d8b15e85cf
--- /dev/null
+++ b/src/main/webapp/META-INF/hsqldb/populateDB.txt
@@ -0,0 +1,53 @@
+INSERT INTO vets VALUES (1, 'James', 'Carter');
+INSERT INTO vets VALUES (2, 'Helen', 'Leary');
+INSERT INTO vets VALUES (3, 'Linda', 'Douglas');
+INSERT INTO vets VALUES (4, 'Rafael', 'Ortega');
+INSERT INTO vets VALUES (5, 'Henry', 'Stevens');
+INSERT INTO vets VALUES (6, 'Sharon', 'Jenkins');
+
+INSERT INTO specialties VALUES (1, 'radiology');
+INSERT INTO specialties VALUES (2, 'surgery');
+INSERT INTO specialties VALUES (3, 'dentistry');
+
+INSERT INTO vet_specialties VALUES (2, 1);
+INSERT INTO vet_specialties VALUES (3, 2);
+INSERT INTO vet_specialties VALUES (3, 3);
+INSERT INTO vet_specialties VALUES (4, 2);
+INSERT INTO vet_specialties VALUES (5, 1);
+
+INSERT INTO types VALUES (1, 'cat');
+INSERT INTO types VALUES (2, 'dog');
+INSERT INTO types VALUES (3, 'lizard');
+INSERT INTO types VALUES (4, 'snake');
+INSERT INTO types VALUES (5, 'bird');
+INSERT INTO types VALUES (6, 'hamster');
+
+INSERT INTO owners VALUES (1, 'George', 'Franklin', '110 W. Liberty St.', 'Madison', '6085551023');
+INSERT INTO owners VALUES (2, 'Betty', 'Davis', '638 Cardinal Ave.', 'Sun Prairie', '6085551749');
+INSERT INTO owners VALUES (3, 'Eduardo', 'Rodriquez', '2693 Commerce St.', 'McFarland', '6085558763');
+INSERT INTO owners VALUES (4, 'Harold', 'Davis', '563 Friendly St.', 'Windsor', '6085553198');
+INSERT INTO owners VALUES (5, 'Peter', 'McTavish', '2387 S. Fair Way', 'Madison', '6085552765');
+INSERT INTO owners VALUES (6, 'Jean', 'Coleman', '105 N. Lake St.', 'Monona', '6085552654');
+INSERT INTO owners VALUES (7, 'Jeff', 'Black', '1450 Oak Blvd.', 'Monona', '6085555387');
+INSERT INTO owners VALUES (8, 'Maria', 'Escobito', '345 Maple St.', 'Madison', '6085557683');
+INSERT INTO owners VALUES (9, 'David', 'Schroeder', '2749 Blackhawk Trail', 'Madison', '6085559435');
+INSERT INTO owners VALUES (10, 'Carlos', 'Estaban', '2335 Independence La.', 'Waunakee', '6085555487');
+
+INSERT INTO pets VALUES (1, 'Leo', '2000-09-07', 1, 1);
+INSERT INTO pets VALUES (2, 'Basil', '2002-08-06', 6, 2);
+INSERT INTO pets VALUES (3, 'Rosy', '2001-04-17', 2, 3);
+INSERT INTO pets VALUES (4, 'Jewel', '2000-03-07', 2, 3);
+INSERT INTO pets VALUES (5, 'Iggy', '2000-11-30', 3, 4);
+INSERT INTO pets VALUES (6, 'George', '2000-01-20', 4, 5);
+INSERT INTO pets VALUES (7, 'Samantha', '1995-09-04', 1, 6);
+INSERT INTO pets VALUES (8, 'Max', '1995-09-04', 1, 6);
+INSERT INTO pets VALUES (9, 'Lucky', '1999-08-06', 5, 7);
+INSERT INTO pets VALUES (10, 'Mulligan', '1997-02-24', 2, 8);
+INSERT INTO pets VALUES (11, 'Freddy', '2000-03-09', 5, 9);
+INSERT INTO pets VALUES (12, 'Lucky', '2000-06-24', 2, 10);
+INSERT INTO pets VALUES (13, 'Sly', '2002-06-08', 1, 10);
+
+INSERT INTO visits VALUES (1, 7, '1996-03-04', 'rabies shot');
+INSERT INTO visits VALUES (2, 8, '1996-03-04', 'rabies shot');
+INSERT INTO visits VALUES (3, 8, '1996-06-04', 'neutered');
+INSERT INTO visits VALUES (4, 7, '1996-09-04', 'spayed');
diff --git a/src/main/webapp/META-INF/orm.xml b/src/main/webapp/META-INF/orm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d7c8f7040a13f121824717b763d879068e24233c
--- /dev/null
+++ b/src/main/webapp/META-INF/orm.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
+		version="1.0">
+
+	<persistence-unit-metadata>
+		<xml-mapping-metadata-complete/>
+		<persistence-unit-defaults>
+			<access>PROPERTY</access>
+		</persistence-unit-defaults>
+	</persistence-unit-metadata>
+
+	<package>org.springframework.samples.petclinic</package>
+
+	<mapped-superclass class="BaseEntity">
+		<attributes>
+			<id name="id">
+				<generated-value strategy="IDENTITY"/>
+			</id>
+			<transient name="new"/>
+		</attributes>
+	</mapped-superclass>
+
+	<mapped-superclass class="NamedEntity">
+		<attributes>
+			<basic name="name">
+				<column name="NAME"/>
+			</basic>
+		</attributes>
+	</mapped-superclass>
+
+	<mapped-superclass class="Person">
+		<attributes>
+			<basic name="firstName">
+				<column name="FIRST_NAME"/>
+			</basic>
+			<basic name="lastName">
+				<column name="LAST_NAME"/>
+			</basic>
+		</attributes>
+	</mapped-superclass>
+
+	<entity class="Vet">
+		<table name="VETS"/>
+		<attributes>
+			<many-to-many name="specialtiesInternal" target-entity="Specialty" fetch="EAGER">
+				<join-table name="VET_SPECIALTIES">
+					<join-column name="VET_ID"/>
+					<inverse-join-column name="SPECIALTY_ID"/>
+				</join-table>
+			</many-to-many>
+			<transient name="specialties"/>
+			<transient name="nrOfSpecialties"/>
+		</attributes>
+	</entity>
+
+	<entity class="Specialty">
+		<table name="SPECIALTIES"/>
+	</entity>
+
+	<entity class="Owner">
+		<table name="OWNERS"/>
+		<attributes>
+			<basic name="address"/>
+			<basic name="city"/>
+			<basic name="telephone"/>
+			<one-to-many name="petsInternal" target-entity="Pet" mapped-by="owner" fetch="EAGER">
+				<cascade>
+					<cascade-all/>
+				</cascade>
+			</one-to-many>
+			<transient name="pets"/>
+		</attributes>
+	</entity>
+
+	<entity class="Pet">
+		<table name="PETS"/>
+		<attributes>
+			<basic name="birthDate">
+				<column name="BIRTH_DATE"/>
+				<temporal>DATE</temporal>
+			</basic>
+			<many-to-one name="owner" fetch="EAGER">
+				<cascade>
+					<cascade-all/>
+				</cascade>
+			</many-to-one>
+			<many-to-one name="type" fetch="EAGER">
+				<cascade>
+					<cascade-all/>
+				</cascade>
+			</many-to-one>
+			<one-to-many name="visitsInternal" target-entity="Visit" mapped-by="pet" fetch="EAGER">
+				<cascade>
+					<cascade-all/>
+				</cascade>
+			</one-to-many>
+			<transient name="visits"/>
+		</attributes>
+	</entity>
+
+	<entity class="PetType">
+		<table name="TYPES"/>
+	</entity>
+
+	<entity class="Visit">
+		<table name="VISITS"/>
+		<attributes>
+			<basic name="date">
+				<column name="VISIT_DATE"/>
+				<temporal>DATE</temporal>
+			</basic>
+			<many-to-one name="pet" fetch="EAGER">
+				<cascade>
+					<cascade-all/>
+				</cascade>
+			</many-to-one>
+		</attributes>
+	</entity>
+
+</entity-mappings>
diff --git a/src/main/webapp/META-INF/persistence.xml b/src/main/webapp/META-INF/persistence.xml
new file mode 100644
index 0000000000000000000000000000000000000000..86bf7c115d83338fa6cbe49e8cb07be48b3dfb94
--- /dev/null
+++ b/src/main/webapp/META-INF/persistence.xml
@@ -0,0 +1,16 @@
+<persistence xmlns="http://java.sun.com/xml/ns/persistence"
+		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
+		version="1.0">
+
+	<persistence-unit name="PetClinic" transaction-type="RESOURCE_LOCAL">
+
+		<!-- Explicitly define mapping file path, else Hibernate won't find the default -->
+		<mapping-file>META-INF/orm.xml</mapping-file>
+
+		<!-- Prevent annotation scanning. In this app we are purely driven by orm.xml -->
+		<exclude-unlisted-classes>true</exclude-unlisted-classes>
+
+	</persistence-unit>
+
+</persistence>
diff --git a/src/main/webapp/WEB-INF/applicationContext-hibernate.xml b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bfc166db6253d6a10eed9680f488b8adb2b15285
--- /dev/null
+++ b/src/main/webapp/WEB-INF/applicationContext-hibernate.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Application context definition for PetClinic on Hibernate.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
+		xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
+			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
+
+	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
+
+	<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
+	<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
+	<context:property-placeholder location="classpath:jdbc.properties"/>
+
+	<!--
+		Uses Apache Commons DBCP for connection pooling. See Commons DBCP documentation
+		for the required JAR files. Alternatively you can use another connection pool
+		such as C3P0, similarly configured using Spring.
+	-->
+	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
+			p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
+			p:password="${jdbc.password}"/>
+
+	<!-- JNDI DataSource for JEE environments -->
+	<!--
+		<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
+	-->
+
+	<!-- Hibernate SessionFactory -->
+	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
+			p:dataSource-ref="dataSource" p:mappingResources="petclinic.hbm.xml">
+		<property name="hibernateProperties">
+			<props>
+				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
+				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
+				<prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
+			</props>
+		</property>
+		<property name="eventListeners">
+			<map>
+				<entry key="merge">
+					<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener"/>
+				</entry>
+			</map>
+		</property>
+	</bean>
+
+	<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
+	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
+			p:sessionFactory-ref="sessionFactory"/>
+
+	<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
+	<!--
+	<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
+	-->
+
+
+	<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
+
+	<!--
+		Activates various annotations to be detected in bean classes:
+		Spring's @Required and @Autowired, as well as JSR 250's @Resource.
+	-->
+	<context:annotation-config/>
+
+	<!--
+		Instruct Spring to perform declarative transaction management
+		automatically on annotated classes.
+	-->
+	<tx:annotation-driven/>
+
+	<!--
+		Exporter that exposes the Hibernate statistics service via JMX. Autodetects the
+		service MBean, using its bean name as JMX object name.
+	-->
+	<context:mbean-export/>
+
+	<!-- PetClinic's central data access object: Hibernate implementation -->
+	<bean id="clinic" class="org.springframework.samples.petclinic.hibernate.HibernateClinic"/>
+
+	<!-- Hibernate's JMX statistics service -->
+	<bean name="petclinic:type=HibernateStatistics" class="org.hibernate.jmx.StatisticsService" autowire="byName"/>
+
+</beans>
diff --git a/src/main/webapp/WEB-INF/applicationContext-jdbc.xml b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..69a2b1f5dcc7f75389f272eb4bc25ede55ba02ff
--- /dev/null
+++ b/src/main/webapp/WEB-INF/applicationContext-jdbc.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Application context definition for PetClinic on JDBC.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
+		xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
+		xmlns:tx="http://www.springframework.org/schema/tx"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
+			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
+			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
+
+	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
+
+	<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
+	<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
+	<context:property-placeholder location="classpath:jdbc.properties"/>
+
+	<!--
+		Spring FactoryBean that creates a DataSource using Apache Commons DBCP for connection 
+		pooling. See Commons DBCP documentation for the required JAR files.  This factory bean
+		can populate the data source with a schema and data scripts if configured to do so.
+		
+		An alternate factory bean can be created for different connection pool implementations,
+		C3P0 for example.
+	-->
+	<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
+			p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" 
+			p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
+			p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"/>
+
+	<!-- JNDI DataSource for JEE environments -->
+	<!--
+	<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
+	-->
+
+	<!-- Transaction manager for a single JDBC DataSource (alternative to JTA) -->
+	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
+			p:dataSource-ref="dataSource"/>
+
+	<!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
+	<!--
+	<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
+	-->
+
+
+	<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
+
+	<!--
+		Activates various annotations to be detected in bean classes: Spring's
+		@Required and @Autowired, as well as JSR 250's @PostConstruct,
+		@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
+		and @PersistenceUnit (if available).
+	-->
+	<context:annotation-config/>
+
+	<!--
+		Instruct Spring to retrieve and apply @AspectJ aspects which are defined
+		as beans in this context (such as the CallMonitoringAspect below).
+	-->
+	<aop:aspectj-autoproxy/>
+
+	<!--
+		Instruct Spring to perform automatic transaction management on annotated classes.
+		The SimpleJdbcClinic implementation declares @Transactional annotations.
+		"proxy-target-class" is set because of SimpleJdbcClinic's @ManagedOperation usage.
+	-->
+	<tx:annotation-driven/>
+
+	<!--
+		Exporter that exposes the Clinic DAO and the CallMonitoringAspect via JMX,
+		based on the @ManagedResource, @ManagedAttribute, and @ManagedOperation annotations.
+	-->
+	<context:mbean-export/>
+
+	<!-- PetClinic's central data access object using Spring's SimpleJdbcTemplate -->
+	<bean id="clinic" class="org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic"/>
+
+	<!-- Call monitoring aspect that monitors call count and call invocation time -->
+	<bean id="callMonitor" class="org.springframework.samples.petclinic.aspects.CallMonitoringAspect"/>
+
+</beans>
diff --git a/src/main/webapp/WEB-INF/applicationContext-jpa.xml b/src/main/webapp/WEB-INF/applicationContext-jpa.xml
new file mode 100644
index 0000000000000000000000000000000000000000..25374e9abe2cf717be38eb4dae3a3ec95b852175
--- /dev/null
+++ b/src/main/webapp/WEB-INF/applicationContext-jpa.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	Application context definition for PetClinic on JPA.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
+		xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee"
+		xmlns:tx="http://www.springframework.org/schema/tx"
+		xsi:schemaLocation="
+			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
+			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+			http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+			http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
+			http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
+
+	<!-- ========================= RESOURCE DEFINITIONS ========================= -->
+
+	<!--
+		Activates a load-time weaver for the context. Any bean within the context that
+		implements LoadTimeWeaverAware (such as LocalContainerEntityManagerFactoryBean)
+		will receive a reference to the autodetected load-time weaver.
+	-->
+	<context:load-time-weaver/>
+
+	<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
+	<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
+	<context:property-placeholder location="classpath:jdbc.properties"/>
+
+	<!--
+		Uses Apache Commons DBCP for connection pooling. See Commons DBCP documentation
+		for the required JAR files. Alternatively you can use another connection pool
+		such as C3P0, similarly configured using Spring.
+	-->
+	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"
+			p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" p:username="${jdbc.username}"
+			p:password="${jdbc.password}"/>
+
+	<!-- JNDI DataSource for JEE environments -->
+	<!--
+	<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
+	-->
+
+	<!-- JPA EntityManagerFactory -->
+	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
+			p:dataSource-ref="dataSource">
+		<property name="jpaVendorAdapter">
+			<bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
+					p:databasePlatform="${jpa.databasePlatform}" p:showSql="${jpa.showSql}"/>
+			<!--
+			<bean class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter"
+					p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
+			-->
+			<!--
+			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
+					p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
+			-->
+		</property>
+	</bean>
+
+	<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->
+	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
+			p:entityManagerFactory-ref="entityManagerFactory"/>
+
+
+	<!-- ========================= BUSINESS OBJECT DEFINITIONS ========================= -->
+
+	<!--
+		Activates various annotations to be detected in bean classes: Spring's
+		@Required and @Autowired, as well as JSR 250's @PostConstruct,
+		@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
+		and @PersistenceUnit (if available).
+	-->
+	<context:annotation-config/>
+
+	<!--
+		Instruct Spring to perform declarative transaction management
+		automatically on annotated classes.
+	-->
+	<tx:annotation-driven mode="aspectj"/>
+
+	<!--
+		Simply defining this bean will cause requests to owner names to be saved.
+		This aspect is defined in petclinic.jar's META-INF/aop.xml file.
+		Note that we can dependency inject this bean like any other bean.
+	-->
+	<bean class="org.springframework.samples.petclinic.aspects.UsageLogAspect" p:historySize="300"/>
+
+	<!--
+		Post-processor to perform exception translation on @Repository classes (from native
+		exceptions such as JPA PersistenceExceptions to Spring's DataAccessException hierarchy).
+	-->
+	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
+
+	<!--
+		Will automatically be transactional due to @Transactional.
+		EntityManager will be auto-injected due to @PersistenceContext.
+		PersistenceExceptions will be auto-translated due to @Repository.
+	-->
+	<bean id="clinic" class="org.springframework.samples.petclinic.jpa.EntityManagerClinic"/>
+
+</beans>
diff --git a/src/main/webapp/WEB-INF/classes/log4j.properties b/src/main/webapp/WEB-INF/classes/log4j.properties
new file mode 100644
index 0000000000000000000000000000000000000000..ebee551aa88864fb8a3ae65dcd1ebe88b66ac4ba
--- /dev/null
+++ b/src/main/webapp/WEB-INF/classes/log4j.properties
@@ -0,0 +1,18 @@
+# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
+# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
+log4j.rootLogger=INFO, stdout, logfile
+
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n
+
+log4j.appender.logfile=org.apache.log4j.RollingFileAppender
+log4j.appender.logfile.File=${petclinic.root}/WEB-INF/petclinic.log
+log4j.appender.logfile.MaxFileSize=512KB
+# Keep three backup files.
+log4j.appender.logfile.MaxBackupIndex=3
+# Pattern to output: date priority [category] - message
+log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
+log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
+
+log4j.logger.org.springframework.samples.petclinic.aspects=DEBUG
diff --git a/src/main/webapp/WEB-INF/classes/messages.properties b/src/main/webapp/WEB-INF/classes/messages.properties
new file mode 100644
index 0000000000000000000000000000000000000000..173417a1014824791ee97decfc43084273fd0723
--- /dev/null
+++ b/src/main/webapp/WEB-INF/classes/messages.properties
@@ -0,0 +1,8 @@
+welcome=Welcome
+required=is required
+notFound=has not been found
+duplicate=is already in use
+nonNumeric=must be all numeric
+duplicateFormSubmission=Duplicate form submission is not allowed
+typeMismatch.date=invalid date
+typeMismatch.birthDate=invalid date
diff --git a/src/main/webapp/WEB-INF/classes/messages_de.properties b/src/main/webapp/WEB-INF/classes/messages_de.properties
new file mode 100644
index 0000000000000000000000000000000000000000..124bee48b2c863f62b80367890392fb0775efcfd
--- /dev/null
+++ b/src/main/webapp/WEB-INF/classes/messages_de.properties
@@ -0,0 +1,8 @@
+welcome=Willkommen
+required=muss angegeben werden
+notFound=wurde nicht gefunden
+duplicate=ist bereits vergeben
+nonNumeric=darf nur numerisch sein
+duplicateFormSubmission=Wiederholtes Absenden des Formulars ist nicht erlaubt
+typeMismatch.date=ungültiges Datum
+typeMismatch.birthDate=ungültiges Datum
diff --git a/src/main/webapp/WEB-INF/classes/messages_en.properties b/src/main/webapp/WEB-INF/classes/messages_en.properties
new file mode 100644
index 0000000000000000000000000000000000000000..05d519bb86d059e73ce879196658c54c1e8cd7dc
--- /dev/null
+++ b/src/main/webapp/WEB-INF/classes/messages_en.properties
@@ -0,0 +1 @@
+# This file is intentionally empty. Message look-ups will fall back to the default "messages.properties" file.
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/geronimo-web.xml b/src/main/webapp/WEB-INF/geronimo-web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b5d88e1ecd2fa8ea9da8d02f63c2fed8bfedde14
--- /dev/null
+++ b/src/main/webapp/WEB-INF/geronimo-web.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns="http://geronimo.apache.org/xml/ns/j2ee/web-1.0"
+		 configId="org/springframework/samples/petclinic">
+	<context-root>/petclinic</context-root>
+	<context-priority-classloader>true</context-priority-classloader>
+</web-app>
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..256cca17786ac11c8add7aa544301df6183c52e6
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/dataAccessFailure.jsp
@@ -0,0 +1,19 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<%
+Exception ex = (Exception) request.getAttribute("exception");
+%>
+
+<h2>Data access failure: <%= ex.getMessage() %></h2>
+<p/>
+
+<%
+ex.printStackTrace(new java.io.PrintWriter(out));
+%>
+
+<p/>
+<br/>
+<a href="<spring:url value="/" htmlEscape="true" />">Home</a>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..52aaffc47e73c0aabb743f735c8670161140cd1a
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/footer.jsp
@@ -0,0 +1,12 @@
+
+  <table class="footer">
+    <tr>
+      <td><a href="<spring:url value="/" htmlEscape="true" />">Home</a></td>
+      <td align="right"><img src="<spring:url value="/static/images/springsource-logo.png" htmlEscape="true" />" alt="Sponsored by SpringSource"/></td>
+    </tr>
+  </table>
+
+  </div>
+</body>
+
+</html>
diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..49393d364c9bb15d9a84810bc78a4e60a8743dcf
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/header.jsp
@@ -0,0 +1,14 @@
+<!--
+	PetClinic :: a Spring Framework demonstration
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+  <link rel="stylesheet" href="<spring:url value="/static/styles/petclinic.css" htmlEscape="true" />" type="text/css"/>
+  <title>PetClinic :: a Spring Framework demonstration</title>	
+</head>
+
+<body>
+
+  <div id="main">
diff --git a/src/main/webapp/WEB-INF/jsp/includes.jsp b/src/main/webapp/WEB-INF/jsp/includes.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..96c3e304cdb3e96bd330210972c3701fd92abf73
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/includes.jsp
@@ -0,0 +1,5 @@
+<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
+<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
diff --git a/src/main/webapp/WEB-INF/jsp/owners/form.jsp b/src/main/webapp/WEB-INF/jsp/owners/form.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..1670a7c1bf529be6b009e304e11ce2c731ef337d
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/owners/form.jsp
@@ -0,0 +1,61 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+<c:choose>
+	<c:when test="${owner.new}"><c:set var="method" value="post"/></c:when>
+	<c:otherwise><c:set var="method" value="put"/></c:otherwise>
+</c:choose>
+
+<h2><c:if test="${owner.new}">New </c:if>Owner:</h2>
+<form:form modelAttribute="owner" method="${method}">
+  <table>
+    <tr>
+      <th>
+        First Name: <form:errors path="firstName" cssClass="errors"/>
+        <br/>
+        <form:input path="firstName" size="30" maxlength="80"/>
+      </th>
+    </tr>
+    <tr>
+      <th>
+        Last Name: <form:errors path="lastName" cssClass="errors"/>
+        <br/>
+        <form:input path="lastName" size="30" maxlength="80"/>
+      </th>
+    </tr>
+    <tr>
+      <th>
+        Address: <form:errors path="address" cssClass="errors"/>
+        <br/>
+        <form:input path="address" size="30" maxlength="80"/>
+      </th>
+    </tr>
+    <tr>
+      <th>
+        City: <form:errors path="city" cssClass="errors"/>
+        <br/>
+        <form:input path="city" size="30" maxlength="80"/>
+      </th>
+    </tr>
+    <tr>
+      <th>
+        Telephone: <form:errors path="telephone" cssClass="errors"/>
+        <br/>
+        <form:input path="telephone" size="20" maxlength="20"/>
+      </th>
+    </tr>
+    <tr>
+      <td>
+        <c:choose>
+          <c:when test="${owner.new}">
+            <p class="submit"><input type="submit" value="Add Owner"/></p>
+          </c:when>
+          <c:otherwise>
+            <p class="submit"><input type="submit" value="Update Owner"/></p>
+          </c:otherwise>
+        </c:choose>
+      </td>
+    </tr>
+  </table>
+</form:form>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/owners/list.jsp b/src/main/webapp/WEB-INF/jsp/owners/list.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..44fc3cac0b8631960ce76cd1a9cc05d9faf87ed3
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/owners/list.jsp
@@ -0,0 +1,34 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<h2>Owners:</h2>
+
+<table>
+  <thead>
+    <th>Name</th>
+    <th>Address</th>
+    <th>City</th>
+    <th>Telephone</th>
+    <th>Pets</th>
+  </thead>
+  <c:forEach var="owner" items="${selections}">
+    <tr>
+      <td>
+          <spring:url value="owners/{ownerId}" var="ownerUrl">
+              <spring:param name="ownerId" value="${owner.id}"/>
+          </spring:url>
+          <a href="${fn:escapeXml(ownerUrl)}">${owner.firstName} ${owner.lastName}</a>
+      </td>
+      <td>${owner.address}</td>
+      <td>${owner.city}</td>
+      <td>${owner.telephone}</td>
+      <td>
+        <c:forEach var="pet" items="${owner.pets}">
+          ${pet.name} &nbsp;
+        </c:forEach>
+      </td>
+    </tr>
+  </c:forEach>
+</table>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/owners/search.jsp b/src/main/webapp/WEB-INF/jsp/owners/search.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..b972390a19fabba33e45845b11733c416de7e38f
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/owners/search.jsp
@@ -0,0 +1,26 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+
+<h2>Find Owners:</h2>
+
+<spring:url value="/owners" var="formUrl"/>
+<form:form modelAttribute="owner" action="${fn:escapeXml(formUrl)}" method="get">
+  <table>
+    <tr>
+      <th>
+        Last Name: <form:errors path="*" cssClass="errors"/>
+        <br/> 
+        <form:input path="lastName" size="30" maxlength="80" />
+      </th>
+    </tr>
+    <tr>
+      <td><p class="submit"><input type="submit" value="Find Owners"/></p></td>
+    </tr>
+  </table>
+</form:form>
+
+<br/>
+<a href='<spring:url value="/owners/new" htmlEscape="true"/>'>Add Owner</a>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/owners/show.jsp b/src/main/webapp/WEB-INF/jsp/owners/show.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..9767c18ae17fdef936aea8ac237622c449c0fca8
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/owners/show.jsp
@@ -0,0 +1,108 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
+
+<h2>Owner Information</h2>
+
+  <table>
+    <tr>
+      <th>Name</th>
+      <td><b>${owner.firstName} ${owner.lastName}</b></td>
+    </tr>
+    <tr>
+      <th>Address</th>
+      <td>${owner.address}</td>
+    </tr>
+    <tr>
+      <th>City</th>
+      <td>${owner.city}</td>
+    </tr>
+    <tr>
+      <th>Telephone </th>
+      <td>${owner.telephone}</td>
+    </tr>
+  </table>
+  <table class="table-buttons">
+    <tr>
+      <td colspan="2" align="center">
+        <spring:url value="{ownerId}/edit" var="editUrl">
+        	<spring:param name="ownerId" value="${owner.id}" />
+        </spring:url>
+        <a href="${fn:escapeXml(editUrl)}">Edit Owner</a>
+      </td>
+      <td>
+        <spring:url value="{ownerId}/pets/new" var="addUrl">
+        	<spring:param name="ownerId" value="${owner.id}" />
+        </spring:url>
+        <a href="${fn:escapeXml(addUrl)}">Add New Pet</a>
+      </td>
+    </tr>
+  </table>
+
+  <h2>Pets and Visits</h2>
+
+  <c:forEach var="pet" items="${owner.pets}">
+    <table width="94%">
+      <tr>
+        <td valign="top">
+          <table>
+            <tr>
+              <th>Name</th>
+              <td><b>${pet.name}</b></td>
+            </tr>
+            <tr>
+              <th>Birth Date</th>
+              <td><fmt:formatDate value="${pet.birthDate}" pattern="yyyy-MM-dd"/></td>
+            </tr>
+            <tr>
+              <th>Type</th>
+              <td>${pet.type.name}</td>
+            </tr>
+          </table>
+        </td>
+        <td valign="top">
+          <table>
+            <thead>
+              <th>Visit Date</th>
+              <th>Description</th>
+            </thead>
+            <c:forEach var="visit" items="${pet.visits}">
+              <tr>
+                <td><fmt:formatDate value="${visit.date}" pattern="yyyy-MM-dd"/></td>
+                <td>${visit.description}</td>
+              </tr>
+            </c:forEach>
+          </table>
+        </td>
+      </tr>
+    </table>
+    <table class="table-buttons">
+      <tr>
+        <td>
+          <spring:url value="{ownerId}/pets/{petId}/edit" var="petUrl">
+            <spring:param name="ownerId" value="${owner.id}"/>
+            <spring:param name="petId" value="${pet.id}"/>
+          </spring:url>
+          <a href="${fn:escapeXml(petUrl)}">Edit Pet</a>
+        </td>
+        <td></td>
+        <td>
+          <spring:url value="{ownerId}/pets/{petId}/visits/new" var="visitUrl">
+            <spring:param name="ownerId" value="${owner.id}"/>
+            <spring:param name="petId" value="${pet.id}"/>
+          </spring:url>
+          <a href="${fn:escapeXml(visitUrl)}">Add Visit</a>
+        </td>
+        <td></td>
+        <td>
+          <spring:url value="{ownerId}/pets/{petId}/visits.atom" var="feedUrl">
+            <spring:param name="ownerId" value="${owner.id}"/>
+            <spring:param name="petId" value="${pet.id}"/>
+          </spring:url>
+          <a href="${fn:escapeXml(feedUrl)}" rel="alternate" type="application/atom+xml">Atom Feed</a>
+        </td>
+      </tr>
+    </table>
+  </c:forEach>
+  
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/pets/form.jsp b/src/main/webapp/WEB-INF/jsp/pets/form.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..459ec63b35d452a3fbd8e138c15465704a40d814
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/pets/form.jsp
@@ -0,0 +1,56 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+<c:choose>
+	<c:when test="${pet.new}"><c:set var="method" value="post"/></c:when>
+	<c:otherwise><c:set var="method" value="put"/></c:otherwise>
+</c:choose>
+
+<h2><c:if test="${pet.new}">New </c:if>Pet</h2>
+
+<b>Owner:</b> ${pet.owner.firstName} ${pet.owner.lastName}
+<br/>
+<form:form modelAttribute="pet" method="${method}">
+  <table>
+    <tr>
+      <th>
+        Name: <form:errors path="name" cssClass="errors"/>
+        <br/>
+        <form:input path="name" size="30" maxlength="30"/>
+      </th>
+    </tr>
+    <tr>
+      <th>
+        Birth Date: <form:errors path="birthDate" cssClass="errors"/>
+        <br/>
+        <form:input path="birthDate" size="10" maxlength="10"/> (yyyy-mm-dd)
+      </th>
+    </tr>
+    <tr>
+      <th>
+        Type: <form:errors path="type" cssClass="errors"/>
+        <br/>
+        <form:select path="type" items="${types}"/>
+      </th>
+    </tr>
+    <tr>
+      <td>
+        <c:choose>
+          <c:when test="${pet.new}">
+            <p class="submit"><input type="submit" value="Add Pet"/></p>
+          </c:when>
+          <c:otherwise>
+            <p class="submit"><input type="submit" value="Update Pet"/></p>
+          </c:otherwise>
+        </c:choose>
+      </td>
+    </tr>
+  </table>
+</form:form>
+
+<c:if test="${!pet.new}">
+  <form:form method="delete">
+    <p class="submit"><input type="submit" value="Delete Pet"/></p>
+  </form:form>
+</c:if>    
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..b1207a00f3ed867235ad65a9773ad86c66818f05
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/pets/visitForm.jsp
@@ -0,0 +1,68 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<h2><c:if test="${visit.new}">New </c:if>Visit:</h2>
+
+<form:form modelAttribute="visit">
+  <b>Pet:</b>
+  <table width="333">
+    <thead>
+      <th>Name</th>
+      <th>Birth Date</th>
+      <th>Type</th>
+      <th>Owner</th>
+    </thead>
+    <tr>
+      <td>${visit.pet.name}</td>
+      <td><fmt:formatDate value="${visit.pet.birthDate}" pattern="yyyy-MM-dd"/></td>
+      <td>${visit.pet.type.name}</td>
+      <td>${visit.pet.owner.firstName} ${visit.pet.owner.lastName}</td>
+    </tr>
+  </table>
+
+  <table width="333">
+    <tr>
+      <th>
+        Date:
+        <br/><form:errors path="date" cssClass="errors"/>
+      </th>
+      <td>
+        <form:input path="date" size="10" maxlength="10"/> (yyyy-mm-dd)
+      </td>
+    <tr/>
+    <tr>
+      <th valign="top">
+        Description:
+        <br/><form:errors path="description" cssClass="errors"/>
+      </th>
+      <td>
+        <form:textarea path="description" rows="10" cols="25"/>
+      </td>
+    </tr>
+    <tr>
+      <td colspan="2">
+        <input type="hidden" name="petId" value="${visit.pet.id}"/>
+        <p class="submit"><input type="submit" value="Add Visit"/></p>
+      </td>
+    </tr>
+  </table>
+</form:form>
+
+<br/>
+<b>Previous Visits:</b>
+<table width="333">
+  <tr>
+    <th>Date</th>
+    <th>Description</th>
+  </tr>
+  <c:forEach var="visit" items="${visit.pet.visits}">
+    <c:if test="${!visit.new}">
+      <tr>
+        <td><fmt:formatDate value="${visit.date}" pattern="yyyy-MM-dd"/></td>
+        <td>${visit.description}</td>
+      </tr>
+    </c:if>
+  </c:forEach>
+</table>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..e97fdf378899784ec4b48949e8c6d6a8e47b4566
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/uncaughtException.jsp
@@ -0,0 +1,49 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<h2/>Internal error</h2>
+<p/>
+
+<% 
+try {
+	// The Servlet spec guarantees this attribute will be available
+	Throwable exception = (Throwable) request.getAttribute("javax.servlet.error.exception"); 
+
+	if (exception != null) {
+		if (exception instanceof ServletException) {
+			// It's a ServletException: we should extract the root cause
+			ServletException sex = (ServletException) exception;
+			Throwable rootCause = sex.getRootCause();
+			if (rootCause == null)
+				rootCause = sex;
+			out.println("** Root cause is: "+ rootCause.getMessage());
+			rootCause.printStackTrace(new java.io.PrintWriter(out)); 
+		}
+		else {
+			// It's not a ServletException, so we'll just show it
+			exception.printStackTrace(new java.io.PrintWriter(out)); 
+		}
+	} 
+	else  {
+    	out.println("No error information available");
+	} 
+
+	// Display cookies
+	out.println("\nCookies:\n");
+	Cookie[] cookies = request.getCookies();
+	if (cookies != null) {
+    	for (int i = 0; i < cookies.length; i++) {
+      		out.println(cookies[i].getName() + "=[" + cookies[i].getValue() + "]");
+		}
+	}
+	    
+} catch (Exception ex) { 
+	ex.printStackTrace(new java.io.PrintWriter(out));
+}
+%>
+
+<p/>
+<br/>
+
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/vets.jsp b/src/main/webapp/WEB-INF/jsp/vets.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..cff2154f2902c343386d3c8421610e90c5c996f8
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/vets.jsp
@@ -0,0 +1,31 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<h2>Veterinarians:</h2>
+
+<table>
+  <thead>
+    <th>Name</th>
+    <th>Specialties</th>
+  </thead>
+  <c:forEach var="vet" items="${vets.vetList}">
+    <tr>
+      <td>${vet.firstName} ${vet.lastName}</td>
+      <td>
+	    <c:forEach var="specialty" items="${vet.specialties}">
+          ${specialty.name}
+        </c:forEach>
+        <c:if test="${vet.nrOfSpecialties == 0}">none</c:if>
+      </td>
+    </tr>
+  </c:forEach>
+</table>
+<table class="table-buttons">
+  <tr>
+    <td>
+      <a href="<spring:url value="/vets.xml" htmlEscape="true" />">View as XML</a>
+    </td>
+  </tr>
+</table>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/jsp/welcome.jsp b/src/main/webapp/WEB-INF/jsp/welcome.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..1b07c65c3c226f9304fe26c287ed4f7788f26dd3
--- /dev/null
+++ b/src/main/webapp/WEB-INF/jsp/welcome.jsp
@@ -0,0 +1,15 @@
+<%@ include file="/WEB-INF/jsp/includes.jsp" %>
+<%@ include file="/WEB-INF/jsp/header.jsp" %>
+
+<img src="<spring:url value="/static/images/pets.png" htmlEscape="true" />" align="right" style="position:relative;right:30px;">
+<h2><fmt:message key="welcome"/></h2>
+
+<ul>
+  <li><a href="<spring:url value="/owners/search" htmlEscape="true" />">Find owner</a></li>
+  <li><a href="<spring:url value="/vets" htmlEscape="true" />">Display all veterinarians</a></li>
+  <li><a href="<spring:url value="/static/html/tutorial.html" htmlEscape="true" />">Tutorial</a></li>
+</ul>
+
+<p>&nbsp;</p>
+
+<%@ include file="/WEB-INF/jsp/footer.jsp" %>
diff --git a/src/main/webapp/WEB-INF/petclinic-servlet.xml b/src/main/webapp/WEB-INF/petclinic-servlet.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3c05fc3000369aebd1021bbe2216ab08de253baa
--- /dev/null
+++ b/src/main/webapp/WEB-INF/petclinic-servlet.xml
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+	- DispatcherServlet application context for PetClinic's web tier.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+		xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
+		xmlns:oxm="http://www.springframework.org/schema/oxm"
+		xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+				http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+				http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">
+
+	<!--
+		- The controllers are autodetected POJOs labeled with the @Controller annotation.
+	-->
+	<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
+
+	<!--
+		- The form-based controllers within this application provide @RequestMapping 
+		- annotations at the type level for path mapping URLs and @RequestMapping 
+		- at the method level for request type mappings (e.g., GET and POST). 
+		- In contrast, ClinicController - which is not form-based - provides 
+		- @RequestMapping only at the method level for path mapping URLs.
+		-
+		- DefaultAnnotationHandlerMapping is driven by these annotations and is 
+		- enabled by default with Java 5+.
+	-->
+	
+	<!--
+		- This bean processes annotated handler methods, applying PetClinic-specific PropertyEditors
+		- for request parameter binding. It overrides the default AnnotationMethodHandlerAdapter.
+	-->
+	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
+		<property name="webBindingInitializer">
+			<bean class="org.springframework.samples.petclinic.web.ClinicBindingInitializer"/>
+		</property>
+	</bean>
+
+	<!--
+		- This bean resolves specific types of exceptions to corresponding logical 
+		- view names for error views. The default behaviour of DispatcherServlet 
+		- is to propagate all exceptions to the servlet container: this will happen 
+		- here with all other types of exceptions.
+	-->
+	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
+		<property name="exceptionMappings">
+			<props>
+				<prop key="org.springframework.web.servlet.PageNotFound">pageNotFound</prop>
+				<prop key="org.springframework.dao.DataAccessException">dataAccessFailure</prop>
+				<prop key="org.springframework.transaction.TransactionException">dataAccessFailure</prop>
+			</props>
+		</property>
+	</bean>
+
+	<!--
+		- This view resolver delegates to the InternalResourceViewResolver and BeanNameViewResolver,
+		- and uses the requested media type to pick a matching view. When the media type is 'text/html',
+		- it will delegate to the InternalResourceViewResolver's JstlView, otherwise to the
+		- BeanNameViewResolver. Note the use of the expression language to refer to the contentType
+		- property of the vets view bean, setting it to 'application/vnd.springsource.samples.petclinic+xml'.
+	-->
+	<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
+		<property name="mediaTypes">
+			<map>
+				<entry key="xml" value="#{vets.contentType}"/>
+				<entry key="atom" value="#{visits.contentType}"/>
+			</map>
+		</property>
+		<property name="order" value="0"/>
+	</bean>
+	
+	<!--
+		- The BeanNameViewResolver is used to pick up the visits view name (below).
+		- It has the order property set to 2, which means that this will
+		- be the first view resolver to be used after the delegating content
+		- negotiating view resolver.
+	 -->
+	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" p:order="1"/>
+	<!--
+
+		- This bean configures the 'prefix' and 'suffix' properties of
+		- InternalResourceViewResolver, which resolves logical view names
+		- returned by Controllers. For example, a logical view name of "vets"
+		- will be mapped to "/WEB-INF/jsp/vets.jsp".
+	-->
+	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/"
+			p:suffix=".jsp" p:order="2"/>
+
+	<!--
+		- The AtomView rendering a Atom feed of the visits
+	 -->
+	<bean id="visits" class="org.springframework.samples.petclinic.web.VisitsAtomView"/>
+
+	<bean id="vets" class="org.springframework.web.servlet.view.xml.MarshallingView">
+		<property name="contentType" value="application/vnd.springsource.samples.petclinic+xml"/>
+		<property name="marshaller" ref="marshaller"/>
+	</bean>
+
+	<oxm:jaxb2-marshaller id="marshaller">
+		<oxm:class-to-be-bound name="org.springframework.samples.petclinic.Vets"/>
+	</oxm:jaxb2-marshaller>
+
+	<!--
+		- Message source for this context, loaded from localized "messages_xx" files.
+		- Could also reside in the root application context, as it is generic,
+		- but is currently just used within PetClinic's web tier.
+	-->
+	<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
+			p:basename="messages"/>
+
+</beans>
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000000000000000000000000000000000000..06a6a311086c1a67449f30b1f12f5e5f851621f0
--- /dev/null
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<web-app version="2.4" 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">
+
+	<display-name>Spring PetClinic</display-name>
+
+	<description>Spring PetClinic sample application</description>
+
+	<!--
+		Key of the system property that should specify the root directory of this
+		web app. Applied by WebAppRootListener or Log4jConfigListener.
+	-->
+	<context-param>
+		<param-name>webAppRootKey</param-name>
+		<param-value>petclinic.root</param-value>
+	</context-param>
+	
+	
+
+	<!--
+		Location of the Log4J config file, for initialization and refresh checks.
+		Applied by Log4jConfigListener.
+	-->
+	<context-param>
+		<param-name>log4jConfigLocation</param-name>
+		<param-value>/WEB-INF/classes/log4j.properties</param-value>
+	</context-param>
+
+	<!--
+		- Location of the XML file that defines the root application context.
+		- Applied by ContextLoaderServlet.
+		-
+		- Can be set to:
+		- "/WEB-INF/applicationContext-hibernate.xml" for the Hibernate implementation,
+		- "/WEB-INF/applicationContext-jpa.xml" for the JPA one, or
+		- "/WEB-INF/applicationContext-jdbc.xml" for the JDBC one.
+	-->
+	<context-param>
+		<param-name>contextConfigLocation</param-name>
+
+		<param-value>/WEB-INF/applicationContext-jdbc.xml</param-value>
+		<!--
+		<param-value>/WEB-INF/applicationContext-hibernate.xml</param-value>
+		<param-value>/WEB-INF/applicationContext-jpa.xml</param-value>
+		-->
+
+		<!--
+			To use the JPA variant above, you will need to enable Spring load-time
+			weaving in your server environment. See PetClinic's readme and/or
+			Spring's JPA documentation for information on how to do this.
+		-->
+	</context-param>
+
+	<!--
+		- Configures Log4J for this web app.
+		- As this context specifies a context-param "log4jConfigLocation", its file path
+		- is used to load the Log4J configuration, including periodic refresh checks.
+		-
+		- Would fall back to default Log4J initialization (non-refreshing) if no special
+		- context-params are given.
+		-
+		- Exports a "web app root key", i.e. a system property that specifies the root
+		- directory of this web app, for usage in log file paths.
+		- This web app specifies "petclinic.root" (see log4j.properties file).
+	-->
+	<!-- Leave the listener commented-out if using JBoss -->
+	<!--
+	<listener>
+		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
+	</listener>
+	-->
+
+	<!--
+		- Loads the root application context of this web app at startup,
+		- by default from "/WEB-INF/applicationContext.xml".
+		- Note that you need to fall back to Spring's ContextLoaderServlet for
+		- J2EE servers that do not follow the Servlet 2.4 initialization order.
+		-
+		- Use WebApplicationContextUtils.getWebApplicationContext(servletContext)
+		- to access it anywhere in the web application, outside of the framework.
+		-
+		- The root context is the parent of all servlet-specific contexts.
+		- This means that its beans are automatically available in these child contexts,
+		- both for getBean(name) calls and (external) bean references.
+	-->
+	<listener>
+		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+	</listener>
+	
+	<!--
+	 - Map static resources to the default servlet
+	 - examples:
+	 -     http://localhost:8080/static/images/pets.png
+	 -     http://localhost:8080/static/styles/petclinic.css
+	-->
+	<servlet-mapping>
+		<servlet-name>default</servlet-name>
+		<url-pattern>/static/*</url-pattern>
+	</servlet-mapping>
+	
+	<!--
+		- Servlet that dispatches request to registered handlers (Controller implementations).
+		- Has its own application context, by default defined in "{servlet-name}-servlet.xml",
+		- i.e. "petclinic-servlet.xml".
+		-
+		- A web app can contain any number of such servlets.
+		- Note that this web app has a shared root application context, serving as parent
+		- of all DispatcherServlet contexts.
+	-->
+	<servlet>
+		<servlet-name>petclinic</servlet-name>
+		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
+		<load-on-startup>2</load-on-startup>
+	</servlet>
+
+	<!--
+		- Maps the petclinic dispatcher to "*.do". All handler mappings in
+		- petclinic-servlet.xml will by default be applied to this subpath.
+		- If a mapping isn't a /* subpath, the handler mappings are considered
+		- relative to the web app root.
+		-
+		- NOTE: A single dispatcher can be mapped to multiple paths, like any servlet.
+	-->
+	<servlet-mapping>
+		<servlet-name>petclinic</servlet-name>
+		<url-pattern>/</url-pattern>
+	</servlet-mapping>
+
+    <filter>
+        <filter-name>httpMethodFilter</filter-name>
+        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>httpMethodFilter</filter-name>
+        <servlet-name>petclinic</servlet-name>
+    </filter-mapping>
+    
+	<session-config>
+		<session-timeout>10</session-timeout>
+	</session-config>
+
+	<error-page>
+		<exception-type>java.lang.Exception</exception-type>
+		<!-- Displays a stack trace -->
+		<location>/WEB-INF/jsp/uncaughtException.jsp</location>
+	</error-page>
+
+	<!--
+		- Reference to PetClinic database.
+		- Only needed if not using a local DataSource but a JNDI one instead.
+	-->
+	<!--
+	<resource-ref>
+		<res-ref-name>jdbc/petclinic</res-ref-name>
+		<res-type>javax.sql.DataSource</res-type>
+		<res-auth>Container</res-auth>
+	</resource-ref>
+	-->
+	
+</web-app>
diff --git a/src/main/webapp/html/tutorial.html b/src/main/webapp/html/tutorial.html
new file mode 100644
index 0000000000000000000000000000000000000000..acc261fb1cf1d2ac8c070fbaa381771b00867453
--- /dev/null
+++ b/src/main/webapp/html/tutorial.html
@@ -0,0 +1,1153 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+	<title>The Spring PetClinic Application</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+	<link rel="stylesheet" href="../styles/petclinic.css" type="text/css">
+</head>
+
+<body>
+
+<div id="main">
+
+	<h1>The Spring PetClinic Application</h1>
+
+   <!--
+   <table class="updated">
+   <tr><td>Updated:</td><td>25.NOV.2009</td><td>Costin Leau(<strong>Work In Progress: not yet fully updated regarding Spring 3.0</strong>)</td></tr>
+	<tr><td></td><td>11.OCT.2009</td><td>Sam Brannen</td></tr>
+	<tr><td></td><td>21.OCT.2007</td><td>Sam Brannen</td></tr>
+	<tr><td></td><td>30.JUN.2006</td><td>Costin Leau</td></tr>
+	<tr><td></td><td>01.DEC.2004</td><td>Ken Krebs</td></tr>
+	<tr><td></td><td>16.AUG.2003</td><td>Ken Krebs</td></tr>
+	</table>
+    -->
+
+<!-- === INTRODUCTION ====================================================== -->
+	<h2>Introduction</h2>
+
+	<p>
+		The Spring Framework is a collection of small, well-focused, loosely coupled Java
+		frameworks that can be used independently or collectively to build
+		industrial strength applications of many different types. The PetClinic
+		sample application is designed to show how the Spring
+		application frameworks can be used to build simple, but powerful
+		database-oriented applications. It will demonstrate the use
+		of Spring's core functionality:
+	</p>
+
+	<ul>
+	  <li>JavaBeans based application configuration using Inversion-Of-Control</li>
+	  <li>Model-View-Controller web Presentation Layer</li>
+	  <li>Practical database access through JDBC, Hibernate, or Java Persistence API</li>
+	  <li>Application monitoring based on JMX</li>
+	  <li>Declarative Transaction Management using AOP</li>
+	  <li>Data Validation that supports but is not dependent on the Presentation Layer</li>
+	</ul>
+
+	<p>
+		The Spring frameworks provide a great deal of useful infrastructure to
+		simplify the tasks faced by application developers. This infrastructure
+		helps developers to create applications that are:
+	</p>
+
+	<ul>
+	  <li>
+	  	<span style="font-weight: bold; text-decoration: underline;">concise</span>
+		by handling a lot of the complex control flow that is needed to use the
+		Java API's, such as JDBC, JNDI, JTA, RMI, and EJB.
+	  </li>
+	  <li>
+	  	<span style="font-weight: bold; text-decoration: underline;">flexible</span>
+		by simplifying the process of external application configuration
+		through the use of Reflection and JavaBeans. This allows the developer to
+		achieve a clean separation of configuration data from application code.
+		All application and web application objects, including validators,
+		workflow controllers, and views, are JavaBeans that can be configured
+		externally.</li>
+	  <li>
+	  	<span style="font-weight: bold; text-decoration: underline;">testable</span>
+		by supplying an interface based design to maximize pluggability. This
+		facilitates unit testing of Business Logic without requiring the
+		presence of application or live database servers.</li>
+	  <li>
+	  	<span style="font-weight: bold; text-decoration: underline;">maintainable</span>
+		by facilitating a clean separation of the application layers. It most
+		importantly helps maintain the independence of the Business Layer
+		from the Presentation layer. PetClinic demonstrates the use of a
+		Model-View-Controller
+		based web presentation framework that can work seamlessly with many
+		different types of view technologies. The Spring web application
+		framework helps developers to implement their Presentation as a clean
+		and thin layer focused on its main missions of translating user actions
+		into application events and rendering model data.</li>
+	</ul>
+
+	<p>
+		It is assumed that users of this tutorial will have a basic knowledge
+		of object-oriented design, Java, Servlets, JSP, and relational
+		databases. It also assumes a basic knowledge of the use of a Java EE web
+		application container.
+	</p>
+
+	<p>
+		Since the purpose of the sample application is tutorial in nature, the
+		implementation presented here will of course provide only a small
+		subset of the functionality that would be needed by a real world version of a
+		PetClinic application.
+	</p>
+
+<!-- === REQUIREMENTS ====================================================== -->
+	<h2>PetClinic Sample Application Requirements</h2>
+
+	<p>
+		The application requirement is for an information system that is
+		accessible through a web browser. The users of the application are
+		employees of the clinic who in the course of their work need to view
+		and manage information regarding the veterinarians, the clients, and their
+		pets. The sample application supports the following:
+	</p>
+
+	<h3>Use Cases</h3>
+	<ul>
+	  <li>View a list of veterinarians and their specialties</li>
+	  <li>View information pertaining to a pet owner</li>
+	  <li>Update the information pertaining to a pet owner</li>
+	  <li>Add a new pet owner to the system</li>
+	  <li>View information pertaining to a pet</li>
+	  <li>Update the information pertaining to a pet</li>
+	  <li>Add a new pet to the system</li>
+	  <li>View information pertaining to a pet's visitation history</li>
+	  <li>Add information pertaining to a visit to the pet's visitation history</li>
+	</ul>
+
+	<h3>Business Rules</h3>
+	<ol>
+	  <li>An owner may not have multiple pets with the same case-insensitive name.</li>
+	</ol>
+
+<!-- === DESIGN AND IMPLEMENTATION ========================================= -->
+	<h2>PetClinic Sample Application Design &amp; Implementation</h2>
+
+	<h3>Server Technology</h3>
+	<p>
+		The sample application should be usable with any Java EE web application
+		container that is compatible with the Servlet 2.4 and JSP 2.0
+		specifications. Some of the deployment files provided are designed
+		specifically for Apache Tomcat. These files specify container-supplied
+		connection-pooled data sources. It is not necessary to use these files.
+		The application has been configured by default to use a data source
+		with connection pooling. Configuration details are
+		provided in the Developer Instructions section. The view technologies
+		that are to be used for rendering the application are Java Server Pages
+		(JSP) along with the Java Standard Tag Library (JSTL).
+	</p>
+
+	<h3>Database Technology</h3>
+	<p>
+		The sample application uses a relational database for data storage.
+		Support has been provided for a choice of 1 of 2 database selections,
+		MySql or HypersonicSQL. HypersonicSQL version 1.8.0 is the default
+		choice. It is possible to
+		easily configure the application to use either database. Configuration
+		details are provided in the Developer Instructions section.
+	</p>
+
+	<h3>Development Environment</h3>
+	<p>
+		A copy of the Spring runtime library jar file is provided with the
+		sample application along with some of the other required jar files. The
+		developer will need to obtain the following tools externally, all of
+		which are freely available:
+	</p>
+
+	<ul>
+	  <li>Java SDK 1.5.x</li>
+	  <li>Maven  2.0.10+</li>
+	  <li>Ant  1.7.1 (for executing scripts, if needed, against the in-memory database)</li>
+	  <li>Tomcat 6.x.x, or some other Java Servlet container</li>
+	  <li>(Optional) MySQL 5.x with MySQL Connector/J 5.x</li>
+	</ul>
+
+	<p>
+		<strong>NOTE:</strong> The version numbers listed are those that were used
+		in the development of the PetClinic application. Other versions of the same
+		tools may or may not work.
+	</p>
+
+	<p>
+		Download links for the various tools needed are provided in the Developer
+		Instructions section.
+	</p>
+
+	<h3>PetClinic Database</h3>
+	<p>
+		The following is an overview of the database schema used in PetClinic.
+		Detailed field descriptions can be found in the
+		<span style="font-weight: bold; font-style: italic;">"initDB.txt"</span>
+		SQL script files in the database-specific "db" sub-directories. All "id" key
+		fields are of Java type <span style="font-weight: bold; font-style: italic;">int</span>.
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">owners</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span>
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">types</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span>
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">pets</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span><br>
+		&nbsp;&nbsp;&nbsp; FOREIGN KEY <span style="font-weight: bold;">type_id</span>
+		references the <span style="font-weight: bold; font-style: italic;">types</span>
+		table<span style="font-weight: bold;"> id</span> field<br>
+		&nbsp;&nbsp;&nbsp; FOREIGN KEY <span style="font-weight: bold;">owner_id</span>
+		references the <span style="font-weight: bold; font-style: italic;">owners</span>
+		table <span style="font-weight: bold;">id</span> field
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">vets</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span>
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">specialties</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span><br>
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">vet_specialties</span> -
+		a link table for <span style="font-weight: bold; font-style: italic;">vets</span>
+		and their <span style="font-weight: bold; font-style: italic;">specialties</span><br>
+		&nbsp;&nbsp;&nbsp; FOREIGN KEY <span style="font-weight: bold;">vet_id</span>
+		references the <span style="font-weight: bold; font-style: italic;">vets</span>
+		table<span style="font-weight: bold;"> id</span> field<br>
+		&nbsp;&nbsp;&nbsp; FOREIGN KEY <span style="font-weight: bold;">specialty_id</span>
+		references the <span style="font-weight: bold; font-style: italic;">specialties</span>
+		table <span style="font-weight: bold;">id</span> field
+	</p>
+
+	<p>
+		TABLE: <span style="font-weight: bold; font-style: italic;">visits</span><br>
+		&nbsp;&nbsp;&nbsp; PRIMARY KEY <span style="font-weight: bold;">id</span><br>
+		&nbsp;&nbsp;&nbsp; FOREIGN KEY <span style="font-weight: bold;">pet_id</span>
+		references the <span style="font-weight: bold; font-style: italic;">pets</span>
+		table <span style="font-weight: bold;">id</span> field
+	</p>
+
+	<h3>Directory Structure</h3>
+
+	<p>
+		d-- indicates a directory holding source code, configuration files, etc.<br>
+		D-- indicates a directory that is created by the build script
+	</p>
+
+	<p>
+		d-- <span style="font-weight: bold; font-style: italic;">petclinic</span>:
+		the root directory of the project contains build related files<br>
+
+		&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">src</span>: contains
+		Java source code files and ORM configuration files<br>
+
+		&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">war</span>: contains
+		the web application resource files<br>
+
+		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">html</span>: contains
+		tutorial files<br>
+
+		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">docs</span>: contains
+		Javadoc files<br>
+
+		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">web-inf</span>:
+		contains web application configuration files and application context
+		files<br>
+
+		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+		d-- <span style="font-weight: bold; font-style: italic;">jsp</span>:
+		contains Java Server Page files<br>
+
+		&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+		D--<span style="font-weight: bold;"> <span style="font-style: italic;">lib</span></span>:
+		contains application dependencies<br>
+
+		&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">test</span>: contains
+		testing related
+		Java source code files<br>
+
+		&nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">db</span>: contains
+		database SQL scripts and other related files/directories<br>
+
+		&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">hsqldb</span>:
+		contains files related to HSQL, contains scripts and a&nbsp;Tomcat
+		context definition file<br>
+
+		&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; d-- <span style="font-weight: bold; font-style: italic;">mysql</span>:
+		contains files related to MySQL, contains scripts and a Tomcat context
+		definition file<br>
+
+		&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">.classes</span>:
+		contains compiled Java class files<br>
+
+		&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">.testclasses</span>:
+		contains compiled testing related Java class files<br>
+
+		&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">junit-reports</span>:
+		contains generated xml-formatted test reports<br>
+
+		&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">reports/html</span>:
+		contains generated html-formatted test reports<br>
+
+		&nbsp;&nbsp;&nbsp; D-- <span style="font-weight: bold; font-style: italic;">dist</span>: contains
+		packaged archives of files
+	</p>
+
+<!-- === DESIGN ============================================================ -->
+	<h2>PetClinic Application Design</h2>
+
+	<h3>Logging</h3>
+	<p>
+		Spring supports the use of the Apache Commons Logging API. This API
+		provides the ability to use Java 1.4 loggers, the simple Commons loggers,
+		and Apache log4j loggers. PetClinic uses log4j to provide sophisticated
+		and configurable logging capabilities. The file,
+		<span style="font-weight: bold; font-style: italic;">src/main/resources/log4j.properties</span>
+		configures the definition of <strong>log4j</strong>loggers.
+	</p>
+
+	<h3>Business Layer</h3>
+	<p>
+		The Business Layer consists of a number of basic JavaBean classes
+		representing the application domain objects and associated validation
+		objects that are used by the Presentation Layer. The validation objects
+		used in PetClinic are all implementations of the
+		<strong>org.springframework.validation.Validator</strong> interface.
+	</p>
+
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Entity</span>
+		is a simple JavaBean superclass used for all persistable objects.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.NamedEntity</span>
+		is an extension of <span style="font-weight: bold;">Entity</span> that adds a name property.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Specialty</span>
+		is an extension of <span style="font-weight: bold;">NamedEntity</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.PetType</span>
+		is an extension of <span style="font-weight: bold;">NamedEntity</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Person</span> is
+		an extension of <span style="font-weight: bold;">Entity</span> that provides a superclass for all objects that
+		implement the notion of a person.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Vet</span> is
+		an extension of <span style="font-weight: bold;">Person</span> that implements a
+		veterinarian. It holds a <span style="font-weight: bold;">List</span> of
+		specialties that the <span style="font-weight: bold;">Vet</span> is capable of.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Owner</span>
+		is an extension of <span style="font-weight: bold;">Person</span> that implements a pet owner.
+		It holds a <span style="font-weight: bold;">List</span> of pets owned.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Pet</span>
+		is an extension of <span style="font-weight: bold;">NamedEntity</span> that
+		implements a pet. It holds a <span style="font-weight: bold;">List</span> of
+		visits made concerning the pet.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.Visit</span>
+		is a simple JavaBean that implements the notion of a clinic visit
+		for a pet. </li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.util.EntityUtils</span>
+	  	provides utility methods for handling entities.</li>
+	</ul>
+
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.validation.OwnerValidator</span>
+		is a Spring <span style="font-weight: bold;">Validator</span> that
+		verifies correct data entry for the Add and Edit Owner forms.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.validation.PetValidator</span>
+		is a Spring <span style="font-weight: bold;">Validator</span> that
+		verifies correct data entry for the Add and Edit Pet forms.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.validation.VisitValidator</span>
+		is a Spring <span style="font-weight: bold;">Validator</span> that
+		verifies correct data entry for the AddVisit form.</li>
+	</ul>
+
+	<h3>Business / Persistence Layer</h3>
+
+	<p>
+		Since the PetClinic application is all about database access and there is
+		very little business logic in the application outside of that, there is
+		no separation of the primary Business and Persistence Layer API's.
+		While this design technique should not be used for an application with more
+		complex business logic, it is acceptable here because all of the
+		non-persistence related business rules have been implemented in
+		business objects and have not leaked into the Persistence Layer. The most
+		important facet of the design is that the Business and Persistence
+		Layers are <strong>COMPLETELY</strong> independent of the Presentation Layer.
+	</p>
+
+	<p>
+		The Persistence Layer can be configured to use either HSQL or MySQL
+		with any one of the following data access technologies aided by
+		infrastructure provided by Spring:
+	</p>
+
+	<ul>
+	  <li>JDBC</li>
+	  <li>Hibernate 3</li>
+	  <li>Java Persistence API</li>
+	</ul>
+
+	<p>
+		<span style="font-weight: bold;">NOTE:</span> Spring also provides
+		infrastructure for using other
+		<strong>O</strong>bject/<strong>R</strong>elational <strong>M</strong>apping
+		frameworks such as JDO and iBATIS SqlMaps, but these are not demonstrated in PetClinic.
+		(See the 'jpetstore' sample application that ships with the full Spring Framework
+		distribution for an example of using iBatis and Spring.)
+	</p>
+
+	<p>
+		One of the key elements provided by Spring is the use of a common set
+		of meaningful data access exceptions that can be used regardless of
+		which database or access strategy is used. All of these exceptions
+		derive from <strong>org.springframework.dao.DataAccessException</strong>.
+		Since most exceptions encountered during database access are indicative
+		of programming errors, <strong>DataAccessException</strong> is an
+		abstract <strong>RuntimeException</strong> whose derivatives only need
+		to be caught by application code to handle recoverable errors when it
+		makes sense to do so. This greatly simplifies application code compared
+		to, for example, code using JDBC directly where <strong>SqlExceptions</strong>
+		must be caught and database specific error codes must be decoded.
+		Examination of the PetClinic source code will show that the
+		persistence-oriented code is completely focused on the relevant
+		transfer of data to/from the referenced objects without extraneous
+		error handling.
+	</p>
+
+	<p>
+		The high-level business/persistence API for PetClinic is the
+		<span style="font-weight: bold;">org.springframework.samples.petclinic.Clinic</span>
+		interface. Each persistence strategy in PetClinic is a different implementation of the
+		<span style="font-weight: bold;">Clinic</span> interface. In each case, the
+		<span style="font-weight: bold;">Clinic</span> implementation is fronted by
+		a transactional proxy, configured via the
+		<span style="font-weight: bold;">@Transactional</span> annotation, that also
+		implements <span style="font-weight: bold;">Clinic</span>. These objects
+		are standard Java dynamic proxies which are created by an instance of
+		<span style="font-weight: bold;">org.springframework.transaction.interceptor.TransactionProxyFactoryBean</span>.
+		These proxies are configured in the respective application context file
+		via <strong>&lt;tx:annotation-driven /&gt;</strong> and specify that all
+		<span style="font-weight: bold;">Clinic</span> methods are run in a
+		transactional context. The transaction managers used in PetClinic are all
+		implementations of the
+		<span style="font-weight: bold;">org.springframework.transaction.PlatformTransactionManager</span>
+		interface. All of the implementations are by default configured
+		to use a local <span style="font-weight: bold;">DataSource</span> that
+		will work in any environment through the use of an instance of
+		<span style="font-weight: bold;">org.springframework.jdbc.datasource.DriverManagerDataSource</span>.
+		While this is appropriate for use in a demo or single user
+		program, a connection pooling <span style="font-weight: bold;">DataSource</span>,
+		such as an instance of <span style="font-weight: bold;">org.apache.commons.dbcp.BasicDataSource</span>,
+		is more appropriate for use in a multi-user application. Another
+		alternative is to obtain one through the Java EE environment
+		using an instance of
+		<span style="font-weight: bold;">org.springframework.jndi.JndiObjectFactoryBean</span>.
+	</p>
+
+	<h3>JDBC Clinic Implementation</h3>
+	<p>
+		Spring provides a number of high-level database
+		access convenience classes in the package
+		<span style="font-weight: bold;">org.springframework.jdbc.object</span>.
+		These classes and the lower-level Spring classes that they use in the
+		<span style="font-weight: bold;">org.springframework.jdbc.core</span> package
+		provide a higher level of abstraction for using JDBC that keeps the developer
+		from having to correctly implement the handling of the checked
+		<span style="font-weight: bold;">SqlExceptions</span> with ugly error-prone
+		nested try-catch-finally blocks. Using the classes in this package
+		allows the developer to focus efforts on the functionality being
+		implemented rather than the mechanics of error handling. When using
+		these classes, it is the responsibility of the developer to provide the
+		SQL needed and to map the parameters to/from the respective domain
+		object. This typically is done by extending one of the
+		<span style="font-weight: bold;">org.springframework.jdbc.object</span> classes,
+		initializing its SQL, and overriding a method that takes care of
+		the mapping. In this way, the developer gets to focus on implementing
+		functionality rather than application plumbing. These classes also
+		take care of closing connections to prevent hard to find resource
+		leakage problems. It should be noted that instances of these classes
+		are lightweight, reusable, and threadsafe.
+	</p>
+
+	<p>
+		The JDBC implementation of the Clinic interface is
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic</span>,
+		which uses Java 5 language features,
+		<strong>org.springframework.jdbc.core.simple.SimpleJdbcTemplate</strong>, and
+		<strong>org.springframework.jdbc.core.simple.SimpleJdbcInsert</strong>.
+		It also takes advantage of classes like
+		<strong>org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource</strong> and
+		<strong>org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper</strong>
+		which provide automatic mapping between JavaBean properties and JDBC
+		parameters or query results. SimpleJdbcClinic is a rewrite of the
+		AbstractJdbcClinic which was the base class for JDBC implementations of
+		the Clinic interface for Spring 2.0.
+	</p>
+
+	<p>
+		The transaction manager used in the JDBC Clinic Implementation is an
+		instance of <span style="font-weight: bold;">org.springframework.jdbc.datasource.DataSourceTransactionManager</span>
+		that can be used for local transactions.
+	</p>
+
+	<h3>Hibernate 3 Clinic Implementation</h3>
+	<p>
+		The Hibernate 3 implementation of the <span style="font-weight: bold;">Clinic</span>
+		interface is
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.hibernate.HibernateClinic</span>.
+		To simplify using Hibernate, Spring provides the
+		<span style="font-weight: bold;">org.springframework.orm.hibernate3.LocalSessionFactoryBean</span>.
+		The Hibernate configuration is provided by the file <span style="font-style: italic;">src/main/resources/petclinic.hbm.xml</span>.
+	</p>
+
+	<h3>Java Persistence API (JPA) Clinic Implementation</h3>
+	<p>
+		The JPA implementation of the <span style="font-weight: bold;">Clinic</span>
+		interface is
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.jpa.EntityManagerClinic</span>,
+		which is based on native JPA usage combined with Spring's
+		<span style="font-weight: bold;">@Repository</span> and
+		<span style="font-weight: bold;">@Transactional</span> annotations but
+		otherwise has no dependencies on any Spring API's.
+		To simplify JPA usage, Spring provides (among other classes) the
+		<span style="font-weight: bold;">org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean</span>.
+		The JPA configuration is provided by
+		<span style="font-style: italic;">src/main/resources/META-INF/orm.xml</span> and
+		<span style="font-style: italic;"> src/main/resources/META-INF/persistence.xml.</span>
+	</p>
+
+	<h3>ApplicationContext</h3>
+	<p>
+		A Spring <span style="font-weight: bold;">org.springframework.context.ApplicationContext</span> object
+		provides a map of user-defined JavaBeans that specify either a singleton
+		object or the initial construction of prototype instances. These beans
+		constitute the <span style="font-weight: bold;">Business/Persistence
+		Layer</span> of PetClinic. The following beans are defined in all 3
+		versions (1 per access strategy) of the PetClinic
+		<span style="font-style: italic;">src/main/webapp/WEB-INF/applicationContext-*.xml</span>
+		file:
+	</p>
+
+	<ol>
+	  <li>A <span style="font-weight: bold; font-style: italic;">PropertyPlaceholderConfigurer</span>,
+	    which is configured via
+	    <strong>&lt;context:property-placeholder ... /&gt;</strong> and
+	    is a singleton bean that replaces ${...} placeholders with values from a
+		properties file, in this case, JDBC-related settings for the
+		<span style="font-weight: bold; font-style: italic;">dataSource</span> bean
+		described below
+		(see <span style="font-weight: bold; font-style: italic;">src/main/resources/jdbc.properties</span>).
+	  </li>
+	  <li><span style="font-weight: bold; font-style: italic;">dataSource</span>,
+		which is a singleton bean that defines the implementation of the source
+		of database connections used by the application.
+	  </li>
+	  <li><span style="font-weight: bold; font-style: italic;">transactionManager</span>,
+		which is a singleton bean that defines the implementation of the transaction
+		management strategy for the application.
+	  </li>
+	  <li><span style="font-weight: bold; font-style: italic;">clinic</span>,
+		which is a singleton bean that defines the implementation of the
+		<span style="font-weight: bold;">Clinic</span> interface that provides the
+		primary Business Layer API of the application.
+	  </li>
+	</ol>
+
+	<h3>Presentation Layer</h3>
+	<p>
+		The Presentation Layer is implemented as a Java EE Web Application and
+		provides a very thin and concise Model-View-Controller type user
+		interface to the Business and Persistence Layers.
+	</p>
+
+	<p>
+		The PetClinic web application is configured via the following files:
+	</p>
+
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">src/main/webapp/WEB-INF/web.xml</span>:
+		the web application configuration file.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">src/main/webapp/WEB-INF/petclinic-servlet.xml</span>:
+		configures the petclinic dispatcher servlet and the other controllers
+		and forms that it uses. The beans defined in this file reference the
+		Business/Persistence Layer beans defined in
+		<span style="font-style: italic;">applicationContext-*.xml.</span></li>
+	  <li><span style="font-weight: bold; font-style: italic;">src/main/resources/messages*.properties</span>:
+		configures the definition of internationalizable message resources.</li>
+	</ul>
+
+	<p>
+		Examine the comments provided in each of these files for a more
+		in-depth understanding of the details of how the application is
+		configured.
+	</p>
+
+	<h3>General</h3>
+
+	<ul>
+	  <li>In <span style="font-weight: bold; font-style: italic;">web.xml</span>,
+		a context-param, "<span style="font-weight: bold;">webAppRootkey</span>",
+		provides the key for a system property that specifies the root directory
+		for the web application. This parameter,
+		<span style="font-weight: bold;">"petclinic.root"</span>, can be used to aid
+		in configuring the application.</li>
+	  <li>In <span style="font-weight: bold; font-style: italic;">web.xml</span>,
+		a <span style="font-weight: bold;">org.springframework.web.context.ContextLoaderListener</span>
+		is defined that loads the root <span style="font-weight: bold;">ApplicationContext</span>
+		object of this webapp at startup, by default from the designated
+		<span style="font-weight: bold; font-style: italic;">/WEB-INF/applicationContext-*.xml</span>.
+		The root <span style="font-weight: bold;">org.springframework.web.context.WebApplicationContext</span>
+		of PetClinic is an instance of
+		<span style="font-weight: bold;">org.springframework.web.context.support.XmlWebApplicationContext</span>
+		and is the parent of all servlet-specific <span style="font-weight: bold;">ApplicationContexts</span>.
+		The Spring root <span style="font-weight: bold;">ApplicationContext</span> object
+		provides a map of user-defined JavaBeans that can be used in any and
+		all layers of the application. Beans defined in the root
+		<span style="font-weight: bold;">ApplicationContext</span> are automatically
+		available in all child <span style="font-weight: bold;">ApplicationContext</span>
+		objects as (external) bean references. Beans defined in an
+		<span style="font-weight: bold;">ApplicationContext</span> can also be
+		accessed directly by Java code through
+		<span style="font-style: italic;">getBean(name)</span> method calls.
+	  </li>
+
+	  <li>In <span style="font-weight: bold; font-style: italic;">web.xml</span>,
+		a <span style="font-weight: bold;">Servlet</span> named
+		<span style="font-weight: bold;">"petclinic"</span> is specified to act as
+		a dispatcher for the entire application. This
+		<span style="font-weight: bold;">org.springframework.web.servlet.DispatcherServlet</span>
+		is used to handle all URL's matching the pattern <span style="font-weight: bold;">"*.do"</span>.
+		As with any <span style="font-weight: bold;">Servlet</span>, multiple URL mappings may
+		be defined. It is also possible to define multiple instances of
+		<span style="font-weight: bold;">DispatcherServlet</span>. Each
+		<span style="font-weight: bold;">DispatcherServlet</span> dispatches
+		requests to registered handlers (<span style="font-weight: bold;">Controller</span>
+		interface implementations or POJOs annotated with <strong>@Controller</strong>)
+		indirectly through a
+		<span style="font-weight: bold;">org.springframework.web.servlet.handler.HandlerMapping</span>
+		implementation. Each <span style="font-weight: bold;">DispatcherServlet</span>
+		has its own <span style="font-weight: bold;">ApplicationContext</span>,
+		by default defined in <span style="font-weight: bold;">"{servlet-name}-servlet.xml"</span>.
+		In this case, it is in the file <span style="font-weight: bold;">"petclinic-servlet.xml"</span>.
+		This <span style="font-weight: bold;">ApplicationContext</span> is
+		used to specify the various web application user interface beans and
+		the URL mappings that are used by the <span style="font-weight: bold;">DispatcherServlet</span>
+		to control the handling of requests.
+	  </li>
+	</ul>
+
+	<p>
+		The files <span style="font-weight: bold; font-style: italic;">web.xml</span> and
+		<span style="font-weight: bold; font-style: italic;">log4j.properties</span> specify
+		the configuration of logging in the system:
+	</p>
+
+	<ul>
+	  <li>In <span style="font-weight: bold; font-style: italic;">web.xml</span>,
+		a <span style="font-weight: bold;">"log4jConfigLocation"</span> context-param
+		is specified that sets the location of the
+		<span style="font-weight: bold;">log4j</span> configuration file. The
+		default location for this file is
+		<span style="font-weight: bold; font-style: italic;">/WEB-INF/classes/log4j.properties</span>.
+		Specifying this parameter explicitly allows the location to be changed
+		from the default and is also used to cause periodic
+		<span style="font-weight: bold;">log4j</span> configuration refresh checks.</li>
+	  <li>In <span style="font-weight: bold; font-style: italic;">web.xml</span>,
+		a <span style="font-weight: bold;">Log4jConfigListener</span> is
+		specified that will initialize <span style="font-weight: bold;">log4j</span> using
+		the specified configuration file when the web app starts. The
+		<span style="font-weight: bold;">Log4jConfigListener</span> is commented out
+		in the file because of a conflict when using JBoss. It should also be
+		noted that if the container initializes Servlets before Listeners as
+		some pre-Servlet 2.4 containers do, a <b>Log4jConfigServlet</b> should
+		be used instead.</li>
+	  <li>In <span style="font-weight: bold; font-style: italic;">log4j.properties</span>,
+		the following loggers are specified:
+		<ul>
+			<li><span style="font-weight: bold; font-style: italic;">"stdout"</span> provides
+				logging messages to the container's log file.</li>
+			<li><span style="font-weight: bold; font-style: italic;">"logfile"</span> provides
+				logging messages to a rolling file that is specified using the
+				previously defined "petclinic.root".</li>
+		</ul>
+	  </li>
+	</ul>
+
+	<p>
+		Examination and study of these logging files will provide insight into
+		the operation of the Spring framework and the application as well as
+		valuable troubleshooting information should something not work
+		correctly.
+	</p>
+
+	<h3>DispatcherServlet</h3>
+	<p>
+		The following beans are accessible to the
+		<span style="font-weight: bold;">DispatcherServlet</span> and are defined
+		in the PetClinic
+		<span style="font-weight: bold; font-style: italic;">petclinic-servlet.xml</span>
+		file. This dispatcher uses these definitions to delegate actual display
+		and form processing tasks to implementations of the Spring
+		<span style="font-weight: bold;">org.springframework.web.servlet.mvc.Controller</span>
+		interface. The <span style="font-weight: bold;">DispatcherServlet</span>
+		acts as the main application <span style="font-weight: bold;">Front Controller</span>
+		and is responsible for dispatching all requests to the appropriate
+		<span style="font-weight: bold;">Controller</span> indirectly through a URL
+		mapping handler. These <span style="font-weight: bold;">Controllers</span> are
+		responsible for the mechanics of interaction with the user and ultimately
+		delegate action to the Business/Persistence Layers.
+	</p>
+
+	<ul>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">messageSource</span>
+		is a singleton bean that defines a message source for this
+		<span style="font-weight: bold;">ApplicationContext</span>. Messages are
+		loaded from localized <span style="font-weight: bold;">"messages_xx"</span>
+		files in the classpath, such as
+		<span style="font-weight: bold; font-style: italic;">"/WEB-INF/classes/messages.properties"</span>
+		or <span style="font-weight: bold; font-style: italic;">"/WEB-INF/classes/messages_de.properties"</span>.
+		<span style="font-style: italic;">getMessage()</span> calls to this context
+		will use this source. Child contexts can have their own message sources,
+		which will inherit all messages from this source and are able to define new
+		messages and override ones defined in the primary message source.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">InternalResourceViewResolver</span>
+		is a singleton bean that defines the view mappings used by the dispatcher.
+		Specifically, logical view names returned by Controllers will be mapped to
+		physical paths using the configured 'prefix' and 'suffix' properties. For
+		example, a logical view name of "vets" will be mapped to "/WEB-INF/jsp/vets.jsp".
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">SimpleMappingExceptionResolver</span>
+		is a singleton bean that defines how exceptions are propagated. Exceptions
+		encountered that are not specified are propagated to the servlet container.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">&lt;context:component-scan ... /&gt;</span>
+		is used to autodetect the controllers in the
+		<strong>org.springframework.samples.petclinic.web</strong> package, which
+		are POJOs labeled with the <strong>@Controller</strong> annotation.
+		<ul>
+			<li>
+				<strong>ClinicController</strong> is a singleton, annotation-driven
+				<em>MultiActionController</em> that is used by the dispatcher to handle
+				non-form based display tasks. A method is provided to handle each
+				type of request that is supported.
+			</li>
+			<li>
+				In addition, there are 6 singleton, annotation-driven <em>Form</em> controllers,
+				which are used to handle the various Search, Add and Edit form processing
+				tasks for the dispatcher.
+			</li>
+	  	</ul>
+	  </li>
+	  <li>
+		The form-based controllers within the PetClinic application provide
+		<strong>@RequestMapping</strong> annotations at the type level for path
+		mapping URLs and @RequestMapping at the method level for request type
+		mappings (e.g., GET and POST). In contrast, <strong>ClinicController</strong>
+		&ndash; which is not form-based &ndash; provides  @RequestMapping only at
+		the method level for path mapping URLs.
+		<strong>DefaultAnnotationHandlerMapping</strong> is driven by these
+		annotations and is enabled by default with Java 5+.
+	  </li>
+	</ul>
+
+	<h3>Views</h3>
+	<p>
+		The <span style="font-weight: bold;">Controllers</span> used by the
+		dispatcher handle the work flow of the application. The actual display
+		tasks are delegated by the <span style="font-weight: bold;">Controllers</span>
+		to implementations of the Spring <span style="font-weight: bold;">View
+		</span>interface. These <span style="font-weight: bold;">View</span> objects are
+		themselves beans that can render a particular type of view. The
+		handling <span style="font-weight: bold;">Controller</span> supplies the
+		<span style="font-weight: bold;">View</span> with a data model to render.
+		The data model is provided to the <span style="font-weight: bold;">View</span>
+		as a <span style="font-weight: bold;">Map</span> of objects.
+		<span style="font-weight: bold;">Views</span> are only responsible for
+		rendering a display of the data model and performing any display logic
+		that is particular to the type of <span style="font-weight: bold;">View</span>
+		being rendered. Spring provides support for rendering many different types of
+		views: JSP, XSLT, PDF, Velocity templates, Excel files, and others. By
+		using a <span style="font-weight: bold;">View</span> mapping strategy,
+		Spring supplies the developer with a great deal of flexibility in supporting
+		easily configurable view substitution.
+	</p>
+	<p>
+		<strong>ClinicController</strong> relies on
+		<strong>RequestToViewNameTranslator</strong> to automatically infer the
+		logical view name from the incoming request URL; whereas, all <em>Form</em>
+		controllers in the PetClinic application return logical view names as Strings.
+		These logical view names are then mapped to physical paths via the
+		configured <strong>InternalResourceViewResolver</strong> (see the
+		DispatcherServlet section above for further details). Logical view names that
+		are prepended with <em>&quot;redirect:&quot;</em> will be resolved to instances
+		of <strong>RedirectView</strong>, which simply redirects to another URL.
+		The other resolved <strong>View</strong>s will be instances of
+		<strong>JstlView</strong>, which provides some handy support for
+		internationalization &amp; localization in JSP pages that use JSTL.
+	</p>
+
+	<h3>Messages</h3>
+	<p>
+		The <span style="font-weight: bold; font-style: italic;">messages*.properties</span>
+		files are loaded from the classpath to provide localized messages for
+		the supported languages. PetClinic supplies a localized
+		<strong>"welcome"</strong> message as well as localized form entry error
+		messages in the default (i.e., English) and German properties files.
+		See the "countries" sample application for a more detailed example of Spring's
+		support for internationalization.
+	</p>
+
+	<h3>Presentation Layer classes</h3>
+	<ul>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.ClinicController</span>
+		is an annotation-driven, POJO <em>MultiActionController</em>
+		that is used to handle simple display-oriented URLs.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.FindOwnersForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to search for
+		<strong>Owner</strong>s by last name.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.AddOwnerForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to add a new <strong>Owner</strong>
+		to the system.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.EditOwnerForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to edit an existing <strong>Owner</strong>.
+		A copy of the existing <strong>Owner</strong> is used for editing.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.AddPetForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to add a new <strong>Pet</strong>
+		to an existing <strong>Owner</strong>.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.EditPetForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to edit an existing <strong>Pet</strong>.
+		A copy of the existing <strong>Pet</strong> is used for editing.
+	  </li>
+	  <li>
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.web.AddVisitForm</span>
+		is an annotation-driven, POJO <em>Form</em> controller that is used to add a new <strong>Visit</strong>
+		to an existing <strong>Pet</strong>.
+	  </li>
+	</ul>
+
+	<h3>Logical Views &amp; Implemented Use Cases</h3>
+
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">welcome</span> is
+		the "home" screen. It provides links to display a list of all vets,
+		find an owner, or view documentation.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">vets</span> displays
+		all vets and their specialties.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">findOwners</span>
+		is used to find owners by last name.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">findOwnersRedirect</span>
+		redirects to findOwner.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">selectOwner</span>
+		allows user to select from a list of multiple owners with the same last
+		name.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">owner</span> displays
+		a owner's data and a list of the owner's pets and their data.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">ownerRedirect</span>
+		redirects to owner.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">owner</span> supports
+		<span style="font-weight: bold; font-style: italic;">AddOwnerForm</span>
+		and <span style="font-weight: bold; font-style: italic;">EditOwnerForm</span></li>
+	  <li><span style="font-weight: bold; font-style: italic;">pet</span> supports
+	  	<span style="font-weight: bold; font-style: italic;">AddPetForm</span>
+		and <span style="font-weight: bold; font-style: italic;">web.EditPetForm</span></li>
+	  <li><span style="font-weight: bold; font-style: italic;">visit</span> supports
+	  	<span style="font-weight: bold; font-style: italic;">AddVisitForm</span></li>
+	  <li><span style="font-weight: bold; font-style: italic;">dataAccessFailure</span>
+		displays a stacktrace</li>
+	</ul>
+
+	<h3>Java Server Pages</h3>
+
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">index.jsp</span>
+	    redirects to the "welcome" page.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">includes.jsp</span> is
+		statically included in <span style="text-decoration: underline;">all</span>
+		JSP's used in the application. It specifies the taglibs that are in use.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">header.jsp</span> and
+	  	<span style="font-style: italic; font-weight: bold;">footer.jsp</span>
+		display info common to virtually all pages. Spring also supplies
+		support for the integration of <a href="http://www.lifl.fr/%7Edumoulin/tiles">Tiles</a>
+		(included in Struts) but this is not used in PetClinic.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">dataAccessFailure.jsp</span>
+	  	is the error page configured via
+		<span style="font-weight: bold; font-style: italic;">SimpleMappingExceptionResolver</span>,
+		which displays a stack trace and normally wouldn't be used in a production
+		version of an application. It can be seen in action by entering a URL of
+		"editOwner.do" or "editPet.do" with an invalid request parameter, for example:
+		<a href="http://localhost:8080/org.springframework.samples.petclinic/owner.do?ownerId=-1">/petclinic/owner.do?ownerId=-1</a>.
+		The handlers for these URLs normally expect to see a respective "ownerId" or "petId"
+		request parameter corresponding to an Owner or Pet in the database. Thus,
+		these handlers will throw a <strong>DataAccessException</strong> when such
+		a request parameter is provided which references a non-existing entity.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">uncaughtException.jsp</span>
+		is the <span style="font-weight: bold; font-style: italic;">web.xml</span> configured
+		"error-page". It displays a stack trace and normally wouldn't be used
+		in a production version of an application. It can be seen in action by
+		entering a URL of "editOwner.do" or "editPet.do" without a valid request
+		parameter, for example:
+		<a href="http://localhost:8080/org.springframework.samples.petclinic/owner.do">/petclinic/owner.do</a>.
+		The handlers for these URLs normally expect to see a respective "ownerId" or "petId"
+		request parameter and throw a <strong>ServletException</strong> when such
+		a request parameter is not found.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">welcome.jsp</span> implements
+	  	<span style="font-weight: bold; font-style: italic;">welcome</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">vets.jsp</span> implements
+	  	<span style="font-weight: bold; font-style: italic;">vets</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">findOwners.jsp</span> implements
+		<span style="font-weight: bold; font-style: italic;">findOwners</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">owners.jsp</span> implements
+		<span style="font-weight: bold; font-style: italic;">selectOwner</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">owner.jsp</span> implements
+		<span style="font-weight: bold; font-style: italic;">owner</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">ownerForm.jsp</span> implements
+		<span style="font-weight: bold; font-style: italic;">ownerForm</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">petForm.jsp</span> implements
+	  	<span style="font-weight: bold; font-style: italic;">petForm</span>.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">visitForm.jsp</span> implements
+		<span style="font-weight: bold; font-style: italic;">visitForm</span>.</li>
+	</ul>
+
+	<p>
+		The following items should be noted regarding the web application
+		implementation design:
+	</p>
+
+	<ol>
+	  <li>all JSP's are stored under <span style="font-weight: bold; font-style: italic;">/WEB-INF/jsp</span> except
+		for <span style="font-weight: bold; font-style: italic;">index.jsp</span> which
+		is the configured "welcome-file"</li>
+	  <li>The use of JSP technology in the application is not exposed to
+		the user, i.e., the end user never sees a URL ending in
+		<span style="font-weight: bold; font-style: italic;">".jsp".</span></li>
+	  <li>By convention, all URL's in the application ending in
+		<span style="font-weight: bold; font-style: italic;">".do"</span> are
+		handled by web application controllers. Static html pages ending in
+		<span style="font-weight: bold; font-style: italic;">".html"</span>, such as
+		Javadoc, will be directly served to the end user.</li>
+	  <li>The results of all form entries are handled using browser round
+		trip redirection to minimize possible end user confusion.</li>
+	  <li>All pages are extremely simple JSP implementations that focus
+		only on providing the necessary functionality.</li>
+	  <li>References to <span style="font-weight: bold;">Entity</span> objects
+		are passed around in the application by supplying the object's <code>ID</code>
+		as a request parameter.</li>
+	</ol>
+
+	<h3>Testing</h3>
+	<ul>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.OwnerTests</span>
+	  	is a simple JUnit 4 based TestCase that supports Business Rule #1.</li>
+	  <li><span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.AbstractClinicTests</span>
+		is a JUnit 4 based TestCase requiring a live database connection that is
+		used to confirm correct operation of the database access objects in the
+		various implementations of the <strong>Clinic</strong> interface.
+		&quot;AbstractClinicTests-context.xml&quot; declares a common
+		<strong>javax.sql.DataSource</strong>. Subclasses specify additional
+		context locations which declare a
+		<strong>org.springframework.transaction.PlatformTransactionManager</strong>
+		and a concrete implementation of <strong>Clinic</strong>.
+		<p>
+			AbstractClinicTests extends
+			<strong>AbstractTransactionalJUnit4SpringContextTests</strong>,
+			one of the valuable testing support classes provided by the
+			<em>Spring TestContext Framework</em> found in the
+			<code>org.springframework.test.context</code> package. The
+			annotation-driven configuration used here represents best practice for
+			integration tests with Spring. Note, however, that
+			AbstractTransactionalJUnit4SpringContextTests serves only as a convenience
+			for extension. For example, if you do not wish for your test classes to be
+			tied to a Spring-specific class hierarchy, you may configure your tests with
+			annotations such as <strong>@ContextConfiguration</strong>,
+			<strong>@TestExecutionListeners</strong>, <strong>@Transactional</strong>, etc.
+		</p>
+		<p>
+			AbstractClinicTests and its subclasses benefit from the following services
+			provided by the Spring TestContext Framework:
+		</p>
+		<ul>
+			<li><strong>Spring IoC container caching</strong> which spares us
+				unnecessary set up time between test execution.</li>
+			<li><strong>Dependency Injection</strong> of test fixture instances,
+				meaning that we don't need to perform application context lookups. See the
+				use of <strong>@Autowired</strong> on the <code>clinic</code> instance
+				variable, which uses autowiring <em>by type</em>. As an alternative, we
+				could annotate <code>clinic</code> with JSR 250's
+				<strong>@Resource</strong> to achieve dependency injection <em>by name</em>.
+				<em>(see: <strong>@ContextConfiguration</strong>,
+				<strong>DependencyInjectionTestExecutionListener</strong>)</em></li>
+			<li><strong>Transaction management</strong>, meaning each test method is
+				executed in its own transaction, which is automatically rolled back by
+				default. Thus, even if tests insert or otherwise change database state, there
+				is no need for a teardown or cleanup script.
+				<em>(see: <strong>@TransactionConfiguration</strong>,
+				<strong>@Transactional</strong>, <strong>TransactionalTestExecutionListener</strong>)</em></li>
+			<li><strong>Useful inherited protected fields</strong>, such as a
+				<strong>SimpleJdbcTemplate</strong> that can be used to verify
+				database state after test operations or to verify the results of
+				queries performed by application code. An
+				<strong>ApplicationContext</strong> is also inherited and can be
+				used for explicit bean lookup if necessary.
+				<em>(see: <strong>AbstractJUnit4SpringContextTests</strong>,
+				<strong>AbstractTransactionalJUnit4SpringContextTests</strong>)</em></li>
+		</ul>
+		<p>
+			The <em>Spring TestContext Framework</em> and related unit and
+			integration testing support classes are shipped in
+			<code>spring-test.jar</code>.
+		</p>
+
+	  </li>
+	</ul>
+
+	<h3>Downloads</h3>
+	<ul>
+	  <li>Download and install the
+	  	<a href="http://www.springsource.com/download/community?project=Spring%20Framework" target="_blank">Spring Framework</a>
+	  	(the PetClinic sample application is included)</li>
+	  <li>Download and install a <a href="http://java.sun.com/" target="_blank">Java</a>
+		Software Developer Kit, version 1.5 or later</li>
+	  <li>Download and install <a href="http://maven.apache.org" target="_blank">Apache Maven</a>,
+		preferably version 2.0.10 or later</li>
+	  <li>Download and install <a href="http://ant.apache.org" target="_blank">Apache Ant</a>,
+		preferably version 1.7.1 or later</li>
+	  <li>Download and install <a href="http://jakarta.apache.org/tomcat/index.html" target="_blank">Apache Tomcat</a>,
+		preferably version 6.0.20 or later</li>
+	  <li>Download and install <a href="http://dev.mysql.com/downloads/" target="_blank">MySQL</a>,
+		preferably version 5.1.x or later (optional)</li>
+	  <li><a href="http://hsqldb.sourceforge.net/" target="_blank">Hypersonic SQL</a>, and
+	  	<a href="http://hibernate.org/" target="_blank">Hibernate</a> are provided with the
+		application.</li>
+	  <li>PetClinic and Spring use the <a href="http://www.apache.org/" target="_blank">Apache</a>
+		<a href="http://commons.apache.org/logging/" target="_blank">Commons Logging</a>
+		and <a href="http://logging.apache.org/log4j/" target="_blank">log4j</a>
+		packages.</li>
+	</ul>
+
+	<h3>Maven Setup</h3>
+	<p>
+		Make sure that the Maven executable is in your command shell path.
+	</p>
+
+	<h3>MYSQL Setup (optional)</h3>
+	<p>
+		Add the PetClinic database to a running MySQL server by following the
+		explicit instructions found in
+		<span style="font-weight: bold; font-style: italic;">db/mysql/petclinic_db_setup_mysql.txt</span>.
+		PetClinic expects by default to be able to access the server via the
+		standard port <code>3306</code>. To use a different port, it will be
+		necessary to change the PetClinic Database Setup.
+	</p>
+
+	<h3>PetClinic Database Setup</h3>
+	<p>
+		To use a Java EE server supplied connection-pooled data source with
+		Tomcat, it will be necessary to use and possibly edit the appropriate
+		context definition file for the petclinic webapp. To use it, deploy a
+		copy of the appropriate context definition file in Tomcat's webapps
+		directory and restart the server. Consult the Tomcat log files if
+		something goes wrong when starting either Tomcat or the PetClinic
+		application. The context files are named
+		<span style="font-weight: bold; font-style: italic;">petclinic_tomcat_*.xml</span>,
+		where <strong>*</strong> is either &quot;hsqldb&quot; or &quot;mysql&quot;.
+		There is a context file supplied for each
+		database in its respective directory. There is also a context file
+		<span style="font-weight: bold; font-style: italic;">db/petclinic_tomcat_all.xml</span>
+		that will provide a JNDI connection-pooled DataSource for all supported
+		databases. Should you use this file, you must of course make sure that all the
+		database servers are running when you restart Tomcat.
+	</p>
+
+	<p>
+		<a name="dbNotes"></a>
+		<span style="font-weight: bold;">NOTES:</span>
+	</p>
+
+	<ol>
+	  <li>Should you deploy one of the context files or define a context in
+		Tomcat's <span style="font-weight: bold; font-style: italic;">server.xml</span>,
+		Tomcat will not automatically deploy the webapp from the
+		<span style="font-weight: bold; font-style: italic;">petclinic.war</span> file.
+		The webapp will then need to be manually extracted to the target
+		directory.</li>
+	  <li>The context files will also configure logging to supply a
+		separate log file for the petclinic context. This will separate the
+		container logging for petclinic from that of the other webapps. This
+		should not be confused with the application log file provided through
+		<span style="font-weight: bold;">log4j.</span></li>
+	  <li>An Ant script (<span style="font-weight: bold; font-style: italic;">db/build.xml</span>)
+		has been provided that can be used to re-initialize either database. To
+		select or configure the data source and database used for the webapp and
+		for testing, you will need to edit the following files:
+		<ul>
+		  <li><span style="font-weight: bold; font-style: italic;">src/main/webapp/WEB-INF/applicationContext-*.xml</span>:
+			for configuring the DataSource in the webapp</li>
+		  <li><span style="font-weight: bold; font-style: italic;">src/main/resources/jdbc.properties</span>:
+			for configuring JDBC connection settings for both the webapp and testing</li>
+		  <li><span style="font-weight: bold; font-style: italic;">build.properties</span>:
+			for running the &quot;tests&quot; target in Ant</li>
+		</ul>
+	  </li>
+	</ol>
+
+	<h3>Building the PetClinic Application</h3>
+	<p>
+		Open a command line shell and navigate to the directory containing
+		PetClinic. Make sure the database is running and execute
+		&quot;mvn clean package&quot;. This will run clean and compile everything
+		and execute the tests, including integration tests against an in-memory
+		database.
+	</p>
+
+	<h3>Deploying the PetClinic Application</h3>
+	<p>
+		Deploy the web application to the server in the usual way (see
+		<a href="#dbNotes">notes</a> regarding database setup). If you need
+		instructions for web application deployment, see the Tomcat
+		documentation for details. The Web Application aRchive file is
+		<span style="font-weight: bold; font-style: italic;">org.springframework.samples.petclinic.war</span>
+		and can be found in the
+		<span style="font-weight: bold; font-style: italic;">target/artifacts</span> directory.
+	</p>
+
+	<h3>Using the PetClinic Application</h3>
+	<p>
+		Make sure the PetClinic web application is running and browse to
+		<a href="http://localhost:8080/org.springframework.samples.petclinic/">http://localhost:8080/org.springframework.samples.petclinic/</a>.
+	</p>
+
+  <table class="footer">
+    <tr>
+      <td><a href="../welcome.do">Home</a></td>
+      <td align="right"><img src="../images/springsource-logo.png"/></td>
+	</tr>
+  </table>
+  </div>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/src/main/webapp/images/banner-graphic.png b/src/main/webapp/images/banner-graphic.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6d01d5885266efbf4dc99431576a13dee5725e4
Binary files /dev/null and b/src/main/webapp/images/banner-graphic.png differ
diff --git a/src/main/webapp/images/bullet-arrow.png b/src/main/webapp/images/bullet-arrow.png
new file mode 100644
index 0000000000000000000000000000000000000000..5909c25b397bb899de0dc010cb1b564b90175893
Binary files /dev/null and b/src/main/webapp/images/bullet-arrow.png differ
diff --git a/src/main/webapp/images/pets.png b/src/main/webapp/images/pets.png
new file mode 100644
index 0000000000000000000000000000000000000000..0fe63c282b189268e53aa34cf523f32ad7772401
Binary files /dev/null and b/src/main/webapp/images/pets.png differ
diff --git a/src/main/webapp/images/springsource-logo.png b/src/main/webapp/images/springsource-logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..e170f8abf778b24ed1de11dad6f1444e849269ba
Binary files /dev/null and b/src/main/webapp/images/springsource-logo.png differ
diff --git a/src/main/webapp/images/submit-bg.png b/src/main/webapp/images/submit-bg.png
new file mode 100644
index 0000000000000000000000000000000000000000..10a94371b642251703b0c2439d5e62578f8e6e5a
Binary files /dev/null and b/src/main/webapp/images/submit-bg.png differ
diff --git a/src/main/webapp/styles/petclinic.css b/src/main/webapp/styles/petclinic.css
new file mode 100644
index 0000000000000000000000000000000000000000..e12f96af7807f9e1baadbffcaa75a7e1ead6abba
--- /dev/null
+++ b/src/main/webapp/styles/petclinic.css
@@ -0,0 +1,234 @@
+/* main elements */
+
+body,div,td {
+	font-family: Arial, Helvetica, sans-serif;
+	font-size: 12px;
+	color: #666;
+}
+
+body {
+	background-color: #fff;
+	background-image: url(../images/banner-graphic.png);
+	background-position: top center;
+	background-repeat: no-repeat;
+	text-align: center;
+	min-width: 600px;
+	margin-top: 60px;
+	margin-left: auto;
+	margin-right: auto;
+}
+
+div {
+	margin: 5px 25px 5px 25px;
+	text-align: left;
+}
+
+/* header and footer elements */
+
+#main {
+  	margin:0 auto;
+  	position:relative;
+  	top: 35px;
+  	left:0px;
+  	width:560px;
+  	text-align:left;
+}
+
+.footer {
+	background:#fff;
+	border:none;
+	margin-top:20px;
+	border-top:1px solid #999999;
+	width:100%;
+}
+
+.footer td {color:#999999;}
+
+.footer a:link {color: #7db223;}
+
+	
+/* text styles */
+
+h1,h2,h3 {
+	font-family: Helvetica, sans-serif;
+	color: #7db223;
+}
+
+h1 {
+	font-size: 20px;
+	line-height: 26px;
+}
+
+h2 {
+	font-size: 18px;
+	line-height: 24px;
+}
+
+h3 {
+	font-size: 15px;
+	line-height: 21px;
+	color:#555;
+}
+
+h4 {
+	font-size: 14px;
+	line-height: 20px;
+}
+
+.errors {
+	color: red;
+	font-weight: bold;
+}
+
+a {
+	text-decoration: underline;
+	font-size: 13px;
+}
+
+a:link {
+	color: #7db223;
+}
+
+a:hover {
+	color: #456314;
+}
+
+a:active {
+	color: #7db223;
+}
+
+a:visited {
+	color: #7db223;
+}
+
+ul {
+	list-style: disc url(../images/bullet-arrow.png);
+}
+
+li {
+	padding-top: 5px;
+	text-align: left;
+}
+
+li ul {
+	list-style: square url(../images/bullet-arrow.png);
+}
+
+li ul li ul {
+	list-style: circle none;
+}
+
+/* table elements */
+
+table {
+	background: #d6e2c3;
+	margin: 3px 0 0 0;
+	border: 4px solid #d6e2c3;
+	border-collapse: collapse;
+}
+
+table table {
+	margin: -5px 0;
+	border: 0px solid #e0e7d3;
+	width: 100%;
+}
+
+table td,table th {
+	padding: 8px;
+}
+
+table th {
+	font-size: 12px;
+	text-align: left;
+	font-weight: bold;
+}
+
+table thead {
+	font-weight: bold;
+	font-style: italic;
+	background-color: #c2ceaf;
+}
+
+table a:link {color: #303030;}
+
+caption {
+	caption-side: top;
+	width: auto;
+	text-align: left;
+	font-size: 12px;
+	color: #848f73;
+	padding-bottom: 4px;
+}
+
+fieldset {
+	background: #e0e7d3;
+	padding: 8px;
+	padding-bottom: 22px;
+	border: none;
+	width: 560px;
+}
+
+fieldset label {
+	width: 70px;
+	float: left;
+	margin-top: 1.7em;
+	margin-left: 20px;
+}
+
+fieldset textfield {
+	margin: 3px;
+	height: 20px;
+	background: #e0e7d3;
+}
+
+fieldset textarea {
+	margin: 3px;
+	height: 165px;
+	background: #e0e7d3;
+}
+
+fieldset input {
+	margin: 3px;
+	height: 20px;
+	background: #e0e7d3;
+}
+
+fieldset table {
+	width: 100%;
+}
+
+fieldset th {
+	padding-left: 25px;
+}
+
+.table-buttons {
+	background-color:#fff;
+	border:none;
+}
+
+.table-buttons td {
+	border:none;
+}
+
+.submit input {
+	background:url(../images/submit-bg.png) repeat-x;
+    border: 2px outset #d7b9c9;
+	color:#383838;
+	padding:2px 10px;
+	font-size:11px;
+	text-transform:uppercase;
+	font-weight:bold;
+}
+
+.updated {
+	background:#ecf1e5;
+	font-size:11px;
+	margin-left:2px;
+	border:4px solid #ecf1e5;
+}
+
+.updated td {
+	padding:2px 8px;
+	font-size:11px;
+	color:#888888;
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java b/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..a698691867a90b98be6dd03edca171e71f1790f2
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/AbstractClinicTests.java
@@ -0,0 +1,224 @@
+package org.springframework.samples.petclinic;
+
+import java.util.Collection;
+import java.util.Date;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.samples.petclinic.util.EntityUtils;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
+
+/**
+ * <p>
+ * Base class for {@link Clinic} integration tests.
+ * </p>
+ * <p>
+ * &quot;AbstractClinicTests-context.xml&quot; declares a common
+ * {@link javax.sql.DataSource DataSource}. Subclasses should specify
+ * additional context locations which declare a
+ * {@link org.springframework.transaction.PlatformTransactionManager PlatformTransactionManager}
+ * and a concrete implementation of {@link Clinic}.
+ * </p>
+ * <p>
+ * This class extends {@link AbstractTransactionalJUnit4SpringContextTests},
+ * one of the valuable testing support classes provided by the
+ * <em>Spring TestContext Framework</em> found in the
+ * <code>org.springframework.test.context</code> package. The
+ * annotation-driven configuration used here represents best practice for
+ * integration tests with Spring. Note, however, that
+ * AbstractTransactionalJUnit4SpringContextTests serves only as a convenience
+ * for extension. For example, if you do not wish for your test classes to be
+ * tied to a Spring-specific class hierarchy, you may configure your tests with
+ * annotations such as {@link ContextConfiguration @ContextConfiguration},
+ * {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners},
+ * {@link org.springframework.transaction.annotation.Transactional @Transactional},
+ * etc.
+ * </p>
+ * <p>
+ * AbstractClinicTests and its subclasses benefit from the following services
+ * provided by the Spring TestContext Framework:
+ * </p>
+ * <ul>
+ * <li><strong>Spring IoC container caching</strong> which spares us
+ * unnecessary set up time between test execution.</li>
+ * <li><strong>Dependency Injection</strong> of test fixture instances,
+ * meaning that we don't need to perform application context lookups. See the
+ * use of {@link Autowired @Autowired} on the <code>clinic</code> instance
+ * variable, which uses autowiring <em>by type</em>. As an alternative, we
+ * could annotate <code>clinic</code> with
+ * {@link javax.annotation.Resource @Resource} to achieve dependency injection
+ * <em>by name</em>.
+ * <em>(see: {@link ContextConfiguration @ContextConfiguration},
+ * {@link org.springframework.test.context.support.DependencyInjectionTestExecutionListener DependencyInjectionTestExecutionListener})</em></li>
+ * <li><strong>Transaction management</strong>, meaning each test method is
+ * executed in its own transaction, which is automatically rolled back by
+ * default. Thus, even if tests insert or otherwise change database state, there
+ * is no need for a teardown or cleanup script.
+ * <em>(see: {@link org.springframework.test.context.transaction.TransactionConfiguration @TransactionConfiguration},
+ * {@link org.springframework.transaction.annotation.Transactional @Transactional},
+ * {@link org.springframework.test.context.transaction.TransactionalTestExecutionListener TransactionalTestExecutionListener})</em></li>
+ * <li><strong>Useful inherited protected fields</strong>, such as a
+ * {@link org.springframework.jdbc.core.simple.SimpleJdbcTemplate SimpleJdbcTemplate}
+ * that can be used to verify database state after test operations or to verify
+ * the results of queries performed by application code. An
+ * {@link org.springframework.context.ApplicationContext ApplicationContext} is
+ * also inherited and can be used for explicit bean lookup if necessary.
+ * <em>(see: {@link org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests AbstractJUnit4SpringContextTests},
+ * {@link AbstractTransactionalJUnit4SpringContextTests})</em></li>
+ * </ul>
+ * <p>
+ * The Spring TestContext Framework and related unit and integration testing
+ * support classes are shipped in <code>spring-test.jar</code>.
+ * </p>
+ *
+ * @author Ken Krebs
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ */
+@ContextConfiguration
+public abstract class AbstractClinicTests extends AbstractTransactionalJUnit4SpringContextTests {
+
+	@Autowired
+	protected Clinic clinic;
+
+
+	@Test
+	public void getVets() {
+		Collection<Vet> vets = this.clinic.getVets();
+		// Use the inherited countRowsInTable() convenience method (from
+		// AbstractTransactionalJUnit4SpringContextTests) to verify the results.
+		assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size());
+		Vet v1 = EntityUtils.getById(vets, Vet.class, 2);
+		assertEquals("Leary", v1.getLastName());
+		assertEquals(1, v1.getNrOfSpecialties());
+		assertEquals("radiology", (v1.getSpecialties().get(0)).getName());
+		Vet v2 = EntityUtils.getById(vets, Vet.class, 3);
+		assertEquals("Douglas", v2.getLastName());
+		assertEquals(2, v2.getNrOfSpecialties());
+		assertEquals("dentistry", (v2.getSpecialties().get(0)).getName());
+		assertEquals("surgery", (v2.getSpecialties().get(1)).getName());
+	}
+
+	@Test
+	public void getPetTypes() {
+		Collection<PetType> petTypes = this.clinic.getPetTypes();
+		assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"),
+				petTypes.size());
+		PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1);
+		assertEquals("cat", t1.getName());
+		PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4);
+		assertEquals("snake", t4.getName());
+	}
+
+	@Test
+	public void findOwners() {
+		Collection<Owner> owners = this.clinic.findOwners("Davis");
+		assertEquals(2, owners.size());
+		owners = this.clinic.findOwners("Daviss");
+		assertEquals(0, owners.size());
+	}
+
+	@Test
+	public void loadOwner() {
+		Owner o1 = this.clinic.loadOwner(1);
+		assertTrue(o1.getLastName().startsWith("Franklin"));
+		Owner o10 = this.clinic.loadOwner(10);
+		assertEquals("Carlos", o10.getFirstName());
+
+		// XXX: Add programmatic support for ending transactions with the
+		// TestContext Framework.
+
+		// Check lazy loading, by ending the transaction:
+		// endTransaction();
+
+		// Now Owners are "disconnected" from the data store.
+		// We might need to touch this collection if we switched to lazy loading
+		// in mapping files, but this test would pick this up.
+		o1.getPets();
+	}
+
+	@Test
+	public void insertOwner() {
+		Collection<Owner> owners = this.clinic.findOwners("Schultz");
+		int found = owners.size();
+		Owner owner = new Owner();
+		owner.setLastName("Schultz");
+		this.clinic.storeOwner(owner);
+		// assertTrue(!owner.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		owners = this.clinic.findOwners("Schultz");
+		assertEquals("Verifying number of owners after inserting a new one.", found + 1, owners.size());
+	}
+
+	@Test
+	public void updateOwner() throws Exception {
+		Owner o1 = this.clinic.loadOwner(1);
+		String old = o1.getLastName();
+		o1.setLastName(old + "X");
+		this.clinic.storeOwner(o1);
+		o1 = this.clinic.loadOwner(1);
+		assertEquals(old + "X", o1.getLastName());
+	}
+
+	@Test
+	public void loadPet() {
+		Collection<PetType> types = this.clinic.getPetTypes();
+		Pet p7 = this.clinic.loadPet(7);
+		assertTrue(p7.getName().startsWith("Samantha"));
+		assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId());
+		assertEquals("Jean", p7.getOwner().getFirstName());
+		Pet p6 = this.clinic.loadPet(6);
+		assertEquals("George", p6.getName());
+		assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId());
+		assertEquals("Peter", p6.getOwner().getFirstName());
+	}
+
+	@Test
+	public void insertPet() {
+		Owner o6 = this.clinic.loadOwner(6);
+		int found = o6.getPets().size();
+		Pet pet = new Pet();
+		pet.setName("bowser");
+		Collection<PetType> types = this.clinic.getPetTypes();
+		pet.setType(EntityUtils.getById(types, PetType.class, 2));
+		pet.setBirthDate(new Date());
+		o6.addPet(pet);
+		assertEquals(found + 1, o6.getPets().size());
+		// both storePet and storeOwner are necessary to cover all ORM tools
+		this.clinic.storePet(pet);
+		this.clinic.storeOwner(o6);
+		// assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		o6 = this.clinic.loadOwner(6);
+		assertEquals(found + 1, o6.getPets().size());
+	}
+
+	@Test
+	public void updatePet() throws Exception {
+		Pet p7 = this.clinic.loadPet(7);
+		String old = p7.getName();
+		p7.setName(old + "X");
+		this.clinic.storePet(p7);
+		p7 = this.clinic.loadPet(7);
+		assertEquals(old + "X", p7.getName());
+	}
+
+	@Test
+	public void insertVisit() {
+		Pet p7 = this.clinic.loadPet(7);
+		int found = p7.getVisits().size();
+		Visit visit = new Visit();
+		p7.addVisit(visit);
+		visit.setDescription("test");
+		// both storeVisit and storePet are necessary to cover all ORM tools
+		this.clinic.storeVisit(visit);
+		this.clinic.storePet(p7);
+		// assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		p7 = this.clinic.loadPet(7);
+		assertEquals(found + 1, p7.getVisits().size());
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/OwnerTests.java b/src/test/java/org/springframework/samples/petclinic/OwnerTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..84b5f62c6c25acc504340a7da38ee50dafee5050
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/OwnerTests.java
@@ -0,0 +1,27 @@
+package org.springframework.samples.petclinic;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+
+/**
+ * JUnit test for the {@link Owner} class.
+ *
+ * @author Ken Krebs
+ */
+public class OwnerTests {
+
+	@Test
+	public void testHasPet() {
+		Owner owner = new Owner();
+		Pet fido = new Pet();
+		fido.setName("Fido");
+		assertNull(owner.getPet("Fido"));
+		assertNull(owner.getPet("fido"));
+		owner.addPet(fido);
+		assertEquals(fido, owner.getPet("Fido"));
+		assertEquals(fido, owner.getPet("fido"));
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java b/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java
new file mode 100644
index 0000000000000000000000000000000000000000..d561993993793a59cc2c130be1ee7c81a46698ca
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/PetClinicTestSuite.java
@@ -0,0 +1,29 @@
+package org.springframework.samples.petclinic;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+import org.springframework.samples.petclinic.hibernate.HibernateClinicTests;
+import org.springframework.samples.petclinic.jdbc.SimpleJdbcClinicTests;
+import org.springframework.samples.petclinic.jpa.EntityManagerClinicTests;
+import org.springframework.samples.petclinic.jpa.HibernateEntityManagerClinicTests;
+import org.springframework.samples.petclinic.jpa.OpenJpaEntityManagerClinicTests;
+import org.springframework.samples.petclinic.web.VisitsAtomViewTest;
+
+/**
+ * JUnit 4 based test suite for all PetClinic tests.
+ *
+ * @author Sam Brannen
+ */
+@RunWith(Suite.class)
+@SuiteClasses({
+	OwnerTests.class,
+	SimpleJdbcClinicTests.class,
+	HibernateClinicTests.class,
+	EntityManagerClinicTests.class,
+	HibernateEntityManagerClinicTests.class,
+	OpenJpaEntityManagerClinicTests.class,
+	VisitsAtomViewTest.class
+})
+public class PetClinicTestSuite {
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..3c275c820b22c9d168063d1fc6aa8b28ffea8b00
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/hibernate/HibernateClinicTests.java
@@ -0,0 +1,20 @@
+package org.springframework.samples.petclinic.hibernate;
+
+import org.springframework.samples.petclinic.AbstractClinicTests;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * <p>
+ * Integration tests for the {@link HibernateClinic} implementation.
+ * </p>
+ * <p>
+ * "HibernateClinicTests-context.xml" determines the actual beans to test.
+ * </p>
+ *
+ * @author Juergen Hoeller
+ * @author Sam Brannen
+ */
+@ContextConfiguration
+public class HibernateClinicTests extends AbstractClinicTests {
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..709100d1a12db583b5a3c9b5cb4afbbd8b3949a5
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests.java
@@ -0,0 +1,19 @@
+package org.springframework.samples.petclinic.jdbc;
+
+import org.springframework.samples.petclinic.AbstractClinicTests;
+import org.springframework.test.context.ContextConfiguration;
+
+/**
+ * <p>
+ * Integration tests for the {@link SimpleJdbcClinic} implementation.
+ * </p>
+ * <p>
+ * "SimpleJdbcClinicTests-context.xml" determines the actual beans to test.
+ * </p>
+ *
+ * @author Thomas Risberg
+ */
+@ContextConfiguration
+public class SimpleJdbcClinicTests extends AbstractClinicTests {
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..251af819d16e09ff4707034db918881d356d9ee0
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/jpa/AbstractJpaClinicTests.java
@@ -0,0 +1,199 @@
+
+package org.springframework.samples.petclinic.jpa;
+
+import java.util.Collection;
+import java.util.Date;
+
+import javax.persistence.EntityManager;
+
+import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+import org.springframework.samples.petclinic.Clinic;
+import org.springframework.samples.petclinic.Owner;
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.Vet;
+import org.springframework.samples.petclinic.Visit;
+import org.springframework.samples.petclinic.util.EntityUtils;
+import org.springframework.test.annotation.ExpectedException;
+import org.springframework.test.jpa.AbstractJpaTests;
+
+/**
+ * <p>
+ * This class extends {@link AbstractJpaTests}, one of the valuable test
+ * superclasses provided in the <code>org.springframework.test</code> package.
+ * This represents best practice for integration tests with Spring for JPA based
+ * tests which require <em>shadow class loading</em>. For all other types of
+ * integration testing, the <em>Spring TestContext Framework</em> is
+ * preferred.
+ * </p>
+ * <p>
+ * AbstractJpaTests and its superclasses provide the following services:
+ * <ul>
+ * <li>Injects test dependencies, meaning that we don't need to perform
+ * application context lookups. See the setClinic() method. Injection uses
+ * autowiring by type.</li>
+ * <li>Executes each test method in its own transaction, which is automatically
+ * rolled back by default. This means that even if tests insert or otherwise
+ * change database state, there is no need for a teardown or cleanup script.</li>
+ * <li>Provides useful inherited protected fields, such as a
+ * {@link SimpleJdbcTemplate} that can be used to verify database state after
+ * test operations, or verify the results of queries performed by application
+ * code. Alternatively, you can use protected convenience methods such as
+ * {@link #countRowsInTable(String)}, {@link #deleteFromTables(String[])},
+ * etc. An ApplicationContext is also inherited, and can be used for explicit
+ * lookup if necessary.</li>
+ * </ul>
+ * <p>
+ * {@link AbstractJpaTests} and related classes are shipped in
+ * <code>spring-test.jar</code>.
+ * </p>
+ *
+ * @author Rod Johnson
+ * @author Sam Brannen
+ * @see AbstractJpaTests
+ */
+public abstract class AbstractJpaClinicTests extends AbstractJpaTests {
+
+	protected Clinic clinic;
+
+
+	/**
+	 * This method is provided to set the Clinic instance being tested by the
+	 * Dependency Injection injection behaviour of the superclass from the
+	 * <code>org.springframework.test</code> package.
+	 *
+	 * @param clinic clinic to test
+	 */
+	public void setClinic(Clinic clinic) {
+		this.clinic = clinic;
+	}
+
+	@ExpectedException(IllegalArgumentException.class)
+	public void testBogusJpql() {
+		this.sharedEntityManager.createQuery("SELECT RUBBISH FROM RUBBISH HEAP").executeUpdate();
+	}
+
+	public void testApplicationManaged() {
+		EntityManager appManaged = this.entityManagerFactory.createEntityManager();
+		appManaged.joinTransaction();
+	}
+
+	public void testGetVets() {
+		Collection<Vet> vets = this.clinic.getVets();
+		// Use the inherited countRowsInTable() convenience method (from
+		// AbstractTransactionalDataSourceSpringContextTests) to verify the
+		// results.
+		assertEquals("JDBC query must show the same number of vets", super.countRowsInTable("VETS"), vets.size());
+		Vet v1 = EntityUtils.getById(vets, Vet.class, 2);
+		assertEquals("Leary", v1.getLastName());
+		assertEquals(1, v1.getNrOfSpecialties());
+		assertEquals("radiology", (v1.getSpecialties().get(0)).getName());
+		Vet v2 = EntityUtils.getById(vets, Vet.class, 3);
+		assertEquals("Douglas", v2.getLastName());
+		assertEquals(2, v2.getNrOfSpecialties());
+		assertEquals("dentistry", (v2.getSpecialties().get(0)).getName());
+		assertEquals("surgery", (v2.getSpecialties().get(1)).getName());
+	}
+
+	public void testGetPetTypes() {
+		Collection<PetType> petTypes = this.clinic.getPetTypes();
+		assertEquals("JDBC query must show the same number of pet types", super.countRowsInTable("TYPES"),
+				petTypes.size());
+		PetType t1 = EntityUtils.getById(petTypes, PetType.class, 1);
+		assertEquals("cat", t1.getName());
+		PetType t4 = EntityUtils.getById(petTypes, PetType.class, 4);
+		assertEquals("snake", t4.getName());
+	}
+
+	public void testFindOwners() {
+		Collection<Owner> owners = this.clinic.findOwners("Davis");
+		assertEquals(2, owners.size());
+		owners = this.clinic.findOwners("Daviss");
+		assertEquals(0, owners.size());
+	}
+
+	public void testLoadOwner() {
+		Owner o1 = this.clinic.loadOwner(1);
+		assertTrue(o1.getLastName().startsWith("Franklin"));
+		Owner o10 = this.clinic.loadOwner(10);
+		assertEquals("Carlos", o10.getFirstName());
+
+		// Check lazy loading, by ending the transaction
+		endTransaction();
+
+		// Now Owners are "disconnected" from the data store.
+		// We might need to touch this collection if we switched to lazy loading
+		// in mapping files, but this test would pick this up.
+		o1.getPets();
+	}
+
+	public void testInsertOwner() {
+		Collection<Owner> owners = this.clinic.findOwners("Schultz");
+		int found = owners.size();
+		Owner owner = new Owner();
+		owner.setLastName("Schultz");
+		this.clinic.storeOwner(owner);
+		// assertTrue(!owner.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		owners = this.clinic.findOwners("Schultz");
+		assertEquals(found + 1, owners.size());
+	}
+
+	public void testUpdateOwner() throws Exception {
+		Owner o1 = this.clinic.loadOwner(1);
+		String old = o1.getLastName();
+		o1.setLastName(old + "X");
+		this.clinic.storeOwner(o1);
+		o1 = this.clinic.loadOwner(1);
+		assertEquals(old + "X", o1.getLastName());
+	}
+
+	public void testLoadPet() {
+		Collection<PetType> types = this.clinic.getPetTypes();
+		Pet p7 = this.clinic.loadPet(7);
+		assertTrue(p7.getName().startsWith("Samantha"));
+		assertEquals(EntityUtils.getById(types, PetType.class, 1).getId(), p7.getType().getId());
+		assertEquals("Jean", p7.getOwner().getFirstName());
+		Pet p6 = this.clinic.loadPet(6);
+		assertEquals("George", p6.getName());
+		assertEquals(EntityUtils.getById(types, PetType.class, 4).getId(), p6.getType().getId());
+		assertEquals("Peter", p6.getOwner().getFirstName());
+	}
+
+	public void testInsertPet() {
+		Owner o6 = this.clinic.loadOwner(6);
+		int found = o6.getPets().size();
+		Pet pet = new Pet();
+		pet.setName("bowser");
+		Collection<PetType> types = this.clinic.getPetTypes();
+		pet.setType(EntityUtils.getById(types, PetType.class, 2));
+		pet.setBirthDate(new Date());
+		o6.addPet(pet);
+		assertEquals(found + 1, o6.getPets().size());
+		this.clinic.storeOwner(o6);
+		// assertTrue(!pet.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		o6 = this.clinic.loadOwner(6);
+		assertEquals(found + 1, o6.getPets().size());
+	}
+
+	public void testUpdatePet() throws Exception {
+		Pet p7 = this.clinic.loadPet(7);
+		String old = p7.getName();
+		p7.setName(old + "X");
+		this.clinic.storePet(p7);
+		p7 = this.clinic.loadPet(7);
+		assertEquals(old + "X", p7.getName());
+	}
+
+	public void testInsertVisit() {
+		Pet p7 = this.clinic.loadPet(7);
+		int found = p7.getVisits().size();
+		Visit visit = new Visit();
+		p7.addVisit(visit);
+		visit.setDescription("test");
+		this.clinic.storePet(p7);
+		// assertTrue(!visit.isNew()); -- NOT TRUE FOR TOPLINK (before commit)
+		p7 = this.clinic.loadPet(7);
+		assertEquals(found + 1, p7.getVisits().size());
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..67c472fdeeacbe91eebd7da70fed0e23951b1504
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/jpa/EntityManagerClinicTests.java
@@ -0,0 +1,51 @@
+package org.springframework.samples.petclinic.jpa;
+
+import java.util.List;
+
+import org.springframework.samples.petclinic.aspects.UsageLogAspect;
+
+/**
+ * <p>
+ * Tests for the DAO variant based on the shared EntityManager approach. Uses
+ * TopLink Essentials (the reference implementation) for testing.
+ * </p>
+ * <p>
+ * Specifically tests usage of an <code>orm.xml</code> file, loaded by the
+ * persistence provider through the Spring-provided persistence unit root URL.
+ * </p>
+ *
+ * @author Rod Johnson
+ * @author Juergen Hoeller
+ */
+public class EntityManagerClinicTests extends AbstractJpaClinicTests {
+
+	private UsageLogAspect usageLogAspect;
+
+	public void setUsageLogAspect(UsageLogAspect usageLogAspect) {
+		this.usageLogAspect = usageLogAspect;
+	}
+
+	@Override
+	protected String[] getConfigPaths() {
+		return new String[] {
+			"applicationContext-jpaCommon.xml",
+			"applicationContext-toplinkAdapter.xml",
+			"applicationContext-entityManager.xml"
+		};
+	}
+
+	public void testUsageLogAspectIsInvoked() {
+		String name1 = "Schuurman";
+		String name2 = "Greenwood";
+		String name3 = "Leau";
+
+		assertTrue(this.clinic.findOwners(name1).isEmpty());
+		assertTrue(this.clinic.findOwners(name2).isEmpty());
+
+		List<String> namesRequested = this.usageLogAspect.getNamesRequested();
+		assertTrue(namesRequested.contains(name1));
+		assertTrue(namesRequested.contains(name2));
+		assertFalse(namesRequested.contains(name3));
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..d95b452e17cf798a84d8dc0aaa0e1a3e0a4b1d02
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/jpa/HibernateEntityManagerClinicTests.java
@@ -0,0 +1,26 @@
+package org.springframework.samples.petclinic.jpa;
+
+/**
+ * <p>
+ * Tests for the DAO variant based on the shared EntityManager approach, using
+ * Hibernate EntityManager for testing instead of the reference implementation.
+ * </p>
+ * <p>
+ * Specifically tests usage of an <code>orm.xml</code> file, loaded by the
+ * persistence provider through the Spring-provided persistence unit root URL.
+ * </p>
+ *
+ * @author Juergen Hoeller
+ */
+public class HibernateEntityManagerClinicTests extends EntityManagerClinicTests {
+
+	@Override
+	protected String[] getConfigPaths() {
+		return new String[] {
+			"applicationContext-jpaCommon.xml",
+			"applicationContext-hibernateAdapter.xml",
+			"applicationContext-entityManager.xml"
+		};
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java b/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java
new file mode 100644
index 0000000000000000000000000000000000000000..98e38ed6134cd0836f91ab3a0680f37e1cbf9d53
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/jpa/OpenJpaEntityManagerClinicTests.java
@@ -0,0 +1,27 @@
+
+package org.springframework.samples.petclinic.jpa;
+
+/**
+ * <p>
+ * Tests for the DAO variant based on the shared EntityManager approach, using
+ * Apache OpenJPA for testing instead of the reference implementation.
+ * </p>
+ * <p>
+ * Specifically tests usage of an <code>orm.xml</code> file, loaded by the
+ * persistence provider through the Spring-provided persistence unit root URL.
+ * </p>
+ *
+ * @author Juergen Hoeller
+ */
+public class OpenJpaEntityManagerClinicTests extends EntityManagerClinicTests {
+
+	@Override
+	protected String[] getConfigPaths() {
+		return new String[] {
+			"applicationContext-jpaCommon.xml",
+			"applicationContext-openJpaAdapter.xml",
+			"applicationContext-entityManager.xml"
+		};
+	}
+
+}
diff --git a/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java b/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..1e82e1d5bb142078dea20c35d749dadc28f44c95
--- /dev/null
+++ b/src/test/java/org/springframework/samples/petclinic/web/VisitsAtomViewTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2002-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.samples.petclinic.web;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.syndication.feed.atom.Entry;
+import com.sun.syndication.feed.atom.Feed;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.springframework.samples.petclinic.Pet;
+import org.springframework.samples.petclinic.PetType;
+import org.springframework.samples.petclinic.Visit;
+
+/**
+ * @author Arjen Poutsma
+ */
+public class VisitsAtomViewTest {
+
+	private VisitsAtomView visitView;
+
+	private Map<String, Object> model;
+
+	private Feed feed;
+
+	@Before
+	public void setUp() {
+		visitView = new VisitsAtomView();
+		PetType dog = new PetType();
+		dog.setName("dog");
+		Pet bello = new Pet();
+		bello.setName("Bello");
+		bello.setType(dog);
+		Visit belloVisit = new Visit();
+		belloVisit.setPet(bello);
+		belloVisit.setDate(new Date(2009, 0, 1));
+		belloVisit.setDescription("Bello visit");
+		Pet wodan = new Pet();
+		wodan.setName("Wodan");
+		wodan.setType(dog);
+		Visit wodanVisit = new Visit();
+		wodanVisit.setPet(wodan);
+		wodanVisit.setDate(new Date(2009, 0, 2));
+		wodanVisit.setDescription("Wodan visit");
+		List<Visit> visits = new ArrayList<Visit>();
+		visits.add(belloVisit);
+		visits.add(wodanVisit);
+
+		model = new HashMap<String, Object>();
+		model.put("visits", visits);
+		feed = new Feed();
+
+	}
+
+	@Test
+	public void buildFeedMetadata() {
+		visitView.buildFeedMetadata(model, feed, null);
+
+		assertNotNull("No id set", feed.getId());
+		assertNotNull("No title set", feed.getTitle());
+		assertEquals("Invalid update set", new Date(2009, 0, 2), feed.getUpdated());
+	}
+
+	@Test
+	public void buildFeedEntries() throws Exception {
+		List<Entry> entries = visitView.buildFeedEntries(model, null, null);
+		assertEquals("Invalid amount of entries", 2, entries.size());
+	}
+}
diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml
new file mode 100644
index 0000000000000000000000000000000000000000..767b96d6206d5fc8eb42f14f9e10be7f5c3251fc
--- /dev/null
+++ b/src/test/resources/log4j.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+
+	<!-- Appenders -->
+	<appender name="console" class="org.apache.log4j.ConsoleAppender">
+		<param name="Target" value="System.out" />
+		<layout class="org.apache.log4j.PatternLayout">
+			<param name="ConversionPattern" value="%-5p: %c - %m%n" />
+		</layout>
+	</appender>
+
+	<logger name="org.springframework.beans">
+		<level value="warn" />
+	</logger>
+
+	<logger name="org.springframework.binding">
+		<level value="debug" />
+	</logger>
+
+	<!-- Root Logger -->
+	<root>
+		<priority value="warn" />
+		<appender-ref ref="console" />
+	</root>
+	
+</log4j:configuration>
\ No newline at end of file
diff --git a/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3f79cbc093998d1bd6b9c63876f759306da35f08
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/AbstractClinicTests-context.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:tx="http://www.springframework.org/schema/tx"
+	xsi:schemaLocation="
+		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
+
+	<context:property-placeholder location="classpath:/jdbc.properties"/>
+
+	<context:annotation-config/>
+
+	<tx:annotation-driven/>
+
+	<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
+			p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" 
+			p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
+			p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"
+			p:dropLocation="${jdbc.dropLocation}"/>
+	
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7320035ceceb6a274cec06980a039bca9da3af21
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/hibernate/HibernateClinicTests-context.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+	<bean class="org.springframework.samples.petclinic.hibernate.HibernateClinic">
+		<constructor-arg ref="sessionFactory"/>
+	</bean>
+
+	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
+		p:dataSource-ref="dataSource" p:mappingResources="petclinic.hbm.xml">
+		<property name="hibernateProperties">
+			<props>
+				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
+				<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
+			</props>
+		</property>
+		<property name="eventListeners">
+			<map>
+				<entry key="merge">
+					<bean class="org.springframework.orm.hibernate3.support.IdTransferringMergeEventListener" />
+				</entry>
+			</map>
+		</property>
+	</bean>
+
+	<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
+		p:sessionFactory-ref="sessionFactory" />
+
+	<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml b/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml
new file mode 100644
index 0000000000000000000000000000000000000000..81a536988bcda95bd6e06638a0c4f8141c5a8ac0
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jdbc/SimpleJdbcClinicTests-context.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
+		p:dataSource-ref="dataSource" />
+
+	<bean class="org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a9d25738584611f2cfef1f74ecf576c2da4c0f51
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-entityManager.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
+	xsi:schemaLocation="
+		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+	<aop:aspectj-autoproxy />
+
+	<bean class="org.springframework.samples.petclinic.aspects.UsageLogAspect" p:historySize="300" />
+
+	<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
+
+	<bean id="clinic" class="org.springframework.samples.petclinic.jpa.EntityManagerClinic" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..447d1bce08f496cf80b6b1e767b5f057e906d994
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-hibernateAdapter.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
+		p:database="${jpa.database}" p:showSql="${jpa.showSql}" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b873dfc47ed0ef3540e55146cbba4ea707eee333
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-jpaCommon.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
+	xmlns:tx="http://www.springframework.org/schema/tx"
+	xsi:schemaLocation="
+		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
+		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
+
+	<context:property-placeholder location="classpath:/jdbc.properties" />
+
+	<tx:annotation-driven />
+
+	<bean id="dataSource" class="org.springframework.samples.petclinic.config.DbcpDataSourceFactory"
+			p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url}" 
+			p:username="${jdbc.username}" p:password="${jdbc.password}" p:populate="${jdbc.populate}"
+			p:schemaLocation="${jdbc.schemaLocation}" p:dataLocation="${jdbc.dataLocation}"
+			p:dropLocation="${jdbc.dropLocation}"/>
+	
+	<!-- Note: the specific "jpaAdapter" bean sits in adapter context file -->
+	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
+		p:dataSource-ref="dataSource" p:jpaVendorAdapter-ref="jpaAdapter">
+		<property name="loadTimeWeaver">
+			<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
+		</property>
+	</bean>
+
+	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
+		p:entityManagerFactory-ref="entityManagerFactory" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8f6f7c4427c4779fbe013b0d5e0e0d4bf455c7cf
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-openJpaAdapter.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter" p:database="${jpa.database}"
+		p:showSql="${jpa.showSql}" />
+
+</beans>
diff --git a/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ac031de8e148870caaa07acbecb3e38e744c49dc
--- /dev/null
+++ b/src/test/resources/org/springframework/samples/petclinic/jpa/applicationContext-toplinkAdapter.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xmlns:p="http://www.springframework.org/schema/p"
+	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
+
+	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"
+		p:databasePlatform="${jpa.databasePlatform}" p:showSql="${jpa.showSql}" />
+
+</beans>