From ChrisBurrell at crosswire.org  Wed Apr 14 13:57:22 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 13:57:22 -0700
Subject: [Tynstep-svn] r107 - trunk
Message-ID: <E1O29eE-00033R-Ra@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 13:57:22 -0700 (Wed, 14 Apr 2010)
New Revision: 107

Removed:
   trunk/.project
   trunk/pom.xml
   trunk/step-checks.xml
   trunk/step-data-loader/
   trunk/step-server/
   trunk/step-tools/
   trunk/step-web-app-old/
Log:
Deleting everything

Deleted: trunk/.project
===================================================================
--- trunk/.project	2010-04-14 20:22:59 UTC (rev 106)
+++ trunk/.project	2010-04-14 20:57:22 UTC (rev 107)
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>step-parent</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.maven.ide.eclipse.maven2Builder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.maven.ide.eclipse.maven2Nature</nature>
-	</natures>
-</projectDescription>

Deleted: trunk/pom.xml
===================================================================
--- trunk/pom.xml	2010-04-14 20:22:59 UTC (rev 106)
+++ trunk/pom.xml	2010-04-14 20:57:22 UTC (rev 107)
@@ -1,199 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<groupId>com.tyndalehouse</groupId>
-	<artifactId>step-parent</artifactId>
-	<packaging>pom</packaging>
-	<version>1.0-SNAPSHOT</version>
-	<name>step-parent</name>
-	
-	<properties>
-		<project.build.sourceEncoding>iso-8859-1
-		</project.build.sourceEncoding>
-		<project.reporting.outputEncoding>iso-8859-1
-		</project.reporting.outputEncoding>
-		<java.version>1.5</java.version>
-		<gwt.version>2.0.3</gwt.version>
-		<db.directory>${user.home}/TyndaleStep/StepDB</db.directory>
-		<derby.version>10.5.3.0_1</derby.version>
-		<db.driver>org.apache.derby.jdbc.EmbeddedDriver</db.driver>
-		<db.connection.string>jdbc:derby:${db.directory}</db.connection.string>
-	</properties>
-
-	<scm>
-		<connection>scm:svn:https://crosswire.org/svn/tynstep/trunk</connection>
-		<developerConnection>scm:svn:https://crosswire.org/svn/tynstep/trunk</developerConnection>
-		<url>https://crosswire.org/svn/tynstep/trunk/</url>
-	</scm>
-
-
-	<modules>
-		<module>step-web-app</module>
-		<module>step-dataloader</module>
-		<module>step-server</module>
-		<module>step-tools</module>
-	</modules>
-
-	<dependencyManagement>
-		<dependencies>
-			<dependency>
-				<groupId>org.crosswire</groupId>
-				<artifactId>jsword</artifactId>
-				<version>1.6.1-SNAPSHOT</version>
-			</dependency>
-
-			<dependency>
-				<groupId>com.google.gwt</groupId>
-				<artifactId>gwt-servlet</artifactId>
-				<version>${gwt.version}</version>
-				<scope>compile</scope>
-			</dependency>
-			<dependency>
-				<groupId>com.google.gwt</groupId>
-				<artifactId>gwt-user</artifactId>
-				<version>${gwt.version}</version>
-				<scope>provided</scope>
-			</dependency>
-
-			<dependency>
-				<groupId>com.googlecode.gwt.inject
-				</groupId>
-				<artifactId>gin</artifactId>
-				<version>1.0</version>
-			</dependency>
-			<dependency>
-				<groupId>com.google.inject</groupId>
-				<artifactId>guice</artifactId>
-				<version>2.0</version>
-			</dependency>
-
-			<dependency>
-				<groupId>com.google.inject.extensions
-				</groupId>
-				<artifactId>guice-servlet</artifactId>
-				<version>2.0</version>
-			</dependency>
-
-			<dependency>
-				<groupId>net.customware.gwt.dispatch
-				</groupId>
-				<artifactId>gwt-dispatch</artifactId>
-				<version>1.0.0</version>
-			</dependency>
-
-			<dependency>
-				<groupId>net.customware.gwt.presenter
-				</groupId>
-				<artifactId>gwt-presenter</artifactId>
-				<version>1.0.0</version>
-			</dependency>
-
-			<dependency>
-				<groupId>com.google.code.gwt-log</groupId>
-				<artifactId>gwt-log</artifactId>
-				<version>2.6.2</version>
-			</dependency>
-
-			<dependency>
-				<groupId>com.extjs</groupId>
-				<artifactId>gxt</artifactId>
-				<version>2.1.1</version>
-			</dependency>
-
-			<dependency>
-				<groupId>commons-logging</groupId>
-				<artifactId>commons-logging</artifactId>
-				<version>1.1.1</version>
-			</dependency>
-
-			<dependency>
-				<groupId>commons-dbcp</groupId>
-				<artifactId>commons-dbcp</artifactId>
-				<version>1.3</version>
-			</dependency>
-
-			<dependency>
-				<groupId>commons-io</groupId>
-				<artifactId>commons-io</artifactId>
-				<version>1.4</version>
-			</dependency>
-
-			<dependency>
-				<groupId>commons-dbutils</groupId>
-				<artifactId>commons-dbutils</artifactId>
-				<version>1.3</version>
-			</dependency>
-
-			<dependency>
-				<groupId>commons-lang</groupId>
-				<artifactId>commons-lang</artifactId>
-				<version>2.5</version>
-			</dependency>
-
-			<dependency>
-				<groupId>org.jmock</groupId>
-				<artifactId>jmock</artifactId>
-				<version>2.5.1</version>
-				<scope>test</scope>
-			</dependency>
-
-			<dependency>
-				<groupId>org.jmock</groupId>
-				<artifactId>jmock-junit4</artifactId>
-				<version>2.5.1</version>
-				<scope>test</scope>
-			</dependency>
-
-			<dependency>
-				<groupId>org.apache.derby</groupId>
-				<artifactId>derbyclient</artifactId>
-				<version>${derby.version}</version>
-				<scope>runtime</scope>
-			</dependency>
-
-			<dependency>
-				<groupId>org.apache.derby</groupId>
-				<artifactId>derby</artifactId>
-				<version>${derby.version}</version>
-				<scope>runtime</scope>
-			</dependency>
-
-			<dependency>
-				<groupId>net.sf.opencsv</groupId>
-				<artifactId>opencsv</artifactId>
-				<version>2.1</version>
-			</dependency>
-		</dependencies>
-	</dependencyManagement>
-
-
-
-	<build>
-		<pluginManagement>
-			<plugins>
-				<plugin>
-					<groupId>org.apache.maven.plugins</groupId>
-					<artifactId>maven-compiler-plugin</artifactId>
-					<configuration>
-						<encoding>iso-8859-1</encoding>
-						<source>${java.version}</source>
-						<target>${java.version}</target>
-					</configuration>
-				</plugin>
-				<plugin>
-					<groupId>org.apache.maven.plugins</groupId>
-					<artifactId>maven-surefire-plugin</artifactId>
-					<configuration>
-						<junitArtifactName>junit:junit-dep
-						</junitArtifactName>
-					</configuration>
-				</plugin>
-				<plugin>
-					<groupId>org.apache.maven.plugins</groupId>
-					<artifactId>maven-eclipse-plugin</artifactId>
-					<version>2.5</version>
-				</plugin>
-			</plugins>
-		</pluginManagement>
-	</build>
-</project>

Deleted: trunk/step-checks.xml
===================================================================
--- trunk/step-checks.xml	2010-04-14 20:22:59 UTC (rev 106)
+++ trunk/step-checks.xml	2010-04-14 20:57:22 UTC (rev 107)
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
-
-<!--
-    This configuration file was written by the eclipse-cs plugin configuration editor
--->
-<!--
-    Checkstyle-Configuration: step-checks
-    Description: none
--->
-<module name="Checker">
-  <property name="severity" value="warning"/>
-  <module name="TreeWalker">
-    <property name="tabWidth" value="4"/>
-    <module name="FileContentsHolder"/>
-    <module name="JavadocMethod">
-      <property name="logLoadErrors" value="true"/>
-      <property name="suppressLoadErrors" value="true"/>
-    </module>
-    <module name="JavadocType"/>
-    <module name="JavadocVariable"/>
-    <module name="JavadocStyle">
-      <property name="checkFirstSentence" value="false"/>
-    </module>
-    <module name="ConstantName"/>
-    <module name="LocalFinalVariableName"/>
-    <module name="LocalVariableName"/>
-    <module name="MemberName"/>
-    <module name="MethodName"/>
-    <module name="PackageName"/>
-    <module name="ParameterName"/>
-    <module name="StaticVariableName"/>
-    <module name="TypeName"/>
-    <module name="AvoidStarImport"/>
-    <module name="IllegalImport"/>
-    <module name="RedundantImport"/>
-    <module name="UnusedImports"/>
-    <module name="FileLength"/>
-    <module name="MethodLength"/>
-    <module name="ParameterNumber"/>
-    <module name="EmptyForIteratorPad"/>
-    <module name="MethodParamPad"/>
-    <module name="NoWhitespaceAfter">
-      <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
-    </module>
-    <module name="NoWhitespaceBefore"/>
-    <module name="OperatorWrap"/>
-    <module name="ParenPad">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="TypecastParenPad"/>
-    <module name="TabCharacter">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="WhitespaceAfter"/>
-    <module name="WhitespaceAround"/>
-    <module name="ModifierOrder"/>
-    <module name="RedundantModifier"/>
-    <module name="AvoidNestedBlocks"/>
-    <module name="EmptyBlock"/>
-    <module name="LeftCurly"/>
-    <module name="NeedBraces"/>
-    <module name="RightCurly"/>
-    <module name="AvoidInlineConditionals">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="DoubleCheckedLocking"/>
-    <module name="EmptyStatement"/>
-    <module name="EqualsHashCode"/>
-    <module name="HiddenField">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="IllegalInstantiation"/>
-    <module name="InnerAssignment"/>
-    <module name="MagicNumber"/>
-    <module name="MissingSwitchDefault"/>
-    <module name="RedundantThrows">
-      <property name="logLoadErrors" value="true"/>
-      <property name="suppressLoadErrors" value="true"/>
-    </module>
-    <module name="SimplifyBooleanExpression"/>
-    <module name="SimplifyBooleanReturn"/>
-    <module name="DesignForExtension">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="FinalClass"/>
-    <module name="HideUtilityClassConstructor"/>
-    <module name="InterfaceIsType"/>
-    <module name="VisibilityModifier"/>
-    <module name="ArrayTypeStyle"/>
-    <module name="FinalParameters"/>
-    <module name="GenericIllegalRegexp">
-      <property name="severity" value="ignore"/>
-      <property name="format" value="\s+$"/>
-      <property name="message" value="Line has trailing spaces."/>
-    </module>
-    <module name="TodoComment">
-      <property name="severity" value="ignore"/>
-    </module>
-    <module name="UpperEll"/>
-    <module name="CyclomaticComplexity">
-      <metadata name="net.sf.eclipsecs.core.comment" value="Cyclomatic Complexity"/>
-    </module>
-  </module>
-  <module name="JavadocPackage">
-    <property name="severity" value="ignore"/>
-  </module>
-  <module name="NewlineAtEndOfFile"/>
-  <module name="Translation"/>
-  <module name="SuppressionCommentFilter">
-    <metadata name="net.sf.eclipsecs.core.comment" value="ignore checkstyle"/>
-  </module>
-</module>



From ChrisBurrell at crosswire.org  Wed Apr 14 14:28:21 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 14:28:21 -0700
Subject: [Tynstep-svn] r108 - in trunk: . step-tools step-tools/.settings
	step-tools/src step-tools/src/main step-tools/src/main/java
	step-tools/src/main/resources
Message-ID: <E1O2A8D-0003TD-55@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 14:28:21 -0700 (Wed, 14 Apr 2010)
New Revision: 108

Added:
   trunk/step-tools/
   trunk/step-tools/.classpath
   trunk/step-tools/.project
   trunk/step-tools/.settings/
   trunk/step-tools/.settings/org.eclipse.jdt.core.prefs
   trunk/step-tools/.settings/org.maven.ide.eclipse.prefs
   trunk/step-tools/pom.xml
   trunk/step-tools/src/
   trunk/step-tools/src/main/
   trunk/step-tools/src/main/java/
   trunk/step-tools/src/main/java/BibleFileGenerator.java
   trunk/step-tools/src/main/java/BibleStatsAnalyser.java
   trunk/step-tools/src/main/java/ScriptureReference.java
   trunk/step-tools/src/main/resources/
   trunk/step-tools/src/main/resources/log4j.properties
Log:
committing tools

Added: trunk/step-tools/.classpath
===================================================================
--- trunk/step-tools/.classpath	                        (rev 0)
+++ trunk/step-tools/.classpath	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/step-tools/.project
===================================================================
--- trunk/step-tools/.project	                        (rev 0)
+++ trunk/step-tools/.project	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-tools</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: trunk/step-tools/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-tools/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-tools/.settings/org.eclipse.jdt.core.prefs	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,6 @@
+#Mon Apr 05 13:57:25 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5

Added: trunk/step-tools/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-tools/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-tools/.settings/org.maven.ide.eclipse.prefs	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,9 @@
+#Mon Apr 05 13:57:25 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-tools/pom.xml
===================================================================
--- trunk/step-tools/pom.xml	                        (rev 0)
+++ trunk/step-tools/pom.xml	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-tools</artifactId>
+	<packaging>jar</packaging>
+	<name>step-tools</name>
+
+	<dependencies>
+				<dependency>
+			<groupId>org.crosswire</groupId>
+			<artifactId>jsword</artifactId>
+		</dependency>
+				<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+		</dependency>
+	</dependencies>
+</project>

Added: trunk/step-tools/src/main/java/BibleFileGenerator.java
===================================================================
--- trunk/step-tools/src/main/java/BibleFileGenerator.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/BibleFileGenerator.java	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,253 @@
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.crosswire.common.util.Language;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookCategory;
+import org.crosswire.jsword.book.BookData;
+import org.crosswire.jsword.book.BookException;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.book.OSISUtil;
+import org.crosswire.jsword.book.install.InstallException;
+import org.crosswire.jsword.book.install.sword.HttpSwordInstaller;
+import org.crosswire.jsword.passage.Key;
+import org.crosswire.jsword.passage.PassageKeyFactory;
+
+public class BibleFileGenerator extends Thread {
+	private final static String proxyHostProperty = "step.proxy.host";
+	private final static String proxyPortProperty = "step.proxy.port";
+	private String initials;
+
+
+	public BibleFileGenerator() {
+		this.initials = "";
+	}
+
+	
+	public BibleFileGenerator(String initials) {
+		this.initials = initials;
+	}
+
+	private String writeBible(String version) throws Exception {
+
+		StringBuffer sb = new StringBuffer(String.format("@%s%s", version, System.getProperty("line.separator")));
+		// check information has been passed in
+		if (StringUtils.isEmpty(version)) {
+			throw new Exception("Version was not provided");
+		}
+
+		Book currentBook = Books.installed().getBook(version);
+
+		Key global = currentBook.getGlobalKeyList();
+		int numVersesInVersion = global.getCardinality();
+
+		String formatBook = "";
+		String formatChapter = "";
+		String formatVerse = "";
+		
+		String previousBook = "none";
+		String previousChapter = "none";
+		String previousVerse = "none" ;
+		
+		String key = null;
+		boolean newBook = true;
+		for (int ii = 0; ii < numVersesInVersion; ii++) {
+			try {
+				key = global.get(ii).getOsisID();
+				
+				//assume just one verse?
+				String[] split = key.split("\\.");
+				formatBook = split[0];
+				formatChapter = split[1];
+				formatVerse = split[2];
+				
+				if(!formatBook.equals(previousBook)) {
+					previousBook = formatBook;
+					
+					sb.append('@');
+					sb.append(formatBook);
+					sb.append(System.getProperty("line.separator"));
+					
+					//if new book, also reset chapter
+					previousChapter = formatChapter;
+					sb.append("@Chapter ");
+					sb.append(formatChapter);
+					sb.append(System.getProperty("line.separator"));
+				} else if(!formatChapter.equals(previousChapter)) {
+					previousChapter = formatChapter;
+					sb.append("@Chapter ");
+					sb.append(formatChapter);
+					sb.append(System.getProperty("line.separator"));				
+				}
+				
+				BookData data = new BookData(currentBook, global.get(ii));
+				
+				sb.append(formatVerse);
+				sb.append(". ");
+				sb.append(OSISUtil.getCanonicalText(data.getOsis()).replace('\n', ' ').replace('\r', '\n'));
+				sb.append(System.getProperty("line.separator"));
+								
+				//ScriptureReference sr = new ScriptureReference(key);
+				
+//				if (!sr.getBook().equals(formatBook)) {
+//					sb.append(String.format("@%s%s", sr.getBook().toUpperCase(), System.getProperty("line.separator")));
+//					formatBook = sr.getBook();
+//					newBook = true;
+//				}
+//
+//				if (sr.getChapter() != null && !sr.getChapter().equals(formatChapter)) {
+//					sb.append(String.format("@Chapter %s%s", sr.getChapter(), System.getProperty("line.separator")));
+//					newBook = false;
+//					formatChapter = sr.getChapter();
+//				} else if(newBook) {
+//					sb.append(String.format("@Chapter 1%s", System.getProperty("line.separator")));
+//					newBook = false;
+//				}
+
+			} catch (BookException e) {
+				System.out
+						.println(initials + ":: A book exception has occurred whilte looking up the passage: " + key);
+				e.printStackTrace();
+				throw new Exception(e);
+			} catch (Exception ex) {
+				System.err.println(initials + ":: Could not parse key: " + key);
+				ex.printStackTrace();
+			} finally {
+				;
+			}
+		}
+		return sb.toString();
+
+	}
+
+	//TODO: here and elsewhere, ensure that the downloaders 
+	//are not hardcoded - there are at least two more sites to get 
+	//bible versions from.
+	private static HttpSwordInstaller getNewCustomInstaller() {
+		System.out.println("Creating new installer for JSword");
+		HttpSwordInstaller resourceInstaller = new HttpSwordInstaller();
+
+		System.out.println("Currently hardcoded installer host to:"
+				+ "www.crosswire.org");
+		System.out.println("Currently hardcoded property names for step");
+		String host = "www.crosswire.org";
+		String proxyHost = System.getProperty(proxyHostProperty);
+		String proxyPort = System.getProperty(proxyPortProperty);
+		System.out.println(String.format("Setting to (%1$s via %2$s:%3$s)",
+				"www.crosswire.org", proxyHost, proxyPort));
+
+		resourceInstaller.setHost(host);
+		if (proxyHost != null) {
+			resourceInstaller.setProxyHost(proxyHost);
+		}
+		if (proxyPort != null) {
+			resourceInstaller.setProxyPort(Integer.parseInt(proxyPort));
+		}
+
+		System.out.println("Setting package and catalog directories");
+		resourceInstaller
+				.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+		resourceInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+		return resourceInstaller;
+	}
+	
+	private void downloadAllBibles() throws InstallException {
+		HttpSwordInstaller installer = getNewCustomInstaller();
+
+		//TODO: ensure the comment in the comment of the function is in a warning
+		//somewhere...
+		installer.reloadBookList();
+		
+		List availableBooks = installer.getBooks();
+		
+		for(int ii = 0; ii < availableBooks.size(); ii++) {
+			Book b = (Book) availableBooks.get(ii);
+			Language en = new Language("en");
+			
+			//check book is a biblical text...
+			if(b.getBookCategory() == BookCategory.BIBLE &&
+					b.getBookMetaData().getLanguage().equals(en)
+					) {
+				String versionKey = b.getInitials();
+				
+				System.out.println("Downloading " + ((Book) availableBooks.get(ii)).getName() + "...");
+				if(Books.installed().getBook(versionKey) == null) {
+					installer.install(installer.getBook(versionKey));
+				}
+			}
+		}		
+	}
+
+	
+	@Override
+	public void run() {
+		try {
+			System.out.println("Starting thread for " + initials);
+			FileUtils.writeStringToFile(new File("output/" + initials + ".txt"), writeBible(initials));
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
+
+	
+	
+	//TODO: could profile the application to figure out if we can speed things
+	//up with memory settings etc, more/less threads...
+	//could also investigate rewriting it so that disk IO happens
+	//during processing to allow other threads to execute.
+	//would be interesting to profile to find out where bottlenecks are.
+	public static void main(String args[]) throws Exception {
+		BibleFileGenerator bfg = new BibleFileGenerator();
+		int numThreads = 2;
+			
+		
+		
+		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
+		ThreadPoolExecutor tpe = new ThreadPoolExecutor(numThreads, numThreads,1, TimeUnit.MINUTES, queue);
+		
+		//add processor thing, to kick off all the downloads, and then
+		//TODO:
+		//wait for the downloads to complete for each version, before it continues on to the 
+		//bible processing...
+		//bfg.downloadAllBibles();
+		List<Book> books = Books.installed().getBooks();
+		
+		//of the installed books
+		for(Book b : books) {
+			System.out.println(String.format("%s %s", b.getInitials(), b.getName()));
+		}
+		
+		System.out.println("of available:\n\n");
+
+		
+		
+		List<Book> availableBooks = getNewCustomInstaller().getBooks();
+		for(Book b : availableBooks) {
+			System.out.println(String.format("%s %s", b.getInitials(), b.getName()));
+		}
+
+		new BibleFileGenerator("ESV").start();
+		
+//		for(int ii = 0; ii < books.size(); ii++) {
+//			if(books.get(ii).getBookCategory().equals(BookCategory.BIBLE)) {
+//				
+//				String initials = books.get(ii).getInitials();
+//				Thread r = new BibleFileGenerator(initials);
+//				tpe.execute(r);
+//				System.out.println("Size of runnable queue: " + queue.size());
+//			}
+//		}
+	}
+}

Added: trunk/step-tools/src/main/java/BibleStatsAnalyser.java
===================================================================
--- trunk/step-tools/src/main/java/BibleStatsAnalyser.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/BibleStatsAnalyser.java	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,34 @@
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Hashtable;
+
+import org.apache.commons.io.FileUtils;
+
+
+public class BibleStatsAnalyser {
+	public BibleStatsAnalyser() {
+		// TODO Auto-generated constructor stub
+	}
+	
+	
+	public static void main(String args[]) throws IOException {
+		String esv = FileUtils.readFileToString(new File("output/ESV.txt"));
+		String[] allWords = esv.split("[ ,\\.!;\\']");
+		Hashtable<String, Integer> count = new Hashtable<String, Integer>();
+		
+		for(String s : allWords) {
+			if(count.containsKey(s)) {
+				Integer i = count.get(s);
+				i++;
+				count.put(s, i);
+			} else {
+				count.put(s, 1);
+			}
+		}
+		
+		for(String s : allWords) {
+			System.out.println(String.format("%s,%d", s, count.get(s).intValue()));
+		}
+	}
+}

Added: trunk/step-tools/src/main/java/ScriptureReference.java
===================================================================
--- trunk/step-tools/src/main/java/ScriptureReference.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/ScriptureReference.java	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,60 @@
+public class ScriptureReference {
+	private String book = null;
+	private String chapter = null;
+	private String verse = null;
+
+	/**
+	 * Given a key looking like 1 Samuel 2:13 or Philemon 1 it stores it
+	 * internally as book,chapter,verse
+	 * 
+	 * @param key
+	 */
+	public ScriptureReference(String key) {
+		int lastColon = key.lastIndexOf(":");
+		int lastSpace = key.lastIndexOf(' ');
+
+		// there are two types of formats:
+		// 1 Samuel 2:13 and Philemon 1 where 1 in this case is the verse
+
+		try {
+			// ie, reference not like Philemon 1
+			if (lastColon != -1) {
+				verse = key.substring(lastColon + 1);
+				chapter = key.substring(lastSpace + 1, lastColon);
+			} else {
+				verse = key.substring(lastSpace + 1);
+				chapter = null;
+			}
+
+			book = key.substring(0, lastSpace);
+		} catch (Exception ex) {
+			System.err.println("Key: " + key);
+			System.err.println("lastColon: " + lastColon);
+			System.err.println("lastSpace: " + lastSpace);
+			System.err.println("verse: " + verse);
+			System.err.println("chapter: " + chapter);
+			
+		}
+	}
+
+	/**
+	 * @return the book
+	 */
+	public String getBook() {
+		return book;
+	}
+
+	/**
+	 * @return the chapter
+	 */
+	public String getChapter() {
+		return chapter;
+	}
+
+	/**
+	 * @return the verse
+	 */
+	public String getVerse() {
+		return verse;
+	}
+}

Added: trunk/step-tools/src/main/resources/log4j.properties
===================================================================
--- trunk/step-tools/src/main/resources/log4j.properties	                        (rev 0)
+++ trunk/step-tools/src/main/resources/log4j.properties	2010-04-14 21:28:21 UTC (rev 108)
@@ -0,0 +1,9 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=WARN, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n



From ChrisBurrell at crosswire.org  Wed Apr 14 14:30:21 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 14:30:21 -0700
Subject: [Tynstep-svn] r110 - in trunk: . step-server step-server/.settings
	step-server/src step-server/src/main
	step-server/src/main/java step-server/src/main/java/com
	step-server/src/main/java/com/tyndalehouse
	step-server/src/main/java/com/tyndalehouse/step
	step-server/src/main/java/com/tyndalehouse/step/server
	step-server/src/main/resources
Message-ID: <E1O2AA9-0003VO-6I@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 14:30:21 -0700 (Wed, 14 Apr 2010)
New Revision: 110

Added:
   trunk/step-server/
   trunk/step-server/.classpath
   trunk/step-server/.project
   trunk/step-server/.settings/
   trunk/step-server/.settings/org.eclipse.jdt.core.prefs
   trunk/step-server/.settings/org.maven.ide.eclipse.prefs
   trunk/step-server/pom.xml
   trunk/step-server/src/
   trunk/step-server/src/main/
   trunk/step-server/src/main/java/
   trunk/step-server/src/main/java/com/
   trunk/step-server/src/main/java/com/tyndalehouse/
   trunk/step-server/src/main/java/com/tyndalehouse/step/
   trunk/step-server/src/main/java/com/tyndalehouse/step/server/
   trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
   trunk/step-server/src/main/resources/
   trunk/step-server/src/main/resources/jetty.xml
   trunk/step-server/src/main/resources/webapps/
Log:
committing step server

Added: trunk/step-server/.classpath
===================================================================
--- trunk/step-server/.classpath	                        (rev 0)
+++ trunk/step-server/.classpath	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/step-server/.project
===================================================================
--- trunk/step-server/.project	                        (rev 0)
+++ trunk/step-server/.project	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,17 @@
+<projectDescription>
+  <name>step-dataloader</name>
+  <comment/>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.maven.ide.eclipse.maven2Builder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.maven.ide.eclipse.maven2Nature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Added: trunk/step-server/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-server/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-server/.settings/org.eclipse.jdt.core.prefs	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,6 @@
+#Mon Apr 05 13:29:00 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5

Added: trunk/step-server/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-server/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-server/.settings/org.maven.ide.eclipse.prefs	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,9 @@
+#Mon Apr 05 13:28:59 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-server/pom.xml
===================================================================
--- trunk/step-server/pom.xml	                        (rev 0)
+++ trunk/step-server/pom.xml	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,24 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-server</artifactId>
+	<packaging>jar</packaging>
+	<name>step-server</name>
+
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.mortbay.jetty</groupId>
+			<artifactId>jetty</artifactId>
+			<version>6.1.22</version>
+		</dependency>
+	</dependencies>
+</project>

Added: trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
===================================================================
--- trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java	                        (rev 0)
+++ trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,161 @@
+package com.tyndalehouse.step.server;
+
+import java.awt.Desktop;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.DefaultHandler;
+import org.mortbay.jetty.handler.HandlerList;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.xml.XmlConfiguration;
+
+
+public class StepServer {
+	
+	StepServer() {
+
+	}
+
+	
+	
+	// creates and configures the Jetty server
+	private Server start() throws Exception {
+		Server jetty = new Server();
+		String[] configFiles = { "jetty.xml" };
+				
+		for (String configFile : configFiles) {
+			
+			XmlConfiguration configuration = new XmlConfiguration(new File(
+					configFile).toURI().toURL());
+			configuration.configure(jetty);
+		}
+
+		// configure our web application
+		WebAppContext appContext = new WebAppContext();
+		appContext.setContextPath("/");
+		File rd = new File("./");
+
+		//This needs to be parameterised
+		String pathToWar = System.getProperty("path.to.war");
+		if(pathToWar == null) {
+			pathToWar = "../../public_html";
+		}
+		
+		File warPath = new File(rd, pathToWar);
+		appContext.setWar(warPath.getAbsolutePath());
+
+		HandlerList handlers = new HandlerList();
+		handlers
+				.setHandlers(new Handler[] { appContext, new DefaultHandler() });
+
+		jetty.setHandler(handlers);
+
+		jetty.start();
+		return jetty;
+	}
+
+	//creates a simple table in the database
+//	private void doDatabase() {
+//		String sql = "CREATE table APP.ADDRESS (    ID          INTEGER NOT NULL                PRIMARY KEY GENERATED ALWAYS AS IDENTITY                (START WITH 1, INCREMENT BY 1),    LASTNAME    VARCHAR(30),    FIRSTNAME   VARCHAR(30),    MIDDLENAME  VARCHAR(30),    PHONE       VARCHAR(20),    EMAIL       VARCHAR(30),    ADDRESS1    VARCHAR(30),    ADDRESS2    VARCHAR(30),    CITY        VARCHAR(30),    STATE       VARCHAR(30),    POSTALCODE  VARCHAR(20),    COUNTRY     VARCHAR(30) )";
+//		
+//		try {
+//			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+//		} catch (ClassNotFoundException e) {
+//			// TODO Auto-generated catch block
+//			e.printStackTrace();
+//		}
+//
+//		Connection dbConnection = null;
+//		String strUrl = "jdbc:derby:DefaultAddressBook;create=true";
+//
+//		try {
+//		    dbConnection = DriverManager.getConnection(strUrl);
+//		} catch (SQLException ex) {
+//		    ex.printStackTrace();
+//		}
+//
+//	    Statement statement = null;
+//	    try {
+//	        statement = dbConnection.createStatement();
+//	        statement.execute(sql);
+//	    } catch (SQLException ex) {
+//	        ex.printStackTrace();
+//	    }
+//	    
+//	    System.out.println("Terminated OK");
+//	    System.exit(0);
+//	}
+
+//	private void checkJSwordInstalled() {
+//        // An installer knows how to install books
+//        Installer installer = getNewCustomInstaller();
+//
+//        
+//        // Get a list of all the available books (ESV, KJV, etc.)
+//        //List availableBooks = installer.getBooks();
+//
+//        // get some available books. In this case, just one book.
+//        List availableBooks = installer.getBooks(new MyBookFilter("ESV")); //$NON-NLS-1$
+//        Book book = null;
+//        if (availableBooks.size() != 0) {
+//        	book = (Book) availableBooks.get(0);
+//        }
+//
+//        //check the book above is available
+//        if (book != null)
+//        {
+//        	//if we have it, log it as an INFO message
+//        	//TODO: if we have it, log as INFO message
+//            System.out.println("Book " + book.getInitials() + " is available"); //$NON-NLS-1$ //$NON-NLS-2$
+//
+//            try
+//            {
+//            	//now check whether it needs installing...
+//                // Now install it. Note this is a background task.
+//            	//TODO: add logging here too.
+//            	if (Books.installed().getBook("ESV") == null) {
+//            		installer.install(book);
+//            		System.out.println("Installing ESV book");
+//            	}
+//            }
+//            catch (InstallException e)
+//            {
+//                e.printStackTrace();
+//            }
+//        }		
+//	}
+//
+//	private HttpSwordInstaller  getNewCustomInstaller() {
+//		HttpSwordInstaller chrisInstaller = new HttpSwordInstaller();
+//        chrisInstaller.setHost("www.crosswire.org");
+//        //chrisInstaller.setProxyHost("xxx.xxx.xxx.xxx");
+//        //chrisInstaller.setProxyPort(new Integer(xxxx));
+//        chrisInstaller.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+//        chrisInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+//        return chrisInstaller;
+//	}
+//
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		try {
+			//doDatabase();
+			StepServer ms = new StepServer();			
+			/* Server s = */ ms.start();			
+			try {
+				   Desktop.getDesktop().browse(new URI("http://localhost:8080"));
+				} 
+				catch (MalformedURLException e1) {
+				   e1.printStackTrace();
+				} 
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+}

Added: trunk/step-server/src/main/resources/jetty.xml
===================================================================
--- trunk/step-server/src/main/resources/jetty.xml	                        (rev 0)
+++ trunk/step-server/src/main/resources/jetty.xml	2010-04-14 21:30:21 UTC (rev 110)
@@ -0,0 +1,204 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!--                                                                 -->
+<!-- Documentation of this file format can be found at:              -->
+<!-- http://docs.codehaus.org/display/JETTY/jetty.xml                -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.mortbay.jetty.Server">
+
+    <!-- =========================================================== -->
+    <!-- Server Thread Pool                                          -->
+    <!-- =========================================================== -->
+    <Set name="ThreadPool">
+      <!-- Default bounded blocking threadpool 
+      -->
+      <New class="org.mortbay.thread.BoundedThreadPool">
+        <Set name="minThreads">10</Set>
+        <Set name="maxThreads">250</Set>
+      </New>
+
+      <!-- Optional Java 5 bounded threadpool with job queue 
+      <New class="org.mortbay.thread.concurrent.ThreadPool">
+        <Set name="corePoolSize">250</Set>
+        <Set name="maximumPoolSize">250</Set>
+      </New>
+      -->
+    </Set>
+
+
+
+    <!-- =========================================================== -->
+    <!-- Set connectors                                              -->
+    <!-- =========================================================== -->
+    <!-- One of each type!                                           -->
+    <!-- =========================================================== -->
+
+    <!-- Use this connector for many frequently idle connections
+         and for threadless continuations.
+    -->    
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.mortbay.jetty.nio.SelectChannelConnector">
+            <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
+            <Set name="maxIdleTime">30000</Set>
+            <Set name="Acceptors">1</Set>
+            <Set name="statsOn">false</Set>
+            <Set name="confidentialPort">8443</Set>
+	    <Set name="lowResourcesConnections">1000</Set>
+	    <Set name="lowResourcesMaxIdleTime">500</Set>
+          </New>
+      </Arg>
+    </Call>
+
+    <!-- Use this connector if NIO is not available.
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.mortbay.jetty.bio.SocketConnector">
+            <Set name="port">8081</Set>
+            <Set name="maxIdleTime">50000</Set>
+            <Set name="lowResourceMaxIdleTime">1500</Set>
+          </New>
+      </Arg>
+    </Call>
+    -->
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    <!-- To add a HTTPS SSL listener                                     -->
+    <!-- see jetty-ssl.xml to add an ssl connector. use                  -->
+    <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml             -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    
+    <!-- =========================================================== -->
+    <!-- Set up global session ID manager                            -->
+    <!-- =========================================================== -->
+    <!--
+    <Set name="sessionIdManager">
+      <New class="org.mortbay.jetty.servlet.HashSessionIdManager">
+        <Set name="workerName">node1</Set>
+      </New>
+    </Set>
+    -->
+
+    <!-- =========================================================== -->
+    <!-- Set handler Collection Structure                            --> 
+    <!-- =========================================================== -->
+    <Set name="handler">
+      <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
+        <Set name="handlers">
+         <Array type="org.mortbay.jetty.Handler">
+           <Item>
+             <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
+           </Item>
+           <Item>
+             <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
+           </Item>
+           <Item>
+             <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
+           </Item>
+         </Array>
+        </Set>
+      </New>
+    </Set>
+    
+    <!-- =========================================================== -->
+    <!-- Configure the context deployer                              -->
+    <!-- A context deployer will deploy contexts described in        -->
+    <!-- configuration files discovered in a directory.              -->
+    <!-- The configuration directory can be scanned for hot          -->
+    <!-- deployments at the configured scanInterval.                 -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy contexts configured   -->
+    <!-- in the $JETTY_HOME/contexts directory                       -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Call name="addLifeCycle">
+      <Arg>
+        <New class="org.mortbay.jetty.deployer.ContextDeployer">
+          <Set name="contexts"><Ref id="Contexts"/></Set>
+          <Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
+          <Set name="scanInterval">1</Set>
+        </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- Configure the webapp deployer.                              -->
+    <!-- A webapp  deployer will deploy standard webapps discovered  -->
+    <!-- in a directory at startup, without the need for additional  -->
+    <!-- configuration files.    It does not support hot deploy or   -->
+    <!-- non standard contexts (see ContextDeployer above).          -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy webapps from the      -->
+    <!-- $JETTY_HOME/webapps directory                               -->
+    <!--                                                             -->
+    <!-- Normally only one type of deployer need be used.            -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Call name="addLifeCycle">
+      <Arg>
+        <New class="org.mortbay.jetty.deployer.WebAppDeployer">
+          <Set name="contexts"><Ref id="Contexts"/></Set>
+          <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
+	  <Set name="parentLoaderPriority">false</Set>
+	  <Set name="extract">true</Set>
+	  <Set name="allowDuplicates">false</Set>
+          <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+        </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- Configure Authentication Realms                             -->
+    <!-- Realms may be configured for the entire server here, or     -->
+    <!-- they can be configured for a specific web app in a context  -->
+    <!-- configuration (see $(jetty.home)/contexts/test.xml for an   -->
+    <!-- example).                                                   -->
+    <!-- =========================================================== -->
+    <Set name="UserRealms">
+      <Array type="org.mortbay.jetty.security.UserRealm">
+        <!--
+        <Item>
+          <New class="org.mortbay.jetty.security.HashUserRealm">
+            <Set name="name">Test Realm</Set>
+            <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
+          </New>
+        </Item>
+	-->
+      </Array>
+    </Set>
+
+    <!-- =========================================================== -->
+    <!-- Configure Request Log                                       -->
+    <!-- Request logs  may be configured for the entire server here, -->
+    <!-- or they can be configured for a specific web app in a       -->
+    <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
+    <!-- for an example).                                            -->
+    <!-- =========================================================== -->
+    <Ref id="RequestLog">
+      <Set name="requestLog">
+        <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
+          <Arg><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Arg>
+          <Set name="retainDays">90</Set>
+          <Set name="append">true</Set>
+          <Set name="extended">false</Set>
+          <Set name="LogTimeZone">GMT</Set>
+        </New>
+      </Set>
+    </Ref>
+
+    <!-- =========================================================== -->
+    <!-- extra options                                               -->
+    <!-- =========================================================== -->
+    <Set name="stopAtShutdown">true</Set>
+    <!-- ensure/prevent Server: header being sent to browsers        -->
+    <Set name="sendServerVersion">true</Set>
+
+
+
+</Configure>



From ChrisBurrell at crosswire.org  Wed Apr 14 14:59:43 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 14:59:43 -0700
Subject: [Tynstep-svn] r111 - trunk
Message-ID: <E1O2AcZ-0003oE-J9@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 14:59:43 -0700 (Wed, 14 Apr 2010)
New Revision: 111

Added:
   trunk/step-web-app/
Log:
committing root of project



From ChrisBurrell at crosswire.org  Wed Apr 14 15:00:35 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:00:35 -0700
Subject: [Tynstep-svn] r112 - trunk/step-web-app
Message-ID: <E1O2AdP-0003os-Pe@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:00:35 -0700 (Wed, 14 Apr 2010)
New Revision: 112

Added:
   trunk/step-web-app/.checkstyle
   trunk/step-web-app/.classpath
   trunk/step-web-app/.fbprefs
   trunk/step-web-app/.project
   trunk/step-web-app/.settings/
   trunk/step-web-app/pom.xml
   trunk/step-web-app/step.launch
Log:
committing root files

Added: trunk/step-web-app/.checkstyle
===================================================================
--- trunk/step-web-app/.checkstyle	                        (rev 0)
+++ trunk/step-web-app/.checkstyle	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true">
+  <local-check-config name="step-checks" location="/step-parent/step-checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="step-checks" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="NonSrcDirs" enabled="true"/>
+</fileset-config>

Added: trunk/step-web-app/.classpath
===================================================================
--- trunk/step-web-app/.classpath	                        (rev 0)
+++ trunk/step-web-app/.classpath	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="war/WEB-INF/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="war/WEB-INF/classes" path="src/main/resources"/>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="war/WEB-INF/classes"/>
+</classpath>

Added: trunk/step-web-app/.fbprefs
===================================================================
--- trunk/step-web-app/.fbprefs	                        (rev 0)
+++ trunk/step-web-app/.fbprefs	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,161 @@
+#FindBugs User Preferences
+#Mon Apr 05 12:08:05 BST 2010
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBCPMethodReturnCheck=BCPMethodReturnCheck|false
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorBuildInterproceduralCallGraph=BuildInterproceduralCallGraph|false
+detectorBuildObligationPolicyDatabase=BuildObligationPolicyDatabase|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
+detectorCalledMethods=CalledMethods|true
+detectorCheckCalls=CheckCalls|false
+detectorCheckExpectedWarnings=CheckExpectedWarnings|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqStringTest=EqStringTest|false
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFieldItemSummary=FieldItemSummary|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast=FindBadCast|false
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadEqualsImplementation=FindBadEqualsImplementation|false
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindBugsSummaryStats=FindBugsSummaryStats|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindFloatMath=FindFloatMath|false
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLockedFields=LockedFields|false
+detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMethods=Methods|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNoise=Noise|false
+detectorNoiseNullDeref=NoiseNullDeref|false
+detectorNoteAnnotationRetention=NoteAnnotationRetention|true
+detectorNoteCheckReturnValue=NoteCheckReturnValue|true
+detectorNoteCheckReturnValueAnnotations=NoteCheckReturnValueAnnotations|true
+detectorNoteDirectlyRelevantTypeQualifiers=NoteDirectlyRelevantTypeQualifiers|true
+detectorNoteJCIPAnnotation=NoteJCIPAnnotation|true
+detectorNoteNonNullAnnotations=NoteNonNullAnnotations|true
+detectorNoteNonnullReturnValues=NoteNonnullReturnValues|true
+detectorNoteSuppressedWarnings=NoteSuppressedWarnings|true
+detectorNoteUnconditionalParamDerefs=NoteUnconditionalParamDerefs|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorReflectiveClasses=ReflectiveClasses|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorResolveAllReferences=ResolveAllReferences|false
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizationOnSharedBuiltinConstant=SynchronizationOnSharedBuiltinConstant|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorTestASM=TestASM|false
+detectorTestDataflowAnalysis=TestDataflowAnalysis|false
+detectorTestingGround=TestingGround|false
+detectorTrainFieldStoreTypes=TrainFieldStoreTypes|true
+detectorTrainNonNullAnnotations=TrainNonNullAnnotations|true
+detectorTrainUnconditionalDerefParams=TrainUnconditionalDerefParams|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+run_at_full_build=true

Added: trunk/step-web-app/.project
===================================================================
--- trunk/step-web-app/.project	                        (rev 0)
+++ trunk/step-web-app/.project	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-web-app</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
+		<nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature>
+	</natures>
+</projectDescription>

Added: trunk/step-web-app/pom.xml
===================================================================
--- trunk/step-web-app/pom.xml	                        (rev 0)
+++ trunk/step-web-app/pom.xml	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,253 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-web-app</artifactId>
+	<packaging>war</packaging>
+	<name>step-web-app</name>
+
+	<properties>
+		<!--
+			this is because the maven gwt plugin apparently has a hard-coded path
+			to /war
+		-->
+		<war.directory>${basedir}/war</war.directory>
+		<output.directory>${basedir}/war/WEB-INF/classes</output.directory>
+	</properties>
+
+	<dependencies>
+		<dependency>
+			<groupId>org.crosswire</groupId>
+			<artifactId>jsword</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.gwt</groupId>
+			<artifactId>gwt-servlet</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.google.gwt</groupId>
+			<artifactId>gwt-user</artifactId>
+			<scope>provided</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>com.googlecode.gwt.inject</groupId>
+			<artifactId>gin</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>com.google.inject</groupId>
+			<artifactId>guice</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.inject.extensions
+			</groupId>
+			<artifactId>guice-servlet</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>net.customware.gwt.dispatch
+			</groupId>
+			<artifactId>gwt-dispatch</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>net.customware.gwt.presenter
+			</groupId>
+			<artifactId>gwt-presenter</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.google.code.gwt-log</groupId>
+			<artifactId>gwt-log</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>com.extjs</groupId>
+			<artifactId>gxt</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-logging</groupId>
+			<artifactId>commons-logging</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-dbcp</groupId>
+			<artifactId>commons-dbcp</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.jmock</groupId>
+			<artifactId>jmock</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.jmock</groupId>
+			<artifactId>jmock-junit4</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derbyclient</artifactId>
+			<scope>runtime</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+			<scope>runtime</scope>
+		</dependency>
+	</dependencies>
+
+	<build>
+		<outputDirectory>${output.directory}</outputDirectory>
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>gwt-maven-plugin</artifactId>
+				<version>1.2</version>
+				<configuration>
+					<gwtVersion>${gwt.version}</gwtVersion>
+					<runTarget>step/Step.html</runTarget>
+					<inplace>true</inplace>
+					<warSourceDirectory>${war.directory}</warSourceDirectory>
+					<webappDirectory>${war.directory}</webappDirectory>
+					<extraJvmArgs>-Dconnection.string="${db.connection.string}" -Ddb.driver=${db.driver}</extraJvmArgs>
+				</configuration>
+				<executions>
+					<execution>
+						<goals>
+							<goal>compile</goal>
+						</goals>
+					</execution>
+				</executions>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-war-plugin</artifactId>
+				<configuration>
+					<warSourceDirectory>${war.directory}</warSourceDirectory>
+					<webappDirectory>${war.directory}</webappDirectory>
+					<webXml>${war.directory}/WEB-INF/web.xml</webXml>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.mortbay.jetty</groupId>
+				<artifactId>maven-jetty-plugin</artifactId>
+				<version>6.1.22</version>
+				<configuration>
+					<webAppSourceDirectory>${war.directory}</webAppSourceDirectory>
+					<webApp>${project.build.directory}/${project.build.finalName}.war</webApp>
+					<contextPath>/</contextPath>
+					<systemProperties>
+						<systemProperty>
+							<name>connection.string</name>
+							<value>jdbc:derby:${db.directory}</value>
+						</systemProperty>
+						<systemProperty>
+							<name>db.driver</name>
+							<value>org.apache.derby.jdbc.EmbeddedDriver</value>
+						</systemProperty>
+					</systemProperties>
+					<scanIntervalSeconds>5</scanIntervalSeconds>
+					<connectors>
+						<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+							<port>8080</port>
+							<maxIdleTime>60000</maxIdleTime>
+						</connector>
+					</connectors>
+				</configuration>
+			</plugin>
+			<plugin>
+				<artifactId>maven-clean-plugin</artifactId>
+				<version>2.4</version>
+				<configuration>
+					<filesets>
+						<fileset>
+							<directory>war</directory>
+							<excludes>
+								<exclude>WEB-INF/web.xml</exclude>
+							</excludes>
+						</fileset>
+					</filesets>
+				</configuration>
+			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.5</version>
+				<configuration>
+					<systemPropertyVariables>
+						<db.driver>${db.driver}</db.driver>
+						<connection.string>${db.connection.string}</connection.string>
+						<step.proxy.host>10.154.1.44</step.proxy.host>
+						<step.proxy.port>8080</step.proxy.port>
+					</systemPropertyVariables>
+					<includes>
+						<include>**/*Test.java</include>
+					</includes>
+				</configuration>
+			</plugin>
+<plugin>
+					<groupId>org.codehaus.mojo</groupId>
+					<artifactId>cobertura-maven-plugin</artifactId>
+					<version>2.3</version>
+					<configuration>
+						<check>
+							<branchRate>85</branchRate>
+							<lineRate>85</lineRate>
+							<haltOnFailure>false</haltOnFailure>
+							<totalBranchRate>60</totalBranchRate>
+							<totalLineRate>60</totalLineRate>
+							<packageLineRate>60</packageLineRate>
+							<packageBranchRate>60</packageBranchRate>
+<!-- 							<regexes>
+								<regex>
+									<pattern>com.example.reallyimportant.*</pattern>
+									<branchRate>90</branchRate>
+									<lineRate>80</lineRate>
+								</regex>
+								<regex>
+									<pattern>com.example.boringcode.*</pattern>
+									<branchRate>40</branchRate>
+									<lineRate>30</lineRate>
+								</regex>
+							</regexes>
+ -->
+						</check>
+					</configuration>
+					<executions>
+						<execution>
+							<goals>
+								<goal>clean</goal>
+								<goal>check</goal>
+							</goals>
+						</execution>
+					</executions>
+				</plugin>
+	
+
+		</plugins>
+	</build>	
+</project>

Added: trunk/step-web-app/step.launch
===================================================================
--- trunk/step-web-app/step.launch	                        (rev 0)
+++ trunk/step-web-app/step.launch	2010-04-14 22:00:35 UTC (rev 112)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.google.gdt.eclipse.suite.webapp">
+<booleanAttribute key="com.google.gdt.eclipse.core.AUTO_PORT_SELECTION" value="true"/>
+<stringAttribute key="com.google.gdt.eclipse.suiteMainTypeProcessor.PREVIOUSLY_SET_MAIN_TYPE_NAME" value="com.google.gwt.dev.DevMode"/>
+<booleanAttribute key="com.google.gdt.eclipse.suiteWarArgumentProcessor.IS_WAR_FROM_PROJECT_PROPERTIES" value="true"/>
+<stringAttribute key="com.google.gwt.eclipse.core.URL" value="step/Step.html"/>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
+<listEntry value="/step-web-app"/>
+</listAttribute>
+<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
+<listEntry value="4"/>
+</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="com.google.gwt.eclipse.core.moduleClasspathProvider"/>
+<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="com.google.gwt.dev.DevMode"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-remoteUI &quot;${gwt_remote_ui_server_port}:${unique_id}&quot; -startupUrl step/Step.html -war D:\TyndaleStep\step-web-app\war -logLevel INFO -port auto com.tyndalehouse.step.web.step"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="step-web-app"/>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Xmx512m -Dgwt.nowarn.legacy.tools &quot;-Dconnection.string=jdbc:derby:${system_property:user.home}/TyndaleStep/StepDB&quot; -Ddb.driver=org.apache.derby.jdbc.ClientDriver"/>
+</launchConfiguration>



From ChrisBurrell at crosswire.org  Wed Apr 14 15:05:03 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:05:03 -0700
Subject: [Tynstep-svn] r113 - trunk/step-web-app
Message-ID: <E1O2Ahj-0003sA-Eb@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:05:03 -0700 (Wed, 14 Apr 2010)
New Revision: 113

Added:
   trunk/step-web-app/src/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:05:24 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:05:24 -0700
Subject: [Tynstep-svn] r114 - trunk/step-web-app/src
Message-ID: <E1O2Ai4-0003sb-A3@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:05:24 -0700 (Wed, 14 Apr 2010)
New Revision: 114

Added:
   trunk/step-web-app/src/main/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:05:34 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:05:34 -0700
Subject: [Tynstep-svn] r115 - trunk/step-web-app/src/main
Message-ID: <E1O2AiE-0003sv-EX@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:05:34 -0700 (Wed, 14 Apr 2010)
New Revision: 115

Added:
   trunk/step-web-app/src/main/java/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:05:44 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:05:44 -0700
Subject: [Tynstep-svn] r116 - trunk/step-web-app/src/main/java
Message-ID: <E1O2AiO-0003tJ-V1@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:05:44 -0700 (Wed, 14 Apr 2010)
New Revision: 116

Added:
   trunk/step-web-app/src/main/java/com/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:05:55 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:05:55 -0700
Subject: [Tynstep-svn] r117 - trunk/step-web-app/src/main/java/com
Message-ID: <E1O2AiZ-0003tb-9j@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:05:55 -0700 (Wed, 14 Apr 2010)
New Revision: 117

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:06:05 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:06:05 -0700
Subject: [Tynstep-svn] r118 -
	trunk/step-web-app/src/main/java/com/tyndalehouse
Message-ID: <E1O2Aij-0003tu-Ly@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:06:05 -0700 (Wed, 14 Apr 2010)
New Revision: 118

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Wed Apr 14 15:06:18 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 15:06:18 -0700
Subject: [Tynstep-svn] r119 -
	trunk/step-web-app/src/main/java/com/tyndalehouse/step
Message-ID: <E1O2Aiw-0003uD-Jd@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:06:18 -0700 (Wed, 14 Apr 2010)
New Revision: 119

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/
Log:
committing root code directory



From ChrisBurrell at crosswire.org  Sat Apr 17 07:32:41 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Sat, 17 Apr 2010 07:32:41 -0700
Subject: [Tynstep-svn] r123 -
	trunk/step-dataloader/src/main/resources/data/timeline
Message-ID: <E1O394b-00036o-EP@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-17 07:32:41 -0700 (Sat, 17 Apr 2010)
New Revision: 123

Added:
   trunk/step-dataloader/src/main/resources/data/timeline/license.txt
Log:
committing extra message

Added: trunk/step-dataloader/src/main/resources/data/timeline/license.txt
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/license.txt	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/license.txt	2010-04-17 14:32:41 UTC (rev 123)
@@ -0,0 +1 @@
+The data contained in this folder is Copyright Tyndale House, Cambridge
\ No newline at end of file



From ChrisBurrell at crosswire.org  Sun Apr 18 14:41:35 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Sun, 18 Apr 2010 14:41:35 -0700
Subject: [Tynstep-svn] r124 - in trunk: . step-dataloader
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders
	step-dataloader/src/main/resources step-web-app
Message-ID: <E1O3cFD-0002x0-C2@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-18 14:41:35 -0700 (Sun, 18 Apr 2010)
New Revision: 124

Added:
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/JSwordModuleInstaller.java
   trunk/step-dataloader/src/main/resources/log4j.properties
Modified:
   trunk/pom.xml
   trunk/step-dataloader/pom.xml
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
   trunk/step-web-app/pom.xml
Log:
committing dataloader changes

Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml	2010-04-17 14:32:41 UTC (rev 123)
+++ trunk/pom.xml	2010-04-18 21:41:35 UTC (rev 124)
@@ -4,7 +4,7 @@
 	<groupId>com.tyndalehouse</groupId>
 	<artifactId>step-parent</artifactId>
 	<packaging>pom</packaging>
-	<version>1.0-SNAPSHOT</version>
+	<version>0.1-SNAPSHOT</version>
 	<name>step-parent</name>
 	
 	<properties>
@@ -28,8 +28,8 @@
 
 
 	<modules>
+		<module>step-dataloader</module>
 		<module>step-web-app</module>
-		<module>step-dataloader</module>
 		<module>step-server</module>
 		<module>step-tools</module>
 	</modules>
@@ -41,6 +41,11 @@
 				<artifactId>jsword</artifactId>
 				<version>1.6.1-SNAPSHOT</version>
 			</dependency>
+			<dependency>
+				<groupId>org.crosswire</groupId>
+				<artifactId>jsword-common</artifactId>
+				<version>1.6.1-SNAPSHOT</version>
+			</dependency>
 
 			<dependency>
 				<groupId>com.google.gwt</groupId>
@@ -193,6 +198,11 @@
 					<artifactId>maven-eclipse-plugin</artifactId>
 					<version>2.5</version>
 				</plugin>
+				<plugin>
+					<groupId>org.codehaus.mojo</groupId>
+					<artifactId>exec-maven-plugin</artifactId>
+					<version>1.1.1</version>
+				</plugin>
 			</plugins>
 		</pluginManagement>
 	</build>

Modified: trunk/step-dataloader/pom.xml
===================================================================
--- trunk/step-dataloader/pom.xml	2010-04-17 14:32:41 UTC (rev 123)
+++ trunk/step-dataloader/pom.xml	2010-04-18 21:41:35 UTC (rev 124)
@@ -3,7 +3,7 @@
 	<parent>
 		<groupId>com.tyndalehouse</groupId>
 		<artifactId>step-parent</artifactId>
-		<version>1.0-SNAPSHOT</version>
+		<version>0.1-SNAPSHOT</version>
 		<relativePath>..</relativePath>
 	</parent>
 
@@ -18,6 +18,14 @@
 			<plugin>
 				<groupId>org.codehaus.mojo</groupId>
 				<artifactId>exec-maven-plugin</artifactId>
+				<executions>
+					<execution>
+						<phase>install</phase>
+						<goals>
+							<goal>java</goal>
+						</goals>
+					</execution>
+				</executions>
 				<configuration>
 					<mainClass>com.tyndalehouse.step.dataloader.Dataloader</mainClass>
 					<systemProperties>
@@ -25,6 +33,14 @@
 							<key>db.location</key>
 							<value>${db.directory}</value>
 						</systemProperty>
+						<systemProperty>
+							<key>step.http.proxy</key>
+							<value>${step.http.proxy}</value>
+						</systemProperty>
+						<systemProperty>
+							<key>step.http.port</key>
+							<value>${step.http.port}</value>
+						</systemProperty>
 					</systemProperties>
 					<classpathScope>runtime</classpathScope>
 				</configuration>
@@ -33,18 +49,19 @@
 	</build>
 
 	<dependencies>
-
 		<dependency>
 			<groupId>org.crosswire</groupId>
 			<artifactId>jsword</artifactId>
 		</dependency>
-
 		<dependency>
+			<groupId>org.crosswire</groupId>
+			<artifactId>jsword-common</artifactId>
+		</dependency>
+		<dependency>
 			<groupId>commons-dbutils</groupId>
 			<artifactId>commons-dbutils</artifactId>
 			<version>1.3</version>
 		</dependency>
-
 		<dependency>
 			<groupId>commons-io</groupId>
 			<artifactId>commons-io</artifactId>
@@ -56,6 +73,11 @@
 		</dependency>
 
 		<dependency>
+			<groupId>commons-logging</groupId>
+			<artifactId>commons-logging</artifactId>
+		</dependency>
+
+		<dependency>
 			<groupId>net.sf.opencsv</groupId>
 			<artifactId>opencsv</artifactId>
 		</dependency>

Modified: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	2010-04-17 14:32:41 UTC (rev 123)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	2010-04-18 21:41:35 UTC (rev 124)
@@ -1,41 +1,55 @@
 package com.tyndalehouse.step.dataloader;
 
+import org.apache.commons.logging.Log;
+import org.apache.log4j.Logger;
+
 import java.io.IOException;
 import java.sql.SQLException;
 import java.util.Calendar;
 
 import org.apache.commons.dbutils.DbUtils;
+import org.crosswire.jsword.book.install.InstallException;
 import org.crosswire.jsword.passage.NoSuchKeyException;
 
 import com.tyndalehouse.step.dataloader.common.DateParsingException;
+import com.tyndalehouse.step.dataloader.loaders.JSwordModuleInstaller;
 import com.tyndalehouse.step.dataloader.loaders.SchemaLoader;
 import com.tyndalehouse.step.dataloader.loaders.TimelineLoader;
 
 public class Dataloader {
-	public static void main(String args[]) throws SQLException, ClassNotFoundException, IOException, DateParsingException, NoSuchKeyException {
-		if(System.getProperty("driver") != null) {
-			DbUtils.loadDriver(System.getProperty("org.apache.derby.jdbc.ClientDriver"));
-		} else {
-			DbUtils.loadDriver("org.apache.derby.jdbc.EmbeddedDriver");	
+	private static Logger log = Logger.getLogger(Dataloader.class);
+
+	public static void main(String args[]) throws SQLException, ClassNotFoundException, IOException, DateParsingException, NoSuchKeyException, InstallException {
+		try {
+			if(System.getProperty("driver") != null) {
+				DbUtils.loadDriver(System.getProperty("org.apache.derby.jdbc.ClientDriver"));
+			} else {
+				DbUtils.loadDriver("org.apache.derby.jdbc.EmbeddedDriver");
+			}
+
+			SchemaLoader sl = new SchemaLoader();
+			TimelineLoader tl = new TimelineLoader();
+			JSwordModuleInstaller jmi = new JSwordModuleInstaller();
+			jmi.installDefaultModules();
+
+//			long startTime= Calendar.getInstance().getTimeInMillis();
+//
+//			sl.recreateAll();
+//			long currentTime = Calendar.getInstance().getTimeInMillis();
+//			System.out.println("Took " + (currentTime-startTime ) + "ms to create schema");
+//			startTime = currentTime;
+//			tl.loadData();
+//
+//			currentTime = Calendar.getInstance().getTimeInMillis();
+//			System.out.println("Took " + (currentTime-startTime ) + "ms to load data");
+//
+//			startTime = currentTime;
+//			currentTime = Calendar.getInstance().getTimeInMillis();
+//			System.out.println("Took " + (currentTime-startTime ) + "ms to install bibles");
+//
+		} catch(Exception ex) {
+			log.error(ex);
 		}
-	
-		SchemaLoader sl = new SchemaLoader();
-		TimelineLoader tl = new TimelineLoader();
-	
-		
-		
-		
-		long startTime= Calendar.getInstance().getTimeInMillis();
-
-		sl.recreateAll();
-		long currentTime = Calendar.getInstance().getTimeInMillis();
-		System.out.println("Took " + (currentTime-startTime ) + "ms to create schema");
-		startTime = currentTime;
-		tl.loadData();
-		
-		currentTime = Calendar.getInstance().getTimeInMillis();
-		System.out.println("Took " + (currentTime-startTime ) + "ms to load data");
-			
 	}
 
 }

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/JSwordModuleInstaller.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/JSwordModuleInstaller.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/JSwordModuleInstaller.java	2010-04-18 21:41:35 UTC (rev 124)
@@ -0,0 +1,93 @@
+package com.tyndalehouse.step.dataloader.loaders;
+
+import org.apache.commons.logging.Log;
+import org.apache.log4j.Logger;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.book.install.InstallException;
+import org.crosswire.jsword.book.install.sword.HttpSwordInstaller;
+
+public class JSwordModuleInstaller {
+	private final static String proxyHostProperty = "step.http.proxy";
+	private final static String proxyPortProperty = "step.http.port";
+
+	private Logger log = Logger.getLogger(getClass());
+
+	/** default set of bibles */
+	String[] defaultModules = new String[] { "ESV", "KJV", "ASV",
+			"StrongsHebrew", "StrongsGreek", "LXX", "BYZ" };
+
+	/**
+	 * a default set of modules need to be installed since unit tests rely on
+	 * them to be present TODO: the whole project should probably be cleaned
+	 * up/rewritten in a neater fashion
+	 * 
+	 * @throws InstallException
+	 *             failed to install bible modules
+	 */
+	public void installDefaultModules() {
+		try {
+			log.info("about to create installer");
+			HttpSwordInstaller installer = getInstaller();
+			log.info("got installer, going to reload books");
+			installer.reloadBookList();
+			log.info("reloaded books");
+			for (String s : defaultModules) {
+				installBible(installer, s);
+			}
+		} catch (Exception ex) {
+			log.error(ex.getMessage(), ex);
+		}
+	}
+
+	private void installBible(HttpSwordInstaller installer, String initials)
+			throws InstallException {
+		log.info("installing " + initials);
+
+		Book b = null;
+		try {
+			Books books = Books.installed();
+			if (books != null) {
+				b = books.getBook(initials);
+
+				if (b == null) {
+					installer.install(installer.getBook(initials));
+				} else {
+					log.warn("Skipping " + initials);
+				}
+			}
+		} catch (Exception ex) {
+			log
+					.info(
+							"An exception occurred while reading the list of installed books (first time?)",
+							ex);
+		}
+	}
+
+	private HttpSwordInstaller getInstaller() {
+		log.warn("Creating new installer for JSword");
+		HttpSwordInstaller resourceInstaller = new HttpSwordInstaller();
+		System.out.println("Currently hardcoded installer host to:"
+				+ "www.crosswire.org");
+		System.out.println("Currently hardcoded property names for step");
+		String host = "www.crosswire.org";
+		String proxyHost = System.getProperty(proxyHostProperty);
+		String proxyPort = System.getProperty(proxyPortProperty);
+		System.out.println(String.format("Setting to (%1$s via %2$s:%3$s)",
+				"www.crosswire.org", proxyHost, proxyPort));
+
+		resourceInstaller.setHost(host);
+		if (proxyHost != null && proxyHost.length() != 0) {
+			resourceInstaller.setProxyHost(proxyHost);
+		}
+		if (proxyPort != null && proxyHost.length() != 0) {
+			resourceInstaller.setProxyPort(Integer.parseInt(proxyPort));
+		}
+
+		System.out.println("Setting package and catalog directories");
+		resourceInstaller
+				.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+		resourceInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+		return resourceInstaller;
+	}
+}

Added: trunk/step-dataloader/src/main/resources/log4j.properties
===================================================================
--- trunk/step-dataloader/src/main/resources/log4j.properties	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/log4j.properties	2010-04-18 21:41:35 UTC (rev 124)
@@ -0,0 +1,8 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, A1
+
+# A1 is set to be a ConsoleAppender.
+# A1 uses PatternLayout.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

Modified: trunk/step-web-app/pom.xml
===================================================================
--- trunk/step-web-app/pom.xml	2010-04-17 14:32:41 UTC (rev 123)
+++ trunk/step-web-app/pom.xml	2010-04-18 21:41:35 UTC (rev 124)
@@ -3,7 +3,7 @@
 	<parent>
 		<groupId>com.tyndalehouse</groupId>
 		<artifactId>step-parent</artifactId>
-		<version>1.0-SNAPSHOT</version>
+		<version>0.1-SNAPSHOT</version>
 		<relativePath>..</relativePath>
 	</parent>
 



From ChrisBurrell at crosswire.org  Sun Apr 18 15:42:42 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Sun, 18 Apr 2010 15:42:42 -0700
Subject: [Tynstep-svn] r125 - trunk/step-server
Message-ID: <E1O3dCM-0004R1-Vx@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-18 15:42:42 -0700 (Sun, 18 Apr 2010)
New Revision: 125

Modified:
   trunk/step-server/pom.xml
Log:
changed version to 0.1-SNAPSHOT

Modified: trunk/step-server/pom.xml
===================================================================
--- trunk/step-server/pom.xml	2010-04-18 21:41:35 UTC (rev 124)
+++ trunk/step-server/pom.xml	2010-04-18 22:42:42 UTC (rev 125)
@@ -3,7 +3,7 @@
 	<parent>
 		<groupId>com.tyndalehouse</groupId>
 		<artifactId>step-parent</artifactId>
-		<version>1.0-SNAPSHOT</version>
+		<version>0.1-SNAPSHOT</version>
 		<relativePath>..</relativePath>
 	</parent>
 



From ChrisBurrell at crosswire.org  Sun Apr 18 15:45:53 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Sun, 18 Apr 2010 15:45:53 -0700
Subject: [Tynstep-svn] r126 - trunk/step-tools
Message-ID: <E1O3dFR-0004Yy-Ak@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-18 15:45:53 -0700 (Sun, 18 Apr 2010)
New Revision: 126

Modified:
   trunk/step-tools/pom.xml
Log:
changing version of pom.xml to 0.1-SNAPSHOT

Modified: trunk/step-tools/pom.xml
===================================================================
--- trunk/step-tools/pom.xml	2010-04-18 22:42:42 UTC (rev 125)
+++ trunk/step-tools/pom.xml	2010-04-18 22:45:53 UTC (rev 126)
@@ -3,7 +3,7 @@
 	<parent>
 		<groupId>com.tyndalehouse</groupId>
 		<artifactId>step-parent</artifactId>
-		<version>1.0-SNAPSHOT</version>
+		<version>0.1-SNAPSHOT</version>
 		<relativePath>..</relativePath>
 	</parent>
 



From ChrisBurrell at crosswire.org  Tue Apr 20 13:05:11 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Tue, 20 Apr 2010 13:05:11 -0700
Subject: [Tynstep-svn] r127 - in trunk:
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader
	step-web-app
Message-ID: <E1O4Jh1-00087R-A1@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-20 13:05:11 -0700 (Tue, 20 Apr 2010)
New Revision: 127

Modified:
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
   trunk/step-web-app/pom.xml
Log:
changed to enable database build to work

Modified: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java	2010-04-18 22:45:53 UTC (rev 126)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java	2010-04-20 20:05:11 UTC (rev 127)
@@ -3,13 +3,14 @@
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.SQLException;
+import java.sql.Statement;
 
 public class ClientDbProvider {
 	//TODO: shove this in a properties file
 	private static String clientConnection = "jdbc:derby:";
 	private static Connection connection = null;
 	
-	public static Connection getConnection(String dbPath) throws SQLException {
+	public synchronized static Connection getConnection(String dbPath) throws SQLException {
 		if(connection == null) {
 			String connectionString = clientConnection + dbPath + ";create=true";
 			System.out.println("Using connection string: " + connectionString);
@@ -28,4 +29,14 @@
 	public static Connection getConnection() {
 		return connection;
 	}
+
+	public static void tearDown() {
+		try {
+			finaliseConnection(getConnection());
+			DriverManager.getConnection("jdbc:derby:;shutdown=true");
+		} catch (SQLException e) {
+			//shutdown exception
+		}
+		
+	}
 }

Modified: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	2010-04-18 22:45:53 UTC (rev 126)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	2010-04-20 20:05:11 UTC (rev 127)
@@ -1,13 +1,11 @@
 package com.tyndalehouse.step.dataloader;
 
-import org.apache.commons.logging.Log;
-import org.apache.log4j.Logger;
-
 import java.io.IOException;
 import java.sql.SQLException;
 import java.util.Calendar;
 
 import org.apache.commons.dbutils.DbUtils;
+import org.apache.log4j.Logger;
 import org.crosswire.jsword.book.install.InstallException;
 import org.crosswire.jsword.passage.NoSuchKeyException;
 
@@ -19,6 +17,11 @@
 public class Dataloader {
 	private static Logger log = Logger.getLogger(Dataloader.class);
 
+	private static void cleanup() {
+		ClientDbProvider.tearDown();
+		
+	}
+	
 	public static void main(String args[]) throws SQLException, ClassNotFoundException, IOException, DateParsingException, NoSuchKeyException, InstallException {
 		try {
 			if(System.getProperty("driver") != null) {
@@ -32,24 +35,21 @@
 			JSwordModuleInstaller jmi = new JSwordModuleInstaller();
 			jmi.installDefaultModules();
 
-//			long startTime= Calendar.getInstance().getTimeInMillis();
-//
-//			sl.recreateAll();
-//			long currentTime = Calendar.getInstance().getTimeInMillis();
-//			System.out.println("Took " + (currentTime-startTime ) + "ms to create schema");
-//			startTime = currentTime;
-//			tl.loadData();
-//
-//			currentTime = Calendar.getInstance().getTimeInMillis();
-//			System.out.println("Took " + (currentTime-startTime ) + "ms to load data");
-//
-//			startTime = currentTime;
-//			currentTime = Calendar.getInstance().getTimeInMillis();
-//			System.out.println("Took " + (currentTime-startTime ) + "ms to install bibles");
-//
+			long startTime= Calendar.getInstance().getTimeInMillis();
+
+			sl.recreateAll();
+			long currentTime = Calendar.getInstance().getTimeInMillis();
+			System.out.println("Took " + (currentTime-startTime ) + "ms to create schema");
+			startTime = currentTime;
+			tl.loadData();
+
+			currentTime = Calendar.getInstance().getTimeInMillis();
+			System.out.println("Took " + (currentTime-startTime ) + "ms to load data");
+
+			cleanup();
+			
 		} catch(Exception ex) {
 			log.error(ex);
 		}
 	}
-
 }

Modified: trunk/step-web-app/pom.xml
===================================================================
--- trunk/step-web-app/pom.xml	2010-04-18 22:45:53 UTC (rev 126)
+++ trunk/step-web-app/pom.xml	2010-04-20 20:05:11 UTC (rev 127)
@@ -188,6 +188,7 @@
 							<directory>war</directory>
 							<excludes>
 								<exclude>WEB-INF/web.xml</exclude>
+								<exclude>.svn</exclude>
 							</excludes>
 						</fileset>
 					</filesets>
@@ -201,15 +202,15 @@
 					<systemPropertyVariables>
 						<db.driver>${db.driver}</db.driver>
 						<connection.string>${db.connection.string}</connection.string>
-						<step.proxy.host>10.154.1.44</step.proxy.host>
-						<step.proxy.port>8080</step.proxy.port>
+						<step.proxy.host>${step.http.proxy}</step.proxy.host>
+						<step.proxy.port>{step.http.port}</step.proxy.port>
 					</systemPropertyVariables>
 					<includes>
 						<include>**/*Test.java</include>
 					</includes>
 				</configuration>
 			</plugin>
-<plugin>
+			<plugin>
 					<groupId>org.codehaus.mojo</groupId>
 					<artifactId>cobertura-maven-plugin</artifactId>
 					<version>2.3</version>



From ChrisBurrell at crosswire.org  Tue Apr 20 15:05:26 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Tue, 20 Apr 2010 15:05:26 -0700
Subject: [Tynstep-svn] r128 - trunk/step-web-app
Message-ID: <E1O4LZO-0001QX-QV@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-20 15:05:26 -0700 (Tue, 20 Apr 2010)
New Revision: 128

Modified:
   trunk/step-web-app/pom.xml
Log:
preventing deletion of .svn folder

Modified: trunk/step-web-app/pom.xml
===================================================================
--- trunk/step-web-app/pom.xml	2010-04-20 20:05:11 UTC (rev 127)
+++ trunk/step-web-app/pom.xml	2010-04-20 22:05:26 UTC (rev 128)
@@ -188,7 +188,8 @@
 							<directory>war</directory>
 							<excludes>
 								<exclude>WEB-INF/web.xml</exclude>
-								<exclude>.svn</exclude>
+								<exclude>**/.svn</exclude>
+        						<exclude>**/.svn/**</exclude>
 							</excludes>
 						</fileset>
 					</filesets>



From ChrisBurrell at crosswire.org  Tue Apr 20 15:23:49 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Tue, 20 Apr 2010 15:23:49 -0700
Subject: [Tynstep-svn] r129 -
	trunk/step-server/src/main/java/com/tyndalehouse/step/server
Message-ID: <E1O4LrB-0001gZ-6y@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-20 15:23:49 -0700 (Tue, 20 Apr 2010)
New Revision: 129

Modified:
   trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
Log:
committing comments to 1.6 code to allow build to work

Modified: trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
===================================================================
--- trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java	2010-04-20 22:05:26 UTC (rev 128)
+++ trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java	2010-04-20 22:23:49 UTC (rev 129)
@@ -1,161 +1,162 @@
-package com.tyndalehouse.step.server;
-
-import java.awt.Desktop;
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URI;
-
-import org.mortbay.jetty.Handler;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.handler.DefaultHandler;
-import org.mortbay.jetty.handler.HandlerList;
-import org.mortbay.jetty.webapp.WebAppContext;
-import org.mortbay.xml.XmlConfiguration;
-
-
-public class StepServer {
-	
-	StepServer() {
-
-	}
-
-	
-	
-	// creates and configures the Jetty server
-	private Server start() throws Exception {
-		Server jetty = new Server();
-		String[] configFiles = { "jetty.xml" };
-				
-		for (String configFile : configFiles) {
-			
-			XmlConfiguration configuration = new XmlConfiguration(new File(
-					configFile).toURI().toURL());
-			configuration.configure(jetty);
-		}
-
-		// configure our web application
-		WebAppContext appContext = new WebAppContext();
-		appContext.setContextPath("/");
-		File rd = new File("./");
-
-		//This needs to be parameterised
-		String pathToWar = System.getProperty("path.to.war");
-		if(pathToWar == null) {
-			pathToWar = "../../public_html";
-		}
-		
-		File warPath = new File(rd, pathToWar);
-		appContext.setWar(warPath.getAbsolutePath());
-
-		HandlerList handlers = new HandlerList();
-		handlers
-				.setHandlers(new Handler[] { appContext, new DefaultHandler() });
-
-		jetty.setHandler(handlers);
-
-		jetty.start();
-		return jetty;
-	}
-
-	//creates a simple table in the database
-//	private void doDatabase() {
-//		String sql = "CREATE table APP.ADDRESS (    ID          INTEGER NOT NULL                PRIMARY KEY GENERATED ALWAYS AS IDENTITY                (START WITH 1, INCREMENT BY 1),    LASTNAME    VARCHAR(30),    FIRSTNAME   VARCHAR(30),    MIDDLENAME  VARCHAR(30),    PHONE       VARCHAR(20),    EMAIL       VARCHAR(30),    ADDRESS1    VARCHAR(30),    ADDRESS2    VARCHAR(30),    CITY        VARCHAR(30),    STATE       VARCHAR(30),    POSTALCODE  VARCHAR(20),    COUNTRY     VARCHAR(30) )";
-//		
-//		try {
-//			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
-//		} catch (ClassNotFoundException e) {
-//			// TODO Auto-generated catch block
-//			e.printStackTrace();
-//		}
-//
-//		Connection dbConnection = null;
-//		String strUrl = "jdbc:derby:DefaultAddressBook;create=true";
-//
-//		try {
-//		    dbConnection = DriverManager.getConnection(strUrl);
-//		} catch (SQLException ex) {
-//		    ex.printStackTrace();
-//		}
-//
-//	    Statement statement = null;
-//	    try {
-//	        statement = dbConnection.createStatement();
-//	        statement.execute(sql);
-//	    } catch (SQLException ex) {
-//	        ex.printStackTrace();
-//	    }
-//	    
-//	    System.out.println("Terminated OK");
-//	    System.exit(0);
-//	}
-
-//	private void checkJSwordInstalled() {
-//        // An installer knows how to install books
-//        Installer installer = getNewCustomInstaller();
-//
-//        
-//        // Get a list of all the available books (ESV, KJV, etc.)
-//        //List availableBooks = installer.getBooks();
-//
-//        // get some available books. In this case, just one book.
-//        List availableBooks = installer.getBooks(new MyBookFilter("ESV")); //$NON-NLS-1$
-//        Book book = null;
-//        if (availableBooks.size() != 0) {
-//        	book = (Book) availableBooks.get(0);
-//        }
-//
-//        //check the book above is available
-//        if (book != null)
-//        {
-//        	//if we have it, log it as an INFO message
-//        	//TODO: if we have it, log as INFO message
-//            System.out.println("Book " + book.getInitials() + " is available"); //$NON-NLS-1$ //$NON-NLS-2$
-//
-//            try
-//            {
-//            	//now check whether it needs installing...
-//                // Now install it. Note this is a background task.
-//            	//TODO: add logging here too.
-//            	if (Books.installed().getBook("ESV") == null) {
-//            		installer.install(book);
-//            		System.out.println("Installing ESV book");
-//            	}
-//            }
-//            catch (InstallException e)
-//            {
-//                e.printStackTrace();
-//            }
-//        }		
-//	}
-//
-//	private HttpSwordInstaller  getNewCustomInstaller() {
-//		HttpSwordInstaller chrisInstaller = new HttpSwordInstaller();
-//        chrisInstaller.setHost("www.crosswire.org");
-//        //chrisInstaller.setProxyHost("xxx.xxx.xxx.xxx");
-//        //chrisInstaller.setProxyPort(new Integer(xxxx));
-//        chrisInstaller.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
-//        chrisInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
-//        return chrisInstaller;
-//	}
-//
-	/**
-	 * @param args
-	 */
-	public static void main(String[] args) {
-		try {
-			//doDatabase();
-			StepServer ms = new StepServer();			
-			/* Server s = */ ms.start();			
-			try {
-				   Desktop.getDesktop().browse(new URI("http://localhost:8080"));
-				} 
-				catch (MalformedURLException e1) {
-				   e1.printStackTrace();
-				} 
-
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
-	}
-
-}
+package com.tyndalehouse.step.server;
+
+//import java.awt.Desktop;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+
+import org.mortbay.jetty.Handler;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.handler.DefaultHandler;
+import org.mortbay.jetty.handler.HandlerList;
+import org.mortbay.jetty.webapp.WebAppContext;
+import org.mortbay.xml.XmlConfiguration;
+
+
+public class StepServer {
+	
+	StepServer() {
+
+	}
+
+	
+	
+	// creates and configures the Jetty server
+	private Server start() throws Exception {
+		Server jetty = new Server();
+		String[] configFiles = { "jetty.xml" };
+				
+		for (String configFile : configFiles) {
+			
+			XmlConfiguration configuration = new XmlConfiguration(new File(
+					configFile).toURI().toURL());
+			configuration.configure(jetty);
+		}
+
+		// configure our web application
+		WebAppContext appContext = new WebAppContext();
+		appContext.setContextPath("/");
+		File rd = new File("./");
+
+		//This needs to be parameterised
+		String pathToWar = System.getProperty("path.to.war");
+		if(pathToWar == null) {
+			pathToWar = "../../public_html";
+		}
+		
+		File warPath = new File(rd, pathToWar);
+		appContext.setWar(warPath.getAbsolutePath());
+
+		HandlerList handlers = new HandlerList();
+		handlers
+				.setHandlers(new Handler[] { appContext, new DefaultHandler() });
+
+		jetty.setHandler(handlers);
+
+		jetty.start();
+		return jetty;
+	}
+
+	//creates a simple table in the database
+//	private void doDatabase() {
+//		String sql = "CREATE table APP.ADDRESS (    ID          INTEGER NOT NULL                PRIMARY KEY GENERATED ALWAYS AS IDENTITY                (START WITH 1, INCREMENT BY 1),    LASTNAME    VARCHAR(30),    FIRSTNAME   VARCHAR(30),    MIDDLENAME  VARCHAR(30),    PHONE       VARCHAR(20),    EMAIL       VARCHAR(30),    ADDRESS1    VARCHAR(30),    ADDRESS2    VARCHAR(30),    CITY        VARCHAR(30),    STATE       VARCHAR(30),    POSTALCODE  VARCHAR(20),    COUNTRY     VARCHAR(30) )";
+//		
+//		try {
+//			Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
+//		} catch (ClassNotFoundException e) {
+//			// TODO Auto-generated catch block
+//			e.printStackTrace();
+//		}
+//
+//		Connection dbConnection = null;
+//		String strUrl = "jdbc:derby:DefaultAddressBook;create=true";
+//
+//		try {
+//		    dbConnection = DriverManager.getConnection(strUrl);
+//		} catch (SQLException ex) {
+//		    ex.printStackTrace();
+//		}
+//
+//	    Statement statement = null;
+//	    try {
+//	        statement = dbConnection.createStatement();
+//	        statement.execute(sql);
+//	    } catch (SQLException ex) {
+//	        ex.printStackTrace();
+//	    }
+//	    
+//	    System.out.println("Terminated OK");
+//	    System.exit(0);
+//	}
+
+//	private void checkJSwordInstalled() {
+//        // An installer knows how to install books
+//        Installer installer = getNewCustomInstaller();
+//
+//        
+//        // Get a list of all the available books (ESV, KJV, etc.)
+//        //List availableBooks = installer.getBooks();
+//
+//        // get some available books. In this case, just one book.
+//        List availableBooks = installer.getBooks(new MyBookFilter("ESV")); //$NON-NLS-1$
+//        Book book = null;
+//        if (availableBooks.size() != 0) {
+//        	book = (Book) availableBooks.get(0);
+//        }
+//
+//        //check the book above is available
+//        if (book != null)
+//        {
+//        	//if we have it, log it as an INFO message
+//        	//TODO: if we have it, log as INFO message
+//            System.out.println("Book " + book.getInitials() + " is available"); //$NON-NLS-1$ //$NON-NLS-2$
+//
+//            try
+//            {
+//            	//now check whether it needs installing...
+//                // Now install it. Note this is a background task.
+//            	//TODO: add logging here too.
+//            	if (Books.installed().getBook("ESV") == null) {
+//            		installer.install(book);
+//            		System.out.println("Installing ESV book");
+//            	}
+//            }
+//            catch (InstallException e)
+//            {
+//                e.printStackTrace();
+//            }
+//        }		
+//	}
+//
+//	private HttpSwordInstaller  getNewCustomInstaller() {
+//		HttpSwordInstaller chrisInstaller = new HttpSwordInstaller();
+//        chrisInstaller.setHost("www.crosswire.org");
+//        //chrisInstaller.setProxyHost("xxx.xxx.xxx.xxx");
+//        //chrisInstaller.setProxyPort(new Integer(xxxx));
+//        chrisInstaller.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+//        chrisInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+//        return chrisInstaller;
+//	}
+//
+	/**
+	 * @param args
+	 */
+	public static void main(String[] args) {
+		try {
+			//doDatabase();
+			StepServer ms = new StepServer();			
+			/* Server s = */ ms.start();			
+			//start the browser - code not available in 1.5 - may need to do something different?
+			//			try {
+//                                   Desktop.getDesktop().browse(new URI("http://localhost:8080"));
+//				} 
+//				catch (MalformedURLException e1) {
+//				   e1.printStackTrace();
+//				} 
+
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+}



From ChrisBurrell at crosswire.org  Wed Apr 14 13:22:59 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 20:22:59 -0000
Subject: [Tynstep-svn] r106 - in trunk: . step-data-loader/src
	step-data-loader/src/main step-data-loader/src/main/java
	step-server step-server/.settings step-server/src
	step-server/src/main step-server/src/main/java
	step-server/src/main/java/com/tyndalehouse/step/server
	step-server/src/main/resources step-tools
	step-tools/.settings step-tools/src step-tools/src/main
	step-tools/src/main/java
Message-ID: <E1O296x-0002bL-AJ@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 13:22:59 -0700 (Wed, 14 Apr 2010)
New Revision: 106

Added:
   trunk/.project
   trunk/pom.xml
   trunk/step-checks.xml
   trunk/step-data-loader/
   trunk/step-data-loader/src/main/
   trunk/step-data-loader/src/main/java/
   trunk/step-data-loader/src/main/java/com/
   trunk/step-server/.settings/
   trunk/step-server/.settings/org.eclipse.jdt.core.prefs
   trunk/step-server/.settings/org.maven.ide.eclipse.prefs
   trunk/step-server/pom.xml
   trunk/step-server/src/main/
   trunk/step-server/src/main/java/
   trunk/step-server/src/main/java/com/
   trunk/step-server/src/main/resources/
   trunk/step-server/src/main/resources/jetty.xml
   trunk/step-server/src/main/resources/webapps/
   trunk/step-tools/
   trunk/step-tools/.classpath
   trunk/step-tools/.project
   trunk/step-tools/.settings/
   trunk/step-tools/.settings/org.eclipse.jdt.core.prefs
   trunk/step-tools/.settings/org.maven.ide.eclipse.prefs
   trunk/step-tools/pom.xml
   trunk/step-tools/src/
   trunk/step-tools/src/main/
   trunk/step-tools/src/main/java/
   trunk/step-tools/src/main/java/BibleFileGenerator.java
   trunk/step-tools/src/main/java/BibleStatsAnalyser.java
   trunk/step-tools/src/main/java/ScriptureReference.java
   trunk/step-tools/src/main/resources/
   trunk/step-web-app-old/
Removed:
   trunk/STEPTestGWT/
   trunk/StepDataLoader/
   trunk/StepTools/
   trunk/step-data-loader/src/com/
   trunk/step-server/bin/
   trunk/step-server/etc/
   trunk/step-server/lib/
   trunk/step-server/src/com/
   trunk/step-server/webapps/
   trunk/step-web-app/
Modified:
   trunk/step-server/.classpath
   trunk/step-server/.project
   trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
Log:
mavenizing step 1 - 3 of 4 project, but moving previous project to old directory

Added: trunk/.project
===================================================================
--- trunk/.project	                        (rev 0)
+++ trunk/.project	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-parent</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: trunk/pom.xml
===================================================================
--- trunk/pom.xml	                        (rev 0)
+++ trunk/pom.xml	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,199 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-parent</artifactId>
+	<packaging>pom</packaging>
+	<version>1.0-SNAPSHOT</version>
+	<name>step-parent</name>
+	
+	<properties>
+		<project.build.sourceEncoding>iso-8859-1
+		</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>iso-8859-1
+		</project.reporting.outputEncoding>
+		<java.version>1.5</java.version>
+		<gwt.version>2.0.3</gwt.version>
+		<db.directory>${user.home}/TyndaleStep/StepDB</db.directory>
+		<derby.version>10.5.3.0_1</derby.version>
+		<db.driver>org.apache.derby.jdbc.EmbeddedDriver</db.driver>
+		<db.connection.string>jdbc:derby:${db.directory}</db.connection.string>
+	</properties>
+
+	<scm>
+		<connection>scm:svn:https://crosswire.org/svn/tynstep/trunk</connection>
+		<developerConnection>scm:svn:https://crosswire.org/svn/tynstep/trunk</developerConnection>
+		<url>https://crosswire.org/svn/tynstep/trunk/</url>
+	</scm>
+
+
+	<modules>
+		<module>step-web-app</module>
+		<module>step-dataloader</module>
+		<module>step-server</module>
+		<module>step-tools</module>
+	</modules>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.crosswire</groupId>
+				<artifactId>jsword</artifactId>
+				<version>1.6.1-SNAPSHOT</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.gwt</groupId>
+				<artifactId>gwt-servlet</artifactId>
+				<version>${gwt.version}</version>
+				<scope>compile</scope>
+			</dependency>
+			<dependency>
+				<groupId>com.google.gwt</groupId>
+				<artifactId>gwt-user</artifactId>
+				<version>${gwt.version}</version>
+				<scope>provided</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>com.googlecode.gwt.inject
+				</groupId>
+				<artifactId>gin</artifactId>
+				<version>1.0</version>
+			</dependency>
+			<dependency>
+				<groupId>com.google.inject</groupId>
+				<artifactId>guice</artifactId>
+				<version>2.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.inject.extensions
+				</groupId>
+				<artifactId>guice-servlet</artifactId>
+				<version>2.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>net.customware.gwt.dispatch
+				</groupId>
+				<artifactId>gwt-dispatch</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>net.customware.gwt.presenter
+				</groupId>
+				<artifactId>gwt-presenter</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.code.gwt-log</groupId>
+				<artifactId>gwt-log</artifactId>
+				<version>2.6.2</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.extjs</groupId>
+				<artifactId>gxt</artifactId>
+				<version>2.1.1</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-logging</groupId>
+				<artifactId>commons-logging</artifactId>
+				<version>1.1.1</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-dbcp</groupId>
+				<artifactId>commons-dbcp</artifactId>
+				<version>1.3</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-io</groupId>
+				<artifactId>commons-io</artifactId>
+				<version>1.4</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-dbutils</groupId>
+				<artifactId>commons-dbutils</artifactId>
+				<version>1.3</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-lang</groupId>
+				<artifactId>commons-lang</artifactId>
+				<version>2.5</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.jmock</groupId>
+				<artifactId>jmock</artifactId>
+				<version>2.5.1</version>
+				<scope>test</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.jmock</groupId>
+				<artifactId>jmock-junit4</artifactId>
+				<version>2.5.1</version>
+				<scope>test</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.derby</groupId>
+				<artifactId>derbyclient</artifactId>
+				<version>${derby.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.derby</groupId>
+				<artifactId>derby</artifactId>
+				<version>${derby.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>net.sf.opencsv</groupId>
+				<artifactId>opencsv</artifactId>
+				<version>2.1</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+
+
+	<build>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<configuration>
+						<encoding>iso-8859-1</encoding>
+						<source>${java.version}</source>
+						<target>${java.version}</target>
+					</configuration>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<configuration>
+						<junitArtifactName>junit:junit-dep
+						</junitArtifactName>
+					</configuration>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-eclipse-plugin</artifactId>
+					<version>2.5</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+</project>

Added: trunk/step-checks.xml
===================================================================
--- trunk/step-checks.xml	                        (rev 0)
+++ trunk/step-checks.xml	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: step-checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="warning"/>
+  <module name="TreeWalker">
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocMethod">
+      <property name="logLoadErrors" value="true"/>
+      <property name="suppressLoadErrors" value="true"/>
+    </module>
+    <module name="JavadocType"/>
+    <module name="JavadocVariable"/>
+    <module name="JavadocStyle">
+      <property name="checkFirstSentence" value="false"/>
+    </module>
+    <module name="ConstantName"/>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName"/>
+    <module name="MethodName"/>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="StaticVariableName"/>
+    <module name="TypeName"/>
+    <module name="AvoidStarImport"/>
+    <module name="IllegalImport"/>
+    <module name="RedundantImport"/>
+    <module name="UnusedImports"/>
+    <module name="FileLength"/>
+    <module name="MethodLength"/>
+    <module name="ParameterNumber"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore"/>
+    <module name="OperatorWrap"/>
+    <module name="ParenPad">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="TypecastParenPad"/>
+    <module name="TabCharacter">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround"/>
+    <module name="ModifierOrder"/>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks"/>
+    <module name="EmptyBlock"/>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="AvoidInlineConditionals">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="DoubleCheckedLocking"/>
+    <module name="EmptyStatement"/>
+    <module name="EqualsHashCode"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="IllegalInstantiation"/>
+    <module name="InnerAssignment"/>
+    <module name="MagicNumber"/>
+    <module name="MissingSwitchDefault"/>
+    <module name="RedundantThrows">
+      <property name="logLoadErrors" value="true"/>
+      <property name="suppressLoadErrors" value="true"/>
+    </module>
+    <module name="SimplifyBooleanExpression"/>
+    <module name="SimplifyBooleanReturn"/>
+    <module name="DesignForExtension">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor"/>
+    <module name="InterfaceIsType"/>
+    <module name="VisibilityModifier"/>
+    <module name="ArrayTypeStyle"/>
+    <module name="FinalParameters"/>
+    <module name="GenericIllegalRegexp">
+      <property name="severity" value="ignore"/>
+      <property name="format" value="\s+$"/>
+      <property name="message" value="Line has trailing spaces."/>
+    </module>
+    <module name="TodoComment">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="UpperEll"/>
+    <module name="CyclomaticComplexity">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Cyclomatic Complexity"/>
+    </module>
+  </module>
+  <module name="JavadocPackage">
+    <property name="severity" value="ignore"/>
+  </module>
+  <module name="NewlineAtEndOfFile"/>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <metadata name="net.sf.eclipsecs.core.comment" value="ignore checkstyle"/>
+  </module>
+</module>

Modified: trunk/step-server/.classpath
===================================================================
--- trunk/step-server/.classpath	2010-03-28 15:56:28 UTC (rev 105)
+++ trunk/step-server/.classpath	2010-04-14 20:22:59 UTC (rev 106)
@@ -1,10 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
-	<classpathentry kind="src" path="src"/>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="lib" path="lib/jetty-6.1.19.jar"/>
-	<classpathentry kind="lib" path="lib/jetty-util-6.1.19.jar"/>
-	<classpathentry kind="lib" path="lib/servlet-api-2.5-20081211.jar"/>
-	<classpathentry combineaccessrules="false" kind="src" path="/StepShared"/>
-	<classpathentry kind="output" path="bin"/>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
 </classpath>

Modified: trunk/step-server/.project
===================================================================
--- trunk/step-server/.project	2010-03-28 15:56:28 UTC (rev 105)
+++ trunk/step-server/.project	2010-04-14 20:22:59 UTC (rev 106)
@@ -1,17 +1,17 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>StepServer</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-	</natures>
-</projectDescription>
+  <name>step-dataloader</name>
+  <comment/>
+  <projects/>
+  <buildSpec>
+    <buildCommand>
+      <name>org.eclipse.jdt.core.javabuilder</name>
+    </buildCommand>
+    <buildCommand>
+      <name>org.maven.ide.eclipse.maven2Builder</name>
+    </buildCommand>
+  </buildSpec>
+  <natures>
+    <nature>org.eclipse.jdt.core.javanature</nature>
+    <nature>org.maven.ide.eclipse.maven2Nature</nature>
+  </natures>
+</projectDescription>
\ No newline at end of file

Added: trunk/step-server/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-server/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-server/.settings/org.eclipse.jdt.core.prefs	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,6 @@
+#Mon Apr 05 13:29:00 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5

Added: trunk/step-server/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-server/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-server/.settings/org.maven.ide.eclipse.prefs	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,9 @@
+#Mon Apr 05 13:28:59 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-server/pom.xml
===================================================================
--- trunk/step-server/pom.xml	                        (rev 0)
+++ trunk/step-server/pom.xml	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,24 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-server</artifactId>
+	<packaging>jar</packaging>
+	<name>step-server</name>
+
+	
+	<dependencies>
+		<dependency>
+			<groupId>org.mortbay.jetty</groupId>
+			<artifactId>jetty</artifactId>
+			<version>6.1.22</version>
+		</dependency>
+	</dependencies>
+</project>

Modified: trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java
===================================================================
--- trunk/step-server/src/com/tyndalehouse/step/server/StepServer.java	2010-03-28 15:56:28 UTC (rev 105)
+++ trunk/step-server/src/main/java/com/tyndalehouse/step/server/StepServer.java	2010-04-14 20:22:59 UTC (rev 106)
@@ -24,7 +24,7 @@
 	// creates and configures the Jetty server
 	private Server start() throws Exception {
 		Server jetty = new Server();
-		String[] configFiles = { "etc/jetty.xml" };
+		String[] configFiles = { "jetty.xml" };
 				
 		for (String configFile : configFiles) {
 			

Added: trunk/step-server/src/main/resources/jetty.xml
===================================================================
--- trunk/step-server/src/main/resources/jetty.xml	                        (rev 0)
+++ trunk/step-server/src/main/resources/jetty.xml	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,204 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
+
+<!-- =============================================================== -->
+<!-- Configure the Jetty Server                                      -->
+<!--                                                                 -->
+<!-- Documentation of this file format can be found at:              -->
+<!-- http://docs.codehaus.org/display/JETTY/jetty.xml                -->
+<!--                                                                 -->
+<!-- =============================================================== -->
+
+
+<Configure id="Server" class="org.mortbay.jetty.Server">
+
+    <!-- =========================================================== -->
+    <!-- Server Thread Pool                                          -->
+    <!-- =========================================================== -->
+    <Set name="ThreadPool">
+      <!-- Default bounded blocking threadpool 
+      -->
+      <New class="org.mortbay.thread.BoundedThreadPool">
+        <Set name="minThreads">10</Set>
+        <Set name="maxThreads">250</Set>
+      </New>
+
+      <!-- Optional Java 5 bounded threadpool with job queue 
+      <New class="org.mortbay.thread.concurrent.ThreadPool">
+        <Set name="corePoolSize">250</Set>
+        <Set name="maximumPoolSize">250</Set>
+      </New>
+      -->
+    </Set>
+
+
+
+    <!-- =========================================================== -->
+    <!-- Set connectors                                              -->
+    <!-- =========================================================== -->
+    <!-- One of each type!                                           -->
+    <!-- =========================================================== -->
+
+    <!-- Use this connector for many frequently idle connections
+         and for threadless continuations.
+    -->    
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.mortbay.jetty.nio.SelectChannelConnector">
+            <Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
+            <Set name="maxIdleTime">30000</Set>
+            <Set name="Acceptors">1</Set>
+            <Set name="statsOn">false</Set>
+            <Set name="confidentialPort">8443</Set>
+	    <Set name="lowResourcesConnections">1000</Set>
+	    <Set name="lowResourcesMaxIdleTime">500</Set>
+          </New>
+      </Arg>
+    </Call>
+
+    <!-- Use this connector if NIO is not available.
+    <Call name="addConnector">
+      <Arg>
+          <New class="org.mortbay.jetty.bio.SocketConnector">
+            <Set name="port">8081</Set>
+            <Set name="maxIdleTime">50000</Set>
+            <Set name="lowResourceMaxIdleTime">1500</Set>
+          </New>
+      </Arg>
+    </Call>
+    -->
+
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    <!-- To add a HTTPS SSL listener                                     -->
+    <!-- see jetty-ssl.xml to add an ssl connector. use                  -->
+    <!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml             -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    
+    <!-- =========================================================== -->
+    <!-- Set up global session ID manager                            -->
+    <!-- =========================================================== -->
+    <!--
+    <Set name="sessionIdManager">
+      <New class="org.mortbay.jetty.servlet.HashSessionIdManager">
+        <Set name="workerName">node1</Set>
+      </New>
+    </Set>
+    -->
+
+    <!-- =========================================================== -->
+    <!-- Set handler Collection Structure                            --> 
+    <!-- =========================================================== -->
+    <Set name="handler">
+      <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection">
+        <Set name="handlers">
+         <Array type="org.mortbay.jetty.Handler">
+           <Item>
+             <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/>
+           </Item>
+           <Item>
+             <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/>
+           </Item>
+           <Item>
+             <New id="RequestLog" class="org.mortbay.jetty.handler.RequestLogHandler"/>
+           </Item>
+         </Array>
+        </Set>
+      </New>
+    </Set>
+    
+    <!-- =========================================================== -->
+    <!-- Configure the context deployer                              -->
+    <!-- A context deployer will deploy contexts described in        -->
+    <!-- configuration files discovered in a directory.              -->
+    <!-- The configuration directory can be scanned for hot          -->
+    <!-- deployments at the configured scanInterval.                 -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy contexts configured   -->
+    <!-- in the $JETTY_HOME/contexts directory                       -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Call name="addLifeCycle">
+      <Arg>
+        <New class="org.mortbay.jetty.deployer.ContextDeployer">
+          <Set name="contexts"><Ref id="Contexts"/></Set>
+          <Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
+          <Set name="scanInterval">1</Set>
+        </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- Configure the webapp deployer.                              -->
+    <!-- A webapp  deployer will deploy standard webapps discovered  -->
+    <!-- in a directory at startup, without the need for additional  -->
+    <!-- configuration files.    It does not support hot deploy or   -->
+    <!-- non standard contexts (see ContextDeployer above).          -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy webapps from the      -->
+    <!-- $JETTY_HOME/webapps directory                               -->
+    <!--                                                             -->
+    <!-- Normally only one type of deployer need be used.            -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Call name="addLifeCycle">
+      <Arg>
+        <New class="org.mortbay.jetty.deployer.WebAppDeployer">
+          <Set name="contexts"><Ref id="Contexts"/></Set>
+          <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
+	  <Set name="parentLoaderPriority">false</Set>
+	  <Set name="extract">true</Set>
+	  <Set name="allowDuplicates">false</Set>
+          <Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
+        </New>
+      </Arg>
+    </Call>
+
+    <!-- =========================================================== -->
+    <!-- Configure Authentication Realms                             -->
+    <!-- Realms may be configured for the entire server here, or     -->
+    <!-- they can be configured for a specific web app in a context  -->
+    <!-- configuration (see $(jetty.home)/contexts/test.xml for an   -->
+    <!-- example).                                                   -->
+    <!-- =========================================================== -->
+    <Set name="UserRealms">
+      <Array type="org.mortbay.jetty.security.UserRealm">
+        <!--
+        <Item>
+          <New class="org.mortbay.jetty.security.HashUserRealm">
+            <Set name="name">Test Realm</Set>
+            <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
+          </New>
+        </Item>
+	-->
+      </Array>
+    </Set>
+
+    <!-- =========================================================== -->
+    <!-- Configure Request Log                                       -->
+    <!-- Request logs  may be configured for the entire server here, -->
+    <!-- or they can be configured for a specific web app in a       -->
+    <!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
+    <!-- for an example).                                            -->
+    <!-- =========================================================== -->
+    <Ref id="RequestLog">
+      <Set name="requestLog">
+        <New id="RequestLogImpl" class="org.mortbay.jetty.NCSARequestLog">
+          <Arg><SystemProperty name="jetty.logs" default="./logs"/>/yyyy_mm_dd.request.log</Arg>
+          <Set name="retainDays">90</Set>
+          <Set name="append">true</Set>
+          <Set name="extended">false</Set>
+          <Set name="LogTimeZone">GMT</Set>
+        </New>
+      </Set>
+    </Ref>
+
+    <!-- =========================================================== -->
+    <!-- extra options                                               -->
+    <!-- =========================================================== -->
+    <Set name="stopAtShutdown">true</Set>
+    <!-- ensure/prevent Server: header being sent to browsers        -->
+    <Set name="sendServerVersion">true</Set>
+
+
+
+</Configure>

Added: trunk/step-tools/.classpath
===================================================================
--- trunk/step-tools/.classpath	                        (rev 0)
+++ trunk/step-tools/.classpath	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/step-tools/.project
===================================================================
--- trunk/step-tools/.project	                        (rev 0)
+++ trunk/step-tools/.project	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-tools</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: trunk/step-tools/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-tools/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-tools/.settings/org.eclipse.jdt.core.prefs	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,6 @@
+#Mon Apr 05 13:57:25 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5

Added: trunk/step-tools/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-tools/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-tools/.settings/org.maven.ide.eclipse.prefs	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,9 @@
+#Mon Apr 05 13:57:25 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-tools/pom.xml
===================================================================
--- trunk/step-tools/pom.xml	                        (rev 0)
+++ trunk/step-tools/pom.xml	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-tools</artifactId>
+	<packaging>jar</packaging>
+	<name>step-tools</name>
+
+	<dependencies>
+				<dependency>
+			<groupId>org.crosswire</groupId>
+			<artifactId>jsword</artifactId>
+		</dependency>
+				<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+		</dependency>
+	</dependencies>
+</project>

Added: trunk/step-tools/src/main/java/BibleFileGenerator.java
===================================================================
--- trunk/step-tools/src/main/java/BibleFileGenerator.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/BibleFileGenerator.java	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,253 @@
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.crosswire.common.util.Language;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookCategory;
+import org.crosswire.jsword.book.BookData;
+import org.crosswire.jsword.book.BookException;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.book.OSISUtil;
+import org.crosswire.jsword.book.install.InstallException;
+import org.crosswire.jsword.book.install.sword.HttpSwordInstaller;
+import org.crosswire.jsword.passage.Key;
+import org.crosswire.jsword.passage.PassageKeyFactory;
+
+public class BibleFileGenerator extends Thread {
+	private final static String proxyHostProperty = "step.proxy.host";
+	private final static String proxyPortProperty = "step.proxy.port";
+	private String initials;
+
+
+	public BibleFileGenerator() {
+		this.initials = "";
+	}
+
+	
+	public BibleFileGenerator(String initials) {
+		this.initials = initials;
+	}
+
+	private String writeBible(String version) throws Exception {
+
+		StringBuffer sb = new StringBuffer(String.format("@%s%s", version, System.getProperty("line.separator")));
+		// check information has been passed in
+		if (StringUtils.isEmpty(version)) {
+			throw new Exception("Version was not provided");
+		}
+
+		Book currentBook = Books.installed().getBook(version);
+
+		Key global = currentBook.getGlobalKeyList();
+		int numVersesInVersion = global.getCardinality();
+
+		String formatBook = "";
+		String formatChapter = "";
+		String formatVerse = "";
+		
+		String previousBook = "none";
+		String previousChapter = "none";
+		String previousVerse = "none" ;
+		
+		String key = null;
+		boolean newBook = true;
+		for (int ii = 0; ii < numVersesInVersion; ii++) {
+			try {
+				key = global.get(ii).getOsisID();
+				
+				//assume just one verse?
+				String[] split = key.split("\\.");
+				formatBook = split[0];
+				formatChapter = split[1];
+				formatVerse = split[2];
+				
+				if(!formatBook.equals(previousBook)) {
+					previousBook = formatBook;
+					
+					sb.append('@');
+					sb.append(formatBook);
+					sb.append(System.getProperty("line.separator"));
+					
+					//if new book, also reset chapter
+					previousChapter = formatChapter;
+					sb.append("@Chapter ");
+					sb.append(formatChapter);
+					sb.append(System.getProperty("line.separator"));
+				} else if(!formatChapter.equals(previousChapter)) {
+					previousChapter = formatChapter;
+					sb.append("@Chapter ");
+					sb.append(formatChapter);
+					sb.append(System.getProperty("line.separator"));				
+				}
+				
+				BookData data = new BookData(currentBook, global.get(ii));
+				
+				sb.append(formatVerse);
+				sb.append(". ");
+				sb.append(OSISUtil.getCanonicalText(data.getOsis()).replace('\n', ' ').replace('\r', '\n'));
+				sb.append(System.getProperty("line.separator"));
+								
+				//ScriptureReference sr = new ScriptureReference(key);
+				
+//				if (!sr.getBook().equals(formatBook)) {
+//					sb.append(String.format("@%s%s", sr.getBook().toUpperCase(), System.getProperty("line.separator")));
+//					formatBook = sr.getBook();
+//					newBook = true;
+//				}
+//
+//				if (sr.getChapter() != null && !sr.getChapter().equals(formatChapter)) {
+//					sb.append(String.format("@Chapter %s%s", sr.getChapter(), System.getProperty("line.separator")));
+//					newBook = false;
+//					formatChapter = sr.getChapter();
+//				} else if(newBook) {
+//					sb.append(String.format("@Chapter 1%s", System.getProperty("line.separator")));
+//					newBook = false;
+//				}
+
+			} catch (BookException e) {
+				System.out
+						.println(initials + ":: A book exception has occurred whilte looking up the passage: " + key);
+				e.printStackTrace();
+				throw new Exception(e);
+			} catch (Exception ex) {
+				System.err.println(initials + ":: Could not parse key: " + key);
+				ex.printStackTrace();
+			} finally {
+				;
+			}
+		}
+		return sb.toString();
+
+	}
+
+	//TODO: here and elsewhere, ensure that the downloaders 
+	//are not hardcoded - there are at least two more sites to get 
+	//bible versions from.
+	private static HttpSwordInstaller getNewCustomInstaller() {
+		System.out.println("Creating new installer for JSword");
+		HttpSwordInstaller resourceInstaller = new HttpSwordInstaller();
+
+		System.out.println("Currently hardcoded installer host to:"
+				+ "www.crosswire.org");
+		System.out.println("Currently hardcoded property names for step");
+		String host = "www.crosswire.org";
+		String proxyHost = System.getProperty(proxyHostProperty);
+		String proxyPort = System.getProperty(proxyPortProperty);
+		System.out.println(String.format("Setting to (%1$s via %2$s:%3$s)",
+				"www.crosswire.org", proxyHost, proxyPort));
+
+		resourceInstaller.setHost(host);
+		if (proxyHost != null) {
+			resourceInstaller.setProxyHost(proxyHost);
+		}
+		if (proxyPort != null) {
+			resourceInstaller.setProxyPort(Integer.parseInt(proxyPort));
+		}
+
+		System.out.println("Setting package and catalog directories");
+		resourceInstaller
+				.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+		resourceInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+		return resourceInstaller;
+	}
+	
+	private void downloadAllBibles() throws InstallException {
+		HttpSwordInstaller installer = getNewCustomInstaller();
+
+		//TODO: ensure the comment in the comment of the function is in a warning
+		//somewhere...
+		installer.reloadBookList();
+		
+		List availableBooks = installer.getBooks();
+		
+		for(int ii = 0; ii < availableBooks.size(); ii++) {
+			Book b = (Book) availableBooks.get(ii);
+			Language en = new Language("en");
+			
+			//check book is a biblical text...
+			if(b.getBookCategory() == BookCategory.BIBLE &&
+					b.getBookMetaData().getLanguage().equals(en)
+					) {
+				String versionKey = b.getInitials();
+				
+				System.out.println("Downloading " + ((Book) availableBooks.get(ii)).getName() + "...");
+				if(Books.installed().getBook(versionKey) == null) {
+					installer.install(installer.getBook(versionKey));
+				}
+			}
+		}		
+	}
+
+	
+	@Override
+	public void run() {
+		try {
+			System.out.println("Starting thread for " + initials);
+			FileUtils.writeStringToFile(new File("output/" + initials + ".txt"), writeBible(initials));
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (Exception e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
+
+	
+	
+	//TODO: could profile the application to figure out if we can speed things
+	//up with memory settings etc, more/less threads...
+	//could also investigate rewriting it so that disk IO happens
+	//during processing to allow other threads to execute.
+	//would be interesting to profile to find out where bottlenecks are.
+	public static void main(String args[]) throws Exception {
+		BibleFileGenerator bfg = new BibleFileGenerator();
+		int numThreads = 2;
+			
+		
+		
+		BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
+		ThreadPoolExecutor tpe = new ThreadPoolExecutor(numThreads, numThreads,1, TimeUnit.MINUTES, queue);
+		
+		//add processor thing, to kick off all the downloads, and then
+		//TODO:
+		//wait for the downloads to complete for each version, before it continues on to the 
+		//bible processing...
+		//bfg.downloadAllBibles();
+		List<Book> books = Books.installed().getBooks();
+		
+		//of the installed books
+		for(Book b : books) {
+			System.out.println(String.format("%s %s", b.getInitials(), b.getName()));
+		}
+		
+		System.out.println("of available:\n\n");
+
+		
+		
+		List<Book> availableBooks = getNewCustomInstaller().getBooks();
+		for(Book b : availableBooks) {
+			System.out.println(String.format("%s %s", b.getInitials(), b.getName()));
+		}
+
+		new BibleFileGenerator("ESV").start();
+		
+//		for(int ii = 0; ii < books.size(); ii++) {
+//			if(books.get(ii).getBookCategory().equals(BookCategory.BIBLE)) {
+//				
+//				String initials = books.get(ii).getInitials();
+//				Thread r = new BibleFileGenerator(initials);
+//				tpe.execute(r);
+//				System.out.println("Size of runnable queue: " + queue.size());
+//			}
+//		}
+	}
+}

Added: trunk/step-tools/src/main/java/BibleStatsAnalyser.java
===================================================================
--- trunk/step-tools/src/main/java/BibleStatsAnalyser.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/BibleStatsAnalyser.java	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,34 @@
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Hashtable;
+
+import org.apache.commons.io.FileUtils;
+
+
+public class BibleStatsAnalyser {
+	public BibleStatsAnalyser() {
+		// TODO Auto-generated constructor stub
+	}
+	
+	
+	public static void main(String args[]) throws IOException {
+		String esv = FileUtils.readFileToString(new File("output/ESV.txt"));
+		String[] allWords = esv.split("[ ,\\.!;\\']");
+		Hashtable<String, Integer> count = new Hashtable<String, Integer>();
+		
+		for(String s : allWords) {
+			if(count.containsKey(s)) {
+				Integer i = count.get(s);
+				i++;
+				count.put(s, i);
+			} else {
+				count.put(s, 1);
+			}
+		}
+		
+		for(String s : allWords) {
+			System.out.println(String.format("%s,%d", s, count.get(s).intValue()));
+		}
+	}
+}

Added: trunk/step-tools/src/main/java/ScriptureReference.java
===================================================================
--- trunk/step-tools/src/main/java/ScriptureReference.java	                        (rev 0)
+++ trunk/step-tools/src/main/java/ScriptureReference.java	2010-04-14 20:22:59 UTC (rev 106)
@@ -0,0 +1,60 @@
+public class ScriptureReference {
+	private String book = null;
+	private String chapter = null;
+	private String verse = null;
+
+	/**
+	 * Given a key looking like 1 Samuel 2:13 or Philemon 1 it stores it
+	 * internally as book,chapter,verse
+	 * 
+	 * @param key
+	 */
+	public ScriptureReference(String key) {
+		int lastColon = key.lastIndexOf(":");
+		int lastSpace = key.lastIndexOf(' ');
+
+		// there are two types of formats:
+		// 1 Samuel 2:13 and Philemon 1 where 1 in this case is the verse
+
+		try {
+			// ie, reference not like Philemon 1
+			if (lastColon != -1) {
+				verse = key.substring(lastColon + 1);
+				chapter = key.substring(lastSpace + 1, lastColon);
+			} else {
+				verse = key.substring(lastSpace + 1);
+				chapter = null;
+			}
+
+			book = key.substring(0, lastSpace);
+		} catch (Exception ex) {
+			System.err.println("Key: " + key);
+			System.err.println("lastColon: " + lastColon);
+			System.err.println("lastSpace: " + lastSpace);
+			System.err.println("verse: " + verse);
+			System.err.println("chapter: " + chapter);
+			
+		}
+	}
+
+	/**
+	 * @return the book
+	 */
+	public String getBook() {
+		return book;
+	}
+
+	/**
+	 * @return the chapter
+	 */
+	public String getChapter() {
+		return chapter;
+	}
+
+	/**
+	 * @return the verse
+	 */
+	public String getVerse() {
+		return verse;
+	}
+}



From ChrisBurrell at crosswire.org  Wed Apr 14 14:29:50 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 21:29:50 -0000
Subject: [Tynstep-svn] r109 - in trunk: . step-dataloader
	step-dataloader/.settings step-dataloader/src
	step-dataloader/src/main step-dataloader/src/main/java
	step-dataloader/src/main/java/com
	step-dataloader/src/main/java/com/tyndalehouse
	step-dataloader/src/main/java/com/tyndalehouse/step
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders
	step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils
	step-dataloader/src/main/resources
	step-dataloader/src/main/resources/data
	step-dataloader/src/main/resources/data/timeline
	step-dataloader/src/main/resources/sql
	step-dataloader/src/main/resources/sql/com
	step-dataloader/src/main/resources/sql/com/tyndalehouse
	step-dataloader/src/main/resources/sql/com/tyndalehouse/step
	step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader
	step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql
	step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create
	step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data
Message-ID: <E1O2A9e-0003Uj-Kp@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 14:29:50 -0700 (Wed, 14 Apr 2010)
New Revision: 109

Added:
   trunk/step-dataloader/
   trunk/step-dataloader/.checkstyle
   trunk/step-dataloader/.classpath
   trunk/step-dataloader/.fbprefs
   trunk/step-dataloader/.project
   trunk/step-dataloader/.settings/
   trunk/step-dataloader/.settings/org.eclipse.jdt.core.prefs
   trunk/step-dataloader/.settings/org.maven.ide.eclipse.prefs
   trunk/step-dataloader/pom.xml
   trunk/step-dataloader/src/
   trunk/step-dataloader/src/main/
   trunk/step-dataloader/src/main/java/
   trunk/step-dataloader/src/main/java/com/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/DbBean.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/EventTypeBean.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PartialDate.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PrecisionType.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TargetTypeEnum.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineBean.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineEventBean.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common/DateParsingException.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/AbstractLoader.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/SchemaLoader.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/TimelineLoader.java
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils/
   trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils/DerbyUtils.java
   trunk/step-dataloader/src/main/resources/
   trunk/step-dataloader/src/main/resources/data/
   trunk/step-dataloader/src/main/resources/data/timeline/
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Africa.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Americas.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_ArchCult.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Asia.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_EarlyChurch.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Egypt.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Europe.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_ExileAndReturn.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Global.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Intertestamental.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Jesus.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Monarchy.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_NTChurch.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_OTNeighbours.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_PatriarchsToJudges.csv
   trunk/step-dataloader/src/main/resources/data/timeline/TL_Rome.csv
   trunk/step-dataloader/src/main/resources/data/timeline_reference_corrections.csv
   trunk/step-dataloader/src/main/resources/sql/
   trunk/step-dataloader/src/main/resources/sql/com/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/1.schema.sql
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/2.scripture_referencing.sql
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/3.timeline.sql
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/1.timeband_units.sql
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/2.timeband_setup.sql
   trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/3.sub_timeband_units.sql
   trunk/step-dataloader/src/main/webapp/
Log:
committing dataloader

Added: trunk/step-dataloader/.checkstyle
===================================================================
--- trunk/step-dataloader/.checkstyle	                        (rev 0)
+++ trunk/step-dataloader/.checkstyle	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fileset-config file-format-version="1.2.0" simple-config="true">
+  <local-check-config name="step-checks" location="/step-parent/step-checks.xml" type="project" description="">
+    <additional-data name="protect-config-file" value="false"/>
+  </local-check-config>
+  <fileset name="all" enabled="true" check-config-name="step-checks" local="true">
+    <file-match-pattern match-pattern="." include-pattern="true"/>
+  </fileset>
+  <filter name="NonSrcDirs" enabled="true"/>
+</fileset-config>

Added: trunk/step-dataloader/.classpath
===================================================================
--- trunk/step-dataloader/.classpath	                        (rev 0)
+++ trunk/step-dataloader/.classpath	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java"/>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
+	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

Added: trunk/step-dataloader/.fbprefs
===================================================================
--- trunk/step-dataloader/.fbprefs	                        (rev 0)
+++ trunk/step-dataloader/.fbprefs	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,127 @@
+#FindBugs User Preferences
+#Mon Apr 05 12:13:43 BST 2010
+detectorAppendingToAnObjectOutputStream=AppendingToAnObjectOutputStream|true
+detectorBadAppletConstructor=BadAppletConstructor|false
+detectorBadResultSetAccess=BadResultSetAccess|true
+detectorBadSyntaxForRegularExpression=BadSyntaxForRegularExpression|true
+detectorBadUseOfReturnValue=BadUseOfReturnValue|true
+detectorBadlyOverriddenAdapter=BadlyOverriddenAdapter|true
+detectorBooleanReturnNull=BooleanReturnNull|true
+detectorCallToUnsupportedMethod=CallToUnsupportedMethod|false
+detectorCheckImmutableAnnotation=CheckImmutableAnnotation|true
+detectorCheckTypeQualifiers=CheckTypeQualifiers|true
+detectorCloneIdiom=CloneIdiom|true
+detectorComparatorIdiom=ComparatorIdiom|true
+detectorConfusedInheritance=ConfusedInheritance|true
+detectorConfusionBetweenInheritedAndOuterMethod=ConfusionBetweenInheritedAndOuterMethod|true
+detectorCrossSiteScripting=CrossSiteScripting|true
+detectorDoInsideDoPrivileged=DoInsideDoPrivileged|true
+detectorDontCatchIllegalMonitorStateException=DontCatchIllegalMonitorStateException|true
+detectorDontIgnoreResultOfPutIfAbsent=DontIgnoreResultOfPutIfAbsent|true
+detectorDontUseEnum=DontUseEnum|true
+detectorDroppedException=DroppedException|true
+detectorDumbMethodInvocations=DumbMethodInvocations|true
+detectorDumbMethods=DumbMethods|true
+detectorDuplicateBranches=DuplicateBranches|true
+detectorEmptyZipFileEntry=EmptyZipFileEntry|true
+detectorEqualsOperandShouldHaveClassCompatibleWithThis=EqualsOperandShouldHaveClassCompatibleWithThis|true
+detectorFinalizerNullsFields=FinalizerNullsFields|true
+detectorFindBadCast2=FindBadCast2|true
+detectorFindBadForLoop=FindBadForLoop|true
+detectorFindCircularDependencies=FindCircularDependencies|false
+detectorFindDeadLocalStores=FindDeadLocalStores|true
+detectorFindDoubleCheck=FindDoubleCheck|true
+detectorFindEmptySynchronizedBlock=FindEmptySynchronizedBlock|true
+detectorFindFieldSelfAssignment=FindFieldSelfAssignment|true
+detectorFindFinalizeInvocations=FindFinalizeInvocations|true
+detectorFindFloatEquality=FindFloatEquality|true
+detectorFindHEmismatch=FindHEmismatch|true
+detectorFindInconsistentSync2=FindInconsistentSync2|true
+detectorFindJSR166LockMonitorenter=FindJSR166LockMonitorenter|true
+detectorFindLocalSelfAssignment2=FindLocalSelfAssignment2|true
+detectorFindMaskedFields=FindMaskedFields|true
+detectorFindMismatchedWaitOrNotify=FindMismatchedWaitOrNotify|true
+detectorFindNakedNotify=FindNakedNotify|true
+detectorFindNonSerializableStoreIntoSession=FindNonSerializableStoreIntoSession|true
+detectorFindNonSerializableValuePassedToWriteObject=FindNonSerializableValuePassedToWriteObject|true
+detectorFindNonShortCircuit=FindNonShortCircuit|true
+detectorFindNullDeref=FindNullDeref|true
+detectorFindNullDerefsInvolvingNonShortCircuitEvaluation=FindNullDerefsInvolvingNonShortCircuitEvaluation|true
+detectorFindOpenStream=FindOpenStream|true
+detectorFindPuzzlers=FindPuzzlers|true
+detectorFindRefComparison=FindRefComparison|true
+detectorFindReturnRef=FindReturnRef|true
+detectorFindRunInvocations=FindRunInvocations|true
+detectorFindSelfComparison=FindSelfComparison|true
+detectorFindSelfComparison2=FindSelfComparison2|true
+detectorFindSleepWithLockHeld=FindSleepWithLockHeld|true
+detectorFindSpinLoop=FindSpinLoop|true
+detectorFindSqlInjection=FindSqlInjection|true
+detectorFindTwoLockWait=FindTwoLockWait|true
+detectorFindUncalledPrivateMethods=FindUncalledPrivateMethods|true
+detectorFindUnconditionalWait=FindUnconditionalWait|true
+detectorFindUninitializedGet=FindUninitializedGet|true
+detectorFindUnrelatedTypesInGenericContainer=FindUnrelatedTypesInGenericContainer|true
+detectorFindUnreleasedLock=FindUnreleasedLock|true
+detectorFindUnsatisfiedObligation=FindUnsatisfiedObligation|true
+detectorFindUnsyncGet=FindUnsyncGet|true
+detectorFindUselessControlFlow=FindUselessControlFlow|true
+detectorFormatStringChecker=FormatStringChecker|true
+detectorHugeSharedStringConstants=HugeSharedStringConstants|true
+detectorIDivResultCastToDouble=IDivResultCastToDouble|true
+detectorIncompatMask=IncompatMask|true
+detectorInconsistentAnnotations=InconsistentAnnotations|true
+detectorInefficientMemberAccess=InefficientMemberAccess|false
+detectorInefficientToArray=InefficientToArray|true
+detectorInfiniteLoop=InfiniteLoop|true
+detectorInfiniteRecursiveLoop=InfiniteRecursiveLoop|true
+detectorInfiniteRecursiveLoop2=InfiniteRecursiveLoop2|false
+detectorInheritanceUnsafeGetResource=InheritanceUnsafeGetResource|true
+detectorInitializationChain=InitializationChain|true
+detectorInstantiateStaticClass=InstantiateStaticClass|true
+detectorInvalidJUnitTest=InvalidJUnitTest|true
+detectorIteratorIdioms=IteratorIdioms|true
+detectorLazyInit=LazyInit|true
+detectorLoadOfKnownNullValue=LoadOfKnownNullValue|true
+detectorLostLoggerDueToWeakReference=LostLoggerDueToWeakReference|true
+detectorMethodReturnCheck=MethodReturnCheck|true
+detectorMultithreadedInstanceAccess=MultithreadedInstanceAccess|true
+detectorMutableLock=MutableLock|true
+detectorMutableStaticFields=MutableStaticFields|true
+detectorNaming=Naming|true
+detectorNumberConstructor=NumberConstructor|true
+detectorOverridingEqualsNotSymmetrical=OverridingEqualsNotSymmetrical|true
+detectorPreferZeroLengthArrays=PreferZeroLengthArrays|true
+detectorPublicSemaphores=PublicSemaphores|false
+detectorQuestionableBooleanAssignment=QuestionableBooleanAssignment|true
+detectorReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass=ReadOfInstanceFieldInMethodInvokedByConstructorInSuperclass|true
+detectorReadReturnShouldBeChecked=ReadReturnShouldBeChecked|true
+detectorRedundantInterfaces=RedundantInterfaces|true
+detectorRepeatedConditionals=RepeatedConditionals|true
+detectorRuntimeExceptionCapture=RuntimeExceptionCapture|true
+detectorSerializableIdiom=SerializableIdiom|true
+detectorStartInConstructor=StartInConstructor|true
+detectorStaticCalendarDetector=StaticCalendarDetector|true
+detectorStringConcatenation=StringConcatenation|true
+detectorSuperfluousInstanceOf=SuperfluousInstanceOf|true
+detectorSuspiciousThreadInterrupted=SuspiciousThreadInterrupted|true
+detectorSwitchFallthrough=SwitchFallthrough|true
+detectorSynchronizeAndNullCheckField=SynchronizeAndNullCheckField|true
+detectorSynchronizeOnClassLiteralNotGetClass=SynchronizeOnClassLiteralNotGetClass|true
+detectorSynchronizingOnContentsOfFieldToProtectField=SynchronizingOnContentsOfFieldToProtectField|true
+detectorURLProblems=URLProblems|true
+detectorUncallableMethodOfAnonymousClass=UncallableMethodOfAnonymousClass|true
+detectorUnnecessaryMath=UnnecessaryMath|true
+detectorUnreadFields=UnreadFields|true
+detectorUseObjectEquals=UseObjectEquals|false
+detectorUselessSubclassMethod=UselessSubclassMethod|false
+detectorVarArgsProblems=VarArgsProblems|true
+detectorVolatileUsage=VolatileUsage|true
+detectorWaitInLoop=WaitInLoop|true
+detectorWrongMapIterator=WrongMapIterator|true
+detectorXMLFactoryBypass=XMLFactoryBypass|true
+detector_threshold=2
+effort=default
+filter_settings=Medium|BAD_PRACTICE,CORRECTNESS,MT_CORRECTNESS,PERFORMANCE,STYLE|false
+filter_settings_neg=MALICIOUS_CODE,NOISE,I18N,SECURITY,EXPERIMENTAL|
+run_at_full_build=true

Added: trunk/step-dataloader/.project
===================================================================
--- trunk/step-dataloader/.project	                        (rev 0)
+++ trunk/step-dataloader/.project	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-dataloader</name>
+	<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature>
+	</natures>
+</projectDescription>

Added: trunk/step-dataloader/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-dataloader/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-dataloader/.settings/org.eclipse.jdt.core.prefs	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,10 @@
+#Mon Apr 05 11:59:37 BST 2010
+eclipse.preferences.version=1
+encoding//src/main/java=iso-8859-1
+encoding//src/main/resources=iso-8859-1
+encoding//src/test/java=iso-8859-1
+encoding//src/test/resources=iso-8859-1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.source=1.5

Added: trunk/step-dataloader/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-dataloader/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-dataloader/.settings/org.maven.ide.eclipse.prefs	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,9 @@
+#Mon Apr 05 11:59:34 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-dataloader/pom.xml
===================================================================
--- trunk/step-dataloader/pom.xml	                        (rev 0)
+++ trunk/step-dataloader/pom.xml	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,75 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<parent>
+		<groupId>com.tyndalehouse</groupId>
+		<artifactId>step-parent</artifactId>
+		<version>1.0-SNAPSHOT</version>
+		<relativePath>..</relativePath>
+	</parent>
+
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-dataloader</artifactId>
+	<packaging>jar</packaging>
+	<name>step-dataloader</name>
+
+	<build>
+		<plugins>
+			<plugin>
+				<groupId>org.codehaus.mojo</groupId>
+				<artifactId>exec-maven-plugin</artifactId>
+				<configuration>
+					<mainClass>com.tyndalehouse.step.dataloader.Dataloader</mainClass>
+					<systemProperties>
+						<systemProperty>
+							<key>db.location</key>
+							<value>${db.directory}</value>
+						</systemProperty>
+					</systemProperties>
+					<classpathScope>runtime</classpathScope>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+
+	<dependencies>
+
+		<dependency>
+			<groupId>org.crosswire</groupId>
+			<artifactId>jsword</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-dbutils</groupId>
+			<artifactId>commons-dbutils</artifactId>
+			<version>1.3</version>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>commons-lang</groupId>
+			<artifactId>commons-lang</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>net.sf.opencsv</groupId>
+			<artifactId>opencsv</artifactId>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derbyclient</artifactId>
+			<scope>runtime</scope>
+		</dependency>
+
+		<dependency>
+			<groupId>org.apache.derby</groupId>
+			<artifactId>derby</artifactId>
+		</dependency>
+
+	</dependencies>
+</project>

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/ClientDbProvider.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,31 @@
+package com.tyndalehouse.step.dataloader;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class ClientDbProvider {
+	//TODO: shove this in a properties file
+	private static String clientConnection = "jdbc:derby:";
+	private static Connection connection = null;
+	
+	public static Connection getConnection(String dbPath) throws SQLException {
+		if(connection == null) {
+			String connectionString = clientConnection + dbPath + ";create=true";
+			System.out.println("Using connection string: " + connectionString);
+			connection = DriverManager.getConnection(connectionString);
+		}
+		
+		return connection;
+	}
+
+	public static void finaliseConnection(Connection connection) throws SQLException {
+		if(connection != null && !connection.isClosed()) {
+			connection.close();
+		}
+	}
+
+	public static Connection getConnection() {
+		return connection;
+	}
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/Dataloader.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,41 @@
+package com.tyndalehouse.step.dataloader;
+
+import java.io.IOException;
+import java.sql.SQLException;
+import java.util.Calendar;
+
+import org.apache.commons.dbutils.DbUtils;
+import org.crosswire.jsword.passage.NoSuchKeyException;
+
+import com.tyndalehouse.step.dataloader.common.DateParsingException;
+import com.tyndalehouse.step.dataloader.loaders.SchemaLoader;
+import com.tyndalehouse.step.dataloader.loaders.TimelineLoader;
+
+public class Dataloader {
+	public static void main(String args[]) throws SQLException, ClassNotFoundException, IOException, DateParsingException, NoSuchKeyException {
+		if(System.getProperty("driver") != null) {
+			DbUtils.loadDriver(System.getProperty("org.apache.derby.jdbc.ClientDriver"));
+		} else {
+			DbUtils.loadDriver("org.apache.derby.jdbc.EmbeddedDriver");	
+		}
+	
+		SchemaLoader sl = new SchemaLoader();
+		TimelineLoader tl = new TimelineLoader();
+	
+		
+		
+		
+		long startTime= Calendar.getInstance().getTimeInMillis();
+
+		sl.recreateAll();
+		long currentTime = Calendar.getInstance().getTimeInMillis();
+		System.out.println("Took " + (currentTime-startTime ) + "ms to create schema");
+		startTime = currentTime;
+		tl.loadData();
+		
+		currentTime = Calendar.getInstance().getTimeInMillis();
+		System.out.println("Took " + (currentTime-startTime ) + "ms to load data");
+			
+	}
+
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/DbBean.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/DbBean.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/DbBean.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,60 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import org.apache.commons.lang.StringEscapeUtils;
+import org.apache.commons.lang.StringUtils;
+
+public class DbBean {
+	public void appendString(StringBuffer sb, String value) {
+		if(StringUtils.isEmpty(value)) {
+			sb.append("null");
+		} else {
+			sb.append(getDbString(value));
+		}
+	}	
+
+	public void appendString(StringBuffer sb, char value) {
+		sb.append(getDbString(value));
+	}	
+
+	
+	//TODO: so much string manipulation here, need to rewrite properly at some point!
+	protected void appendString(StringBuffer event, Calendar date) {
+		if(date == null) {
+			event.append("null");
+		} else {
+			event.append(getDbDate(date));
+		}
+		
+	}
+
+	//TODO: shocking, this could be done much much better...
+	protected String getDbDate(Calendar date) {
+		StringBuffer sb = new StringBuffer();
+		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
+		
+		sb.append('\'')
+			.append(StringEscapeUtils.escapeSql(sdf.format(date.getTime())))
+			.append('\'');
+		
+		return sb.toString();
+		
+	}
+
+	public static String getDbString(Object value) {
+		StringBuffer sb = new StringBuffer();
+		
+		sb.append('\'')
+			.append(StringEscapeUtils.escapeSql(value.toString()))
+			.append('\'');
+		
+		return sb.toString();
+	}
+	
+	public void appendComma(StringBuffer event) {
+		event.append(", ");
+	}
+
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/EventTypeBean.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/EventTypeBean.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/EventTypeBean.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,52 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+public class EventTypeBean extends DbBean {
+	private final int eventTypeId;
+	private final String eventType;
+	private final String eventTypeDescription;
+
+	public EventTypeBean(int id, String eventType, String eventDescription) {
+		this.eventTypeId = id;
+		this.eventType = eventType;
+		this.eventTypeDescription = eventDescription;	
+	}
+
+	/**
+	 * @return the id
+	 */
+	public int getEventTypeId() {
+		return eventTypeId;
+	}
+
+	/**
+	 * @return the eventType
+	 */
+	public String getEventTypeCode() {
+		return eventType;
+	}
+
+	/**
+	 * @return the eventDescription
+	 */
+	public String getEventTypeDescription() {
+		return eventTypeDescription;
+	}
+
+	/**
+	 * returns the insert statement to fill up the event_type table
+	 * @return the insert statement
+	 */
+	public String getInsertStatement() {
+		StringBuffer statement = new StringBuffer();
+		statement.append("insert into step.event_type(event_type_id, event_code, event_description) values(")
+			.append(getEventTypeId())
+			.append(", ")
+			.append(getDbString(getEventTypeCode()))			
+			.append(", ")
+			.append(getDbString(getEventTypeDescription()))
+			.append(");");
+		
+		return statement.toString();
+
+	}
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PartialDate.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PartialDate.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PartialDate.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,123 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+import java.text.ParseException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.apache.commons.lang.StringUtils;
+
+import com.tyndalehouse.step.dataloader.common.DateParsingException;
+
+/**
+ * This class is the way dates are represented in the databased
+ * and they should be parsed back into this object on their way out!
+ * 
+ * The date field indicates when the event (or start of the event) took 
+ * place, the precision type indicates whether how much of the date
+ * can be trusted...
+ * 
+ * This means we can store dates such as (01/03/1900, MONTH), meaning
+ * March 1900 (and not 1st March 1900).
+ * @author CJBurrell
+ */
+public class PartialDate {
+	/**
+	 * The date to be represented (whether fully accurate or not)
+	 */
+	private final Calendar c;
+	
+	/**
+	 * The precision specifier which tells us just quite
+	 * how accurate the date is (year, month, day)
+	 * @see com.tyndalehouse.step.dataloader.beans.PrecisionType
+	 */
+	private final PrecisionType precision;
+
+	/**
+	 * Public constructor to give us a partial date.
+	 * @param c date partial reprentation of a date
+	 * @param precision precision indicating how much of the 
+	 * date can be trusted day/month/year or month/year or just year
+	 */
+	public PartialDate(final Calendar c, final PrecisionType precision) {
+		this.c = c;
+		this.precision = precision;
+	}
+	
+	/**
+	 * Date is specified in yy-mm-dd or yyyy-mm-dd and gets parsed in to a date.
+	 * the mm and dd are optional which is what determines the precision of the date.
+	 * @param date date to be parsed as a string
+	 * @param delimiter delimiter in the date, say a - or a /
+	 * @return a PartialDate
+	 * @throws ParseException an error during the parsing of the date
+	 */
+	public static PartialDate parseDate(final String date, char delimiter) throws DateParsingException {
+		String[] parts;
+		Calendar c = Calendar.getInstance();
+		PrecisionType p;
+		int yearSign = 1;										// -1 for negative
+		
+		//if passed in empty, return null and be done with empty strings!
+		if(StringUtils.isEmpty(date)) {
+			return new PartialDate(null, PrecisionType.NONE);
+		}
+		
+		//the date might start with a dash, so best not to split and do it character by character?
+		if(date.charAt(0) == '-') {
+			yearSign = -1;
+			
+			//check we have more than one character left after substring:
+			if(date.length() < 2) {
+				throw new DateParsingException("The date " + date + " was not long enough.");
+			}
+		
+			//split the remainder of the date into parts
+			parts = date.substring(1).trim().split("" + delimiter);	// ignore first character
+		} else {
+ 			parts = date.trim().split(""+delimiter);
+		}
+		
+		try {
+			//length of field determines how much of the date has been specified
+			switch(parts.length) {
+				case 0: throw new DateParsingException("The date " + date + " could not be parsed.");
+				case 1:
+					//only the year is specified, so use 1st of Jan Year
+					c.set(Integer.parseInt(parts[0]), 1, 1);
+					p = PrecisionType.YEAR;
+					if(yearSign == -1) { c.set(Calendar.ERA, GregorianCalendar.BC); }
+					c.set(Calendar.HOUR_OF_DAY, 0);
+					c.set(Calendar.MINUTE, 0);
+					break;
+				case 2: 
+					c.set(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), 1);
+					p = PrecisionType.MONTH;
+					break;
+				case 3:
+					c.set(Integer.parseInt(parts[0]), Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
+					p = PrecisionType.DAY;
+					break;
+				default: throw new DateParsingException("Too many parts to the date: " + date);
+					
+			}
+		} catch(NumberFormatException nfe) {
+			throw new DateParsingException("Could not parse date into year, month or day.");
+		}
+
+		c.set(Calendar.HOUR_OF_DAY, 0);
+		c.set(Calendar.MINUTE, 0);
+		if(yearSign == -1) { c.set(Calendar.ERA, GregorianCalendar.BC); }
+		return new PartialDate(c, p);
+	}
+
+	public Calendar getDate() {
+		return c;
+	}
+	
+	public PrecisionType getPrecision() {
+		return precision;
+	}
+}
+
+

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PrecisionType.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PrecisionType.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/PrecisionType.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,44 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+public enum PrecisionType {
+	/**
+	 * This means the associated date is only meaningful until the year
+	 */
+	YEAR ('Y'),
+	
+	/**
+	 * This means the month and year are to be taken as accurate 
+	 */
+	MONTH ('M'),
+	
+	/**
+	 * The day, month and year are accurate
+	 */
+	DAY ('D'),
+	
+	//TODO: should this actually be null that goes into the database? probably yes...
+	/**
+	 * No date available so, we'll set to none.
+	 */
+	NONE ('N')
+	; 
+	
+	/**
+	 * precision type
+	 */
+	private final char pt;
+
+	private PrecisionType(char pt) {
+		this.pt = pt;
+		
+	}
+
+	/**
+	 * @return the pt
+	 */
+	public char getShortCode() {
+		return pt;
+	}
+	
+	
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TargetTypeEnum.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TargetTypeEnum.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TargetTypeEnum.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,17 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+public enum TargetTypeEnum {
+	TIMELINE_EVENT(1);
+	
+	private final int id;
+
+	TargetTypeEnum(int id) {
+		this.id = id;
+		
+	}
+	
+	public int getId() {
+		return id;
+	}
+	
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineBean.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineBean.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineBean.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,71 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+/**
+ * Timeline bean represents the different timelines on which events can be found...
+ * @author CJBurrell
+ *
+ */
+public class TimelineBean extends DbBean {
+	private final int timelineId;
+	private final String timelineDescription;
+	private final String timelineCode;
+	
+	public TimelineBean(int timelineId, String timelineDescription, String timelineCode) {
+		this.timelineId = timelineId;
+		this.timelineDescription = timelineDescription;
+		this.timelineCode = timelineCode;
+	}
+	
+	/**
+	 * @return the timelineId
+	 */
+	public int getTimelineId() {
+		return timelineId;
+	}
+
+	/**
+	 * @return the timelineDescription
+	 */
+	public String getTimelineDescription() {
+		return timelineDescription;
+	}
+
+	/**
+	 * @return the timelineCode
+	 */
+	public String getTimelineCode() {
+		return timelineCode;
+	}
+
+	public String getInsertStatement() {
+		StringBuffer statement = new StringBuffer();
+		statement.append("insert into step.timeband(timeband_id, timeband_code, timeband_description) values(")
+			.append(getTimelineId())
+			.append(", ")
+			.append(getDbString(getTimelineCode()))			
+			.append(", ")
+			.append(getDbString(getTimelineDescription()))
+			.append(");");
+		
+		return statement.toString();
+	}
+
+	/**
+	 * TODO: this is a bit hacky. make it with the own POJO
+	 * @return
+	 */
+	public String getSubTimebandInsertStatement() {
+		StringBuffer statement = new StringBuffer();
+		statement.append("insert into step.sub_timeband(sub_timeband_id, sub_timeband_code, sub_timeband_description) values(")
+			.append(getTimelineId())
+			.append(", ")
+			.append(getDbString(getTimelineCode()))			
+			.append(", ")
+			.append(getDbString(getTimelineDescription()))
+			.append(");");
+		
+		return statement.toString();
+	}
+}
+
+

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineEventBean.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineEventBean.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/beans/TimelineEventBean.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,265 @@
+package com.tyndalehouse.step.dataloader.beans;
+
+
+//TODO: Refactor eventually so use as we load data out of the database...
+public class TimelineEventBean extends DbBean {
+	private String ID;	
+	private String name;	
+	private String from;
+	private String to;	
+	private String from2;	
+	private String to2;
+	private String importance;	
+	private String certainty;	
+	private String flags;
+	private String timeline;	
+	private String type;
+	private String description;	
+	private String refs;
+	private String source;
+	private String notes;
+	private String timebandId;
+
+	private static final String alternativeDateInsertStatement = "insert into step.alternative_date" +
+			"(event_id, from_date, to_date, from_date_precision, to_date_precision) values" +
+			"(?,?,?,?,?)";
+	
+	private static final String eventInsert = "insert into step.event(" +
+		"event_id, event_text_id, name, from_date, to_date, from_precision, to_precision, timeband_id, sub_timeband_id, importance_id, certainty, " +
+		"flags, event_type_id, description, source, notes) values(" +
+		"?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
+	
+	private static final String scriptureReferenceInsertStatement = "insert into scripture_reference(" +
+			"target_id, target_type, start_verse_id, end_verse_id) values (?, ?, ?, ?)";
+	
+	/*create table scripture_reference (
+	target_id						int,
+	target_type						int,
+	verse_id						int
+
+);*/
+	
+	public static String getInsertStatement() {
+		return eventInsert;
+	}
+
+
+
+
+
+	/**
+	 * @return the notes
+	 */
+	public String getNotes() {
+		return notes;
+	}
+	/**
+	 * @param notes the notes to set
+	 */
+	public void setNotes(String notes) {
+		this.notes = notes;
+	}
+	/**
+	 * @return the iD
+	 */
+	public String getID() {
+		return ID;
+	}
+	/**
+	 * @param id the iD to set
+	 */
+	public void setID(String id) {
+		ID = id;
+	}
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+	/**
+	 * @param name the name to set
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+	/**
+	 * @return the from
+	 */
+	public String getFrom() {
+		return from;
+	}
+	/**
+	 * @param from the from to set
+	 */
+	public void setFrom(String from) {
+		this.from = from;
+	}
+	/**
+	 * @return the to
+	 */
+	public String getTo() {
+		return to;
+	}
+	/**
+	 * @param to the to to set
+	 */
+	public void setTo(String to) {
+		this.to = to;
+	}
+	/**
+	 * @return the from2
+	 */
+	public String getFrom2() {
+		return from2;
+	}
+	/**
+	 * @param from2 the from2 to set
+	 */
+	public void setFrom2(String from2) {
+		this.from2 = from2;
+	}
+	/**
+	 * @return the to2
+	 */
+	public String getTo2() {
+		return to2;
+	}
+	/**
+	 * @param to2 the to2 to set
+	 */
+	public void setTo2(String to2) {
+		this.to2 = to2;
+	}
+	/**
+	 * @return the importance
+	 */
+	public String getImportance() {
+		return importance;
+	}
+	/**
+	 * @param importance the importance to set
+	 */
+	public void setImportance(String importance) {
+		this.importance = importance;
+	}
+	/**
+	 * @return the certainty
+	 */
+	public String getCertainty() {
+		return certainty;
+	}
+	/**
+	 * @param certainty the certainty to set
+	 */
+	public void setCertainty(String certainty) {
+		this.certainty = certainty;
+	}
+	/**
+	 * @return the flags
+	 */
+	public String getFlags() {
+		return flags;
+	}
+	/**
+	 * @param flags the flags to set
+	 */
+	public void setFlags(String flags) {
+		this.flags = flags;
+	}
+	/**
+	 * @return the timeline
+	 */
+	public String getTimeline() {
+		return timeline;
+	}
+	/**
+	 * @param timeline the timeline to set
+	 */
+	public void setTimeline(String timeline) {
+		this.timeline = timeline;
+	}
+	/**
+	 * @return the type
+	 */
+	public String getType() {
+		return type;
+	}
+	/**
+	 * @param type the type to set
+	 */
+	public void setType(String type) {
+		this.type = type;
+	}
+	/**
+	 * @return the description
+	 */
+	public String getDescription() {
+		return description;
+	}
+	/**
+	 * @param description the description to set
+	 */
+	public void setDescription(String description) {
+		this.description = description;
+	}
+	/**
+	 * @return the refs
+	 */
+	public String getRefs() {
+		return refs;
+	}
+	/**
+	 * @param refs the refs to set
+	 */
+	public void setRefs(String refs) {
+		this.refs = refs;
+	}
+	/**
+	 * @return the source
+	 */
+	public String getSource() {
+		return source;
+	}
+	/**
+	 * @param source the source to set
+	 */
+	public void setSource(String source) {
+		this.source = source;
+	}
+
+
+
+	/**
+	 * @return the timeband_id
+	 */
+	public String getTimebandId() {
+		return timebandId;
+	}
+
+
+
+
+
+	/**
+	 * @param timebandId the timeband_id to set
+	 */
+	public void setTimebandId(String timebandId) {
+		this.timebandId = timebandId;
+	}
+
+
+
+	public static String getAlternativeDateStatement() {
+		return alternativeDateInsertStatement;
+	}
+
+
+
+
+	//TODO: move this out to a seperate logical unit
+	public static String getScriptureReferenceStatement() {
+		return scriptureReferenceInsertStatement;
+	}
+	
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common/DateParsingException.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common/DateParsingException.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/common/DateParsingException.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,23 @@
+package com.tyndalehouse.step.dataloader.common;
+
+public class DateParsingException extends Exception {
+
+	/**
+	 * generated serial version UID
+	 */
+	private static final long serialVersionUID = -5685008606295145634L;
+	private final String message;
+
+	public DateParsingException(final String message) {
+		this.message = message;
+	}
+
+	/**
+	 * @return the message
+	 */
+	public String getMessage() {
+		return message;
+	}
+	
+	
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/AbstractLoader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/AbstractLoader.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/AbstractLoader.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,65 @@
+package com.tyndalehouse.step.dataloader.loaders;
+
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.apache.commons.dbutils.QueryRunner;
+import org.apache.commons.io.IOUtils;
+
+import com.tyndalehouse.step.dataloader.ClientDbProvider;
+
+public abstract class AbstractLoader {
+	final protected Connection c;
+	
+	public AbstractLoader() throws SQLException {
+		
+		c = ClientDbProvider.getConnection(System.getProperty("db.location"));
+	}
+	
+
+	protected void executeFile(final String filename) throws IOException, SQLException {
+		executeFile(filename, false);
+	}
+	
+	//TODO: there must be a better way, since at the moment it doesn't cope with 
+	// semi colons in the sql file comments., nor i guess in default values and so on...
+	protected void executeFile(final String filename, boolean allowErrors) throws IOException, SQLException {
+		String sql = IOUtils.toString(getClass().getResourceAsStream((filename)));
+		runSQLText(sql, allowErrors);
+	}
+
+	protected void executeSQLText(final String sqlText)  throws SQLException {
+		runSQLText(sqlText, false);
+	}
+	
+	protected void runSQLText(final String sqlText, boolean allowErrors) throws SQLException {
+		QueryRunner qr = new QueryRunner();
+				
+		String[] statements = sqlText.split(";");
+		for(String s : statements) {
+			if(s.trim().length() != 0) {
+				try {
+					qr.update(c, s.replace("\n", " "));
+				} catch(SQLException ex) {
+					System.err.println(ex.getMessage());
+					if(!allowErrors) {
+						throw ex;
+					}
+				}
+			}
+		}
+	}
+	
+	protected void error(String errorMsg) {
+		error(errorMsg, true);
+	}
+
+	private void error(String errorMsg, boolean exit) {
+		System.out.println("errorMsg");
+		if(exit) {
+			System.exit(-1);
+		}
+	}
+
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/SchemaLoader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/SchemaLoader.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/SchemaLoader.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.dataloader.loaders;
+
+import java.io.IOException;
+import java.sql.SQLException;
+
+
+public class SchemaLoader extends AbstractLoader {
+	
+	public SchemaLoader() throws SQLException {
+		super();
+	}
+	
+	public SchemaLoader recreateAll() throws IOException, SQLException {
+		//delete database first
+		//the recreate
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/create/1.schema.sql", true);
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/create/2.scripture_referencing.sql");
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/create/3.timeline.sql");
+		return this;
+	}
+
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/TimelineLoader.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/TimelineLoader.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/loaders/TimelineLoader.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,377 @@
+package com.tyndalehouse.step.dataloader.loaders;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.crosswire.jsword.passage.KeyFactory;
+import org.crosswire.jsword.passage.NoSuchKeyException;
+import org.crosswire.jsword.passage.NoSuchVerseException;
+import org.crosswire.jsword.passage.PassageKeyFactory;
+import org.crosswire.jsword.passage.RestrictionType;
+import org.crosswire.jsword.passage.RocketPassage;
+import org.crosswire.jsword.passage.Verse;
+import org.crosswire.jsword.passage.VerseRange;
+
+import au.com.bytecode.opencsv.CSVReader;
+import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;
+import au.com.bytecode.opencsv.bean.CsvToBean;
+
+import com.tyndalehouse.step.dataloader.beans.EventTypeBean;
+import com.tyndalehouse.step.dataloader.beans.PartialDate;
+import com.tyndalehouse.step.dataloader.beans.TargetTypeEnum;
+import com.tyndalehouse.step.dataloader.beans.TimelineBean;
+import com.tyndalehouse.step.dataloader.beans.TimelineEventBean;
+import com.tyndalehouse.step.dataloader.common.DateParsingException;
+
+public class TimelineLoader extends AbstractLoader {
+	private HashMap<String, TimelineBean> subTimebands;
+	private HashMap<String, TimelineBean> timebands;
+	private HashMap<String, EventTypeBean> eventTypes;
+
+	public TimelineLoader() throws SQLException {
+		super();
+	}
+
+	/**
+	 * Reads the timeline directory into beans...
+	 * 
+	 * @param directoryPath
+	 *            directory path
+	 * @throws FileNotFoundException
+	 *             the directory specified was not found
+	 * @throws IOException
+	 *             an error occured while reading the data
+	 */
+	private List<TimelineEventBean> readDataFromTimelineDirectory(String directoryPath) throws FileNotFoundException, IOException {
+		File directory = new File(directoryPath);
+
+		if (!directory.isDirectory()) {
+			error("The directory specified is not a valid directory");
+		}
+
+		// then get list of files in directory
+		File[] listOfFiles = directory.listFiles(new FileFilter() {
+
+			public boolean accept(File file) {
+				if (!file.getName().endsWith(".csv")) {
+					return false;
+				}
+				return true;
+			}
+		});
+
+		List<TimelineEventBean> events = new ArrayList<TimelineEventBean>();
+		int count = 0;
+
+
+		for (File f : listOfFiles) {
+			// TODO: use log4j
+			CSVReader reader = new CSVReader(new FileReader(f));	
+			reader.readNext();
+			ColumnPositionMappingStrategy<TimelineEventBean> mappings = new ColumnPositionMappingStrategy<TimelineEventBean>();
+			mappings.setType(TimelineEventBean.class);
+			mappings.captureHeader(reader);
+			mappings.setColumnMapping(new String[] { "ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes" });
+			
+			CsvToBean<TimelineEventBean> csv = new CsvToBean<TimelineEventBean>();
+			
+			List<TimelineEventBean> beans = csv.parse(mappings, reader);
+			
+			for(TimelineEventBean tb : beans) {
+				tb.setTimebandId(f.getName().substring(0, f.getName().length()-4));
+			}
+			count += beans.size();
+			events.addAll(beans);
+		}
+		System.out.println(String.format("Read %d events", count));
+
+		return events;
+	}
+
+	/**
+	 * Adds the timeline to the hashmap passed in, assuming it is not already in
+	 * there This is just a helper function really
+	 * 
+	 * @param subTimebandCode
+	 */
+	public void addSubTimebandIfNotExists(final String subTimebandCode) {
+		if(subTimebandCode == null) {
+			//do nothing, it is not attached to a subtimeband or an importance
+			return;
+		}
+		
+		if (!subTimebands.containsKey(subTimebandCode)) {
+			// debatable as to whether or not we want to set the id here...
+			TimelineBean tb = new TimelineBean(subTimebands.size() + 1, subTimebandCode, subTimebandCode);
+			subTimebands.put(subTimebandCode, tb);
+		}
+	}
+
+	/**
+	 * Adds the timeline to the hashmap passed in, assuming it is not already in
+	 * there This is just a helper function really
+	 * 
+	 * @param timelineCode
+	 */
+	public void addTimebandIfNotExists(final String timelineCode) {
+		if (!timebands.containsKey(timelineCode)) {
+			// debatable as to whether or not we want to set the id here...
+			TimelineBean tb = new TimelineBean(timebands.size() + 1, timelineCode, timelineCode);
+			timebands.put(timelineCode, tb);
+		}
+	}
+	
+	private void addEventTypeIfNotExists(final String eventType) {
+		if (!eventTypes.containsKey(eventType)) {
+			// debatable as to whether or not we want to set the id here...
+			EventTypeBean tb = new EventTypeBean(eventTypes.size() + 1, eventType, eventType);
+			eventTypes.put(eventType, tb);
+		}
+	}
+
+	/**
+	 * main entry function to read in the timeline data into the database
+	 * 
+	 * @param directoryPath
+	 *            path to the timeline directory
+	 * @throws SQLException
+	 *             sql exception occuring when trying to load the data
+	 * @throws IOException
+	 *             unable to read the timeline from the disk
+	 * @throws NoSuchKeyException
+	 * @throws ParseException
+	 *             unable to parse dates contained in timeline source files
+	 */
+	public void loadData() throws SQLException, IOException, DateParsingException, NoSuchKeyException {
+		String directoryPath = getClass().getResource("/data/timeline").getPath();
+		List<TimelineEventBean> events = readDataFromTimelineDirectory(directoryPath);
+
+		// first parse - get all the different timeline and populate timeline
+		// table  also add what's in the importance field in case it's not there already		
+		cleanupInputFile(events);
+		
+		populateTimebandTable(events);
+		populateSubTimebandTable(events);
+		populateEventTypeTable(events);
+		populateEventsTable(events);
+		executeTimebandUnitUpdates();
+	}
+
+	/** 
+	 * If the importance field or subtimeband field are empty, then set to null
+	 * @param events
+	 */
+	private void cleanupInputFile(List<TimelineEventBean> events) {
+		for(int ii = 0; ii < events.size(); ii++) {
+			TimelineEventBean teb = events.get(ii);
+			if(teb.getTimeline() != null && 
+					(teb.getTimeline().equals("-") ||
+					teb.getTimeline().equals(" "))) {
+				events.remove(ii);
+			
+				//readjust ii, so that we're looking at the next event
+				ii--;
+			} else if(teb.getTimeline() != null && teb.getTimeline().length() == 0) {
+				teb.setTimeline(null);
+			} else if(teb.getImportance() != null && teb.getImportance().length() == 0) {
+				teb.setImportance(null);
+			}
+		}
+	}
+
+	private void executeTimebandUnitUpdates() throws IOException, SQLException {
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/data/1.timeband_units.sql");
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/data/2.timeband_setup.sql");
+		executeFile("/sql/com/tyndalehouse/step/dataloader/sql/data/3.sub_timeband_units.sql");
+	}
+
+	private void setDate(PreparedStatement ps, int index, PartialDate d) throws SQLException {
+		if (d == null || d.getDate() == null) {
+			ps.setNull(index, Types.BIGINT);
+		} else {
+			ps.setLong(index, d.getDate().getTimeInMillis());
+		}
+	}
+
+	private void setString(PreparedStatement ps, int index, String value) throws SQLException {
+		if (value == null || value.length() == 0) {
+			ps.setNull(index, Types.VARCHAR);
+		} else {
+			ps.setString(index, value);
+		}
+	}
+
+	/**
+	 * sets a nullable integer
+	 * @param ps prepared statement
+	 * @param index, the index of the parameter
+	 * @param value the value
+	 * @throws SQLException
+	 */
+	private void setInt(PreparedStatement ps, int index, Integer value) throws SQLException {
+		if (value == null) {
+			ps.setNull(index, Types.INTEGER);
+		} else {
+			ps.setInt(index, value);
+		}
+	}
+
+	// TODO: all foreign key constraint, indexes and checks
+	// TODO: Rewrite to get rid of all the parameter indexes. It should be
+	// feasible to give a bunch
+	// of things to a function, and it add it to the right function.
+	private void populateEventsTable(List<TimelineEventBean> events) throws SQLException, DateParsingException, NoSuchKeyException {
+		PreparedStatement timelineInsert = c.prepareStatement(TimelineEventBean.getInsertStatement());
+		PreparedStatement alternativeDates = c.prepareStatement(TimelineEventBean.getAlternativeDateStatement());
+		PreparedStatement scriptureReferences = c.prepareStatement(TimelineEventBean.getScriptureReferenceStatement());
+		RocketPassage rp = null;
+		int currentId = 1;
+
+		// set up the key factory once
+		KeyFactory keyFactory = PassageKeyFactory.instance();
+
+		try {
+			for (TimelineEventBean event : events) {
+				// System.out.println(event.getName() + " " + event.getID() +
+				// " " + event.getTimeline());
+				int timelineParameterIndex = 1;
+				int alternativeDateParameterIndex = 1;
+
+				PartialDate from = PartialDate.parseDate(event.getFrom(), '-');
+				PartialDate to = PartialDate.parseDate(event.getTo(), '-');
+
+				timelineInsert.setInt(timelineParameterIndex++, currentId);
+				setString(timelineInsert, timelineParameterIndex++, event.getID()); // event_text_id
+				setString(timelineInsert, timelineParameterIndex++, event.getName()); // name
+				setDate(timelineInsert, timelineParameterIndex++, from); // from_date
+				setDate(timelineInsert, timelineParameterIndex++, to); // to_date
+				setString(timelineInsert, timelineParameterIndex++, "" + from.getPrecision().getShortCode()); // from_precision
+				setString(timelineInsert, timelineParameterIndex++, "" + to.getPrecision().getShortCode()); // to_precision
+				timelineInsert.setInt(timelineParameterIndex++, timebands.get(event.getTimebandId()).getTimelineId()); // timeband_id
+				timelineInsert.setInt(timelineParameterIndex++, subTimebands.get(event.getTimeline()).getTimelineId()); // timeband_id
+				setInt(timelineInsert, timelineParameterIndex++, event.getImportance() == null ? null : subTimebands.get(event.getImportance()).getTimelineId()); // importance_id
+				setString(timelineInsert, timelineParameterIndex++, event.getCertainty()); // certainty
+				setString(timelineInsert, timelineParameterIndex++, event.getFlags()); // flags
+				timelineInsert.setInt(timelineParameterIndex++, eventTypes.get(event.getType()).getEventTypeId()); // event_type_id
+				setString(timelineInsert, timelineParameterIndex++, event.getDescription()); // description
+				setString(timelineInsert, timelineParameterIndex++, event.getSource()); // source
+				setString(timelineInsert, timelineParameterIndex++, event.getNotes()); // notes
+
+				// Now do the alternative dates bit
+				PartialDate from2 = PartialDate.parseDate(event.getFrom2(), '-');
+				PartialDate to2 = PartialDate.parseDate(event.getTo2(), '-');
+				timelineInsert.addBatch();
+
+				//TODO: bug - alternative dates aren't being pulled through at the moment, due to the condition clause
+				//which is inverted.
+				if (from2.getDate() == null && to2.getDate() == null) {
+					// set event_id from previous timeline insert
+					alternativeDates.setInt(alternativeDateParameterIndex++, currentId);
+					setDate(alternativeDates, alternativeDateParameterIndex++, from2); // from_date
+					setDate(alternativeDates, alternativeDateParameterIndex++, to2); // to_date
+					setString(alternativeDates, alternativeDateParameterIndex++, "" + from2.getPrecision().getShortCode()); // from_precision
+					setString(alternativeDates, alternativeDateParameterIndex++, "" + to2.getPrecision().getShortCode()); // to_precision
+					alternativeDates.addBatch();
+				}
+
+				// now do the insert into scripture bit!
+				if (event.getRefs() != null && event.getRefs().length() != 0) {
+					try {
+						rp = (RocketPassage) keyFactory.getKey(event.getRefs());
+						for (int ii = 0; ii < rp.countRanges(RestrictionType.NONE); ii++) {
+							VerseRange vr = rp.getRangeAt(ii, RestrictionType.NONE);
+							Verse start = vr.getStart();
+							Verse end = vr.getEnd();
+
+							int startVerseId = start.getOrdinal();
+							int endVerseId = end.getOrdinal();
+
+							scriptureReferences.setInt(1, currentId);
+							scriptureReferences.setInt(2, TargetTypeEnum.TIMELINE_EVENT.getId());
+							scriptureReferences.setInt(3, startVerseId);
+							scriptureReferences.setInt(4, endVerseId);
+							scriptureReferences.addBatch();
+						}
+					} catch(NoSuchVerseException nsve) {
+						//Nehemiah 6.20 might not exist for example...
+						//TODO: proper logging
+						System.err.println(event.getRefs() + " => " + nsve.getMessage());
+						}
+				}
+				currentId++;
+			}
+
+			timelineInsert.executeBatch();
+			alternativeDates.executeBatch();
+			scriptureReferences.executeBatch();
+		} catch (SQLException ex) {
+			// TODO: get some proper logging framework in there...
+			// output warnings here...
+			System.err.println(ex.getMessage());
+			ex.printStackTrace();
+
+		}
+	}
+
+	/**
+	 * populates the timeline table, ie. the different timelines
+	 * 
+	 * @param events
+	 *            the list of all the events to be uploaded.
+	 * @throws SQLException
+	 *             error running the sql statement
+	 */
+	private void populateTimebandTable(final List<TimelineEventBean> events) throws SQLException {
+		timebands = new HashMap<String, TimelineBean>();
+
+		for (TimelineEventBean event : events) {
+			addTimebandIfNotExists(event.getTimebandId());
+		}
+
+		for (TimelineBean timeline : timebands.values()) {
+			executeSQLText(timeline.getInsertStatement());
+		}
+	}
+
+	/**
+	 * populates the sub timeband table in a similar way to above
+	 * @param events
+	 * @throws SQLException
+	 */
+	private void populateSubTimebandTable(final List<TimelineEventBean> events) throws SQLException {
+		subTimebands = new HashMap<String, TimelineBean>();
+
+		for (TimelineEventBean event : events) {
+			addSubTimebandIfNotExists(event.getTimeline());
+			addSubTimebandIfNotExists(event.getImportance());
+		}
+
+		for (TimelineBean timeline : subTimebands.values()) {
+			executeSQLText(timeline.getSubTimebandInsertStatement());
+			//TODO: in any case this is poor as not using prepared statement
+		}
+	}
+	
+	private void populateEventTypeTable(List<TimelineEventBean> events) throws SQLException {
+		eventTypes = new HashMap<String, EventTypeBean>();
+
+		for (TimelineEventBean event : events) {
+			addEventTypeIfNotExists(event.getType());
+		}
+
+		for (EventTypeBean eventType : eventTypes.values()) {
+			executeSQLText(eventType.getInsertStatement());
+			//TODO: in any case this is poor as not using prepared statement
+		}
+	}
+}

Added: trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils/DerbyUtils.java
===================================================================
--- trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils/DerbyUtils.java	                        (rev 0)
+++ trunk/step-dataloader/src/main/java/com/tyndalehouse/step/dataloader/utils/DerbyUtils.java	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,31 @@
+package com.tyndalehouse.step.dataloader.utils;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import com.tyndalehouse.step.dataloader.ClientDbProvider;
+
+
+public class DerbyUtils {
+	
+	//TODO: optimize: creating a new connection each time sounds like a waste of time...
+	public static void dropIfExists(String tableName) throws SQLException {
+		//Connection conn = DriverManager.getConnection("jdbc:default:connection");
+		Connection conn = ClientDbProvider.getConnection();
+		
+		PreparedStatement exists = conn.prepareStatement("select count(*) from sys.systables where tablename = upper('" + tableName + "')");
+		ResultSet exRs = exists.executeQuery();
+		
+		exRs.next();
+		//get count out:
+		int count = exRs.getInt(1);
+		if(count > 0) {
+			//System.out.println("Dropping table " + tableName);
+			PreparedStatement s = conn.prepareStatement("drop table " + tableName);	
+			s.executeUpdate();
+		}		
+		//conn.close();
+	}
+}

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Africa.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Africa.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Africa.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,5 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Africa","Events in Africa",-3000,1000,,,"T_All",,,"T_All","Timeline",,,
+"E_AFR1","Bantu expansion from Cameroon to Central Africa","-3000","-1500",,,"T_Africa","200",,"T_Africa","Period",,,
+"E_AFR2","Bantu expansion from Central to SouthernAfrica","-1000","500",,,"T_Africa","200",,"T_Africa","Period",,,
+"E_AFR3","Kingdom of Axum in Ethiopia","1","1000",,,"T_Africa","50",,"T_Africa","Dynasty",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Americas.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Americas.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Americas.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,7 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Americas","Events in the Americas",-4000,900,,,"T_All",,,"T_All","Timeline",,,"From Finegan, adding post-1917. Fuzzinesses mine. NB: these seem to assume a late Exodus"
+"E_AME1","First date on the Mayan Long Count calendar","-3112-08-11",,,,"T_Americas",,,"T_Americas","Event",,,
+"E_AME2","Mayan pre-classical period","-1000","250",,,"T_Americas","100/25",,"T_Americas","Period",,,
+"E_AME3","Mayan classical period","250","900",,,"T_Americas","25",,"T_Americas","Period",,,
+"E_AME4","Olmec civilisation","-1200","-400",,,"T_Americas","50",,"T_Americas","Period",,,
+"E_AME5","Hopewell tradition","-500","200",,,"T_Americas","50",,"T_Americas","Period","in eastern half of what's now the USA",,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_ArchCult.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_ArchCult.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_ArchCult.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,38 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_ArchCult","Archaeological and Cultural ",,,,,"T_All",,,"T_All","Timeline","Archaeological and Cultural Periods in the Holy Land. These are based on general archaeology and history, rather than Biblical accounts, so diverge from Biblical chronology particularly before the Exodus. ",,"From Finegan, adding post-1917. Fuzzinesses mine. NB: these seem to assume a late Exodus"
+"T_ACBronzeAge","Bronze Age","-3300","-1200",,,"T_ArchCult","50/25",,"T_ArchCult","Timeline","Canaanite Period",,
+"T_ACIronAge","Iron Age","-1200","-586",,,"T_ArchCult","25/0",,"T_ArchCult","Timeline","Israelite Period",,
+"T_ACBabylonPersia","Babylonian and Persian Periods","-586","-332",,,"T_ACIronAge",,,"T_ACIronAge","Timeline",,,
+"T_ACHellenistic","Hellenistic Period","-332","-37",,,"T_ACBabylonPersia",,,"T_ACBabylonPersia","Timeline",,,
+"T_ACJewishPeriod","Jewish periods of Tanakh scholarship","-175","500",,,"T_ArchCult","25",,"T_ArchCult","Timeline",,,"(best description? David IB's the expert here!)"
+"T_ACRomeByzantium","Roman and Byzantine Periods","-37","638",,,"T_ArchCult",,,"T_ArchCult","Timeline",,,
+"T_ACModern","Early Arab Period","638","1099",,,"T_ArchCult",,,"T_ArchCult","Timeline",,,
+"E_AC1","Palaeolithic",,"-18000",,,"T_ArchCult","/100",,"T_ArchCult","Period","Old Stone Age",,
+"E_AC2","Epipalaeolithic","-18000","-8300",,,"T_ArchCult","100/50",,"T_ArchCult","Period","Middle Stone Age",,
+"E_AC3","Neolithic","-8300","-4500",,,"T_ArchCult","50",,"T_ArchCult","Period","New Stone Age",,
+"E_AC4","Chalcolithic","-4500","-3300",,,"T_ArchCult","50",,"T_ArchCult","Period","Copper-Stone Age",,
+"E_AC5","Early Bronze Age I","-3300","-3000",,,"T_ACBronzeAge","50/25",,"T_ACBronzeAge","Period",,,
+"E_AC6","Early Bronze Age II","-3000","-2700",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC7","Early Bronze Age III","-2700","-2200",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC8","Middle Bronze Age I","-2200","-2000",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC9","Middle Bronze Age II","-2000","-1550",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC10","Late Bronze Age I","-1550","-1400",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC11","Late Bronze Age II","-1400","-1200",,,"T_ACBronzeAge","25",,"T_ACBronzeAge","Period",,,
+"E_AC12","Iron Age I ","-1200","-1000",,,"T_ACIronAge","25",,"T_ACIronAge","Period",,,
+"E_AC13","Iron Age II","-1000","-586",,,"T_ACIronAge","25/0",,"T_ACIronAge","Period",,,
+"E_AC14","Babylonian Period","-586","-538",,,"T_ArchCult",,,"T_ArchCult","Period",,,
+"E_AC15","Persian Period","-538","-332",,,"T_ACBabylonPersia",,,"T_ACBabylonPersia","Period",,,
+"E_AC16","Hellenistic Period I","-332","-167",,,"T_ACBabylonPersia",,,"T_ACBabylonPersia","Period",,,
+"E_AC17","Soferim and Tannaiam","-175","200",,,"T_ACJewishPeriod","25",,"T_ACJewishPeriod","Period",,,
+"E_AC18","Hellenistic Period II","-167","-37",,,"T_ACBabylonPersia",,,"T_ACBabylonPersia","Period",,,
+"E_AC19","Early Roman Period","-37","132",,,"T_ACRomeByzantium",,,"T_ACRomeByzantium","Period",,,
+"E_AC20","Herodian Period","-37","70",,,"T_ACRomeByzantium",,,"T_ACRomeByzantium","Period",,,
+"E_AC21","Late Roman Period","132","324",,,"T_ACRomeByzantium",,,"T_ACRomeByzantium","Period",,,
+"E_AC22","Amoraim","200","500",,,"T_ACJewishPeriod","25",,"T_ACJewishPeriod","Period",,,
+"E_AC23","Byzantine Period","324","638",,,"T_ACRomeByzantium",,,"T_ACRomeByzantium","Period",,,
+"E_AC24","Talmudic","350","500",,,"T_ACJewishPeriod","25",,"T_ACJewishPeriod","Period",,,
+"E_AC25","Crusader Period","1099","1291",,,"T_ACModern",,,"T_ACModern","Period",,,
+"E_AC26","Late Arab Period","1291","1516",,,"T_ACModern",,,"T_ACModern","Period","Fatimid and Mameluke",,
+"E_AC27","Ottoman Period","1516","1917",,,"T_ACModern",,,"T_ACModern","Period",,,
+"E_AC28","British Mandate","1917","1948",,,"T_ACModern",,,"T_ACModern","Period",,,
+"E_AC29","Israel and Palestine","1948",,,,"T_ACModern",,,"T_ACModern","Period","The area occupied by Biblical Israel has formed the modern state of Israel and various Palestinian entities. ",,"(need to word this one carefully)"

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Asia.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Asia.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Asia.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,32 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Asia","Events in Asia",-3300,600,,,"T_All",,,"T_All","Timeline",,,"From Finegan, adding post-1917. Fuzzinesses mine. NB: these seem to assume a late Exodus"
+"T_India","Indian subcontinent",-3300,600,,,"T_Asia",,,"T_Asia","Timeline",,,
+"T_China","China",-2070,420,,,"T_Asia",,,"T_Asia","Timeline",,,
+"E_ASIA1","Xia Dynasty","-2070","-1600",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA2","Shang Dynasty","-1600","-1046",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA3","Western Zhou Dynasty","-1046","-771",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA4","Eastern Zhou Dynasty","-770","-256",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA5","Spring and Autumn Period","-722","-476",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA6","Warring States Period","-475","-221",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA7","Qin Dynasty","-221","-206",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA8","Western Han Dynasty","-206","9",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA9","Xin Dynasty","9","23",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA10","Eastern Han Dynasty","23","220",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA11","Three Kingdoms","220","265",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA12","Western Jin Dynasty","265","317",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA13","Eastern Jin Dynasty","317","420",,,"T_China",,,"T_China","Dynasty",,,
+"E_ASIA14","Building of original Great Wall","-500","-221",,,"T_China",,,"T_China","Event","Current wall dates mainly from 15th century",,
+"E_ASIA15","Confucius","-551","-479",,,"T_China",,,"T_China","Life",,,
+"E_ASIA16","Lao Tzu","-600","-470",,,"T_China","50",,"T_China","Life","Traditional dates. Unclear whether he actually existed.",,
+"E_ASIA17","Indus Valley Civilisation","-3300","-1400",,,"T_India","100",,"T_India","Period","Mature phase 2600-1900 ",,
+"E_ASIA18","Vedic period","-1000","-321",,,"T_India","100/0",,"T_India","Period",,,
+"E_ASIA19","Composition of Rigveda","-1700","-1100",,,"T_India","100",,"T_India","Event",,,
+"E_ASIA20","Composition of Mahabharata and Ramayana","-750","-350",,,"T_India","100",,"T_India","Event",,,
+"E_ASIA21","Composition of Upanishads","-900","-600",,,"T_India","100",,"T_India","Event",,,
+"E_ASIA22","Mauryan Empire","-321","-184",,,"T_India","10",,"T_India","Dynasty",,,
+"E_ASIA23","Ashoka the Great","-269","-232",,,"T_India","10",,"T_India","Reign",,,
+"E_ASIA24","Sunga Dynasty","-183","-71",,,"T_India","10",,"T_India","Dynasty",,,
+"E_ASIA25","Kanva Dynasty","-71","-45",,,"T_India","10",,"T_India","Dynasty",,,
+"E_ASIA26","Sautavahana Empire","-230","220",,,"T_India","10",,"T_India","Dynasty",,,
+"E_ASIA27","Gupta Empire","320","550",,,"T_India","10",,"T_India","Dynasty",,,
+"E_ASIA28","Buddha","-560","-480",,,"T_India","10",,"T_India","Life",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_EarlyChurch.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_EarlyChurch.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_EarlyChurch.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,40 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"E_EC1","First Council of Nicaea","325",,,,"T_EarlyChurch",,,"T_EarlyChurch","Council",,,"Dates taken from Wikipedia mainly. Need checking."
+"E_EC2","First Council of Constantinople","381",,,,"T_EarlyChurch",,,"T_EarlyChurch","Council",,,
+"E_EC3","First Council of Ephesus","431",,,,"T_EarlyChurch",,,"T_EarlyChurch","Council",,,
+"E_EC4","Council of Chalcedon","451",,,,"T_EarlyChurch",,,"T_EarlyChurch","Council",,,
+"E_EC5","Constantine converts to Christianity","312",,,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,
+"E_EC6","Edict of Milan","313",,,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,
+"E_EC7","Alexander of Alexandria","280","326",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC8","Athanasius","293","373",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC9","Arius","253","336",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC10","Eusebius of Caesarea","265","339",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC11","Justin Martyr","100","165",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC12","Gregory Nazianzus","330","389",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC13","John Chystostom","347","407",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC14","Cyril of Alexandria","378","444",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC15","Nestorius","386","451",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC16","Pelagius","354","420",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC17","Augustine of Hippo","354","430",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC18","Eutyches","380","456",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC19","Theodoret of Cyrus","393","457",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC20","Theodore of Mopsuestia","350","428",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC21","Apollinarius of Laodicea","330","390",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC22","Ambrose of Milan","338","397",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC23","Jerome","347","420",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC24","Ignatius of Antioch","50","117",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC25","Polycarp of Smyrna","69","155",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC26","Irenaeous of Lyons","150","202",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC27","Tertullian","160","220",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC28","Clement of Alexandria","150","215",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC29","Origen of Alexandria","185","254",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC30","Clement of Rome","40","101",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC31","Didache","100",,,,"T_EarlyChurch",,,"T_EarlyChurch","Book",,,
+"E_EC32","Shepherd of Hermas","120",,,,"T_EarlyChurch",,,"T_EarlyChurch","Book",,,
+"E_EC33","Marcion","85","160",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC34","Gregory of Nyssa","335","394",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC35","Basil of Caesarea","330","379",,,"T_EarlyChurch",,,"T_EarlyChurch","Life",,,
+"E_EC36","Persecution in Lyon","177",,,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,
+"E_EC37","Edict of Decius","250-01",,,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,
+"E_EC38","Persecution under Decius and Valerian","250","260",,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,
+"E_EC39","Persecution under Diocletian","303","311",,,"T_EarlyChurch",,,"T_EarlyChurch","Event",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Egypt.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Egypt.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Egypt.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,71 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Egypt","Egyptian Dynasties","-3005","-332",,,"T_All","45/0",,"T_All","Timeline","3050/2960-332",,"From Finegan except where noted. His ranges given in the description, which I've converted into our system by taking a middle date (except where noted)"
+"E_EgyptD1","1st Dynasty","-3005","-2820",,,"T_Egypt","45/40",,"T_Egypt","Reign","3050/2960-2860/2780",,
+"E_EgyptD2","2nd Dynasty","-2820","-2670",,,"T_Egypt","40/30",,"T_Egypt","Reign","2860/2780-2695/2640",,
+"E_EgyptD3","3rd Dynasty","-2670","-2600",,,"T_Egypt","30/30",,"T_Egypt","Reign","2695/2640-2630/2575",,
+"E_EgyptD4","4th Dynasty","-2600","-2480",,,"T_Egypt","30/25",,"T_Egypt","Reign","2630/2575-2505/2460",,
+"E_EgyptD5","5th Dynasty","-2480","-2330",,,"T_Egypt","25/20",,"T_Egypt","Reign","2505/2460-2345/2310",,
+"E_EgyptD6_8","6th - 8th Dynasties","-2330","-2147",,,"T_Egypt","20/13",,"T_Egypt","Reign","2345/2310-2160/2134",,
+"E_EgyptD9_10","9th and 10th Dynasties","-2147","-2040",,,"T_Egypt","13/7",,"T_Egypt","Reign","2160/2134-2047/2033",,
+"E_EgyptD11","11th Dynasty","-2134","-1991",,,"T_Egypt",,,"T_Egypt","Reign","2134-1991",,
+"T_EgyptD12","12th Dynasty","-1991","-1785",,,"T_Egypt",,,"T_Egypt","Timeline","1991-1785",,
+"E_EgyptD13_14","13th and 14th Dynasties","-1785","-1655",,,"T_Egypt","0/5",,"T_Egypt","Reign","1785-1660/1650",,
+"E_EgyptD15_17","15th-17th Dynasties","-1655","-1552",,,"T_Egypt","5/10",,"T_Egypt","Reign","1660/1651-1560/1541",,"Finegan gives a partial table of 15th dynasty pharaohs, but not enough to be useful, I think."
+"T_EgyptD18","18th Dynasty","-1552","-1295",,,"T_Egypt","5/7",,"T_Egypt","Timeline","1560/1551-1320/1306",,"Using dates from Finegan's Table 116. Note that the date given here for the 18/19 endpoint (1295) contradicts the (1320/1306) range in on xxxvi. Wikipedia gives 1292, or 1295 on a page citing Ian Shaw, so taking this one."
+"T_EgyptD19","19th Dynasty","-1295","-1196",,,"T_Egypt","7/8",,"T_Egypt","Timeline","1320/1306-1200/1185",,"Dates from Finnegan's Table 117"
+"E_EgyptD20","20th Dynasty","-1192","-1077",,,"T_Egypt","8/8",,"T_Egypt","Reign","1200/1185-1085/1070",,
+"E_EgyptD21","21st Dynasty","-1077","-944",,,"T_Egypt","8/4",,"T_Egypt","Reign","1085/1070-947/940",,
+"E_EgyptD22_24","22nd - 24th Dynasties","-944","-712",,,"T_Egypt","4/2",,"T_Egypt","Reign","947/940-714/711",,
+"E_EgyptD25","25th Dynasty","-712","-656",,,"T_Egypt","2/1",,"T_Egypt","Reign","714/711-656/655",,
+"E_EgyptD26","26th Dynasty","-664","-525",,,"T_Egypt",,,"T_Egypt","Reign","664-525",,
+"E_EgyptD27","27th Dynasty","-525","-404",,,"T_Egypt",,,"T_Egypt","Reign","525-404",,
+"E_EgyptD28","28th Dynasty","-404","-398",,,"T_Egypt",,,"T_Egypt","Reign","404-398",,
+"E_EgyptD29","29th Dynasty","-399","-380",,,"T_Egypt",,,"T_Egypt","Reign","399-380",,
+"E_EgyptD30","30th Dynasty","-380","-342",,,"T_Egypt",,,"T_Egypt","Reign","380-342",,
+"E_EgyptD31","31th Dynasty","-342","-332",,,"T_Egypt",,,"T_Egypt","Reign","342-332",,
+"T_EgyptPtolemaic","Ptolemaic Kingdom","-332","-30",,,"T_Egypt",,,"T_Egypt","Timeline","332-30. Incomplete.",,"IVP dictionary 323-180, filled out from Wikipedia"
+"E_EgyptP1","Amenemhet I","-1991","-1962",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP2","Sesostris I","-1962","-1928",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP3","Amenemhet II","-1928","-1895",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP4","Sesostris II","-1895","-1878",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP5","Sesostris III","-1878","-1842",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP6","Amenemhet III","-1842","-1797",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP7","Amenemhet IV","-1797","-1790",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP8","Nefrusobek","-1790","-1785",,,"T_EgyptD12",,,"T_EgyptD12","Reign",,,
+"E_EgyptP9","Ahmose","-1552","-1526",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP10","Ahmenhotep","-1526","-1506",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP11","Thutmose I","-1506","-1493",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP12","Thutmose II","-1493","-1479",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP13","Thutmose III","-1479","-1425",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP14","Hatshepsut","-1478","-1458",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP15","Amenhotep II","-1425","-1401",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP16","Thutmose IV","-1401","-1390",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP17","Amenhotep III","-1390","-1352",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP18","Amenhotep IV","-1352","-1348",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP19","Akhenaten","-1348","-1338",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP20","Smenkhkare","-1338","-1336",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP21","Tutenkhaten/Tutankhamen","-1336","-1327",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP22","Ay","-1327","-1323",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP23","Horemheb","-1323","-1295",,,"T_EgyptD18",,,"T_EgyptD18","Reign",,,
+"E_EgyptP24","Ramses I","-1295","-1294",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP25","Seti I","-1294","-1279",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP26","Ramses II","-1279","-1212",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP27","Merneptah","-1212","-1202",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP28","Amenmesse","-1202","-1199",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP29","Seti II","-1202","-1196",,,"T_EgyptD19",,,"T_EgyptD19","Reign",,,
+"E_EgyptP30","Shesonq I","-944","-924",,,"T_Egypt","2/0",,"T_Egypt","Reign","22nd Dynasty. Shishak of the Bible","1Kgs.11.29-40;1Kgs.14.25-26; 2Chr.12.2-12","This and next four entries from IVP dictionary."
+"E_EgyptP31","Osorkon IV","-727","-716",,,"T_Egypt",,,"T_Egypt","Reign","22nd Dynasty. Most likely candidate for So of the Bible","2Kgs.17.4","Kitchen gives accession date as 732/730"
+"E_EgyptP32","Taharqa","-690","-664",,,"T_Egypt",,,"T_Egypt","Reign","25th Dynasty. Tirhakah of the Bible (although before he became Pharaoh)","2Kgs.19.9",
+"E_EgyptP33","Necho II","-610","-595",,,"T_Egypt",,,"T_Egypt","Reign","26th Dynasty. Neco of the Bible","2Kgs.23.29-35; 2Chr.35.20-36.4;Jer.25.19",
+"E_EgyptP34","Apries","-589","-570",,,"T_Egypt",,,"T_Egypt","Reign","26th Dynasty. Hophra of the Bible","Jer.37.5-11; Ezek.17.17; Ezek.29.2-3",
+"E_EgyptP35","Alexander the Great","-332","-323",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP36","Ptolemy I Soter","-323","-282",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP37","Judaea annexed by Ptolemy I","-320",,,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Event",,,
+"E_EgyptP38","Ptolemy II Philadelphus","-282","-246",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP39","Ptolemy III Euergetes","-246","-222",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP40","Ptolemy IV Philopator","-222","-205",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP41","Ptolemy V Epiphanes","-204","-180",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP42","Battle of Panium","-198",,,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Battle","Most foreign possessions lost to Syria",,
+"E_EgyptP43","Cleopatra (VII)","-51","-30",,,"T_EgyptPtolemaic",,,"T_EgyptPtolemaic","Reign",,,
+"E_EgyptP44","Main pyramid-building period",-2630,-2400,,,"T_Egypt",50,,"T_Egypt","Period","(from Wikipedia. Needs review.)",,
+"E_EgyptP45 ","Twelfth dynasty pyramid-building period",-1991,-1820,,,"T_Egypt",50,,"T_Egypt","Period",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Europe.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Europe.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Europe.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,42 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Europe","Events in Europe",,,,,"T_All",,,"T_All","Timeline","Archaeological and Cultural Periods in the Holy Land. These are based on general archaeology and history, rather than Biblical accounts, so diverge from Biblical chronology particularly before the Exodus. ",,"From Finegan, adding post-1917. Fuzzinesses mine. NB: these seem to assume a late Exodus"
+"T_Greece","Greece",,,,,"T_Europe",,,"T_Europe","Timeline",,,
+"E_EUR1","Minoan civilisation","-2000","-1450",,,"T_Greece","300/50",,"T_Greece","Period","Considerable debate as to start date, depending on what you define as ""civilisation""!",,
+"E_EUR2","Mycenaean civilisation","-1500","-1200",,,"T_Greece","50/50",,"T_Greece","Period","Wikipedia c1600-c1100",,
+"E_EUR3","Volcanic eruption on Thera","-1628",,,,"T_Greece","30 ",,"T_Greece","Event","Tree-counting date is 1628. Other datings up to 1600 or beyond",,
+"E_EUR4","Trojan War","-1190",,,,"T_Greece","50 ",,"T_Greece","War",,,
+"E_EUR5","Greek Dark Ages","-1200","-800",,,"T_Greece","50 ",,"T_Greece","Period",,,
+"E_EUR6","Growth of city states","-800","-510",,,"T_Greece","50/0",,"T_Greece","Period",,,
+"E_EUR7","Classical Greek period","-510","-323",,,"T_Greece",,,"T_Greece","Period",,,
+"E_EUR8","Persian Wars","-499","-450",,,"T_Greece","0/1",,"T_Greece","War",,,
+"E_EUR9","First Persion invasion of Greece","-492","-490",,,"T_Greece",,,"T_Greece","War",,,
+"E_EUR10","Battle of Marathon","-490-08",,,,"T_Greece","1",,"T_Greece","Battle",,,
+"E_EUR11","Second Persion invasion of Greece","-480-03","-479-07",,,"T_Greece",,,"T_Greece","War",,,
+"E_EUR12","Battle of Thermopylae","-480-08",,,,"T_Greece",,,"T_Greece","Battle",,,
+"E_EUR13","Battle of Salamis","-480-09",,,,"T_Greece",,,"T_Greece","Battle",,,
+"E_EUR14","Battles of Plataea and Mycale","-479-06",,,,"T_Greece",,,"T_Greece","Battle",,,
+"E_EUR15","Peloponnesian War","-431","-404",,,"T_Greece",,,"T_Greece","War",,,
+"E_EUR16","Hellenistic Greek period","-323","-146",,,"T_Greece",,,"T_Greece","Period",,,
+"E_EUR17","Annexation of Greece by Rome","-146",,,,"T_Greece",,,"T_Greece","Event",,,
+"E_EUR18","Hippocrates","-460","-370",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR19","Socrates","-469","-399",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR20","Plato","-428","-348",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR21","Aristotle","-384","-322",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR22","Zeno of Citium","-334","-262",,,"T_Greece",,,"T_Greece","Life","Founder of Stoicism",,
+"E_EUR23","Epicurus","-341","-270",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR24","Aeschylus","-525","-456",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR25","Sophocles","-495","-406",,,"T_Greece","5/0",,"T_Greece","Life",,,
+"E_EUR26","Euripedes","-480","-406",,,"T_Greece","5/0",,"T_Greece","Life",,,
+"E_EUR27","Aristophanes","-446","-388",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR28","Thales","-626","-546",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR29","Pythagoras","-582","-507",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR30","Archimedes","-287","-212",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR31","Euclid","-325","-265",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR32","Hipparchus","-190","-120",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR33","Eratosthenes","-276","-195",,,"T_Greece",,,"T_Greece","Life",,,
+"E_EUR34","Herodotus","-484","-425",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR35","Thucydides","-460","-395",,,"T_Greece","5",,"T_Greece","Life",,,
+"E_EUR36","Urnfield culture","-1300","-750",,,"T_Europe","50 ",,"T_Europe","Life","Celtic culture in central Europe",,
+"E_EUR37","Hallstatt culture","-750","-550",,,"T_Europe","50 ",,"T_Europe","Life","in central Europe",,
+"E_EUR38","La Tene culture","-450","-1",,,"T_Europe","50",,"T_Europe","Life","western and central Europe",,
+"E_EUR39","Stonehenge construction","-3100","-1600",,,"T_Europe","50",,"T_Europe","Life",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_ExileAndReturn.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_ExileAndReturn.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_ExileAndReturn.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,70 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_EzraNehemiah","Books of Ezra and Nehemiah","-538","-445",,,"T_Return",,,"T_Return","Timeline","Timeline of the books of Ezra and Nehemiah","Ezra.*;Neh.*","Following Finnegan where available, otherwise IVP (which in some cases differ by a year where both list the same date). Need to confirm regnal dates with PDBC then adjust. Assuming (as Finnegan does) that Artaxerxes is Artaxerxes I, not II as per some scholars."
+"E_EzNe1","Proclamation of Cyrus","-538",,,,"T_Return",,,"T_Return","Event",,"Ezra.1",
+"E_EzNe2","Return of the exiles following the proclamation of Cyrus","-538",,,,"T_Return",,,"T_Return","Event",,"Ezra.2",
+"E_EzNe3","Rebuilding the altar","-538-07",,,,"T_Return",,,"T_Return","Event",,"Ezra.3.1-7",
+"E_EzNe4","Start of the rebuilding of the temple","-536-02",,,,"T_Return",,,"T_Return","Event",,"Ezra.3.8-13",
+"E_EzNe5","Opposition to the rebuilding of the temple","-536","-486",,,"T_Return",,,"T_Return","Event",,"Ezra.4.1-5","To end of Darius's reign"
+"E_EzNe6","Accusation in the reign of Ahaseurus (Xerxes)","-485",,,,"T_Return",,,"T_Return","Event",,"Ezra.4.6","Started reign 486"
+"E_EzNe7","Letter to King Artaxeres and his response","-455",,,,"T_Return","10Y",,"T_Return","Event",,"Ezra.4.7-23","Artaxerxes reigned 465-424. However, this must logically predate Nehemiah 1 (445)."
+"E_EzNe8","Rebuilding the temple resumes following the prophesies of Haggai and Zechariah","-520-06",,,,"T_Return",,,"T_Return","Event","Aug/Sep ","Ezra.4.24-5.5","Haggai's prophecy on -06-01, Aug 29th"
+"E_EzNe9","Darius confirms Cyrus's decree","-520-06","-520-12",,,"T_Return","EM",,"T_Return","Event",,"Ezra.5.6-6.12","Allowing some travel time!"
+"E_EzNe10","Temple rebuilt","-520-06-24","-516-12-03",,,"T_Return",,,"T_Return","Event","Completion Mar 12th 515","Ezra.6.13-15;Hag.1.15",
+"E_EzNe11","Celebration of rebuilding of the temple and the first Passover","-516-12","-515-01",,,"T_Return",,,"T_Return","Event","Mar/Apr 515","Ezra.6.16-22",
+"E_EzNe12","Ezra sent to Jerusalem by Artaxerxes ","-458-01-01","-458-05-01",,,"T_Return",,,"T_Return","Event","Apr 8-Aug4","Ezra.7-8.32",
+"E_EzNe13","Silver and gold deposited in the temple","-458-05-04",,,,"T_Return",,,"T_Return","Event","Aug 7","Ezra.8.33-36",
+"E_EzNe14","Ezra prays about the problem of intermarriage","-458-05","-458-09",,,"T_Return",,,"T_Return","Event",,"Ezra.9-10.6",
+"E_EzNe15","Ezra's proclamation that the men of Judah should assemble","-458-09-07",,,,"T_Return",,,"T_Return","Event",,"Ezra.10.7-8",
+"E_EzNe16","Ezra's teaching on intermarriage","-458-09-10",,,,"T_Return",,,"T_Return","Event",,"Ezra.10.9-44",
+"E_EzNe17","Nehemiah visited by Hanani; his prayer","-446-09",,,,"T_Return",,,"T_Return","Event","Nov/Dec 446","Neh.1","A problem with the dating here, as Kislev is after Nisan in the year. Finnegan doesn't discuss this. Williamson (WBC Ezra-Nehemiah p167), following Bickermann, suggests we should be following regnal, not calendar years. Whether that changes other datings relating to Persian kings is unclear."
+"E_EzNe18","Artaxerxes sends Nehemiah to Jerusalem","-445-01",,,,"T_Return",,,"T_Return","Event","Apr/May 445","Neh.2.1-10",
+"E_EzNe19","Nehemiah governor of Israel","-445","-433",,,"T_Return",,,"T_Return","Event",,"Neh.5.14",
+"E_EzNe20","Nehemiah arrives in Jerusalem","-445-04-28",,,,"T_Return",,,"T_Return","Event","Aug 7","Neh.2.11",
+"E_EzNe21","Nehemiah inspects the walls","-445-05-02",,,,"T_Return",,,"T_Return","Event","night of Aug 10","Neh.2.12-16",
+"E_EzNe22","Rebuilding of the walls of Jerusalem","-445-05-03","-445-06-25",,,"T_Return",,,"T_Return","Event","Aug 11-Oct 2","Neh.2.17-6.19","End date given, plus length of 52 days. (Not sure which months were 30 days, which 29, so may be one or two days off.)"
+"E_EzNe23","Appointing of gatekeepers, singers and Levites","-445-06-26","-445-06-29",,,"T_Return",,,"T_Return","Event","Oct 3-Oct 6","Neh.6.20-7.72",
+"E_EzNe24","Ezra reads the Law","-445-07-01","-445-07-08",,,"T_Return",,,"T_Return","Event","Oct 7-Oct 14","Neh.7.73-8.18",
+"E_EzNe25","The Israelites confess their sins","-445-07-24",,,,"T_Return",,,"T_Return","Event",,"Neh.9-10",
+"E_EzNe26","Resettlement in Jerusalem","-445","-444",,,"T_Return",,,"T_Return","Event",,"Neh.11-12.26","No end time. Months seem reasonable"
+"E_EzNe27","Dedication of the walls of Jerusalem","-445-08",,,,"T_Return","EM",,"T_Return","Event",,"Neh.12.27-43",
+"E_EzNe28","Nehemiah's final reforms","-432",,,,"T_Return","EY",,"T_Return","Event",,"Neh.12.44-13.6","After 433. A dating issue in that the implication of 12:44, 13:1 is that everything from 12:27 to 13:6 is at the same time, but Nehemiah is present at 12:38 but not 13:6. Following Williamson in that the dedication of the walls was not long afterwards, and 12:44 onwards is one block."
+"E_EzNe29","Nehemiah returns to Jerusalem","-430",,,,"T_Return","EY",,"T_Return","Event",,"Neh.13.6-31","After the previous. No information how much later. Worth seeing how this parallels Malachi."
+"T_HagZech","Prophecies of Haggai and Zechariah","-520-06-01","-500",,,"T_Return",,,"T_Return","Timeline",,"Hag.*;Zech.*",
+"B_Hag","Haggai","-520-06-01","-520-09-23",,,"T_Return",,,"T_HagZech","Book",,"Hag.*",
+"B_Zech","Zechariah","-520-08","-500",,,"T_Return","0/20Y",,"T_HagZech","Book",,"Zech.*","No information on when chapters 9-14 were written."
+"B_Mal","Malachi","-430",,,,"T_Return","10 ",,"T_Return","Book",,"Mal.*","Contemporary with Nehemiah's return to Jerusalem, perhaps. IVP gives 433 in one article, 460 in another."
+"E_HagZech1","Prophecy through Haggai to rebuild the Temple","-520-06-01",,,,"T_HagZech",,,"T_HagZech","Event",,"Hag.1",
+"E_HagZech2","Prophecy through Haggai to be strong because the Lord is with them","-520-07-21",,,,"T_HagZech",,,"T_HagZech","Event",,"Hag.2.1-9",
+"E_HagZech3","Prophecies through Haggai that the people will be blessed, and to Zerubbabel","-520-09-23",,,,"T_HagZech",,,"T_HagZech","Event",,"Hag.2.10-19",
+"E_HagZech4","Prophecy through Zechariah to return to the Lord","-520-08",,,,"T_HagZech",,,"T_HagZech","Event","Oct/Nov 520","Zech.1.1-6",
+"E_HagZech5","Prophecy through Zechariah of various images","-520-11-24",,,,"T_HagZech",,,"T_HagZech","Event","Feb 519","Zech.1.7-6.15",
+"E_HagZech6","Prophecy through Zechariah concerning fasting and feasting","-518-04-09",,,,"T_HagZech",,,"T_HagZech","Event","Nov 518. Unclear if all one day","Zech.7-8",
+"E_HagZech7","Zechariah's oracles concerning Israel and her enemies","-500",,,,"T_HagZech","20Y",,"T_HagZech","Event","No dating information","Zech.9-14",
+"T_Ezekiel","Prophecies of Ezekiel","-593","-570",,,"T_Exile",,,"T_Exile","Timeline","Prophecies in Ezekiel which are dated.","Ezek.*","IVP gives 593-570. Note there are quite a few textual difficulties with the numbers."
+"B_Ezek","Ezekiel","-593","-570",,,"T_Exile","0/10",,"T_Ezekiel","Book",,"Ezek.*",
+"E_Ezek1","Call of Ezekiel","-593-04-05",,,,"T_Ezekiel",,,"T_Ezekiel",,"Jul 31","Ezek.1.1-.3.14",
+"E_Ezek2","Warning to Israel of the siege of Jerusalem","-593-04-12",,,,"T_Ezekiel",,,"T_Ezekiel",,"Aug 7","Ezek.3.16-5.17",
+"E_Ezek3","Prophecy about the Temple and Israel's leaders","-592-06-05",,,,"T_Ezekiel",,,"T_Ezekiel",,"Sep 17","Ezek.8.1-11.25",
+"E_Ezek4","Prophecy about Israel rebelling","-591-05-10",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.20.1-44",
+"E_Ezek5","Prophecy about a cooking pot","-589-10-10",,,,"T_Ezekiel",,,"T_Ezekiel",,"Jan 15 588","Ezek.24.1-14",
+"E_Ezek6","Prophecy against Tyre","-587-01-01",,,,"T_Ezekiel",,,"T_Ezekiel",,"First day of month, no month given. Assuming first month as per WBC best guess?","Ezek.26","Whatever month this is in, predates the fall of Jerusalem, which is surprising. Discussion in WBC about this."
+"E_Ezek7","Prophecy against Egypt","-588-10-12",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.29.1-16",
+"E_Ezek8","Prophecy that Nebuchadnezzar will conquer Egypt","-571-01-01",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.29.17-21",
+"E_Ezek9","Prophecy about Egypt and Babylon","-587-01-07",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.30.20-26",
+"E_Ezek10","Prophecy to Egypt about Assyria (the cedar of Lebanon)","-587-03-01",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.31",
+"E_Ezek11","Lament concerning Pharaoh","-586-12-01",,,,"T_Ezekiel",,,"T_Ezekiel",,,"Ezek.32.1-16",
+"E_Ezek12","Warning to Egypt that other nations have already been destroyed","-586-12-15",,,,"T_Ezekiel",,,"T_Ezekiel",,"No month, assuming same as previous","Ezek.32.17-32",
+"E_Ezek13","Explanation of Jerusalem's fall","-586-10-05",,,,"T_Ezekiel",,,"T_Ezekiel",,"Jan 8 585","Ezek.33.21-33",
+"E_Ezek14","Vision of the new Temple","-573-01-10",,,,"T_Ezekiel",,,"T_Ezekiel",,"Apr 28 573","Ezek.40-48",
+"B_Lam","Lamentations","-586",,,,"T_Exile","5",,"T_Exile","Book",,"Lam.*","(not IVP. Assuming 586 or shortly after.)"
+"B_Obad","Obadiah","-586",,,,"T_Exile",,,"T_Exile","Book",,"Obad.*","c586 or later, from IVP"
+"T_Esther","Timeline of Esther",-484,-475,,,"T_Return",,,"T_Return","Timeline",,"Esth.*",
+"E_Est1","Queen Vashti deposed",-484,,,,"T_Esther",,,"T_Esther","Event",,"Esth.1",
+"E_Est2","Esther becomes queen ",-481,-480,,,"T_Esther",,,"T_Esther","Event",,"Esth.2.1-18",
+"E_Est3","Mordecai discovers the plot to assassinate Xerxes",-479,,,,"T_Esther","EY",,"T_Esther","Event",,"Esth.2.19-23",
+"E_Est4","Haman honoured",-476,,,,"T_Esther","EY",,"T_Esther","Event",,"Esth.3.1-6",
+"E_Est5","The plot to kill the Jews; the Jews saved","-475-01","-475-12",,,"T_Esther",,,"T_Esther","Event",,"Esth.3.7-10.3",
+"B_Job","Job",-500,,,,"T_Return",100,,"T_Return","Book","Possible date for the book of Job in its present form. (Opinions vary from about 1500 to 150BC.) It is likely that the story in some form is much older. ","Job.*","WBC"
+"B_Eccl","Ecclesiastes",-500,-200,,,"T_Return",100,,"T_Return","Book","Likely date for Ecclesiastes in its present form. ","Eccl.*","WBC"
+"B_Prov","Proverbs",-500,-400,,,"T_Return",100,,"T_Return","Book","Likely date for Proverbs in its present form. (Chapters 10-31 probably pre-date the exile)","Prov.*","WBC"
+"B_Song","Song of Solomon",-1011,-971,,,"T_UnitedMonarchy",,,"T_UnitedMonarchy","Book","Reflecting Solomon's authorship.","Song.*","(don't have a commentary - need to check what opinions are)"

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Global.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Global.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Global.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,24 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_All","All","-3800","2000","-4112","2000",,,,"-","Timeline","Container for everything",,"All refs very approximate"
+"T_Bible","Bible ","-3800","400","-4112","400","T_All",,,"T_All","Timeline","All OT dates need sorting out",,
+"T_Patriarchs","Patriarchs","-4000","-1547","-4112","-1859","T_All",,,"T_Bible","Timeline",,"Gen.*",
+"T_AdamToAbraham","Adam to Abraham","-4000","-1854","-4000","-1854","T_Patriarchs",,,"T_Patriarchs","Timeline",,"Gen.1-11",
+"T_Abraham","Abraham","-1854","-1679","-1854","-1679","T_Patriarchs",,,"T_Patriarchs","Timeline",,"Gen.12.1-25.18","These divisions from ""These are the generations of"""
+"T_Isaac","Isaac","-1754","-1574","-1754","-1574","T_Patriarchs",,,"T_Patriarchs","Timeline",,"Gen.25.19-35.29","These divisions from ""These are the generations of"""
+"T_Jacob","Jacob","-1694","-1547","-1694","-1547","T_Patriarchs",,,"T_Patriarchs","Timeline",,"Gen.37.1-50.26","These divisions from ""These are the generations of"""
+"T_BirthOfTheNation","Birth of the Nation","-1250","-1045","-1446","-1045","T_Bible",,,"T_Bible","Timeline",,"Exod.*; Josh.*; Judg.*; 1Sam.*",
+"T_Exodus","Exodus","-1250-01-01","-1250-12-31","-1446-01-01","-1446-12-31","T_BirthOfTheNation",,,"T_BirthOfTheNation","Timeline",,,"[**] All timelines need to be a range"
+"T_Wilderness","Wilderness","-1250","-1210","-1446","-1406","T_BirthOfTheNation",,,"T_BirthOfTheNation","Timeline",,,"[**] Need to ensure that this links with the previous"
+"T_Conquest","Conquest","-1210","-1190","-1406","-1386","T_BirthOfTheNation",,,"T_BirthOfTheNation","Timeline",,,
+"T_Judges","Judges","-1190","-1045","-1386","-1045","T_BirthOfTheNation",,,"T_BirthOfTheNation","Timeline",,,
+"T_Monarchy","Monarchy","-1045","-586",,,"T_Bible",,,"T_Bible","Timeline","During this period, Israel was ruled by kings. At first one king ruled all the people, but in 931 the nation split into two, Israel or Samaria, and Judah. Both gradually turned away from God, and were conquered by other nations, leading to the people going into exile. ","1Sam.8-31; 2Sam.*;1Kgs.*; 2Kgs.*; 1Chr.10-29;  2Chr.*",
+"T_UnitedMonarchy","United monarchy","-1045","-931",,,"T_Monarchy",,,"T_Monarchy","Timeline","[subline of Monarchy] After a period being ruled by judges, the Israeli nation asked God for a king. God called Saul, who was then succeeded by David, then Solomon. After this the kingdom split in two.","1Sam.8-31; 2Sam.*;  1Kgs.1-11; 1Chr.10-29; 2Chr.1-9",
+"T_JudahMonarchy","Judah (split kingdom)","-931","-586",,,"T_Monarchy",,,"T_Monarchy","Timeline","[subline of Monarchy] Judah was the southern and smaller of the two Jewish kingdoms, and included the city of Jerusalem. It outlived its northern rival, and was finally conquered by Babylon in 586.","1Kgs.12-22; 2Kgs.*; 2Chr.10-36",
+"T_IsraelMonarchy","Israel (split kingdom)","-931","-723",,,"T_Monarchy",,,"T_Monarchy","Timeline","[subline of Monarchy] Israel, also known as Samaria after its capital city, was the northern and larger of the two Israeli kingdoms. It was conquered by Assyria in 722.",,
+"T_ExileAndReturn","Exile and return","-586","-432",,,"T_Bible",,,"T_Bible","Timeline",,"Ezra.*; Neh.*",
+"T_Exile ","Exile  ","-586","-537",,,"T_ExileAndReturn",,,"T_ExileAndReturn","Timeline",,,
+"T_Return","Return","-537","-432",,,"T_ExileAndReturn",,,"T_ExileAndReturn","Timeline",,,
+"T_NewTestament","New Testament period","-3-12","100",,,"T_All",,,"T_Bible","Timeline",,,
+"T_LifeOfJesus","Life of Jesus","-3-12","33-05-14",,,"T_NewTestament",,,"T_NewTestament","Timeline",,,
+"T_NTChurch","NT church","33-05-24","100",,,"T_NewTestament",,,"T_NewTestament","Timeline",,,
+"T_EarlyChurch","Early church","100","500",,,"T_All",,,"T_All","Timeline",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Intertestamental.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Intertestamental.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Intertestamental.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,25 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Intertestamental","Intertestamental Period","-537","-1",,,"T_Bible",,,"T_Bible","Timeline","Intertestamental period. Needs further work",,
+"E_INT1","Judaea under Persian control","-537","-332",,,"T_Intertestamental",,,"T_Intertestamental","Event",,,
+"E_INT2","Judaea part of Alexander the Great's Empire","-331","-323",,,"T_Intertestamental",,,"T_Intertestamental","Event",,,
+"E_INT3","Judaea ruled by Egypt","-323","-198",,,"T_Intertestamental",,,"T_Intertestamental","Event",,,
+"E_INT4","Judaea ruled by Syria (the Seleucids)","-198","-164",,,"T_Intertestamental",,,"T_Intertestamental","Event",,,
+"T_Hasmonean","Hasmonean kingdom","-164",-37,,,"T_Intertestamental",,,"T_Intertestamental","Timeline",,,
+"E_INT5","Judea under Roman rule","-63","-1",,,"T_Intertestamental",,,"T_Intertestamental","Event","- and well after this of course",,
+"E_INT6","Maccabean Revolt","-167","-164",,,"T_Intertestamental",,,"T_Intertestamental","Event",,,
+"E_INT7","Judas Maccabaeus","-166","-161",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT8","Jonathan Maccabaeus","-161","-143",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT9","Simon Maccabaeus","-143","-135",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT10","John Hyrcanus I","-135","-104",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT11","Aristobalus I","-104",,,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT12","Alexander Jannaeus","-103","-76",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT13","Queen Salome Alexandra and Hyrcanus II","-76","-67",,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT14","Hyrcanus II and Aristobalus II","-67",-40,,,"T_Hasmonean",,,"T_Hasmonean","Reign",,,
+"E_INT15","Pompey establishes Roman protection","-63",,,,"T_Hasmonean",,,"T_Hasmonean","Event",,,
+"E_INT16","Antigonus",-40,-36,,,"T_Hasmonean",,,"T_Hasmonean","Event",,,
+"T_Herodians","Herodian rulers of Judea",-40,44,,,"T_Intertestamental",,,"T_Intertestamental","Timeline","Overlaps with Jesus's ministry and beyond",,
+"E_INT17","Herod the Great",-36,-1,,,"T_Herodians",,,"T_Herodians","Reign",,,
+"E_INT18","Herod Archelaus, ethnarch of Samaria, Judea and Edom",-4,6,,,"T_Herodians",,,"T_Herodians","Reign",,,
+"E_INT19","Herod Antipas, tetrarch of Galilee",-4,39,,,"T_Herodians",,,"T_Herodians","Reign",,,
+"E_INT20","Herod Philip II, tetrarch of Iturea and Trachonitis",-4,34,,,"T_Herodians",,,"T_Herodians","Reign",,,
+"E_INT21","Herod Agrippa I, king of Israel",39,44,,,"T_Herodians",,,"T_Herodians","Reign","The Herod who died in Acts 12",,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Jesus.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Jesus.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Jesus.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,64 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Source"
+"T_JesusEarly","Early Years of Jesus Christ and John the Baptist","-04-10","11",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"T_JesusJohn","John's ministry and the start of Jesus's","29-01","31-02",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline","Jesus mainly in Judea",,
+"T_JesusGalilee","Jesus's ministry in Galilee","31-02","31-12",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"T_JesusGalileeArea","Jesus's minstry in areas around Galilee","32-01","32-09",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline","Phoenicia, Mt Hermon, Decapolis",,
+"T_JesusJudea","Jesus's minstry in Judea","32-09","32-12",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"T_JesusPerea","Jesus's minstry in Perea","33-01","33-03",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"T_PassionWeek","Passion Week","33-03-28","33-04-05",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"T_JesusResurrected","The resurrected Jesus","33-04-05","33-05-14",,,"T_LifeOfJesus",,,"T_LifeOfJesus","Timeline",,,
+"E_JES1","Birth of John the Baptist promised","-04-10",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.1.5-25",
+"E_JES2","Birth of Jesus promised","-03-04",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.1.26-56;Matt.1.18-24",
+"E_JES3","Birth of John the Baptist","-03-07",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.1.57-80",
+"E_JES4","Birth of Jesus ","-02-01",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.2.1-20; Matt.1.25",
+"E_JES5","Jesus presented in the Temple","-02-01",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.2.21-40",
+"E_JES6","Visit of the Magi","-02-09",,,,"T_JesusEarly",,,"T_JesusEarly","Event","Two theories in Finnegan (550-551). Summer/late-fall, or Dec 25. Star seen on Jun 17th","Matt.2.1-12",
+"E_JES7","Flight to Egypt","-02-10",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Matt.2.13-18",
+"E_JES8","Herod's death","-01-04",,,,"T_JesusEarly",,,"T_JesusEarly","Event","Between January and Passover, probably later rather than earlier",,
+"E_JES9","Return from Egypt",1,,,,"T_JesusEarly",,,"T_JesusEarly","Event","By tradition two years after the flight","Matt.2.19-23",
+"E_JES10","Jesus in the Temple at age 12","11-05",,,,"T_JesusEarly",,,"T_JesusEarly","Event",,"Luke.2.41-52",
+"E_JES11","Public ministry of John the Baptist","29-01","29-09",,,"T_JesusJohn",,,"T_JesusJohn","Event",,"Matt.3.1-12;Mark.1.1-8;Luke.3.1-20;John.1.19-28",
+"E_JES12","Jesus's baptism","29-09",,,,"T_JesusJohn","EM",,"T_JesusJohn","Event",,"Matt.3.13-17;Mark.1.9-11;Luke.3.21-22;John.1.29-34",
+"E_JES13","Jesus's temptation in the desert","29-10","29-11",,,"T_JesusJohn","EM",,"T_JesusJohn","Event",,"Matt.4.1-11;Mark.1.12-13;Luke.4.1-13",
+"E_JES14","End of John's Ministry and the beginning of Jesus's.","29-09","31-02",,,"T_JesusJohn",,,"T_JesusJohn","Event","Autumn 29. John 2:20 in Spring 30. John 4:35 in Jan/Feb 31","Matt.4.12;Mark.1.14;Luke.4.14;John.1.35-4.45",
+"E_JES15","Opposition at home and a new headquarters","31-03",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.4.13-17;Mark.1.14-15;Luke.4.14-31;John.4.46-54",
+"E_JES16","Disciples called","31-03",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.4.18-24;Matt.8.2-4;Matt.8.14-17;Matt.9.1-17;Mark.1.16-2.22;Luke.4.31-5.39",
+"E_JES17","Sabbath controversies","31-05","31-10",,,"T_JesusGalilee",,,"T_JesusGalilee","Event","Matt 12:1 and parallels around Passover 31. John 5:1 Oct 31","Matt.4.25;Matt.12.1-21;Mark.2.23-3.12;Luke.6.1-11;John.5.1-47",
+"E_JES18","Appointment of the Twelve and Sermon on the Mount","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.5.1-7.29;Mark.3.13-19;Luke.6.12-49",
+"E_JES19","Growing fame; emphasis on repentance","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.8.1;Matt.8.5-13;Matt.11.2-30;Luke.7.1-50",
+"E_JES20","First public rejection by Jewish leaders","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.12.22-50;Mark.3.20-35;Luke.8.1-3;Luke.8.19-21",
+"E_JES21","Secrets about the kingdom taught in parables","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.13.1-52;Mark.4.1-34;Luke.8.4-18",
+"E_JES22","Continuing opposition","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.8.18;Matt.8.23-34;Matt.9.18-34;Matt.13.54-58;Mark.4.35-6.6;Luke.8.22-56",
+"E_JES23","Final Galilean campaign","31-11",,,,"T_JesusGalilee","EM",,"T_JesusGalilee","Event",,"Matt.9.35-11.1;Matt.14.1-12;Mark.6.6-30;Luke.9.1-10",
+"E_JES24","Lesson on the bread of life","32-04",,,,"T_JesusGalileeArea",,,"T_JesusGalileeArea","Event","April 32","Matt.14.13-36;Mark.6.31-56;Luke.9.10-17;John.6.1-71",
+"E_JES25","Lesson on the yeast of the Pharisees, Sadducees and Herodians","32-04",,,,"T_JesusGalileeArea","EM",,"T_JesusGalileeArea","Event",,"Matt.15.1-16.12;Mark.7.1-8.26;John.7.1",
+"E_JES26","Lesson of Messiahship learned and confirmed","32-04",,,,"T_JesusGalileeArea","EM",,"T_JesusGalileeArea","Event",,"Matt.16.13-17.13;Mark.8.27-9.13;Luke.9.18-36",
+"E_JES27","Lessons on responsibility to others","32-04",,,,"T_JesusGalileeArea","EM",,"T_JesusGalileeArea","Event",,"Matt.17.14-18.35;Mark.9.14-50;Luke.9.37-50",
+"E_JES28","Journey to Jerusalem for Tabernacles","32-09",,,,"T_JesusGalileeArea","EM",,"T_JesusGalileeArea","Event",,"Matt.8.19-22;Luke.9.51-62;John.7.2-10",
+"E_JES29","Teachings at Tabernacles","32-09",,,,"T_JesusJudea",,,"T_JesusJudea","Event","Sep 32","John.7.11-8.59",
+"E_JES30","Private lessons on loving service and prayer","32-10",,,,"T_JesusJudea","EM",,"T_JesusJudea","Event",,"Luke.10.1-11.13",
+"E_JES31","Second debate with the scribes and Pharisees","32-11",,,,"T_JesusJudea","EM",,"T_JesusJudea","Event",,"Luke.11.14-13.21",
+"E_JES32","Teaching at the Feast of Dedication","32-12",,,,"T_JesusJudea",,,"T_JesusJudea","Event","Dec 32","John.9.1-10.39",
+"E_JES33","Principles of discipleship","33-01",,,,"T_JesusPerea","EM",,"T_JesusPerea","Event",,"Luke.13.22-17.10;John.10.40-42",
+"E_JES34","Raising of Lazarus and a brief tour through Samaria and Galilee","33-01",,,,"T_JesusPerea","EM",,"T_JesusPerea","Event",,"Luke.17.11-37;John.11.1-54",
+"E_JES35","Teaching on final journey to Jerusalem","33-02",,,,"T_JesusPerea","EM",,"T_JesusPerea","Event",,"Matt.19.1-20.34;Mark.10.1-52;Luke.18.1-19.28",
+"E_JES36","Arrived at Bethany","33-03-28",,,,"T_PassionWeek",,,"T_PassionWeek","Event","Bethany over the Jordan, not the same Bethany as in Matt.26","John.12.1-8",
+"E_JES37","Crowd came to see Jesus","33-03-29",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"John.12.9-11",
+"E_JES38","Triumphal Entry into Jerusalem","33-03-30",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.21.1-11;Mark.11.1-11; Luke.19.28-44;John.12.12-19",
+"E_JES39","Jesus curses the fig tree","33-03-31",,,,"T_PassionWeek",,,"T_PassionWeek","Event","NB: discrepancy between Matthew and Mark here","Mark.11.12-14",
+"E_JES40","Cleansing of the temple","33-03-31",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.21.12-17;Mark.11.15-19;Luke.19.45-46",
+"E_JES41","The fig tree is withered","33-04-01",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.21.18-22;Mark.11.20-25",
+"E_JES42","Jesus teaches and disputes in the temple","33-04-01",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.21.23-23.39; Mark.11.27-12.44;Luke.19.47-21:4",
+"E_JES43","Jesus on the Mount of Olives","33-04-01",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.24.1-25.46;Mark.13.1-37;Luke.21.5-36",
+"E_JES44","Jesus anointed at Bethany","33-04-01",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.4-13;Mark.14.1-9",
+"E_JES45","Judas arranges to betray Jesus","33-04-01",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.14-16;Mark.14.10-11;Luke.22.1-6",
+"E_JES46","The Last Supper","33-04-02",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.17-30;Mark.14.12-26;Luke.22.7-30;John.13.1-30",
+"E_JES47","Jesus's last teaching","33-04-02",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.31-35;Mark.14.27-31;Luke.22.31-38;John.13.31-17.26",
+"E_JES48","The garden of Gethsemane","33-04-02",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.36-46;Mark.14.32-42;Luke.22.39-46;John.18.1",
+"E_JES49","Jesus is arrested","33-04-03",,,,"T_PassionWeek",,,"T_PassionWeek","Event","(With Hastings) assuming arrested around midnight, so start a new day here.","Matt.26.47-56;Mark.14.43-52;Luke.22.47-53;John.18.2-12",
+"E_JES50","Jesus's trials","33-04-03",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.26.57-27.26;Mark.14.53-15.15;Luke.22.54-23.25;John.18.13-19.16",
+"E_JES51","Crucifixion","33-04-03",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.27.27-56;Mark.15.16-41;Luke.22.26-49;John.19.17-37",
+"E_JES52","Burial","33-04-03",,,,"T_PassionWeek",,,"T_PassionWeek","Event","NB: the ""next day"" would start at sunset. Assuming this happened that evening","Matt.27.57-66;Mark.15.42-47;Luke.22.50-56;John.19.38-42",
+"E_JES53","Resurrection","33-04-05",,,,"T_PassionWeek",,,"T_PassionWeek","Event",,"Matt.28.1-15;Mark.16.1-11;Luke.24.1-12;John.20.1-18",
+"E_JES54","Post-resurrection appearances","33-04-05","33-05-14",,,"T_JesusResurrected",,,"T_JesusResurrected","Event",,"Matt.28.16-20;Mark.16.12-18;Luke.24.13-49;John.20.19-21.25;Acts.1.3-8",
+"E_JES55","Ascension","33-05-14",,,,"T_JesusResurrected",,,"T_JesusResurrected","Event",,"Luke.24.50-53;Mark.16.19-20;Acts.1.9-11",

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Monarchy.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Monarchy.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Monarchy.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,175 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Saul","Saul","-1042","-1011","-1050","-1011","T_UnitedMonarchy",,,"T_UnitedMonarchy","Timeline",,,
+"T_David","David ","-1011","-971",,,"T_UnitedMonarchy",,,"T_UnitedMonarchy","Timeline",,,
+"T_Solomon","Solomon","-971","-931",,,"T_UnitedMonarchy",,,"T_UnitedMonarchy","Timeline",,,
+"E_MON1","Saul","-1042","-1011","-1050","-1011",,"10Y",,"T_Saul","Reign",,"1Sam.9-31",
+"E_MON2","Saul anointed as king; Samuel retires","-1042",,"-1050",,"T_Saul","10Y",,"T_Saul","Event",,"1Sam.9-12",
+"E_MON3","Saul fights the Philistines at Gibeah","-1040",,"-1048",,"T_Saul","10Y",,"T_Saul","Event",,"1Sam.13-14",
+"E_MON4","Saul fights the Amalekites; rejected by God","-1026",,"-1034",,"T_Saul","10Y",,"T_Saul","Event",,"1Sam.15",
+"E_MON5","David anointed by Samuel","-1018",,,,"T_Saul",,,"T_Saul","Event",,"1Sam.16",
+"E_MON6","David and Goliath","-1018",,,,"T_Saul",,,"T_Saul","Event",,"1Sam.17",
+"E_MON7","Saul's later reign","-1018","-1011",,,"T_Saul",,,"T_Saul","Event",,"1Sam.18-30","Needs splitting up"
+"E_MON8","Saul's death","-1011",,,,"T_Saul",,,"T_Saul","Event",,"1Sam.31; 1Chr.10",
+"E_MON9","Genealogies",,,,,,,,"T_Bible","Event","not clear what to do with this","1Chr.1-9",
+"E_MON10","David hears of Saul's death","-1011",,,,"T_David",,,"T_David","Event",,"2Sam.1",
+"E_MON11","David ","-1011","-971",,,"T_David",,,"T_David","Reign",,"2Sam.2-24;1Kgs.1-2.9;1Chr.11-29",
+"E_MON12","David king over Judah; fighting with the house of Saul","-1011","-1004",,,"T_David",,,"T_David","Event",,"2Sam.2-4",
+"E_MON13","David anointed king over Israel at Hebron","-1004",,,,"T_David",,,"T_David","Event",,"2Sam.5.1-5; 1Chr.11.1-3; 1Chr.11.10-12.40",
+"E_MON14","David conquers Jerusalem","-1004",,,,"T_David",,,"T_David","Event",,"2Sam.5.6-16; 1Chr.11.4-9",
+"E_MON15","David defeats the Philisines in the Valley of Rephaim","-1003",,,,"T_David",,,"T_David","Event",,"2Sam.5.17-23; 1Chr.17",
+"E_MON16","David brings the Ark to Jerusalem; promise of the Temple","-1001",,,,"T_David",,,"T_David","Event",,"2Sam.6-7;1Chr.13.1-14; 1Chr.15-16","Split?"
+"E_MON17","David builds his palace","-1001",,,,"T_David",,,"T_David","Event",,"1Chr.14.1-7",
+"E_MON18","David's various victories","-1001","-996",,,"T_David",,,"T_David","Event",,"2Sam.8; 1Chr.18",
+"E_MON19","David and Mephibosheth","-996",,,,"T_David",,,"T_David","Event",,"2Sam.9",
+"E_MON20","David defeats the Ammonites","-993",,,,"T_David",,,"T_David","Event",,"2Sam.10; 1Chr.19",
+"E_MON21","David and Bathsheba","-991",,,,"T_David",,,"T_David","Event",,"2Sam.11;1Chr.20.1-3",
+"E_MON22","Nathan rebukes David; death of Bathsheba's child","-990",,,,"T_David",,,"T_David","Event",,"2Sam.12",
+"E_MON23","Amnon and Tamar","-988",,,,"T_David",,,"T_David","Event",,"2Sam.13.1-22",
+"E_MON24","Absalom kills Amnon","-986",,,,"T_David",,,"T_David","Event",,"2Sam.13.23-36",
+"E_MON25","Absalom in Geshur","-986","-983",,,"T_David",,,"T_David","Event",,"2Sam.13.37-39",
+"E_MON26","Absalom returns to Jerusalem","-983",,,,"T_David",,,"T_David","Event",,"2Sam.14",
+"E_MON27","Absalom's rebellion and death","-983","-979",,,"T_David",,,"T_David","Event",,"2Sam.15-19","Split?"
+"E_MON28","Sheba rebels against David","-978",,,,"T_David",,,"T_David","Event",,"2Sam.20",
+"E_MON29","David avenges the Gibeonites","-977",,,,"T_David",,,"T_David","Event",,"2Sam.21.1-14",
+"E_MON30","Wars against the Philistines","-977","-974",,,"T_David",,,"T_David","Event",,"2Sam.21.15-22",
+"E_MON31","David's last words","-972",,,,"T_David",,,"T_David","Event",,"2Sam.22-23",
+"E_MON32","David's census","-971",,,,"T_David",,,"T_David","Event",,"2Sam.24.1-17;1Chr.21.1-17",
+"E_MON33","David's preparations for the building of the Temple and organisation of worship","-971",,,,"T_David",,,"T_David","Event",,"2Sam.24.18-25;1Chr.21.18-29.20",
+"E_MON34","Adonijah's rebellion","-971",,,,"T_David",,,"T_David","Event",,"1Kgs.1",
+"E_MON35","David names Solomon his successor; instructions to Solomon","-971",,,,"T_David",,,"T_David","Event",,"1Kgs.2.1-9;1Chr.22.5-19;1Chr.29.21-25",
+"E_MON36","David's death","-971",,,,"T_David",,,"T_David","Event",,"1Kgs.2.10-12;1Chr.29.26-30",
+"E_MON37","Solomon","-971","-931",,,"T_Solomon",,,"T_Solomon","Reign",,"1Kgs.1.28-11.43;2Chr.1.1-9.31",
+"E_MON38","Solomon establishes his kingdom, granted wisdom","-971","-968",,,"T_Solomon",,,"T_Solomon","Event",,"1Kgs.2.13-4.34;2Chr.1",
+"E_MON39","Building of the Temple","-967-02-02","-960-08",,,"T_Solomon",,,"T_Solomon","Event",,"1Kgs.5-6;1Kgs.7.13-21;2Chr.2-4","See Finnegan S424 for exact 480  dating issue"
+"E_MON40","Building of Solomon's Palace","-960","-947",,,"T_Solomon",,,"T_Solomon","Event",,"1Kgs.7.1-12",
+"E_MON41","Dedication of the Temple","-959-07",,,,"T_Solomon",,,"T_Solomon","Event",,"1Kgs.8;2Chr.5-7",
+"E_MON42","Further activities of Solomon","-958","-936",,,"T_Solomon","EY",,"T_Solomon","Event",,"1Kgs.9.1-11.13;2Chr.8-9",
+"E_MON43","Solomon fights Hadad and Rezon","-936",,,,"T_Solomon","EY",,"T_Solomon","Event",,"1Kgs.11.14-25",
+"E_MON44","Jeroboam rebels against Solomon and flees to Egypt","-934",,,,"T_Solomon","EY",,"T_Solomon","Event",,"1Kgs.11.26-40",
+"E_MON45","Solomon's death","-931",,,,"T_Solomon",,,"T_Solomon","Event",,"1Kgs.11.41-43",
+"E_MON46","Jeroboam I","-931","-910",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.12.16-14.20",
+"E_MON47","Prophecy against Jeroboam by the man of Judah","-930",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.13",
+"E_MON48","Prophecy against Jeroboam by Ahijah","-928",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.14.1-18",
+"E_MON49","Nadab","-910","-909",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.15.25-32",
+"E_MON50","Baasha","-909","-886",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.15.33-16.7",
+"E_MON51","Elah","-886","-885-01-01",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.16.8-14",
+"E_MON52","Zimri","-885-01-01","-885-01-07",,,"T_IsraelMonarchy","EM",,"T_IsraelMonarchy","Reign",,"1Kgs.16.15-20",
+"E_MON53","Tibni","-885-01-07","-885-04",,,"T_IsraelMonarchy","EM",,"T_IsraelMonarchy","Reign","Arguable whether he counts as a king ","1Kgs.16.21-22",
+"E_MON54","Omri","-885-01-07","-874",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.16.21-28",
+"E_MON55","Capital of Israel moved from Tirzah to Samaria","-879",,,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Event",,"1Kgs.16.23-24",
+"E_MON56","Ahab","-874","-853",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.16.29-22.40",
+"E_MON57","Elijah prophesies a drought; fed by ravens","-861",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.17.1-6",
+"E_MON58","The widow at Zarephath","-860",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.17.7-24",
+"E_MON59","Elijah and the prophets of Baal at Mount Carmel","-857",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.18-19.18","Three years after the previous"
+"E_MON60","Elijah calls Elisha","-857",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.19.19-21",
+"E_MON61","Ahab defeats Ben-Hadad of Aram","-856",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.20.1-34",
+"E_MON62","Naboth's vineyard","-855",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"1Kgs.21",
+"E_MON63","Micaiah prophesies against Ahab; Ahab dies in battle at Ramoth Gilead","-853",,,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Event","Attested in Assyrian records as the battle of Qarqar, summer 853. See Finnegan S422","1Kgs.22.1-40;2Chr.18.1-19.3",
+"E_MON64","Ahaziah","-853","-852",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"1Kgs.22.51-53;2Kgs.1.1-18",
+"E_MON65","Joram","-852","-841",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Event","Also Jehoram in the Hebrew, but not to be confused with Jehoram of Judah","2Kgs.3.1-27;2Kgs.9.14-26",
+"E_MON66","Elijah taken up into heaven","-852",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.2.1-18","Usher's estimate. Not even clear in which reign this happens!"
+"E_MON67","Elisha heals the water supply; Elisha jeered for being bald","-851",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.2.19-25",
+"E_MON68","Moab revolts","-850",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.3.14-27",
+"E_MON69","Elisha performs various miracles including healing Naaman","-850",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.4.1-6.23","Split?"
+"E_MON70","Siege of Samaria","-849",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.6.24-7.20",
+"E_MON71","Shunammite woman's land restored","-849","-842",,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event","Takes seven years","2Kgs.8.1-6",
+"E_MON72","Ben-Hadad of Aram murdered and succeeded by Hazael","-842",,,,"T_IsraelMonarchy","EY",,"T_IsraelMonarchy","Event",,"2Kgs.8.7-15",
+"E_MON73","Jehu","-841","-814",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.9.1-10.36",
+"E_MON74","Jehoahaz","-814","-798",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.13.1-9",
+"E_MON75","Jehoash","-798","-782",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.13.10-25",
+"E_MON76","Jeroboam II","-793","-753-06",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign","Co-regent 793-782","2Kgs.14.23-29",
+"E_MON77","Zechariah","-753-06","-752-01",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.15.8-12",
+"E_MON78","Shallum","-752-01","-752-02",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.15.13-16",
+"E_MON79","Menahem","-752-02","-742",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.15.17-22",
+"E_MON80","Pekahiah","-742","-740",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.15.23-26",
+"E_MON81","Pekah","-740","-732",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.15.27-31",
+"E_MON82","Hoshea","-732","-723",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Reign",,"2Kgs.17.1-6",
+"E_MON83","Siege of Samaria","-726","-723",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Event",,"2Kgs.17.4-6",
+"E_MON84","Israel expelled and Samaria resettled","-723","-720",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Event",,"2Kgs.17.7-41;2Kgs.18.9-12",
+"E_MON85","Rehoboam","-931","-913",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"1Kgs.12.1-24;1Kgs.14.21-31;2Chr.10.1-12.16",
+"E_MON86","Accession of Rehoboam and split of the kingdom","-931",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"1Kgs.12.1-24;2Chr.10",
+"E_MON87","Attack by Shishak of Egypt","-927",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"1Kgs.14.25-26;2Chr.12.1-9",
+"E_MON88","Abijah","-913","-911",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Abijam in 1 Kings","1Kgs.15.1-8;2Chr.13.1-22",
+"E_MON89","Asa","-911","-870",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"1Kgs.15.9-24;2Chr.14.1-16.14",
+"E_MON90","Attack by Zerah the Cushite","-901",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.14.9-15",
+"E_MON91","Prophecy by Azariah son of Oded and Asa's reforms","-896-03",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.15.1-19",
+"E_MON92","Asa at war with Baasha of Israel","-895",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event","Dating issue here. Cannot be the 36th year of Asa's reign, since Baasha is dead. Usher proposed 36th year of the split kingdom, which I've followed, but need to check with other sources (Thiele preferably).","1Kgs.15.16-22;2Chr.16.1-10",
+"E_MON93","Asa afflicted with a disease in his foot","-873",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.16.12",
+"E_MON94","Jehoshaphat","-870","-848",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Co-regent 873-871","1Kgs.22.41-50;2Chr.17.1-21.1",
+"E_MON95","Jehoshaphat appoints officials to teach the Law","-867",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.17.7-9",
+"E_MON96","Jehoshaphat marries his son Jehoram to Athaliah of Israel","-864",,,,"T_JudahMonarchy","EY",,"T_JudahMonarchy","Event",,"2Chr.18.1","Needs to be before 863 when their son is born!"
+"E_MON97","Jehoshaphat appoints judges","-852",,,,"T_JudahMonarchy","EY",,"T_JudahMonarchy","Event",,"2Chr.19.4-11","After Ahab dies"
+"E_MON98","Jehoshaphat defeats the Moabites and Ammonites","-850",,,,"T_JudahMonarchy","EY",,"T_JudahMonarchy","Event",,"2Chr.20.1-30",
+"E_MON99","Jehoram","-848","-841",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Co-regent 856-848","2Kgs.8.16-24;2Chr.21.1-20",
+"E_MON100","Ahaziah","-841",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.8.25-29;2Kgs.9.27-29;2Chr.22.1-9",
+"E_MON101","Athaliah","-841","-835",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.11.1-20;2Chr.22.10-23.15",
+"E_MON102","Joash","-835","-796",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Also Jehoash","2Kgs.11.21-12.21;2Chr.23.16-24.27",
+"E_MON103","Joash repairs the Temple","-813",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.12.4-16;2Chr.24.1-14",
+"E_MON104","Joash killed by the Arameans","-796",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.24.23-27",
+"E_MON105","Amaziah","-796","-767",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.14.1-22;2Chr.25.1-28",
+"E_MON106","Azariah","-767","-739",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Also Uzziah. Co-regent 790-767","2Kgs.15.1-7;2Chr.26.1-23",
+"E_MON107","Jotham","-739","-732",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Co-regent 750-739","2Kgs.15.32-38;2Chr.27.1-9",
+"E_MON108","Ahaz","-732","-715-01",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Co-regent 736-732","2Kgs.16.1-20;2Chr.28-1.27",
+"E_MON109","Hezekiah","-715-01","-687",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.18.1-20.21;2Chr.29.1-32.33",
+"E_MON110","Hezekiah reconsecrates the Temple and re-establishes Passover","-715-01","-715-03",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Chr.29.3-31.20",
+"E_MON111","Sennacherib attacks Judah","-701-06",,,,"T_JudahMonarchy","EM",,"T_JudahMonarchy","Event",,"2Kgs.18.13-19.37;2Chr.32.1-23",
+"E_MON112","Hezekiah's illness","-701-08",,,,"T_JudahMonarchy","EM",,"T_JudahMonarchy","Event",,"2Kgs.20.1-11",
+"E_MON113","Hezekiah receives messengers from Merodach-Baladan of Bablyon","-701-09",,,,"T_JudahMonarchy","EM",,"T_JudahMonarchy","Event",,"2Kgs.20.12-19",
+"E_MON114","Manasseh","-687","-643",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Co-regent 698-687","2Kgs.21.1-18;2Chr.33.1-20",
+"E_MON115","Amon","-643","-641",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.21.19-26;2Chr.33.21-25",
+"E_MON116","Josiah","-641","-609-04",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.22.1-23.30;2Chr.34.1-35.27",
+"E_MON117","Book of the Law found; renewal of the covenant","-628",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.22.3-23.25;2Chr.34.3-35.19",
+"E_MON118","Battle of Megiddo","-609-04",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event","June/July","2Kgs.23.29-30;2Chr.35.20-24",
+"E_MON119","Jehoahaz","-609-04","-609-07",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign",,"2Kgs.23.31-35;2Chr.36.1-4",
+"E_MON120","Jehoiakim","-609-07","-598-07-22",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Dec 9th [really? check]","2Kgs.23.36-24.7;2Chr.36.5-8",
+"E_MON121","Jehoiachin","-598-07-22","-597-01-10",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Dec 9th - Mar 16th","2Kgs.24.7-17;2Chr.36.9-11",
+"E_MON122","Zedekiah","-597-01-10","-586-04-09",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Reign","Mar 16th - July 18th","2Kgs.24.18-25.7;2Chr.36.11-21",
+"E_MON123","Capture of Jerusalem and beginning of Exile","-597-01-10",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event","Mar 16th","2Kgs.24.10-14",
+"E_MON124","Final fall of Jerusalem","-586-04-09",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event","July 18th ","2Kgs.25.1-7",
+"E_MON125","Destruction of the Temple","-586-05-07",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.25.8-21",
+"E_MON126","Gedaliah murdered and the exile to Egypt","-586-07","-586-12",,,"T_JudahMonarchy","EM ",,"T_JudahMonarchy","Event",,"2Kgs.25.22-26",
+"E_MON127","Jehoiachin released","-562",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.25.27-30; Jer.52.31-34",
+"B_Isa","Isaiah","-740","-700",,,"T_JudahMonarchy",,,"T_Isaiah","Book","Estimated dates that the prophet was active","Isa.*","IVP dates for these books. Need confirming"
+"B_Jer","Jeremiah","-627","-586",,,"T_JudahMonarchy",,,"T_Jeremiah","Book",,"Jer.*",
+"B_Dan","Daniel","-605","-535",,,"T_Exile",,,"T_Exile","Book",,"Dan.*",
+"B_Hos","Hosea","-760","-722",,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Book",,"Hos.*",
+"B_Joel","Joel","-810","-750",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Book",,"Joel.*",
+"B_Amos","Amos","-760",,,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Book",,"Amos.*",
+"B_Jonah","Jonah","-760",,,,"T_IsraelMonarchy",,,"T_IsraelMonarchy","Book",,"Jonah.*",
+"B_Mic","Micah","-742","-687",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Book",,"Mic.*",
+"B_Nah","Nahum","-664","-612",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Book",,"Nah.*",
+"B_Zeph","Zephaniah","-640",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Book",,"Zeph.*",
+"B_Hab","Habakkuk","-605",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Book",,"Hab.*",
+"E_MON128","Start of siege of Jerusalem","-588-10-10",,,,"T_JudahMonarchy",,,"T_JudahMonarchy","Event",,"2Kgs.25.1",
+"T_Jeremiah","Timeline of Jeremiah","-627","-586",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Timeline",,"Jer.*",
+"E_Jer1","Call and initial prophecies","-627",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.1.4-3.5",
+"E_Jer2","Prophecy during the reign of Josiah","-627","-609",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.3.6-6.30",
+"E_Jer3","Prophecies foretelling the exile ","-627","-597",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.7.1-20.18",
+"E_Jer4","Request from Zedekiah","-588",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.21",
+"E_Jer5","Prophecies against kings of Judah","-609","-586",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.22",
+"E_Jer6","Vision of two baskets of figs","-597",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.24",
+"E_Jer7","Prophecy of disaster but a return after 70 years","-605",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.25",
+"E_Jer8","Jeremiah threatened with death","-609",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.26",
+"E_Jer9","Symbol of the yoke, and Hananiah","-594",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.27-28",
+"E_Jer10","Letter to the exiles","-597","-586",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.29-31",
+"E_Jer11","Jeremiah buys a field; prophecy of destruction but later healing","-587",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.32-33",
+"E_Jer12","A warning to Zedekiah that Jerusalem will fall","-588","-586",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.34.1-7",
+"E_Jer13","Freeing the slaves and re-enslavement","-597","-586",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.34.8-22",
+"E_Jer14","The Recabites","-609","-598",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.35",
+"E_Jer15","Burning Jeremiah's scroll","-605",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.36",
+"E_Jer16","Jeremiah in prison and in a cistern","-597",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.37-38",
+"E_Jer17","The fall of Jerusalem","-588","-586",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.39;Jer.52.1-30",
+"E_Jer18","Jerusalem freed and the exile to Egypt","-586-07","-586-12",,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.40-44",
+"E_Jer19","Message to Baruch ","-605",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.45",
+"E_Jer20","Prophecy against Egypt at the time of Carchemish","-605",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.46",
+"E_Jer21","Prophecy about Elam","-597",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.49.34-39",
+"E_Jer22","Prophecies against Babylon ","-594",,,,"T_Jeremiah",,,"T_Jeremiah","Event",,"Jer.50-51",
+"T_Isaiah","Timeline of Isaiah","-740","-520",,,"T_JudahMonarchy",,,"T_JudahMonarchy","Timeline",,"Isa.*",
+"T_Isa1","Commission of Isaiah","-739",,,,"T_Isaiah",,,"T_Isaiah","Event",,"Isa.6",
+"T_Isa2","Prophecy about Emmanuel and Assyria","-732",,,,"T_Isaiah",,,"T_Isaiah","Event","It isn't clear where this prophecy ends, possibly as late as chapter 12.","Isa.7-8.10",
+"T_Isa3","Prophecy against the Philistines","-715",,,,"T_Isaiah",,,"T_Isaiah","Event",,"Isa.14.28-32",
+"T_Isa4","Prophecy against Egypt and Cush","-712",,,,"T_Isaiah",,,"T_Isaiah","Event",,"Isa.20",
+"T_Isa5","Sennacherib's invasion","-701",,,,"T_Isaiah",,,"T_Isaiah","Event",,"Isa.36-39",
+"T_Isa6","Setting of ""Second Isaiah""","-540",,,,"T_Isaiah","5",,"T_Isaiah","Event",,"Isa.40-55",
+"T_Isa7","Setting of ""Third Isaiah""","-520",,,,"T_Isaiah","5",,"T_Isaiah","Event",,"Isa.56-66",
+"B_Ps","Psalms","-1018","-971",,,"T_UnitedMonarchy",,,"T_UnitedMonarchy","Book","Dating the Psalms is in many cases difficult or impossible, and they seem to have been composed over a wide timeframe. Placed here given the large number written by David (and Asaph, his contemporary) and the traditional association with him.","Ps.*",

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_NTChurch.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_NTChurch.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_NTChurch.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,115 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"E_NTC1","Pentecost","33-05-24",,,,"T_NewTestament",,,"T_NTChurch","Event",,"Acts.2",
+"E_NTC2","Execution of James","41-03",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.12.1-2",
+"E_NTC3","Imprisonment of Peter","41-04","41-05",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.12.3-5",
+"E_NTC4","Death of Herod Agrippa","44-05-01",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.12.23",
+"E_NTC5","Council of Jerusalem","49-01",,,,"T_NewTestament",,,"T_NTChurch","Event",,"Acts.15",
+"E_NTC6","Confrontation of Peter and Paul in Antioch","49-03",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Gal.2.11",
+"E_NTC7","Paul and Barnabas separate","49-04",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.15.36-39",
+"E_NTC8","Execution of Peter and Paul","67-06-29",,,,"T_NewTestament",,,"T_NTChurch","Event",,,
+"E_NTC9","Conversion of Paul ","36-06",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.9.1-7",
+"T_PaulMJ1","Paul's first missionary journey","47-04","48-09",,,"T_NewTestament",,,"T_NTChurch","Timeline",,"Acts.13-14",
+"T_PaulMJ2","Paul's second missionary journey","49-04","51-11",,,"T_NewTestament",,,"T_NTChurch","Timeline",,"Acts.15.36-18.23",
+"T_PaulMJ3","Paul's third missionary journey","52-04","55-05-27",,,"T_NewTestament",,,"T_NTChurch","Timeline",,"Acts.18.23-21.16",
+"E_NTC10","Paul imprisoned in Caesarea","55-05-29","57",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.24.27",
+"T_PaulToRome","Paul's shipwreck journey to Rome","57-08","58-02",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.27.1-28.16",
+"E_NTC12","Paul in custody in Rome","58","60",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.28.30-31",
+"E_NTC13","Peter's second sermon","33-07",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.4.31",
+"E_NTC14","Death of Ananias and Sapphira","33-12",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.4.32-5.11",
+"E_NTC15","Peter brought before Sanhedrin","34-06",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.5.12-42",
+"E_NTC16","Selection of deacons","34-12",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.6.1-7",
+"E_NTC17","Death of Stephen","35-04",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.6.8-7.60",
+"E_NTC18","Paul in Damascus and Arabia","36-06","37-05",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.9.8-25; Gal.1.16-17",
+"E_NTC19","Paul to Jerusalem","37-06",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.9.26-29; Gal.1.18-20",
+"E_NTC20","Paul to Tarsus and Syria-Cilicia","37-10",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.9.30; Gal.1.21",
+"E_NTC21","Peter's ministry to Gentiles","38",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.11-18",
+"E_NTC22","Barnabas to Antioch","39",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.11.19-24",
+"E_NTC23","Paul to Antioch","40-01",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.11.25-26",
+"E_NTC24","Agabus's prediction of famine","41-01",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.11.27-28","[** when was the famine?]"
+"E_NTC25","Paul and Barnabas's relief visit to Jerusalem","41-02",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.11.30",
+"E_NTC26","Paul and Barnabas sent from Antioch","47-04",,,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.13.1-4",
+"E_NTC27","Paul and Barnabas on Cyprus","47-04","47-06",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.13.5-12",
+"E_NTC28","Paul and Barnabas at Pamphylia","47-07-01","47-07-15",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.13.13",
+"E_NTC29","Paul and Barnabs at Pisidian Antioch","47-07-15","47-09-15",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.13.14-52",
+"E_NTC30","Paul and Barnanas at Iconium","47-10","48-02",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.14.1-7",
+"E_NTC31","Paul and Barnabas at Lystra","48-03","48-04",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.14.8-19",
+"E_NTC32","Paul and Barnabas at Derbe","48-05","48-06",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.14.20-23",
+"E_NTC33","Paul and Barnabas return visits","48-06","48-08",,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.14.24-25",
+"E_NTC34","Paul and Barnabas return to Antioch","48-09",,,,"T_PaulMJ1",,,"T_PaulMJ1","Event",,"Acts.14.26",
+"B_Gal","BOOK: Galatians","49-04",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Gal.*","written in Antioch immediately after the events"
+"E_NTC36","Paul departs from Antioch","49-04",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.15.40",
+"E_NTC37","Paul in Syria and Cilicia","49-04",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.15.41",
+"E_NTC38","Paul in Lystra and Derbe ","49-05",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.16.1",
+"E_NTC39","Paul in Iconium","49-06",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.16.4",
+"E_NTC40","Paul in Pisidian Antioch","49-06","49-07",,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.16.4",
+"E_NTC41","Paul from Antoich to Troas","49-07",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.16.6-10",
+"E_NTC42","Paul in Philippi","49-08","49-10",,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.16.11-40",
+"E_NTC43","Paul in Thessalonica","49-10","50-01",,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.17.1-9",
+"E_NTC44","Paul in Berea","50-02",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.17.10-15",
+"E_NTC45","Paul in Athens","50-02","50-03",,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.17.16-34",
+"E_NTC46","Paul in Corinth","50-03","51-09",,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.18.1-17",
+"E_NTC47","Silas and Timothy arrive from Berea","50-04",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.18.5",
+"B_1Thess","BOOK: 1 Thessalonians","50-06",,,,"T_PaulMJ2",,,"T_PaulMJ2","Book",,"1Thess.*","written in Corinth"
+"B_2Thess","BOOK: 2 Thessalonians","50-08",,,,"T_PaulMJ2",,,"T_PaulMJ2","Book",,"2Thess.*","written in Corinth"
+"E_NTC50","Paul in Ephesus","51-09",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.18.19-20",
+"E_NTC51","Paul in Jerusalem (fourth visit)","51-09-30",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.18.22",
+"E_NTC52","Paul in Antioch again","51-11",,,,"T_PaulMJ2",,,"T_PaulMJ2","Event",,"Acts.18.22",
+"E_NTC53","Paul departs from Antioch","52-04",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.18.23",
+"E_NTC54","Paul visits Galatian churches","52-04","52-06",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.18.23",
+"E_NTC55","Paul in Ephesus","52-06","54-07",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.19.1-41",
+"E_NTC56","Paul in Macedonia","54-08","54-11",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.1",
+"B_1Cor","BOOK: 1 Corinthians","54-03",,,,"T_NTChurch",,,"T_NTChurch","Book",,"1Cor.*","written in Ephesus late in stay"
+"B_2Cor","BOOK: 2 Corinthians","54-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"2Cor.*","written in Macedonia"
+"E_NTC59","Paul in Corinth","54-11","55-02",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.2-3",
+"B_Rom","BOOK: Romans","54-12",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Rom.*","written in Corinth"
+"E_NTC61","Paul in Philippi","55-04-06","55-04-14",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.3-5","dates from here on need calibrating for festival dates in 55, not 57"
+"E_NTC62","Paul in Troas","55-04-19","55-04-25",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.6",
+"E_NTC63","Eutychus raised from the dead","55-04-24",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.7-12",
+"E_NTC64","Troas to Assos","55-04-25",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.13","a Monday!"
+"E_NTC65","Assos to Mitylene","55-04-26",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.14",
+"E_NTC66","Mitylene to Chios","55-04-27",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.15",
+"E_NTC67","Chios to Trogyllium","55-04-28",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.15",
+"E_NTC68","Trogyllium to Miletus","55-04-29",,,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.15",
+"E_NTC69","Ephesian elders' visit Paul","55-04-30","55-05-02",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.20.7-38",
+"E_NTC70","Miletus to Patara","55-05-02","55-05-04",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.1 ",
+"E_NTC71","Patara to Tyre","55-05-05","55-05-09",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.2-3",
+"E_NTC72","Paul at Tyre","55-05-10","55-05-16",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.4-6",
+"E_NTC73","Tyre to Caeserea","55-05-17","55-05-19",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.7",
+"E_NTC74","Paul at Caeserea","55-05-19","55-05-25",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.8-14",
+"E_NTC75","Caeserea to Jerusalem","55-05-25","55-05-27",,,"T_PaulMJ3",,,"T_PaulMJ3","Event",,"Acts.21.15-16",
+"E_NTC76","Paul in Jerusalem (fifth visit)","55-05-27",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.21.17","eve of Pentecost"
+"E_NTC77","Paul's meeting with James","55-05-28",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.21.18-26",
+"E_NTC78","Paul's arrest and trial before Felix","55-05-29","55-06-09",,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.21.27-24.22","House includes breakdown of this event"
+"E_NTC79","Paul before Felix and Drusilla","55-06",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.24.24-26","Last event needing calibration"
+"E_NTC80","Paul's trial before Festus","57-07",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.25.7-12",
+"E_NTC81","Paul's trial before Agrippa","57-08-01",,,,"T_NTChurch",,,"T_NTChurch","Event",,"Acts.26",
+"E_NTC82","Paul departs from Caesarea","57-08-15",,,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.27.1-4",
+"E_NTC83","Paul at Myra","57-09-01",,,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.27.5-6",
+"E_NTC84","Paul at Fair Havens","57-10-05","57-10-10",,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.27.8",
+"E_NTC85","Paul shipwrecked at Malta","57-10-31",,,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.27.39-44",
+"E_NTC85a","Paul on Malta","58-11-01","58-01-31",,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.28.1-10",
+"E_NTC86","Paul leaves Malta","58-02-01",,,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.28.11",
+"E_NTC87","Paul arrives at Rome","58-02-25",,,,"T_PaulToRome",,,"T_PaulToRome","Event",,"Acts.28.16",
+"B_Eph","BOOK: Ephesians","58-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Eph.*",
+"B_Col","BOOK: Colossians","59-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Col.*",
+"B_Philemon","BOOK: Philemon","59-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Phlm.*",
+"B_Phil","BOOK: Philippians","60-03",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Phil.*",
+"E_NTC92","Martyrdom of James, brother of Jesus","62-03",,,,"T_NTChurch",,,"T_NTChurch","Event",,,"Spring 62 in House. Other sources give 62 or sometimes 61. (Thought Finegan said 61 but cannot find again.)"
+"E_NTC93","Paul's further journeys","60-04","67-01",,,"T_NTChurch",,,"T_NTChurch","Event",,,"Following Moody and Hoehner (in House). They reconstruct similar schemes but have Paul dying in early 68, not our 67. Killed in the 3 or 4 month interregnum after Porcius Festus died."
+"B_1Tim","BOOK: 1 Timothy","62-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"1Tim.*",
+"B_Tit","BOOK: Titus","66-06",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Titus.*",
+"B_2Tim","BOOK: 2 Timothy","66-09",,,,"T_NTChurch",,,"T_NTChurch","Book",,"2Tim.*","Moody/Hoehner give autumn of 67. Moved a year to fit in with Paul's lifespan"
+"B_Luke","BOOK: Luke","60",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Luke.*","This and remainder from House. Need to substitute Carson/Moo or Moody dates."
+"B_Acts","BOOK: Acts ","61",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Acts.*",
+"B_Mark","BOOK: Mark","62",,,,"T_NTChurch",,,"T_NTChurch","Book",,"Mark.*",
+"B_1Pet","BOOK: 1 Peter","63",,,,"T_NTChurch",,,"T_NTChurch","Book",,"1Pet.*",
+"B_2Pet","BOOK: 2 Peter","64",,,,"T_NTChurch",,,"T_NTChurch","Book","63 or 64","2Pet.*",
+"B_Matt","BOOK: Matthew","67",,,,"T_NTChurch",,,"T_NTChurch","Book","60s","Matt.*",
+"B_Heb","BOOK: Hebrews","67",,,,"T_NTChurch",,,"T_NTChurch","Book","60s","Heb.*",
+"B_Jude","BOOK: Jude","70",,,,"T_NTChurch",,,"T_NTChurch","Book","60s or 70s","Jude.*",
+"B_John","BOOK: John","90",,,,"T_NTChurch",,,"T_NTChurch","Book","late 80s or early 90s","John.*",
+"B_1John","BOOK: 1 John","90",,,,"T_NTChurch",,,"T_NTChurch","Book","late 80s or early 90s","1John.*",
+"B_2John","BOOK: 2 John","90",,,,"T_NTChurch",,,"T_NTChurch","Book","late 80s or early 90s","2John.*",
+"B_3John","BOOK: 3 John","90",,,,"T_NTChurch",,,"T_NTChurch","Book","late 80s or early 90s","3John.*",
+"B_Rev","BOOK: Revelation","90",,,,"T_NTChurch",,,"T_NTChurch","Book","late 80s or early 90s","Rev.*",
+"B_Jas","BOOK: James","45",,,,"T_NTChurch",,,"T_NTChurch","Book","c45 from House. Considerable uncertainty","Jas.*",

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_OTNeighbours.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_OTNeighbours.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_OTNeighbours.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,57 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Persia","Persian kings","-539","-331",,,"T_All",,,"T_All","Timeline","List of the kings of Persia and Media during their period of dominance.",,"From IVP dictionary, entry on Ezra. Finnegan has some slight differences. He's working from source PDBC - check with that"
+"E_PER1","Cyrus","-539","-530",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER2","Cambyses","-530","-522",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER3","Darius I Hystaspes","-522","-486",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER4","Xerxes I","-486","-465",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER5","Artaxerxes I Longimanus","-465","-424",,,"T_Persia",,,"T_Persia","Reign","F has 464-424",,
+"E_PER6","Darius II Nothus","-423","-404",,,"T_Persia",,,"T_Persia","Reign","F has 423-405",,
+"E_PER7","Artaxerxes II Mnemon","-404","-359",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER8","Artaxerxes III Ochus","-359","-338",,,"T_Persia","0/1",,"T_Persia","Reign","Latter is 338/7, ditto with next few unclear dates",,
+"E_PER9","Arses","-338","-336",,,"T_Persia","1",,"T_Persia","Reign",,,
+"E_PER10","Darius III Codomanus","-336","-331",,,"T_Persia","1/0",,"T_Persia","Reign",,,
+"E_PER11","Alexander of Macedon","-331","-323",,,"T_Persia",,,"T_Persia","Reign",,,
+"E_PER12","Persians take Babylon","-539-10-12",,,,"T_Persia",,,"T_Persia","Battle","Tashritu 16 = Oct 12th",,"From Finnegan. S454. Two other related dates here too"
+"T_Mesopotamia","Mesopotamia","-1894","-1329",,,"T_All",,,"T_All","Timeline",,,"From IVP dictionary, entry on Chronology. Certainties are my guesses for now."
+"E_MES1","First Dynasty of Bablyon","-1894","-1595",,,"T_Mesopotamia","100/20",,"T_Mesopotamia","Dynasty",,,
+"E_MES2","Hammurabi","-1792","-1750",,,"T_Mesopotamia","50",,"T_Mesopotamia","Reign",,,
+"E_MES3","Kessite Dynasty","-1500","-1329",,,"T_Mesopotamia","25",,"T_Mesopotamia","Dynasty",,,
+"E_MES4","Burnaburiash I","-1500",,,,"T_Mesopotamia","25",,"T_Mesopotamia","Reign",,,
+"E_MES5","Kurigalzu I","-1350",,,,"T_Mesopotamia","25",,"T_Mesopotamia","Reign",,,
+"E_MES6","Kuilgalzu II","-1345","-1329",,,"T_Mesopotamia","25",,"T_Mesopotamia","Reign",,,
+"T_Assyria","Assyria","-1274","-609",,,"T_All",,,"T_All","Timeline",,,
+"E_ASS1","Shalmeneser I","-1274","-1245",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS2","Tukulti-Ninurta I","-1244","-1208",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS3","Adad-shuma-iddina","-1244","-1219",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS4","Nebuchadrezzar I","-1124","-1103",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS5","Tiglath-pileser I","-1115","-1077",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS6","Ashur-dan II","-933",,,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS7","Ashurnasirpal II","-883","-859",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS8","Shalmaneser III","-859","-824",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS9","Tiglath-pileser III","-745","-727",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS10","Shalmaneser V","-727","-722",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS11","Sargon II","-722","-705",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS12","Sennacherib","-705","-681",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS13","Esarhaddon","-681","-669",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS14","Ashurbanipal","-669","-627",,,"T_Assyria",,,"T_Assyria","Reign",,,
+"E_ASS15","Fall of Ninevah","-612",,,,"T_Assyria",,,"T_Assyria","Event",,,
+"E_ASS16","End of Assyria","-609",,,,"T_Assyria",,,"T_Assyria","Event",,,
+"T_Babylon","Babylon","-626","-539",,,"T_All",,,"T_All","Timeline",,,
+"E_BAB1","Nabopolassar","-626","-605",,,"T_Babylon",,,"T_Babylon","Reign",,,
+"E_BAB2","Nebuchadrezzar II","-605","-562",,,"T_Babylon",,,"T_Babylon","Reign",,,
+"E_BAB3","Amel-Marduk (Evil-merodach)","-562","-560",,,"T_Babylon",,,"T_Babylon","Reign",,,
+"E_BAB4","Neriglissar","-560","-556",,,"T_Babylon",,,"T_Babylon","Reign",,,
+"E_BAB5","Labshi-Marduk","-556",,,,"T_Babylon",,,"T_Babylon","Reign",,,
+"E_BAB6","Nabonidus","-556","-539",,,"T_Babylon",,,"T_Babylon","Reign",,,
+"T_Syria","Syria","-312","-129",,,"T_All",,,"T_All","Timeline",,,
+"E_SYR1","Seleucus I Nicator","-312","-281",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR2","Antiochus I Soter","-281","-261",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR3","Antiochus II Theos","-261","-246",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR4","Seleucus II","-246 ","-226",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR5","Seleucus III Soter","-226","-223",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR6","Antiochus III the Great","-223","-187",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR7","Seleucus IV","-187","-175",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR8","Antiochus IV Epiphanes","-175","-163",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR9","Antiochus V","-163","-162",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR10","Demetrius I","-162","-150",,,"T_Syria",,,"T_Syria","Reign",,,
+"E_SYR11","Antiochus VII Sidetes","-139","-129",,,"T_Syria",,,"T_Syria","Reign",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_PatriarchsToJudges.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_PatriarchsToJudges.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_PatriarchsToJudges.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,186 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"E_PAT1","Birth of Abraham","-1854",,"-2166",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.11.27",
+"E_PAT2","Call of Abraham; Abraham goes from Haran to Canaan","-1779",,"-2091",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.12.1-9",
+"E_PAT3","Birth of Ishmael","-1768",,"-2080",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.16.15-17",
+"E_PAT4","Birth of Isaac","-1754",,"-2066",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.21.1-5",
+"E_PAT5","Mount Moriah","-1739",,"-2051",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.22",
+"E_PAT6","Isaac marries Rebekah","-1714",,"-2026",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.24",
+"E_PAT7","Birth of Jacob and Esau","-1694",,"-2006",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.25.19-26",
+"E_PAT8","Death of Abraham","-1679",,"-1991",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.25.7-11",
+"E_PAT9","Jacob goes to Haran","-1617-02",,"-1929-02",,"T_Isaac","20Y",,"T_Isaac","Event",,"Gen.28-29.14",
+"E_PAT10","Jacob marries Leah and Rachel","-1610",,"-1922",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.29.21-30; Gen.30.1; Gen.30.22-26",
+"E_PAT11","Isaac dies","-1574",,"-1886",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.35.23-29",
+"E_PAT12","Jacob and family move to Egypt","-1564",,"-1876",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.46.1-47.11",
+"E_PAT13","Jacob dies","-1547-01",,"-1859-01",,"T_Isaac","20Y",,"T_Isaac","Event",,"Gen.47.28-49.33",
+"E_PAT14","Birth of Joseph ","-1604",,"-1916",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.30.22-24",
+"E_PAT15","Joseph sold into slavery","-1587",,"-1899",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.37.1-36",
+"E_PAT16","Joseph enters the service of Pharaoh","-1574",,"-1886",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.41.1-45",
+"E_PAT17","Seven years of plenty","-1574","-1567","-1886","-1879","T_Jacob","20",,"T_Jacob","Event",,"Gen.41.46-53",
+"E_PAT18","Seven years of famine","-1567","-1560","-1879","-1872","T_Jacob","20",,"T_Jacob","Event",,"Gen.41.53-47.26",
+"E_PAT19","Joseph dies","-1494",,"-1806",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.50.22-26",
+"E_PAT20","Creation","-3800-09",,"-4112-09",,"T_AdamToAbraham","150Y",,"T_AdamToAbraham","Event",,"Gen.1-2","made up"
+"E_PAT21","The Fall","-3800-10",,"-4112-10",,"T_AdamToAbraham","125Y",,"T_AdamToAbraham","Event",,"Gen.3","made up"
+"E_PAT22","Cain and Abel","-3700","-3670","-4012","-3982","T_AdamToAbraham","100",,"T_AdamToAbraham","Event",,"Gen.4","made up"
+"E_PAT23","The Flood","-2145",,"-2457",,"T_AdamToAbraham","70",,"T_AdamToAbraham","Event",,"Gen.6.1-8.17",
+"E_PAT24","Table of Nations","-2145","-2045","-2457","-2357",,"70","EY","T_AdamToAbraham","Event",,"Gen.10","and probably later, but a reasonable place to put it on the timeline"
+"E_PAT25","Tower of Babel","-2045",,"-2357",,"T_AdamToAbraham","70",,"T_AdamToAbraham","Event",,"Gen.11.1-9","Usher dates here on the grounds of Gen 10:25 (at Peleg's birth)"
+"E_PAT26","Abraham in Egypt","-1775",,"-2087",,"T_Abraham","20","EY","T_Abraham","Event",,"Gen.12.10-20","Usher puts in same year as vv1-9"
+"E_PAT27","Abraham returns from Egypt","-1773",,"-2085",,"T_Abraham","20","EY","T_Abraham","Event",,"Gen.13","ditto"
+"E_PAT28","Abraham rescues Lot","-1770-01",,"-2082-01",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.14","Usher's dating"
+"E_PAT29","God's first covenant with Abraham","-1770-07",,"-2082-07",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.15","ditto"
+"E_PAT30","Abraham sleeps with Hagar","-1769",,"-2081",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.16.1-14","10 years after Gen 12:1-9 (v3)"
+"E_PAT31","Circumcision covenant ","-1755-01",,"-2067-01",,"T_Abraham","20Y","EM","T_Abraham","Event",,"Gen.17",
+"E_PAT32","The three visitors; Abraham pleads for Sodom","-1755-04",,"-2067-04",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.18","Usher has same year as previous"
+"E_PAT33","Destruction of Sodom and Gomorrah","-1755-05",,"-2067-05",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.19",
+"E_PAT34","Abraham in Gerar with Abimelech","-1755-09",,"-2067-09",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.20",
+"E_PAT35","Hagar and Ishmael sent away","-1750-01",,"-2062-01",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.21.8-21",
+"E_PAT36","Treaty at Beersheba","-1750-07",,"-2062-07",,"T_Abraham","20Y","EY","T_Abraham","Event",,"Gen.21.22-34",
+"E_PAT37","Death of Sarah; purchase of field at Machpelah","-1717",,"-2029",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.23",
+"E_PAT38","Abraham marries Keturah","-1711",,"-2023",,"T_Abraham","20","EY","T_Abraham","Event",,"Gen.25.1-6","(from Thompson cross-reference, shifted. Not in Usher.)"
+"E_PAT39","Ishmael's descendents","-1738","-1708","-2050","-2020","T_Abraham","20","EY","T_Abraham","Event",,"Gen.25.12-16","made up"
+"E_PAT40","Death of Ishmael","-1629",,"-1941",,"T_Abraham","20",,"T_Abraham","Event",,"Gen.25.17-18",
+"E_PAT41","Isaac in Gerar with Abimelech","-1670","-1660","-1982","-1972","T_Isaac","20","EY","T_Isaac","Event",,"Gen.26.1-33","made up"
+"E_PAT42","Esau marries Judith and Basemath","-1654",,"-1966",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.26.34-35",
+"E_PAT43","Jacob steals Esau's birthright","-1617",,"-1929",,"T_Isaac","20",,"T_Isaac","Event",,"Gen.27",
+"E_PAT44","Birth of Jacob's oldest ten sons","-1610","-1604","-1922","-1916","T_Isaac","20","EY","T_Isaac","Event",,"Gen.29.31-30.21",
+"E_PAT45","Jacob leaves Laban and returns to Israel","-1598",,"-1910",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.30.25-33.20","split into bits?"
+"E_PAT46","Dinah and the Shechenites","-1595",,"-1907",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.34","Thompson again (no evidence)"
+"E_PAT47","Jacob builds an altar at Bethel","-1592",,"-1904",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.35.1-15","ditto"
+"E_PAT48","Rachel dies","-1576",,"-1888",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.35.16-20","before Jacob dies, but not clear how much"
+"E_PAT49","Reuben sleeps with Bilhah","-1575",,"-1887",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.35.21-22",
+"E_PAT50","Esau's descendants","-1644","-1544","-1956","-1856","T_Jacob","20","EY","T_Jacob","Event",,"Gen.36","made up"
+"E_PAT51","Judith and Tamar","-1587",,"-1899",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.38",
+"E_PAT52","Joseph and Potiphar's wife","-1582",,"-1894",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.39","made up"
+"E_PAT53","Joseph, the cupbearer and the baker","-1576",,"-1888",,"T_Jacob","20","EY","T_Jacob","Event",,"Gen.40",
+"E_PAT54","Joseph's brothers visit Egypt","-1566",,"-1878",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.42",
+"E_PAT55","Joseph's brothers visit Egypt a second time ","-1565",,"-1877",,"T_Jacob","20",,"T_Jacob","Event",,"Gen.43-45",
+"E_PAT56","Joseph buries Jacob","-1547-07",,"-1859-07",,"T_Jacob","20Y",,"T_Jacob","Event",,"Gen.50-1-21",
+"E_PAT57","Adam","-3800","-2870","-4112","-3182","T_AdamToAbraham","100",,"T_AdamToAbraham","Event",,"Gen.1.26-28; Gen.2.15-3.24; Gen.5.1-5",
+"E_PAT58","Seth","-3670","-2758","-3982","-3070","T_AdamToAbraham","100",,"T_AdamToAbraham","Event",,"Gen.5.6-8",
+"E_PAT59","Enosh","-3565","-2660","-3877","-2972","T_AdamToAbraham","100",,"T_AdamToAbraham","Event",,"Gen.5.9-11",
+"E_PAT60","Kenan","-3475","-2565","-3787","-2877","T_AdamToAbraham","100",,"T_AdamToAbraham","Event",,"Gen.5.12-14",
+"E_PAT61","Mahalaleel","-3405","-2510","-3717","-2822","T_AdamToAbraham","95",,"T_AdamToAbraham","Event",,"Gen.5.15-17",
+"E_PAT62","Jared","-3340","-2378","-3652","-2690","T_AdamToAbraham","90",,"T_AdamToAbraham","Event",,"Gen.5.18-20",
+"E_PAT63","Enoch","-3178","-2813","-3490","-3125","T_AdamToAbraham","85",,"T_AdamToAbraham","Event",,"Gen.5.21-24",
+"E_PAT64","Methusaleh","-3113","-2144","-3425","-2456","T_AdamToAbraham","80",,"T_AdamToAbraham","Event",,"Gen.5.25-27",
+"E_PAT65","Lamech","-2926","-2149","-3238","-2461","T_AdamToAbraham","75",,"T_AdamToAbraham","Event",,"Gen.5.28-30",
+"E_PAT66","Noah","-2744","-1794","-3056","-2106","T_AdamToAbraham","70",,"T_AdamToAbraham","Event",,"Gen.5.31-9.29",
+"E_PAT67","Shem","-2244","-1644","-2556","-1956","T_AdamToAbraham","65",,"T_AdamToAbraham","Event",,"Gen.5.32;Gen.11.10-11",
+"E_PAT68","Arphaxad","-2144","-1706","-2456","-2018","T_AdamToAbraham","60",,"T_AdamToAbraham","Event",,"Gen.11.12-13",
+"E_PAT69","Shelah","-2109","-1676","-2421","-1988","T_AdamToAbraham","55",,"T_AdamToAbraham","Event",,"Gen.11.14-15",
+"E_PAT70","Eber","-2079","-1615","-2391","-1927","T_AdamToAbraham","50",,"T_AdamToAbraham","Event",,"Gen.11.16-17",
+"E_PAT71","Peleg","-2045","-1806","-2357","-2118","T_AdamToAbraham","45",,"T_AdamToAbraham","Event",,"Gen.11.18-19",
+"E_PAT72","Reu","-2015","-1776","-2327","-2088","T_AdamToAbraham","40",,"T_AdamToAbraham","Event",,"Gen.11.20-21",
+"E_PAT73","Serug","-1983","-1753","-2295","-2065","T_AdamToAbraham","35",,"T_AdamToAbraham","Event",,"Gen.11.22-23",
+"E_PAT74","Nahor","-1953","-1805","-2265","-2117","T_AdamToAbraham","30",,"T_AdamToAbraham","Event",,"Gen.11.24-25",
+"E_PAT75","Terah","-1924","-1719","-2236","-2031","T_AdamToAbraham","25",,"T_AdamToAbraham","Event",,"Gen.11.26-32",
+"E_PAT76","Sojourn in Egypt","-1564","-1251","-1876","-1446","T_BirthOfTheNation","20/10",,"T_BirthOfTheNation","Event",,"Exod.1.1-7",
+"E_PAT79","Joshua and the Elders","-1210","-1200","-1406","-1385","T_Judges","10Y",,"T_Judges","Reign",,,
+"E_PAT80","Mesopotamia/Cushan-rishathaim","-1200","-1192","-1385","-1377","T_Judges","10Y",,"T_Judges","Reign",,"Judg.3.8",
+"E_PAT81","Othniel","-1192","-1152","-1377","-1337","T_Judges","10Y",,"T_Judges","Reign",,"Judg.3.9-11",
+"E_PAT82","Moabites/Eglon","-1200","-1182","-1337","-1319","T_Judges","10Y",,"T_Judges","Reign",,"Judg.3.12-14",
+"E_PAT83","Ehud (and peace)","-1182","-1102","-1319","-1239","T_Judges","10Y",,"T_Judges","Reign",,"Judg.3.15-30",
+"E_PAT84","Philistines","-1175","-1170","-1265","-1260","T_Judges","10Y",,"T_Judges","Reign","No time information given. Allotted a random 5 years","Judg.3.31",
+"E_PAT85","Shamgar","-1170",,"-1260","-1250","T_Judges","10Y",,"T_Judges","Reign","No idea why Walton picks 10 years, or this particular time frame","Judg.3.31",
+"E_PAT86","Canaanites/Jabin","-1180","-1160","-1259","-1239","T_Judges","10Y",,"T_Judges","Reign",,"Judg.4.2-3",
+"E_PAT87","Deborah","-1165","-1150","-1239","-1199","T_Judges","10Y",,"T_Judges","Reign",,"Judg.4.4-5.31",
+"E_PAT88","Midianites/Oreb etc","-1186","-1179","-1199","-1192","T_Judges","10Y",,"T_Judges","Reign",,"Judg.6.1-6",
+"E_PAT89","Gideon","-1179","-1139","-1192","-1152","T_Judges","10Y",,"T_Judges","Reign",,"Judg.6.7-8.35",
+"E_PAT90","Civil War of Abimelech","-1139","-1136","-1152","-1149","T_Judges","10Y",,"T_Judges","Reign",,"Judg.9",
+"E_PAT91","Tola","-1136","-1113","-1149","-1126","T_Judges","10Y",,"T_Judges","Reign",,"Judg.10.1-2",
+"E_PAT92","Jair","-1113","-1091","-1126","-1104","T_Judges","10Y",,"T_Judges","Reign",,"Judg.10.3-6",
+"E_PAT93","Ammonites","-1091","-1073","-1104","-1086","T_Judges","10Y",,"T_Judges","Reign",,"Judg.10.7-9",
+"E_PAT94","Jepthtah","-1073","-1067","-1086","-1080","T_Judges","10Y",,"T_Judges","Reign",,"Judg.10.10-12.7",
+"E_PAT95","Ibzan","-1067","-1060","-1080","-1072","T_Judges","10Y",,"T_Judges","Reign",,"Judg.12.8-10",
+"E_PAT96","Elon","-1060","-1050","-1072","-1062","T_Judges","10Y",,"T_Judges","Reign",,"Judg.12.11-12",
+"E_PAT97","Abdon","-1050","-1042","-1062","-1055","T_Judges","10Y",,"T_Judges","Reign",,"Judg.12.13-15",
+"E_PAT98","Philistines again","-1100","-1060","-1115","-1075","T_Judges","10Y",,"T_Judges","Reign",,"Judg.13.1",
+"E_PAT99","Samson","-1080","-1060","-1075","-1055","T_Judges","10Y",,"T_Judges","Reign",,"Judg.13.2-16.31",
+"E_PAT100","Eli","-1102","-1062","-1100","-1060","T_Judges","10Y",,"T_Judges","Reign","Walton puts 1Sam4 at 1060, 1Sam7 at 1050 so this and next entry inferred","1Sam.1-4",
+"E_PAT101","Samuel","-1062","-1042","-1060","-1050","T_Judges","10Y",,"T_Judges","Reign",,"1Sam.3-12",
+"E_PAT102","Pharoah oppresses Israel and orders the death of the children","-1332",,"-1528",,"T_Exodus","10Y",,"T_Exodus","Event","All month/days are in the Jewish calendar","Exod.1.8-22",
+"E_PAT103","Birth of Moses","-1330",,"-1526",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.2.1-10",
+"E_PAT104","Moses flees to Midian","-1290",,"-1486",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.2.11-22",
+"E_PAT105","God hears Israel's groaning","-1290","-1252","-1486","-1448",,"10Y",,"T_Exodus","Event",,"Exod.2.23-25",
+"E_PAT106","Burning Bush and call of Moses","-1251-02",,"-1447-02",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.3-4.17",
+"E_PAT107","Moses returns to Egypt and meets Pharaoh","-1251-06",,"-1447-06",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.4.18-6.30",
+"E_PAT108","Moses and Aaron before Pharaoh; the threat of the plagues","-1251-10",,"-1447-10",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.7.1-13",
+"E_PAT109","1st plague: water turned to blood","-1251-12-18","-1251-12-24","-1447-12-18","-1447-12-24","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.7.14-25","No evidence to suggest how separated the plagues were"
+"E_PAT110","2nd plague: frogs","-1251-12-25","-1251-12-26","-1447-12-25","-1447-12-26","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.8.1-15",
+"E_PAT111","3rd plague: gnats","-1251-12-27",,"-1447-12-27",,"T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.8.16-19",
+"E_PAT112","4th plague: flies","-1251-12-28","-1251-12-30","-1447-12-28","-1447-12-30","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.8.20-32",
+"E_PAT113","5th plague: livestock die","-1250-01-01",,"-1446-01-01",,"T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.9.1-7",
+"E_PAT114","6th plague: boils","-1250-01-03",,"-1446-01-03",,"T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.9.8-12",
+"E_PAT115","7th plague: hail","-1250-01-04","-1250-01-05","-1446-01-04","-1446-01-05","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.9.13-35",
+"E_PAT116","8th plague: locusts","-1250-01-07","-1250-01-09","-1446-01-07","-1446-01-09","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.10.1-20",
+"E_PAT117","9th plague: darkness","-1250-01-11","-1250-01-13","-1446-01-11","-1446-01-13","T_Exodus","10Y","EM","T_Exodus","Event",,"Exod.10.21-23",
+"E_PAT118","Moses before Pharaoh for the last time; last plague promised","-1250-01-14",,"-1446-01-14",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.10.24-11.10",
+"E_PAT119","Passover commanded","-1250-01-14",,"-1446-01-14",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.12.1-28",
+"E_PAT120","10th plague: death of the firstborn","-1250-01-15",,"-1446-01-15",,"T_Exodus","10Y",,"T_Exodus","Event",,"Exod.12.29-32",
+"E_PAT121","Departure from Egypt","-1250-01-15","-1250-01-20","-1446-01-15","-1446-01-20","T_Exodus","10Y",,"T_Exodus","Event",,"Exod.12.33-13.22",
+"E_PAT122","Crossing the Red Sea","-1250-01-21",,"-1446-01-21",,"T_Exodus","10Y",,"T_Exodus","Event","Jewish tradition is that this is on the 21st.","Exod.14-15.21",
+"E_PAT123","Red Sea to Marah","-1250-01-22","-1250-01-24","-1446-01-22","-1446-01-24","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.15.22",
+"E_PAT124","At Marah","-1250-01-24",,"-1446-01-24",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.15.23-26",
+"E_PAT125","At Elim","-1250-02-01","-1250-02-08","-1446-02-01","-1446-02-08","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.15.27",
+"E_PAT126","Giving of Manna","-1250-02-15","-1250-02-21","-1446-02-15","-1446-02-21","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.16",
+"E_PAT127","Water from the Rock at Rephidim","-1250-02-22",,"-1446-02-22",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.17.1-7",
+"E_PAT128","Israel defeats Amalek","-1250-02-24",,"-1446-02-24",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.17-8-16",
+"E_PAT129","Jethro visits Moses","-1250-02-25","-1250-02-28","-1446-02-25","-1446-02-28","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.18",
+"E_PAT130","Israel arrive at Mount Sinai","-1250-03-01",,"-1446-03-01",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.19.1-15",
+"E_PAT131","Giving of the Ten Commandments","-1250-03-03",,"-1446-03-03",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.19-16-20.21",
+"E_PAT132","Moses given the Law","-1250-03-04",,"-1446-03-04",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.20.22-23.33",
+"E_PAT133","The seventy elders worship God","-1250-03-05",,"-1446-03-05",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.24.1-14",
+"E_PAT134","Moses on the mountain for 40 days","-1250-03-06","-1250-04-15","-1446-03-06","-1446-04-15","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.24.15-31.18",
+"E_PAT135","The Golden Calf","-1250-04-16","-1250-04-17","-1446-04-16","-1446-04-17","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.32",
+"E_PAT136","Moss on the mountain a second time for 40 days","-1250-04-21","-1250-05-30","-1446-04-21","-1446-05-30","T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.33.1-34.28",
+"E_PAT137","Construction of the Tabernacle","-1250-06-01","-1250-12-30","-1446-06-01","-1446-12-30","T_Wilderness","10Y","EM","T_Wilderness","Event",,"Exod.34.29-39.43",
+"E_PAT138","Erection of the Tabernacle","-1249-01-01",,"-1445-01-01",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Exod.40",
+"E_PAT139","Giving of the Levitical Law and other commands","-1249-01-01","-1249-02-19","-1445-01-01","-1445-02-19","T_Wilderness","10Y",,"T_Wilderness","Event",,"Lev.*; Num.6-8; Num.10.1-10",
+"E_PAT140","Celebrating the Passover at Sinai","-1249-01-14",,"-1445-01-14",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Num.9",
+"E_PAT141","Taking a census at Sinai","-1249-02-01",,"-1445-02-01",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Num.1-5",
+"E_PAT142","The Israelites leave Sinai","-1249-02-20",,"-1445-02-20",,"T_Wilderness","10Y",,"T_Wilderness","Event",,"Num.10.11-36",
+"E_PAT143","Sinai to Paran","-1249-03-01","-1249-04-30","-1445-03-01","-1445-04-30","T_Wilderness","10Y","EM","T_Wilderness","Event","timing is Ussher","Num.11-12",
+"E_PAT144","Exploring Canaan","-1249-05-01","-1249-06-30","-1445-05-01","-1445-06-30","T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.13-14",
+"E_PAT145","Israel in the Wilderness","-1249-07-01","-1212-12-30","-1445-07-07","-1408-12-30","T_Wilderness","10Y",,"T_Wilderness","Event","No dating information here","Num.15.1-19.22",
+"E_PAT146","Death of Miriam","-1211-01-01",,"-1407-01-01","-1407-01-01","T_Wilderness","10Y",,"T_Wilderness","Event","20.1 has ""in the first month"". Ussher reads this as the last year. Scattered events across the year","Num.20.1",
+"E_PAT147","Waters of Meribah","-1211-01-15",,"-1407-01-15",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.20.1-13",
+"E_PAT148","Edom refuses passage","-1211-02",,"-1407-02",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.20.14-21",
+"E_PAT149","Death of Aaron ","-1211-03",,"-1407-03",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.20.22-28",
+"E_PAT150","Defeat of Arad, Sihon king of the Amorites and Og king of Bashan","-1211-04",,"-1407-04",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.21",
+"E_PAT151","Balak and Balaam","-1211-05",,"-1407-05",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.22-24",
+"E_PAT152","The plague of Peor","-1211-06-07",,"-1407-06-07",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.25",
+"E_PAT153","Census of the new generation","-1211-06-21",,"-1407-06-21",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.26.1-27.11",
+"E_PAT154","Joshua consecrated as successor to Moses","-1211-07",,"-1407-07",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.27.12-23",
+"E_PAT155","Laws concerning offerings and vows","-1211-07",,"-1407-07",,,"10Y","EM","T_Wilderness","Event",,"Num.28-30",
+"E_PAT156","Vengeance on Midian","-1211-08",,"-1407-08",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.31",
+"E_PAT157","Reuben and Gad settle in Gilead","-1211-09",,"-1407-09",,"T_Wilderness","10Y","EM","T_Wilderness","Event",,"Num.32",
+"E_PAT158","Summary of the journey","-1250","-1211","-1446","-1407",,"10Y","EM","T_Wilderness","Event",,"Num.33",
+"E_PAT159","Further commandments","-1211-10",,"-1407-10",,,"10Y","EM","T_Wilderness","Event",,"Num.34-36",
+"E_PAT160","Moses speaks to Israel in Moab","-1211-11-01","-1211-11-30","-1407-11-01","-1407-11-30","T_Wilderness","10Y",,"T_Wilderness","Event","Unclear how long all this takes","Deut.1-33",
+"E_PAT161","Moses's death","-1211-12-01","-1211-12-01","-1407-12-01","-1407-12-01","T_Wilderness","10Y",,"T_Wilderness","Event",,"Deut.34",
+"E_PAT162","Commissioning of Joshua","-1210-01-01",,"-1406-01-01",,"T_Conquest","10Y",,"T_Conquest","Event",,"Josh.1","First available day after the mourning period."
+"E_PAT163","Spies sent to Jericho","-1210-01-03","-1210-01-08","-1406-01-03","-1406-01-08","T_Conquest","10Y",,"T_Conquest","Event",,"Josh.2","Hid for three days, plus travelling time"
+"E_PAT164","Crossing of the Jordan ","-1210-01-10",,"-1406-01-10",,"T_Conquest","10Y",,"T_Conquest","Event",,"Josh.3-4","Stated date (4:19)"
+"E_PAT165","Circumcision of the new generation","-1210-01-11","-1210-01-13","-1406-01-11","-1406-01-13","T_Conquest","10Y",,"T_Conquest","Event",,"Josh.5.1-9",
+"E_PAT166","First Passover in Canaan","-1210-01-14",,"-1406-01-14",,"T_Conquest","10Y",,"T_Conquest","Event",,"Josh.5.10-12","Stated date (5:10)"
+"E_PAT167","Fall of Jericho","-1210-01-18","-1210-01-24","-1406-01-18","-1406-01-24","T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.5.13-6.27","7 days, presumably not long after Passover"
+"E_PAT168","Defeat at Ai","-1210-02-01",,"-1406-02-01",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.7","Spread these events out a bit"
+"E_PAT169","Fall of Ai","-1210-02-08",,"-1406-02-08",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.8.1-29",
+"E_PAT170","Renewal of the covenant","-1210-02-14",,"-1406-02-14",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.8.30-35",
+"E_PAT171","Treaty with the Gibeonites","-1210-04",,"-1406-04",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.9",
+"E_PAT172","Battle with the five kings of the Amorites","-1210-05",,"-1406-05",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.10.1-28",
+"E_PAT173","Conquest of Southern Canaan","-1209","-1208","-1405","-1404","T_Conquest","10Y","EY","T_Conquest","Event",,"Josh.10.29-43",
+"E_PAT174","Conquest of Northern Canaan","-1207","-1206","-1403","-1402","T_Conquest","10Y","EY","T_Conquest","Event",,"Josh.11 ","We have four years before chapter 13, so split N and S 50/50"
+"E_PAT175","Summaries of conquests","-1211","-1206","-1407","-1402",,"10Y","EY","T_Conquest","Event",,"Josh.12 ",
+"E_PAT176","Division of the land of Canaan","-1204-01",,"-1200-01",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.13-21","45 years after Num13-14 (vv7-10)"
+"E_PAT177","Eastern tribes return home and build an altar","-1204-02",,"-1200-02",,"T_Conquest","10Y","EM","T_Conquest","Event",,"Josh.22","Immediately after previous"
+"E_PAT178","Joshua's death","-1200",,"-1385",,"T_Conquest","10Y",,"T_Conquest","Event",,"Josh.23-24","Joshua 110, but this is of no use given no other dating for him"
+"E_PAT179","Samuel's birth","-1092",,"-1090",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.1.1-23",
+"E_PAT180","Samuel's dedication","-1089",,"-1087",,"T_Judges","10Y","EY","T_Judges","Event",,"1Sam.1.24-2.11","Age 3 seems reasonable given other events"
+"E_PAT181","Prophecies against Eli's sons","-1089","-1086","-1087","-1084","T_Judges","10Y",,"T_Judges","Event",,"1Sam.2.12-36",
+"E_PAT182","Samuel called as a prophet","-1086",,"-1084",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.3.1-18",
+"E_PAT183","Samuel recognised as a prophet","-1086","-1062","-1084","-1060","T_Judges","10Y",,"T_Judges","Event",,"1Sam.3.19-21",
+"E_PAT184","Philistines capture the Ark; Death of Eli","-1062",,"-1060",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.4-5",
+"E_PAT185","Ark returned to Israel at Kiriath Jearim","-1042",,"-1050",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.6-7.1",
+"E_PAT186","Samuel defeats the Philistines at Mizpah","-1042",,"-1050",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.7.2-17",
+"E_PAT187","Israel asks for a king","-1042",,"-1050",,"T_Judges","10Y",,"T_Judges","Event",,"1Sam.8",

Added: trunk/step-dataloader/src/main/resources/data/timeline/TL_Rome.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline/TL_Rome.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline/TL_Rome.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,36 @@
+"ID","Name","From","To","From2","To2","Importance","Certainty","Flags","Timeline","Type","Description","Refs","Notes"
+"T_Rome","Ancient Rome","-753","476",,,"T_All",,,"T_All","Timeline",,,"Taken from House (selected items)"
+"E_RomanKingdom","Roman Kingdom","-753","-509",,,"T_Rome",,,"T_Rome","Event","Rome ruled by seven kings",,"(Not enough for a timeline?)"
+"T_RomanRepublic","Roman Republic","-508","-27",,,"T_Rome",,,"T_Rome","Timeline","Rome a republic",,
+"T_RomanEmpire","Roman Empure","-27","476",,,"T_Rome",,,"T_Rome","Timeline","Period of the Roman Empire until its fall in the west",,
+"E_Rome1","Roman capture of Jerusalem","-63",,,,"T_RomanRepublic",,,"T_RomanRepublic","Event","Pompey captures Jerusalem",,
+"E_Rome2","Julius Caesar's invasions of Britain","-55","-54",,,"T_RomanRepublic",,,"T_RomanRepublic","Event",,,
+"E_Rome3","Assassination of Julius Caesar","-44-03-15",,,,"T_RomanRepublic",,,"T_RomanRepublic","Event",,,
+"E_Rome4","Roman annexation of Egypt","-30",,,,"T_RomanRepublic",,,"T_RomanRepublic","Event",,,
+"E_Rome5","Augustus","-27","14",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome6","Tiberius","14","37",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome7","Caligula","37","41",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome8","Claudius","41","54",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome9","Nero","54","68-06-09",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome10","Galba","68-06-09","69-01-15",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome11","Otho","69-01-15","69-04-16",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome12","Vitellius","69-04-26","69-12-20",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome13","Vespasian","69-12-21","79",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome14","Titus","79","81",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome15","Domitian","81","96",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome16","Nerva","96","98",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome17","Trajan ","98","117",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome18","Hadrian","117","138",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome19","Roman annexation of Galatia","-25",,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome20","Roman invasion of Britain","43",,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome21","Great Fire of Rome","64",,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome22","Destruction of Jerusalem","70",,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,"(Needs to go into both Roman and Jewish timelines)"
+"E_Rome23","Destruction of Pompeii and Herculaneum","79",,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome24","Revolt of the Jews in the East","132","134",,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome25","Constantine converts to Christianity",312,,,,"T_RomanEmpire",,,"T_RomanEmpire","Event",,,
+"E_Rome26","Theodosius I","379","395",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome27","Constantine I","306","337",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome28","Marcus Aurelius","161","180",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome29","Decius","249","251",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome30","Valerian","253","260",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,
+"E_Rome31","Dicocletian","284","305",,,"T_RomanEmpire",,,"T_RomanEmpire","Reign",,,

Added: trunk/step-dataloader/src/main/resources/data/timeline_reference_corrections.csv
===================================================================
--- trunk/step-dataloader/src/main/resources/data/timeline_reference_corrections.csv	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/data/timeline_reference_corrections.csv	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,76 @@
+SUB_TIMEBAND_CODE,
+T_EgyptD12,CENTURY
+,#DELETE#
+T_BirthOfTheNation,CENTURY
+T_ArchCult,CENTURY
+T_Ezekiel,DECADE
+T_LifeOfJesus,YEAR
+T_Europe,CENTURY
+T_EgyptD19,CENTURY
+T_PaulToRome,YEAR
+T_China,CENTURY
+T_ACModern,CENTURY
+T_All,MILLENIUM
+T_EgyptD18,CENTURY
+T_Abraham,YEAR
+T_Bible,MILLENIUM
+T_PaulMJ1,MONTH
+T_Isaac,YEAR
+T_NewTestament,DECADE
+T_PaulMJ3,MONTH
+T_PaulMJ2,MONTH
+T_Babylon,MILLENIUM
+T_JesusGalilee,MONTH
+T_Monarchy,DECADE
+T_JesusPerea,MONTH
+T_ACBronzeAge,MILLENIUM
+T_JudahMonarchy,DECADE
+T_Patriarchs,YEAR
+T_Syria,MILLENIUM
+T_Wilderness,DECADE
+T_ACIronAge,MILLENIUM
+T_Herodians,CENTURY
+T_Africa,MILLENIUM
+-,#DELETE#
+T_Rome,CENTURY
+T_Assyria,CENTURY
+T_PassionWeek,DAY
+T_JesusEarly,YEAR
+T_EgyptPtolemaic,MILLENIUM
+T_Judges,DECADE
+T_Solomon,DECADE
+T_JesusResurrected,WEEK
+T_Jacob,YEAR
+T_ExileAndReturn,YEAR
+T_UnitedMonarchy,YEAR
+T_Persia,CENTURY
+T_Isaiah,CENTURY
+T_ACBabylonPersia,CENTURY
+T_Saul,YEAR
+T_Americas,MILLENIUM
+T_ACRomeByzantium,MILLENIUM
+T_Mesopotamia,MILLENIUM
+T_David,DECADE
+T_EarlyChurch,YEAR
+T_India,CENTURY
+T_Hasmonean,CENTURY
+T_AdamToAbraham,MILLENIUM
+T_NTChurch,YEAR
+T_Conquest,YEAR
+T_Greece,CENTURY
+T_JesusJudea,MONTH
+T_RomanRepublic,CENTURY
+T_Jeremiah,DECADE
+T_IsraelMonarchy,DECADE
+T_ACJewishPeriod,CENTURY
+T_Esther,YEAR
+T_Return,YEAR
+T_JesusJohn,MONTH
+T_Exile,YEAR
+T_Asia,CENTURY
+T_Exodus,YEAR
+T_Intertestamental,DECADE
+T_JesusGalileeArea,MONTH
+T_RomanEmpire,CENTURY
+T_Egypt,MILLENIUM
+T_HagZech,YEAR

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/1.schema.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/1.schema.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/1.schema.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,11 @@
+create schema step;
+set schema step;
+
+drop procedure step.dropIfExists;
+
+
+create procedure step.dropIfExists(tableName varchar(30))
+parameter style java
+language java
+external name 'com.tyndalehouse.step.dataloader.utils.DerbyUtils.dropIfExists';
+

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/2.scripture_referencing.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/2.scripture_referencing.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/2.scripture_referencing.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,27 @@
+set schema step;
+
+
+call dropIfExists('scripture_reference');
+
+
+-- should probably add index on start_verse_id and end_verse_id
+
+/** need to define standards and whether we want to include seperate creates in each file
+ * or one file per area
+ */
+create table scripture_reference (
+	scripture_reference_id		int NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
+	target_id  					int NOT NULL, -- could be for eg. a timeline event, or an article, etc. no referential integrity here
+    target_type					int  NOT NULL, -- description of the event, defined in enum in java code...
+	start_verse_id				int NOT NULL,	
+	end_verse_id				int	NOT NULL -- this may be a single verse so can be null here? 
+);
+
+create index target_id_target_type_id_ind 
+on scripture_reference(target_id, target_type);
+
+create index start_verse_id_ind
+on scripture_reference(start_verse_id);
+
+create index end_verse_id_ind
+on scripture_reference(end_verse_id);

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/3.timeline.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/3.timeline.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/create/3.timeline.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,84 @@
+set schema step;
+
+call dropIfExists('alternative_date');
+call dropIfExists('event');
+call dropIfExists('timeband');
+call dropIfExists('sub_timeband');
+call dropIfExists('event_type');
+
+/**
+ * Timeline table indicating different types of timelines.
+ */
+create table timeband (
+	timeband_id 				int PRIMARY KEY,
+	timeband_description		varchar(50),			-- TODO: this should probably be made an ID to timeline_description
+														-- table, so that we can localise, or remove this
+														-- and localise in the java layer...
+	timeband_code				varchar(50),
+	timeband_unit				varchar(10) default 'DECADE',
+	is_biblical					char(1)
+);
+
+/**
+ * Timeline table indicating different types of timelines.
+ */
+create table sub_timeband (
+	sub_timeband_id 				int PRIMARY KEY,
+	sub_timeband_description		varchar(50),			-- TODO: this should probably be made an ID to timeline_description
+														-- table, so that we can localise, or remove this
+														-- and localise in the java layer...
+	sub_timeband_code				varchar(50),
+	sub_timeband_unit				varchar(10) default 'DECADE'
+);
+
+
+/**
+ * Timeline table indicating different types of timelines.
+ */
+create table event_type (
+	event_type_id 			int PRIMARY KEY,
+	event_description		varchar(50),			
+	event_code				varchar(50)
+);
+
+/**
+ * the main event table that holds all the events of the timeline widget
+ *  
+ */
+create table event (
+	event_id 					int PRIMARY KEY generated by default as IDENTITY,
+	event_text_id 				varchar(20) 	NOT NULL,	
+	name 						varchar(100) 	NOT NULL,	
+	from_date 					bigint 			,				
+	to_date 					bigint,			-- nullable, may a point in time.
+	from_precision 				char(1), 		-- D/M/Y:: D=> take the whole date, M=>only month and year, Y=>only year is relevant
+	to_precision				char(1),
+	timeband_id					int CONSTRAINT timeband_id_fk REFERENCES timeband (timeband_id),
+	sub_timeband_id 			int CONSTRAINT sub_timeband_id_fk REFERENCES sub_timeband (sub_timeband_id),	
+	importance_id 				int CONSTRAINT importance_id_fk REFERENCES sub_timeband (sub_timeband_id),
+	certainty 					varchar(25),	
+	flags 						varchar(50),
+	event_type_id				int CONSTRAINT event_type_id_fk REFERENCES event_type(event_type_id),
+	description 				varchar(512),	
+	source 						varchar(512),
+	notes 						varchar(512)
+);
+
+create table alternative_date (
+	alternative_date_id			int PRIMARY KEY GENERATED BY DEFAULT as IDENTITY,
+    event_id 					int CONSTRAINT event_id_fk REFERENCES event (event_id),
+	from_date 					bigint,
+	to_date 					bigint,
+	from_date_precision 		char(1),
+	to_date_precision			char(1)
+);
+
+
+-- finally create indexes:
+-- do some performance tests - it may be that full table scans might be better.
+-- TODO: these are just guesses at the moment!
+-- can't remember if we need to created indexes on foreign keys in javaDB
+create index timeband_id_ind on event(timeband_id);
+create index sub_timeband_id_ind on event(sub_timeband_id);
+create index from_date_from_precision_ind on event(from_date, from_precision);
+create index to_date_to_precision_ind on event(from_date, from_precision);

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/1.timeband_units.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/1.timeband_units.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/1.timeband_units.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,21 @@
+set schema step;
+
+-- updating the timeband units 
+update step.timeband set timeband_unit = 'YEAR' 		where timeband_code = 'TL_Jesus';
+update step.timeband set timeband_unit = 'YEAR' 		where timeband_code = 'TL_NTChurch';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_PatriarchsToJudges';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_Rome';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_Egypt';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_Monarchy';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_EarlyChurch';
+update step.timeband set timeband_unit = 'CENTURY' 		where timeband_code = 'TL_ArchCult';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_OTNeighbours';
+update step.timeband set timeband_unit = 'CENTURY'		where timeband_code = 'TL_Global';
+update step.timeband set timeband_unit = 'YEAR' 		where timeband_code = 'TL_ExileAndReturn';
+update step.timeband set timeband_unit = 'CENTURY' 		where timeband_code = 'TL_Intertestamental';
+update step.timeband set timeband_unit = 'MILLENIUM' 	where timeband_code = 'TL_Africa';
+update step.timeband set timeband_unit = 'CENTURY'		where timeband_code = 'TL_Asia';
+update step.timeband set timeband_unit = 'DECADE' 		where timeband_code = 'TL_Europe';
+update step.timeband set timeband_unit = 'MILLENIUM' 	where timeband_code = 'TL_Americas';
+
+

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/2.timeband_setup.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/2.timeband_setup.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/2.timeband_setup.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,11 @@
+set schema step;
+
+update timeband 
+set is_biblical = 'Y'
+where timeband_id in ( 
+    select timeband_id from scripture_reference, event
+    where target_type = 1
+      and target_id = event_id
+    group by timeband_id
+);
+

Added: trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/3.sub_timeband_units.sql
===================================================================
--- trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/3.sub_timeband_units.sql	                        (rev 0)
+++ trunk/step-dataloader/src/main/resources/sql/com/tyndalehouse/step/dataloader/sql/data/3.sub_timeband_units.sql	2010-04-14 21:29:50 UTC (rev 109)
@@ -0,0 +1,77 @@
+set schema step;
+
+-- updating the sub timeband units
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_EgyptD12';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_BirthOfTheNation';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_ArchCult';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Europe';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_EgyptD19';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_China';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_ACModern';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_EgyptD18';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Herodians';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Rome';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Assyria';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Persia';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Isaiah';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_ACBabylonPersia';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_India';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Hasmonean';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Greece';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_RomanRepublic';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_ACJewishPeriod';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_Asia';
+update step.sub_timeband set sub_timeband_unit = 'CENTURY' where sub_timeband_code = 'T_RomanEmpire';
+update step.sub_timeband set sub_timeband_unit = 'DAY' where sub_timeband_code = 'T_PassionWeek';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Ezekiel';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_NewTestament';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Monarchy';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_JudahMonarchy';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Wilderness';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Judges';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Solomon';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_David';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Jeremiah';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_IsraelMonarchy';
+update step.sub_timeband set sub_timeband_unit = 'DECADE' where sub_timeband_code = 'T_Intertestamental';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_All';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Bible';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Babylon';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_ACBronzeAge';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Syria';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_ACIronAge';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Africa';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_EgyptPtolemaic';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Americas';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_ACRomeByzantium';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Mesopotamia';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_AdamToAbraham';
+update step.sub_timeband set sub_timeband_unit = 'MILLENIUM' where sub_timeband_code = 'T_Egypt';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_PaulMJ1';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_PaulMJ3';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_PaulMJ2';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_JesusGalilee';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_JesusPerea';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_JesusJudea';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_JesusJohn';
+update step.sub_timeband set sub_timeband_unit = 'MONTH' where sub_timeband_code = 'T_JesusGalileeArea';
+update step.sub_timeband set sub_timeband_unit = 'WEEK' where sub_timeband_code = 'T_JesusResurrected';
+update step.sub_timeband set sub_timeband_unit = 'WEEK' where sub_timeband_code = 'T_Exodus';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_LifeOfJesus';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_PaulToRome';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Abraham';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Isaac';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Patriarchs';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_JesusEarly';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Jacob';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_ExileAndReturn';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_UnitedMonarchy';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Saul';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_EarlyChurch';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_NTChurch';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Conquest';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Esther';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Return';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_Exile';
+update step.sub_timeband set sub_timeband_unit = 'YEAR' where sub_timeband_code = 'T_HagZech';
+



From ChrisBurrell at crosswire.org  Wed Apr 14 15:11:51 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 22:11:51 -0000
Subject: [Tynstep-svn] r120 - in
	trunk/step-web-app/src/main/java/com/tyndalehouse/step/web: .
	client client/common client/event client/eventhandler
	client/gin client/presenter client/service
	client/service/eventbus client/service/refdata client/toolkit
	client/toolkit/scripture client/toolkit/timeline
	client/toolkit/timeline/components client/toolkit/timeline/events
	client/toolkit/timeline/exceptions
	client/toolkit/timeline/helpers client/view server
	server/common server/db server/db/framework
	server/db/timeline server/guice server/handler
	server/handler/util server/handler/util/passage server/jsword
	server/jsword/com server/jsword/com/tyndalehouse
	server/jsword/com/tyndalehouse/step
	server/jsword/com/tyndalehouse/step/web shared shared/command
	shared/common shared/common/maps
	shared/common/scripturelookup shared/common/timeline
	shared/result shared/scripture shared/timeline
Message-ID: <E1O2AoJ-0003w3-KG@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:11:51 -0700 (Wed, 14 Apr 2010)
New Revision: 120

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/StepEntryPoint.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/common/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/common/CachingDispatchAsync.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/BookSelectedEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/DictionaryDefinitionFoundEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/LemmaClickedEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ModuleChangeEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ScriptureChangeEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimebandListUpdateRequiredEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimelineScrollEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/UserInterestInBandEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/VersionChangeEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/BookSelectedEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/DictionaryDefinitionFoundHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/LemmaClickedEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ModuleChangeEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ScriptureChangeEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimebandListUpdateRequiredEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimelineScrollEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/UserInterestInBandEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/VersionChangeEventHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepClientModule.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepInjector.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/AppPresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/HistoryModulePresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ModuleSelectorPresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScriptureSelectorPresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/StepPresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimebandListPresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimelinePresenter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/eventbus/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/eventbus/StepEventBusImpl.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleName.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleRefData.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HasSource.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HtmlList.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SimpleListBox.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SourceListBox.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/ScriptureDisplayConstants.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/VerseLabel.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TapeTrack.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEvent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEventDescriptor.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeScale.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeband.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeline.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/Orientation.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimebandRequestWindow.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimelineConstants.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/events/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/events/TimelineMouseHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/CannotDeleteEventException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/IncapableOfCalculatingRequestWindowException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/TimeBandNotFoundException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/UnknownFiredElement.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/CurrentBandStats.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/TimeConversionUtil.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/painters/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/HistoryModuleView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ModuleSelectorView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureSelectorView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/StepView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimebandListView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimelineView.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/AbstractStepHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigNotLoadedException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigProvider.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/JSwordConstants.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/MalformedStepQueryException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/Query.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/QueryImpl.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/ResultSetProcessor.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQuery.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunner.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunnerImpl.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/UnableToRunQueryException.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimeBandVisibleDateProcessor.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginDbBean.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginProcessor.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineSetupDataProcessor.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/CustomDispatchServiceServlet.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/DispatchServletModule.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/LogProvider.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/MyGuiceServletConfig.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/ServerModule.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetAvailableBibleVersionsHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetBibleBooksHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetDictionaryDefinitionHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetEventsForDateRangeHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetLocationsHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineOriginForScriptureHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineUISetupHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/InstallJswordModuleHandler.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/passage/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/passage/StrongMorphMap.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/ConfigurableHTMLConverter.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/XSLTProperty.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/com/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/com/tyndalehouse/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/com/tyndalehouse/step/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/com/tyndalehouse/step/web/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/com/tyndalehouse/step/web/server/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/BooksRequiredType.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetAvailableBibleVersionsCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetBibleBooksCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetCurrentBibleTextCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetDictionaryDefinitionCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetEventsForDateRangeCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetLocationsCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineOriginForScriptureCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineUISetupCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/InstallJswordModuleCommand.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocation.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocationType.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/LatLong.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/scripturelookup/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/scripturelookup/BibleTextLookupType.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimeBandVisibleDate.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineBean.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineEventBean.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetAvailableBibleVersionsResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetBibleBooksCommandResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetCurrentBibleTextResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetDictionaryDefinitionResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetEventsForDateRangeResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetLocationsResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineOriginForScriptureResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineUISetupResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/InstallJswordModuleResult.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Milestone.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Note.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/OSISConstants.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Text.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TextualElement.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Title.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TransChange.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Verse.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/VerseContent.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Word.java
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/timeline/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/timeline/Unit.java
Log:
committing the core code

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/StepEntryPoint.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/StepEntryPoint.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/StepEntryPoint.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,32 @@
+package com.tyndalehouse.step.web.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.ui.RootPanel;
+import com.tyndalehouse.step.web.client.gin.StepInjector;
+import com.tyndalehouse.step.web.client.presenter.AppPresenter;
+
+/**
+ * Entry point to the one and only application page
+ * 
+ * @author cjburrell
+ * 
+ */
+public class StepEntryPoint implements EntryPoint {
+
+	/**
+	 * Main step injector
+	 */
+	private final StepInjector injector = GWT.create(StepInjector.class);
+
+	/**
+	 * Entry point to the Step application
+	 */
+	public void onModuleLoad() {
+		final AppPresenter appPresenter = injector.getAppPresenter();
+		appPresenter.go(RootPanel.get());
+
+		// injector.getPlaceManager().fireCurrentPlace();
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/common/CachingDispatchAsync.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/common/CachingDispatchAsync.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/common/CachingDispatchAsync.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,92 @@
+package com.tyndalehouse.step.web.client.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.dispatch.shared.Action;
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.google.inject.Inject;
+
+//TODO: investigate the user of this client side cache
+/**
+ * Dispatcher which support caching of data in memory
+ * 
+ */
+public class CachingDispatchAsync implements DispatchAsync {
+	/**
+	 * 
+	 */
+	private final Map<Action<Result>, Result> cache = new HashMap<Action<Result>, Result>();
+
+	/**
+	 * The default dispatcher
+	 */
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * The default constructor
+	 * 
+	 * @param dispatcher uses the default dispatcher
+	 */
+	@Inject
+	public CachingDispatchAsync(final DispatchAsync dispatcher) {
+		this.dispatcher = dispatcher;
+	}
+
+	/**
+	 * Clear the cache
+	 */
+	public void clear() {
+		cache.clear();
+	}
+
+	/**
+	 * This method is a simple wrapper around the DispatchAsync class at the
+	 * moment
+	 * 
+	 * @param <A> Action implementation
+	 * @param <R> Result implementation
+	 * @param action the action
+	 * @param callback the callback
+	 * @see net.customware.gwt.dispatch.client.DispatchAsync#execute(A,
+	 *      com.google.gwt.user.client.rpc.AsyncCallback)
+	 */
+	public <A extends Action<R>, R extends Result> void execute(final A action,
+			final AsyncCallback<R> callback) {
+		dispatcher.execute(action, callback);
+	}
+
+	/**
+	 * Execute the given Action. If the Action was executed before it will get
+	 * fetched from the cache
+	 * 
+	 * @param <A> Action implementation
+	 * @param <R> Result implementation
+	 * @param action the action
+	 * @param callback the callback
+	 */
+	@SuppressWarnings("unchecked")
+	public <A extends Action<R>, R extends Result> void executeWithCache(final A action,
+			final AsyncCallback<R> callback) {
+		final Result r = cache.get(action);
+
+		if (r != null) {
+			callback.onSuccess((R) r);
+		} else {
+			dispatcher.execute(action, new AsyncCallback<R>() {
+
+				public void onFailure(final Throwable caught) {
+					callback.onFailure(caught);
+				}
+
+				public void onSuccess(final R result) {
+					cache.put((Action) action, (Result) result);
+					callback.onSuccess(result);
+				}
+			});
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/BookSelectedEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/BookSelectedEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/BookSelectedEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,32 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.BookSelectedEventHandler;
+
+/**
+ * The user has selected a book on the UI, and this is being fired to the
+ * DefaultEventBus
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class BookSelectedEvent extends GwtEvent<BookSelectedEventHandler> {
+
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	private static Type<BookSelectedEventHandler> TYPE = new Type<BookSelectedEventHandler>();
+
+	@Override
+	public Type<BookSelectedEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	@Override
+	protected void dispatch(final BookSelectedEventHandler handler) {
+		handler.onBookSelected(this);
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/DictionaryDefinitionFoundEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/DictionaryDefinitionFoundEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/DictionaryDefinitionFoundEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,59 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.DictionaryDefinitionFoundHandler;
+
+/**
+ * The dictionary definition found event. This is fired when the server has
+ * responded with a dictionary definition and different parts of the system may
+ * require notification of it.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class DictionaryDefinitionFoundEvent extends GwtEvent<DictionaryDefinitionFoundHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	private static Type<DictionaryDefinitionFoundHandler> TYPE = new Type<DictionaryDefinitionFoundHandler>();
+
+	/**
+	 * the definition that was retrieved
+	 */
+	private String definition;
+
+	/**
+	 * default constructor
+	 * 
+	 * @param defintion this is the definition that was retrieved from the
+	 *            server
+	 */
+	public DictionaryDefinitionFoundEvent(final String defintion) {
+		this.definition = defintion;
+	}
+
+	@Override
+	public Type<DictionaryDefinitionFoundHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * @return the definition
+	 */
+	public String getDefinition() {
+		return definition;
+	}
+
+	/**
+	 * @param definition the definition to set
+	 */
+	public void setDefinition(final String definition) {
+		this.definition = definition;
+	}
+
+	@Override
+	protected void dispatch(final DictionaryDefinitionFoundHandler handler) {
+		handler.onDefinitionFound(this);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/LemmaClickedEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/LemmaClickedEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/LemmaClickedEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,59 @@
+package com.tyndalehouse.step.web.client.event;
+
+import java.util.List;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.LemmaClickedEventHandler;
+
+/**
+ * This event is fired when a portion of scripture tagged with 1 or more lemma
+ * (strong number for e.g.) has been clicked. The event contains details of the
+ * lemmas references.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class LemmaClickedEvent extends GwtEvent<LemmaClickedEventHandler> {
+	/**
+	 * Type of event
+	 */
+	public static Type<LemmaClickedEventHandler> TYPE = new Type<LemmaClickedEventHandler>();
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	private List<String> lemma;
+
+	/**
+	 * constructing the event with a list of lemmas
+	 * 
+	 * @param lemmas the list of lemmas that were clicked upon
+	 */
+	public LemmaClickedEvent(final List<String> lemmas) {
+		this.lemma = lemmas;
+	}
+
+	@Override
+	public Type<LemmaClickedEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * @return the lemma
+	 */
+	public List<String> getLemma() {
+		return lemma;
+	}
+
+	/**
+	 * @param lemma the lemma to set
+	 */
+	public void setLemma(final List<String> lemma) {
+		this.lemma = lemma;
+	}
+
+	@Override
+	protected void dispatch(final LemmaClickedEventHandler handler) {
+		handler.onLemmaClicked(this);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ModuleChangeEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ModuleChangeEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ModuleChangeEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,75 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.ModuleChangeEventHandler;
+
+/**
+ * Event is fired when part of the module definition (module, sub module, depth)
+ * has been changed
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ModuleChangeEvent extends GwtEvent<ModuleChangeEventHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	private static Type<ModuleChangeEventHandler> TYPE = new Type<ModuleChangeEventHandler>();
+
+	/** newly selected depth of stud */
+	private final String newDepth;
+	/** newly selected module */
+	private final String newModule;
+	/** newly selected submodule */
+	private final String newSubModule;
+
+	/**
+	 * creates an event alerting of the new chosen combination of
+	 * module/sub-module/depth
+	 * 
+	 * @param newModule new module
+	 * @param newSubModule new sub module
+	 * @param newDepth new depth of study
+	 */
+	public ModuleChangeEvent(final String newModule, final String newSubModule,
+		final String newDepth) {
+		this.newModule = newModule;
+		this.newSubModule = newSubModule;
+		this.newDepth = newDepth;
+	}
+
+	@Override
+	public Type<ModuleChangeEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * 
+	 * @return the depth
+	 */
+	public String getNewDepth() {
+		return newDepth;
+	}
+
+	/**
+	 * @return the new module
+	 */
+	public String getNewModule() {
+		return newModule;
+	}
+
+	/**
+	 * 
+	 * @return the new sub module
+	 */
+	public String getNewSubModule() {
+		return newSubModule;
+	}
+
+	@Override
+	protected void dispatch(final ModuleChangeEventHandler handler) {
+		handler.onModuleChange(this);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ScriptureChangeEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ScriptureChangeEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/ScriptureChangeEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,53 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.ScriptureChangeEventHandler;
+
+/**
+ * Scripture change is fired when the scripture viewed on the screen is
+ * requested to be different
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ScriptureChangeEvent extends GwtEvent<ScriptureChangeEventHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	// TODO: remove this type into an abstract layer
+	public static Type<ScriptureChangeEventHandler> TYPE = new Type<ScriptureChangeEventHandler>();
+
+	/**
+	 * This is the new reference that is being fired.
+	 */
+	private final String newReference;
+
+	/**
+	 * Constructor to create a scripture change even with a biblical reference
+	 * 
+	 * @param newReference the new reference that has been chosen by the user
+	 */
+	public ScriptureChangeEvent(final String newReference) {
+		this.newReference = newReference;
+	}
+
+	@Override
+	public Type<ScriptureChangeEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * @return the new biblical reference that has been selected
+	 */
+	public String getNewReference() {
+		return newReference;
+	}
+
+	@Override
+	protected void dispatch(final ScriptureChangeEventHandler handler) {
+		handler.onScriptureChange(this);
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimebandListUpdateRequiredEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimebandListUpdateRequiredEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimebandListUpdateRequiredEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,60 @@
+package com.tyndalehouse.step.web.client.event;
+
+import java.util.List;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.TimebandListUpdateRequiredEventHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.CurrentBandStats;
+
+/**
+ * Event signalling that the timebands have been changed and an update is
+ * required from any component keeping track of counts
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimebandListUpdateRequiredEvent extends
+	GwtEvent<TimebandListUpdateRequiredEventHandler> {
+
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	public static Type<TimebandListUpdateRequiredEventHandler> TYPE = new Type<TimebandListUpdateRequiredEventHandler>();
+
+	/**
+	 * List of new statistics, one for each band
+	 */
+	private final List<CurrentBandStats> stats;
+
+	/**
+	 * The timeline is passed in, so that the timeband list can know what the
+	 * new values are
+	 * 
+	 * @param stats timeline to be passed in
+	 */
+	public TimebandListUpdateRequiredEvent(final List<CurrentBandStats> stats) {
+		this.stats = stats;
+
+	}
+
+	@Override
+	public Type<TimebandListUpdateRequiredEventHandler> getAssociatedType() {
+		// TODO Auto-generated method stub
+		return TYPE;
+	}
+
+	/**
+	 * @return the stats
+	 */
+	public List<CurrentBandStats> getTimelineStats() {
+		return stats;
+	}
+
+	@Override
+	protected void dispatch(final TimebandListUpdateRequiredEventHandler handler) {
+		handler.onTimebandListRequiringUpdate(this);
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimelineScrollEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimelineScrollEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/TimelineScrollEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,85 @@
+package com.tyndalehouse.step.web.client.event;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.TimelineScrollEventHandler;
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+
+/**
+ * Event signalling the timeline has been scrolled. This event contains the list
+ * of timebands, and the portions of those that need updating
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimelineScrollEvent extends GwtEvent<TimelineScrollEventHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	public static Type<TimelineScrollEventHandler> TYPE = new Type<TimelineScrollEventHandler>();
+
+	/**
+	 * list of requests to the server on which portions of which bands need to
+	 * be updated
+	 */
+	private List<TimeBandVisibleDate> timebandVisibleDates;
+
+	/**
+	 * default constructor
+	 */
+	public TimelineScrollEvent() {
+		timebandVisibleDates = new ArrayList<TimeBandVisibleDate>();
+	}
+
+	/**
+	 * adds a timeband and the portion of time that needs updating
+	 * 
+	 * @param timebandId the timeband id
+	 * @param minDate the minimum date
+	 * @param maxDate the maximum date
+	 */
+	public void addTimebandVisibleDate(final int timebandId, final long minDate, final long maxDate) {
+		final TimeBandVisibleDate visibleDate = new TimeBandVisibleDate(timebandId, minDate,
+			maxDate);
+		addTimebandVisibleDate(visibleDate);
+	}
+
+	/**
+	 * adds a @see {@link TimeBandVisibleDate} to the event
+	 * 
+	 * @param visibleDate the TimeBandVisibleDate object containing details of
+	 *            which parts of the timeband (min, max) need updating.
+	 */
+	public void addTimebandVisibleDate(final TimeBandVisibleDate visibleDate) {
+		if (!visibleDate.isNoRequest()) {
+			timebandVisibleDates.add(visibleDate);
+		}
+	}
+
+	@Override
+	public Type<TimelineScrollEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * @return the timebandVisibleDates
+	 */
+	public List<TimeBandVisibleDate> getTimebandVisibleDates() {
+		return timebandVisibleDates;
+	}
+
+	/**
+	 * @param timebandVisibleDates the timebandVisibleDates to set
+	 */
+	public void setTimebandVisibleDates(final List<TimeBandVisibleDate> timebandVisibleDates) {
+		this.timebandVisibleDates = timebandVisibleDates;
+	}
+
+	@Override
+	protected void dispatch(final TimelineScrollEventHandler handler) {
+		handler.onScroll(this);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/UserInterestInBandEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/UserInterestInBandEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/UserInterestInBandEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,64 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.UserInterestInBandEventHandler;
+
+/**
+ * Event signalling the user is interested or not interested in a new timeband
+ * 
+ * @author cjburrell
+ * 
+ */
+public class UserInterestInBandEvent extends GwtEvent<UserInterestInBandEventHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	public static Type<UserInterestInBandEventHandler> TYPE = new Type<UserInterestInBandEventHandler>();
+
+	/**
+	 * the band the user has selected to choose or dismiss
+	 */
+	private final int bandId;
+
+	/**
+	 * whether the user wants to see the band or not
+	 */
+	private final Boolean isOfInterest;
+
+	/**
+	 * creates the event
+	 * 
+	 * @param bandId the band that the user selected
+	 * @param isOfInterest whether the user is interested in it or not
+	 */
+	public UserInterestInBandEvent(final int bandId, final Boolean isOfInterest) {
+		this.bandId = bandId;
+		this.isOfInterest = isOfInterest;
+	}
+
+	@Override
+	public Type<UserInterestInBandEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	/**
+	 * @return the bandId
+	 */
+	public int getBandId() {
+		return bandId;
+	}
+
+	/**
+	 * @return the isOfInterest
+	 */
+	public Boolean isOfInterest() {
+		return isOfInterest;
+	}
+
+	@Override
+	protected void dispatch(final UserInterestInBandEventHandler handler) {
+		handler.onUserInterestedInBand(this);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/VersionChangeEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/VersionChangeEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/event/VersionChangeEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,29 @@
+package com.tyndalehouse.step.web.client.event;
+
+import com.google.gwt.event.shared.GwtEvent;
+import com.tyndalehouse.step.web.client.eventhandler.VersionChangeEventHandler;
+
+/**
+ * Event signalling a change of bible version of the UI
+ * 
+ * @author cjburrell
+ * 
+ */
+public class VersionChangeEvent extends GwtEvent<VersionChangeEventHandler> {
+	/**
+	 * The default Type Handler Type is parameterized by the handler type in
+	 * order to make the addHandler method type safe.
+	 */
+	public static Type<VersionChangeEventHandler> TYPE = new Type<VersionChangeEventHandler>();
+
+	@Override
+	public Type<VersionChangeEventHandler> getAssociatedType() {
+		return TYPE;
+	}
+
+	@Override
+	protected void dispatch(final VersionChangeEventHandler handler) {
+		handler.onVersionChange(this);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/BookSelectedEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/BookSelectedEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/BookSelectedEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.BookSelectedEvent;
+
+/**
+ * Contract for any handler wanting to handle a BookSelectedEvent In particular
+ * this means handling a click for e.g. on the UI in the list of bible books
+ * (Genesis, Exodus, etc.)
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface BookSelectedEventHandler extends EventHandler {
+
+	/**
+	 * This method is called when a @see {@link BookSelectedEvent} is triggered
+	 * 
+	 * @param event that is provided to the handler
+	 */
+	void onBookSelected(BookSelectedEvent event);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/DictionaryDefinitionFoundHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/DictionaryDefinitionFoundHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/DictionaryDefinitionFoundHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.DictionaryDefinitionFoundEvent;
+
+/**
+ * This contract is relevant to any handler who wants to be notified when a
+ * definition was looked up from the server
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface DictionaryDefinitionFoundHandler extends EventHandler {
+	/**
+	 * This method is fired when a dictionary definition has been looked up from
+	 * the server
+	 * 
+	 * @param dictionaryDefintionFoundEvent the dictionary definition found
+	 *            event, containing the results from the server
+	 */
+	void onDefinitionFound(DictionaryDefinitionFoundEvent dictionaryDefintionFoundEvent);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/LemmaClickedEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/LemmaClickedEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/LemmaClickedEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,21 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.LemmaClickedEvent;
+
+/**
+ * Contract for handlers who are interested in the user clicking on a portion of
+ * scripture which was tagged with a lemma
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface LemmaClickedEventHandler extends EventHandler {
+	/**
+	 * This is fired when a click on a portion of scripture tagged with a lemma
+	 * has occured
+	 * 
+	 * @param lemmaClickedEvent the event that is provided to the handler
+	 */
+	void onLemmaClicked(LemmaClickedEvent lemmaClickedEvent);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ModuleChangeEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ModuleChangeEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ModuleChangeEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,20 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.ModuleChangeEvent;
+
+/**
+ * Contract for handlers interested in a selection of a different module
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface ModuleChangeEventHandler extends EventHandler {
+	/**
+	 * Called when the user has selected a different module
+	 * 
+	 * @param event provided to the handler containing the new module
+	 *            combination
+	 */
+	void onModuleChange(ModuleChangeEvent event);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ScriptureChangeEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ScriptureChangeEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/ScriptureChangeEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,20 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.ScriptureChangeEvent;
+
+/**
+ * Handler contract for when the user changes the portion of scripture he is
+ * viewing
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface ScriptureChangeEventHandler extends EventHandler {
+	/**
+	 * Fired when the user changes the portion of scripture currently viewed
+	 * 
+	 * @param event event containing the details of the new scripture requested
+	 */
+	void onScriptureChange(ScriptureChangeEvent event);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimebandListUpdateRequiredEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimebandListUpdateRequiredEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimebandListUpdateRequiredEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.TimebandListUpdateRequiredEvent;
+
+/**
+ * Contract for handlers requiring notification of updates to the number of
+ * events on the timebands
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface TimebandListUpdateRequiredEventHandler extends EventHandler {
+	/**
+	 * This is fired when new events are added to the timeband, or when events
+	 * are no longer in the visible section
+	 * 
+	 * @param timebandListUpdateRequiredEvent the event containing the new
+	 *            statistics to be displayed
+	 */
+	void onTimebandListRequiringUpdate(TimebandListUpdateRequiredEvent timebandListUpdateRequiredEvent);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimelineScrollEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimelineScrollEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/TimelineScrollEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,23 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.TimelineScrollEvent;
+
+/**
+ * Contract for handlers wanting to be alerted when the timeline is being
+ * scrolled
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface TimelineScrollEventHandler extends EventHandler {
+
+	/**
+	 * Fired when the timeline is being scrolled, before new events are
+	 * requested from the server
+	 * 
+	 * @param event event containing the new portions of time to be requested
+	 *            from the server
+	 */
+	void onScroll(TimelineScrollEvent event);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/UserInterestInBandEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/UserInterestInBandEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/UserInterestInBandEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,23 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.UserInterestInBandEvent;
+
+/**
+ * Contract for handlers requiring notifications of timebands being
+ * selected/unselected
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface UserInterestInBandEventHandler extends EventHandler {
+
+	/**
+	 * fired when a timeband has been selected/nselected
+	 * 
+	 * @param userInterestInBandEvent contains information about the timeband
+	 *            that was selected/nselected
+	 */
+	void onUserInterestedInBand(UserInterestInBandEvent userInterestInBandEvent);
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/VersionChangeEventHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/VersionChangeEventHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/eventhandler/VersionChangeEventHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,21 @@
+package com.tyndalehouse.step.web.client.eventhandler;
+
+import com.google.gwt.event.shared.EventHandler;
+import com.tyndalehouse.step.web.client.event.VersionChangeEvent;
+
+/**
+ * Contract for handlers requiring updates when the user changes the version of
+ * the bible he is currently accessing
+ * 
+ * @author cjburrell
+ * 
+ */
+public interface VersionChangeEventHandler extends EventHandler {
+
+	/**
+	 * fired when the user selects a different bible version
+	 * 
+	 * @param event the event containing the new version information
+	 */
+	void onVersionChange(VersionChangeEvent event);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepClientModule.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepClientModule.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepClientModule.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,74 @@
+package com.tyndalehouse.step.web.client.gin;
+
+import net.customware.gwt.dispatch.client.DefaultDispatchAsync;
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.gin.AbstractPresenterModule;
+import net.customware.gwt.presenter.client.place.PlaceManager;
+
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.web.client.common.CachingDispatchAsync;
+import com.tyndalehouse.step.web.client.presenter.AppPresenter;
+import com.tyndalehouse.step.web.client.presenter.HistoryModulePresenter;
+import com.tyndalehouse.step.web.client.presenter.ModuleSelectorPresenter;
+import com.tyndalehouse.step.web.client.presenter.ScripturePresenter;
+import com.tyndalehouse.step.web.client.presenter.ScriptureSelectorPresenter;
+import com.tyndalehouse.step.web.client.presenter.StepPresenter;
+import com.tyndalehouse.step.web.client.presenter.TimebandListPresenter;
+import com.tyndalehouse.step.web.client.presenter.TimelinePresenter;
+import com.tyndalehouse.step.web.client.service.eventbus.StepEventBusImpl;
+import com.tyndalehouse.step.web.client.view.HistoryModuleView;
+import com.tyndalehouse.step.web.client.view.ModuleSelectorView;
+import com.tyndalehouse.step.web.client.view.ScriptureSelectorView;
+import com.tyndalehouse.step.web.client.view.ScriptureView;
+import com.tyndalehouse.step.web.client.view.StepView;
+import com.tyndalehouse.step.web.client.view.TimebandListView;
+import com.tyndalehouse.step.web.client.view.TimelineView;
+
+/**
+ * Gin configuration for the the step client. In addition to normal guice
+ * operations, this binds presenters to their views
+ * 
+ * @author cjburrell
+ * 
+ */
+public class StepClientModule extends AbstractPresenterModule {
+
+	@Override
+	protected void configure() {
+
+		// put the bindings in here
+
+		bind(EventBus.class).to(StepEventBusImpl.class).in(Singleton.class);
+		bind(TimebandListPresenter.Display.class).to(TimebandListView.class);
+
+		bind(AppPresenter.class).in(Singleton.class);
+		bind(PlaceManager.class).in(Singleton.class);
+
+		bindPresenter(StepPresenter.class, StepPresenter.Display.class, StepView.class);
+		bind(ScriptureSelectorPresenter.class);
+		bind(ScriptureSelectorPresenter.Display.class).to(ScriptureSelectorView.class).in(
+			Singleton.class);
+		bind(ModuleSelectorPresenter.class);
+		bind(ModuleSelectorPresenter.Display.class).to(ModuleSelectorView.class)
+			.in(Singleton.class);
+		bind(ScripturePresenter.class);
+		bind(ScripturePresenter.Display.class).to(ScriptureView.class); // .in(Singleton.class);
+		bind(TimelinePresenter.class);
+		bind(TimelinePresenter.Display.class).to(TimelineView.class); // .in(Singleton.class);
+		
+		//		
+		// bind(ITimeLineRender.class).to(TimelineRenderer.class);
+
+		bind(HistoryModulePresenter.class);
+		bind(HistoryModulePresenter.Display.class).to(HistoryModuleView.class);
+
+		// bind(new TypeLiteral<StepModulePresenter<? extends
+		// StepModulePresenter.Display>>() {
+		// }).to(HistoryModulePresenter.class);
+
+		bind(DispatchAsync.class).to(DefaultDispatchAsync.class).in(Singleton.class);
+		bind(CachingDispatchAsync.class);
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepInjector.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepInjector.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/gin/StepInjector.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,30 @@
+package com.tyndalehouse.step.web.client.gin;
+
+import net.customware.gwt.presenter.client.place.PlaceManager;
+
+import com.google.gwt.inject.client.GinModules;
+import com.google.gwt.inject.client.Ginjector;
+import com.tyndalehouse.step.web.client.presenter.AppPresenter;
+
+/**
+ * Gin injector. This defines the modules all the Gin modules
+ * 
+ * @author cjburrell
+ * 
+ */
+ at GinModules( StepClientModule.class )
+public interface StepInjector extends Ginjector {
+	/**
+	 * Returns the App Presenter, the main presenter for STEP
+	 * 
+	 * @return the main presenter for STEP
+	 */
+	AppPresenter getAppPresenter();
+
+	/**
+	 * Returns a place manager
+	 * 
+	 * @return the step place manager
+	 */
+	PlaceManager getPlaceManager();
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/AppPresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/AppPresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/AppPresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,67 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.ui.HasWidgets;
+import com.google.inject.Inject;
+
+/**
+ * Main presenter for STEP, entry point
+ * 
+ * @author cjburrell
+ * 
+ */
+public class AppPresenter {
+	/**
+	 * container for any main widgets
+	 */
+	private HasWidgets container;
+
+	// TODO: investigate whether there is a neater way of doing this
+	/**
+	 * Main dispatcher.
+	 */
+	@SuppressWarnings(value = "unused")
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * The step presenter - TODO: probably one layer of abstration too many,
+	 * should be moved this class into StepPresenter
+	 */
+	private final StepPresenter stepPresenter;
+
+	/**
+	 * The default app presenter for STEP.
+	 * 
+	 * @param dispatcher the dispatcher to use within this class (passed in here
+	 *            to get it initialised)
+	 * @param stepPresenter the step presenter responsible for handling all
+	 *            other presenters and views
+	 */
+	// passing them in to have GIN initialise them!
+	@Inject
+	public AppPresenter(final DispatchAsync dispatcher, final StepPresenter stepPresenter) {
+		this.dispatcher = dispatcher;
+		this.stepPresenter = stepPresenter;
+		Log.debug("AppPresenter is being initialised");
+	}
+
+	/**
+	 * Call go to initialise the step application and render
+	 * 
+	 * @param container container on which to add the Step Application
+	 */
+	public void go(final HasWidgets container) {
+		this.container = container;
+		showMain();
+	}
+
+	/**
+	 * Repaints the page with the step presenter/view
+	 */
+	private void showMain() {
+		container.clear();
+		container.add(stepPresenter.getDisplay().asWidget());
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/HistoryModulePresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/HistoryModulePresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/HistoryModulePresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,102 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.google.inject.Inject;
+
+/**
+ * History module presenter, responsible for displaying articles on the page
+ * 
+ * @author cjburrell
+ * 
+ */
+public class HistoryModulePresenter extends WidgetPresenter<HistoryModulePresenter.Display> {
+
+	/**
+	 * Interface for the History Module View
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+
+	}
+
+	/**
+	 * default constructor, injected by Gin
+	 * 
+	 * @param display display, comes from Gin
+	 * @param eventBus eventBus comes from Gin
+	 */
+	@Inject
+	public HistoryModulePresenter(final Display display, final EventBus eventBus) {
+		super(display, eventBus);
+		bind();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onBind() {
+
+		// eventBus.addHandler(MultipleWordsSelectedEvent.TYPE, new
+		// MultipleWordsSelectedEventHandler() {
+		//
+		// @Override
+		// public void onMultipleWordsSelected(MultipleWordsSelectedEvent event)
+		// {
+		// // TODO Auto-generated method stub
+		//				
+		// }
+		// });
+		//
+		// eventBus.addHandler(WordSelectedEvent.TYPE, new
+		// WordSelectedEventHandler() {
+		//
+		// @Override
+		// public void onWordSelectedEvent(WordSelectedEvent event) {
+		//				
+		// }
+		// });
+		//
+		// eventBus.addHandler(DepthChangeEvent.TYPE, new
+		// DepthChangeEventHandler() {
+		//
+		// @Override
+		// public void onDepthChange(DepthChangeEvent event) {
+		//				
+		// }
+		// });
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ModuleSelectorPresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ModuleSelectorPresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ModuleSelectorPresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,205 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.HasChangeHandlers;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.ModuleChangeEvent;
+import com.tyndalehouse.step.web.client.service.refdata.ModuleRefData;
+import com.tyndalehouse.step.web.client.toolkit.HasSource;
+
+/**
+ * Module selector module, responsible for displaying the dropdowns on the user
+ * interface
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ModuleSelectorPresenter extends WidgetPresenter<ModuleSelectorPresenter.Display> implements
+		ChangeHandler {
+
+	/**
+	 * Interface to the module selector view
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+		/**
+		 * 
+		 * @return Returns any change handlers so that the presenter can
+		 *         register event handlers
+		 */
+		HasChangeHandlers getModuleChangeHandlers();
+
+		/**
+		 * 
+		 * @return returns a change handler for the "Depth" dropdown/list
+		 */
+		HasChangeHandlers getModuleDepthChangeHandlers();
+
+		/**
+		 * @return returns the source associated to the Module Depth
+		 *         dropdown/list
+		 */
+		HasSource<List<String>> getModuleDepthSource();
+
+		/**
+		 * 
+		 * @return the source for the module list/dropdown
+		 */
+		HasSource<List<String>> getModuleSource();
+
+		/**
+		 * 
+		 * @return current selected depth (for example scholarly detail)
+		 */
+		String getSelectedDepth();
+
+		/**
+		 * 
+		 * @return currently selected module
+		 */
+		String getSelectedModule();
+
+		/**
+		 * 
+		 * @return currently selected sub-module
+		 */
+		String getSelectedSubModule();
+
+		/**
+		 * 
+		 * @return change handlers on which to register event handlers for the
+		 *         sub module dropdown/list
+		 */
+		HasChangeHandlers getSubModuleChangeHandlers();
+
+		/**
+		 * 
+		 * @return source for the sub module dropdown/list
+		 */
+		HasSource<List<String>> getSubModuleSource();
+
+		/**
+		 * Changes the selected module
+		 * 
+		 * @param newlySelectedModule the new module to be selected
+		 */
+		void setSelectedModule(String newlySelectedModule);
+	}
+
+	/**
+	 * Default constructor
+	 * 
+	 * @param display display passed in by Gin
+	 * @param eventBus eventBus passed in by Gin
+	 * @param dispatcher dispatch passed in by Gin
+	 */
+	@Inject
+	public ModuleSelectorPresenter(final Display display, final EventBus eventBus,
+			final DispatchAsync dispatcher) {
+		super(display, eventBus);
+		bind();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	/**
+	 * Used for submodule and depth
+	 * 
+	 * @param event event that was fired by the view.
+	 */
+	public void onChange(final ChangeEvent event) {
+		fireChange();
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * adds the module change handlers, for module list, sub module list and
+	 * depth list
+	 */
+	private void addDropdownChangeHandlers() {
+		// fires the dropdown change event as a ModuleChangeEvent
+		display.getModuleChangeHandlers().addChangeHandler(new ChangeHandler() {
+
+			public void onChange(final ChangeEvent event) {
+				// in here, we need to reload the events
+				display.getSubModuleSource().setSource(
+						ModuleRefData.getInstance().getListOfModules(display.getSelectedModule()));
+				// this hopefully fires the on Change below since the sub module
+				// dropdown changes...
+				// but it doesn't :( so...
+				fireChange();
+			}
+		});
+
+		display.getSubModuleChangeHandlers().addChangeHandler(this);
+		display.getModuleDepthChangeHandlers().addChangeHandler(this);
+	}
+
+	/**
+	 * fires the change of dropdown selectors to the event bus.
+	 */
+	private void fireChange() {
+		eventBus.fireEvent(new ModuleChangeEvent(display.getSelectedModule(), display.getSelectedSubModule(),
+				display.getSelectedDepth()));
+
+	}
+
+	@Override
+	protected void onBind() {
+		// do nothing at the moment
+		// add event notifications...
+		addDropdownChangeHandlers();
+
+		// TODO: remove default into configurable options, preferences, etc.
+		final String defaultModule = "History";
+		final ModuleRefData mrd = ModuleRefData.getInstance();
+		final List<String> moduleNames = mrd.getListOfModules("Module");
+		final List<String> subModules = mrd.getListOfModules(defaultModule);
+		final List<String> depths = mrd.getDepths();
+
+		display.setSelectedModule(defaultModule);
+		display.getModuleSource().setSource(moduleNames);
+		display.getSubModuleSource().setSource(subModules);
+		display.getModuleDepthSource().setSource(depths);
+
+		// do i need to fire an module change event?
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScripturePresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,230 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.List;
+import java.util.SortedMap;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.DisplayCallback;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.dom.client.ChangeEvent;
+import com.google.gwt.event.dom.client.ChangeHandler;
+import com.google.gwt.event.dom.client.HasChangeHandlers;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.LemmaClickedEvent;
+import com.tyndalehouse.step.web.client.event.ScriptureChangeEvent;
+import com.tyndalehouse.step.web.client.event.VersionChangeEvent;
+import com.tyndalehouse.step.web.client.eventhandler.LemmaClickedEventHandler;
+import com.tyndalehouse.step.web.client.eventhandler.ScriptureChangeEventHandler;
+import com.tyndalehouse.step.web.client.toolkit.HasSource;
+import com.tyndalehouse.step.web.shared.command.GetAvailableBibleVersionsCommand;
+import com.tyndalehouse.step.web.shared.command.GetCurrentBibleTextCommand;
+import com.tyndalehouse.step.web.shared.common.scripturelookup.BibleTextLookupType;
+import com.tyndalehouse.step.web.shared.result.GetAvailableBibleVersionsResult;
+import com.tyndalehouse.step.web.shared.result.GetCurrentBibleTextResult;
+import com.tyndalehouse.step.web.shared.scripture.Passage;
+
+/**
+ * This presenter is responsible for displaying scripture to the user, in an
+ * interactive way including the highlight-on-click, querying the server for
+ * portions of text, etc.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ScripturePresenter extends WidgetPresenter<ScripturePresenter.Display> {
+
+	/**
+	 * Description of the view for presenting scripture to the user
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+		/**
+		 * TODO: change the name, it's a bit meaningless change handlers to the
+		 * bible versions dropdown
+		 * 
+		 * @return bible versions change handlers
+		 */
+		HasChangeHandlers getChangeHandlers();
+
+		/**
+		 * 
+		 * @return the currently selected bible version on the UI
+		 */
+		String getSelectedBibleVersion();
+
+		/**
+		 * 
+		 * @return a map (intials -> bible Name) used as the source of the bible
+		 *         versions dropdown
+		 */
+		HasSource<SortedMap<String, String>> getSource();
+
+		/**
+		 * action to highlight portions of the biblical text that are tagged
+		 * with a lemma
+		 * 
+		 * @param lemmas lemmas to look for in the presented biblical text.
+		 */
+		void highlight(List<String> lemmas);
+
+		/**
+		 * @param passage a logical passage to be displayed
+		 */
+		void setPassage(Passage passage);
+
+		/**
+		 * @param text the text form of the passage
+		 */
+		void setPassage(String text);
+	}
+
+	/**
+	 * default asynchronous dispatcher
+	 */
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * the view itself, used to interact with it
+	 */
+	private final ScriptureSelectorPresenter.Display scriptureSelectorView;
+
+	/**
+	 * 
+	 * @param display the view, provided by Gin
+	 * @param eventBus the event bus, provided by Gin
+	 * @param dispatcher the dispatcher, provided by Gin
+	 * @param scriptureSelectorView the scripture selector view (i.e. the bit
+	 *            with the reference in it), provided by Gin
+	 */
+	@Inject
+	public ScripturePresenter(final Display display, final EventBus eventBus,
+		final DispatchAsync dispatcher,
+		final ScriptureSelectorPresenter.Display scriptureSelectorView) {
+		super(display, eventBus);
+		// TODO: remove dependency on scripture selector view
+		this.dispatcher = dispatcher;
+		this.scriptureSelectorView = scriptureSelectorView;
+		Log.debug("Initialising Scripture Presenter");
+		bind();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * Sends a request to the server to get the new text to be displayed. TODO:
+	 * this should be parameterized since the cmd options are set to defaults
+	 * here for testing
+	 */
+	private void doRefreshScripture() {
+		final GetCurrentBibleTextCommand cmd = new GetCurrentBibleTextCommand(display
+			.getSelectedBibleVersion(), scriptureSelectorView.getReference().getValue());
+		// TODO: decide if this should be made static or UI driven
+		cmd.setTypeOfLookup(BibleTextLookupType.REVERSE_INTERLINEAR);
+
+		dispatcher.execute(cmd, new DisplayCallback<GetCurrentBibleTextResult>(display) {
+
+			@Override
+			protected void handleFailure(final Throwable e) {
+				Log.error("An error has occurred", e);
+			}
+
+			@Override
+			protected void handleSuccess(final GetCurrentBibleTextResult result) {
+				// String text = result.getPassageText();
+				display.setPassage(result.getPassage());
+			}
+
+		});
+	}
+
+	@Override
+	protected void onBind() {
+		Log.debug("Binding Scripture Presenter");
+		// get list of versions now...
+		dispatcher.execute(new GetAvailableBibleVersionsCommand(),
+			new DisplayCallback<GetAvailableBibleVersionsResult>(display) {
+				@Override
+				protected void handleFailure(final Throwable e) {
+					Log.error("An error occurred while retrieving bible versions: ", e);
+				}
+
+				@Override
+				protected void handleSuccess(final GetAvailableBibleVersionsResult result) {
+					display.getSource().setSource(result.getBooks());
+				}
+			});
+
+		display.getChangeHandlers().addChangeHandler(new ChangeHandler() {
+			public void onChange(final ChangeEvent event) {
+				eventBus.fireEvent(new VersionChangeEvent());
+				doRefreshScripture();
+			}
+		});
+
+		eventBus.addHandler(ScriptureChangeEvent.TYPE, new ScriptureChangeEventHandler() {
+
+			public void onScriptureChange(final ScriptureChangeEvent event) {
+				Log.debug("Scripture Change event captured");
+				doRefreshScripture();
+			}
+		});
+
+		// TODO: this handler needs to be moved somewhere else, and fire off
+		// definition found
+		// TODO: given the handler name, our event bus, should be able to derive
+		// the type of it,
+		// since the type = Type<HandlerName>, at which point we can probably
+		// get rid of
+		// the type variable in the event.
+		// we would have to change the event to return the static type declared
+		// in the
+		// event handler
+
+		final LemmaClickedEventHandler lceh = new LemmaClickedEventHandler() {
+			public void onLemmaClicked(final LemmaClickedEvent lemmaClickedEvent) {
+				Log.error("Lemma Clicked event handler invoked");
+				highlightAllLemmas(lemmaClickedEvent.getLemma());
+			}
+
+			private void highlightAllLemmas(final List<String> lemmas) {
+				display.highlight(lemmas);
+			}
+		};
+		eventBus.addHandler(LemmaClickedEvent.TYPE, lceh);
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScriptureSelectorPresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScriptureSelectorPresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/ScriptureSelectorPresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,160 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.Collection;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.DisplayCallback;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.user.client.ui.HasValue;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.ScriptureChangeEvent;
+import com.tyndalehouse.step.web.shared.command.GetBibleBooksCommand;
+import com.tyndalehouse.step.web.shared.result.GetBibleBooksCommandResult;
+
+/**
+ * Presenter for the Scripture Selector Presenter module. This module aims to
+ * present the user with a way of selecting a passage, including suggesting the
+ * bible book.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ScriptureSelectorPresenter extends WidgetPresenter<ScriptureSelectorPresenter.Display> {
+	/**
+	 * The contract with the view, which will disaply a way for the user to
+	 * select/key in a bible reference
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+		/**
+		 * adds a suggestion to the list of bibles
+		 * 
+		 * @param suggestion a suggestion, such as a bible book name
+		 */
+		void addSuggestion(String suggestion);
+
+		/**
+		 * Adds a list of suggestions
+		 * 
+		 * @param suggestions the collection of suggestions (bible book names,
+		 *            for e.g.)
+		 */
+		void addSuggestions(Collection<String> suggestions);
+
+		/**
+		 * @return the reference which is currently keyed in
+		 */
+		HasValue<String> getReference();
+
+		/**
+		 * @return the handler for clicking on a search button
+		 */
+		HasClickHandlers getSearch();
+
+	}
+
+	/**
+	 * The default dispatcher to use to send requests to the server
+	 */
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * Constructor to set up the timeline module
+	 * 
+	 * @param display the view, passed in by Gin
+	 * @param eventBus the event bus, passed in by Gin
+	 * @param dispatcher the dispatcher, passed in by Gin
+	 */
+	@Inject
+	public ScriptureSelectorPresenter(final Display display, final EventBus eventBus,
+			final DispatchAsync dispatcher) {
+		super(display, eventBus);
+
+		this.dispatcher = dispatcher;
+
+		Log.debug("ScriptureSelectorPresenter initialised");
+		bind();
+	}
+
+	/**
+	 * @return the current reference as keyed in by the user.
+	 */
+	public String getCurrentReference() {
+		return display.getReference().getValue();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onBind() {
+		Log.debug("onBind called in ScriptureSelector");
+
+		dispatcher.execute(new GetBibleBooksCommand(), new DisplayCallback<GetBibleBooksCommandResult>(
+				display) {
+			@Override
+			protected void handleFailure(final Throwable e) {
+				// TODO Auto-generated method stub
+				Log.error("Unable to get books from server", e);
+			}
+
+			@Override
+			protected void handleSuccess(final GetBibleBooksCommandResult value) {
+				display.addSuggestions(value.getBooks());
+			}
+		});
+
+		display.getSearch().addClickHandler(new ClickHandler() {
+
+			public void onClick(final ClickEvent event) {
+				// can't use complicated classes here, as GWT java doesn't cope!
+				final String reference = display.getReference().getValue();
+				if (reference == null || reference.length() == 0) {
+					// return validation message perhaps? or ignore?
+					Log.error("No reference was provided, so no lookup can occur.");
+					return;
+				}
+
+				eventBus.fireEvent(new ScriptureChangeEvent(display.getReference().getValue()));
+			}
+		});
+
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/StepPresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/StepPresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/StepPresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,139 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.DisplayCallback;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.PopupPanel;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.LemmaClickedEvent;
+import com.tyndalehouse.step.web.client.eventhandler.LemmaClickedEventHandler;
+import com.tyndalehouse.step.web.shared.command.GetDictionaryDefinitionCommand;
+import com.tyndalehouse.step.web.shared.result.GetDictionaryDefinitionResult;
+
+/**
+ * This is the main Presenter, when the view is created, all other presenters
+ * are created as a result.
+ * 
+ * It acts as a singleton for each browser
+ * 
+ * @author cjburrell
+ * 
+ */
+public class StepPresenter extends WidgetPresenter<StepPresenter.Display> {
+	/**
+	 * The contract with the Step View, the main layout of Step
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+	}
+
+	/**
+	 * the default dispatcher for async server requests
+	 */
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * Constructor to set up the timeline module
+	 * 
+	 * @param display the view, passed in by Gin
+	 * @param eventBus the event bus, passed in by Gin
+	 * @param dispatcher the dispatcher, passed in by Gin
+	 */
+	@Inject
+	public StepPresenter(final Display display, final EventBus eventBus, final DispatchAsync dispatcher) {
+		super(display, eventBus);
+		this.dispatcher = dispatcher;
+
+		Log.debug("StepPresenter initialised");
+		bind();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+	}
+
+	/**
+	 * adds event handlers when they need to be parsed only once, but multiple
+	 * presenters may be interested this is a proxy. Typically an event should
+	 * then be fired if necessary to the presenters
+	 */
+	private void addSingletonEventHandlers() {
+		// TODO: this handler needs to be moved somewhere else, and fire off
+		// definition found
+		eventBus.addHandler(LemmaClickedEvent.TYPE, new LemmaClickedEventHandler() {
+
+			public void onLemmaClicked(final LemmaClickedEvent lemmaClickedEvent) {
+				Log.error("Lemma Clicked event handler invoked");
+				getLemmaDefinition(lemmaClickedEvent.getLemma());
+			}
+
+			private void getLemmaDefinition(final List<String> lemmaDefs) {
+				final GetDictionaryDefinitionCommand cmd = new GetDictionaryDefinitionCommand();
+				cmd.setLookupReference(lemmaDefs);
+
+				dispatcher.execute(cmd, new DisplayCallback<GetDictionaryDefinitionResult>(display) {
+					@Override
+					protected void handleFailure(final Throwable e) {
+						Log.error(e.getMessage());
+					}
+
+					@Override
+					protected void handleSuccess(final GetDictionaryDefinitionResult lemmaDefinition) {
+						Log.warn(lemmaDefinition.getXsltedDefinition());
+
+						// TODO: check whether definition came back alright!
+						// TODO: change the XSLT to something nicer
+						final PopupPanel popup = new PopupPanel();
+						popup.setWidget(new HTML(lemmaDefinition.getXsltedDefinition()));
+						popup.setAutoHideEnabled(true);
+						popup.show();
+
+						// scripture view doesn't need to know about this...
+						// TODO: remove DictionaryDefinitionFoundEvent and
+						// Handler
+						// eventBus.fireEvent(new
+						// DictionaryDefinitionFoundEvent(lemmaDefinition.getXsltedDefinition()));
+					}
+				});
+			}
+		});
+
+	}
+
+	@Override
+	protected void onBind() {
+		Log.debug("onBind called in STEP presenter");
+		addSingletonEventHandlers();
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimebandListPresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimebandListPresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimebandListPresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,98 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.List;
+
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.TimebandListUpdateRequiredEvent;
+import com.tyndalehouse.step.web.client.eventhandler.TimebandListUpdateRequiredEventHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.CurrentBandStats;
+
+/**
+ * The TimebandList presenter is the presenter for the Timeband list module.
+ * This module is a list of items, each one representing one timeband. Each item
+ * contains the real-time statistics of what is displayed on the timeband,
+ * including the number of event and the number of events currently visible
+ * 
+ * @author cjburrell
+ * 
+ */
+// TODO: refactor to ensure events get captured and dealt with in the presenter,
+// rather than in the view.
+
+public class TimebandListPresenter extends WidgetPresenter<TimebandListPresenter.Display> {
+
+	/**
+	 * Contract with any TimebandList view
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+		/**
+		 * This method updates the list displayed with the latest statistics
+		 * 
+		 * @param stats statistics to be sent to the view for update
+		 */
+		void updateList(List<CurrentBandStats> stats);
+	}
+
+	/**
+	 * Default constructor, injected with Gin
+	 * 
+	 * @param display the view, provided by Gin
+	 * @param eventBus the event bus, provided by Gin
+	 */
+	@Inject
+	public TimebandListPresenter(final TimebandListPresenter.Display display, final EventBus eventBus) {
+		super(display, eventBus);
+		bind();
+	}
+
+	@Override
+	protected void onBind() {
+		eventBus.addHandler(TimebandListUpdateRequiredEvent.TYPE,
+				new TimebandListUpdateRequiredEventHandler() {
+
+					public void onTimebandListRequiringUpdate(
+							final TimebandListUpdateRequiredEvent timebandListUpdateRequiredEvent) {
+						final List<CurrentBandStats> stats = timebandListUpdateRequiredEvent
+								.getTimelineStats();
+						display.updateList(stats);
+					}
+				});
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+	
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+		
+	}
+	
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+		
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimelinePresenter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimelinePresenter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/presenter/TimelinePresenter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,301 @@
+package com.tyndalehouse.step.web.client.presenter;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.client.DispatchAsync;
+import net.customware.gwt.presenter.client.DisplayCallback;
+import net.customware.gwt.presenter.client.EventBus;
+import net.customware.gwt.presenter.client.place.Place;
+import net.customware.gwt.presenter.client.place.PlaceRequest;
+import net.customware.gwt.presenter.client.widget.WidgetDisplay;
+import net.customware.gwt.presenter.client.widget.WidgetPresenter;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.ScriptureChangeEvent;
+import com.tyndalehouse.step.web.client.event.TimebandListUpdateRequiredEvent;
+import com.tyndalehouse.step.web.client.event.TimelineScrollEvent;
+import com.tyndalehouse.step.web.client.eventhandler.ScriptureChangeEventHandler;
+import com.tyndalehouse.step.web.client.eventhandler.TimelineScrollEventHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.TimeEvent;
+import com.tyndalehouse.step.web.client.toolkit.timeline.Timeband;
+import com.tyndalehouse.step.web.client.toolkit.timeline.Timeline;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimelineConstants;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.TimeBandNotFoundException;
+import com.tyndalehouse.step.web.shared.command.GetEventsForDateRangeCommand;
+import com.tyndalehouse.step.web.shared.command.GetTimelineOriginForScriptureCommand;
+import com.tyndalehouse.step.web.shared.command.GetTimelineUISetupCommand;
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineBean;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineEventBean;
+import com.tyndalehouse.step.web.shared.result.GetEventsForDateRangeResult;
+import com.tyndalehouse.step.web.shared.result.GetTimelineOriginForScriptureResult;
+import com.tyndalehouse.step.web.shared.result.GetTimelineUISetupResult;
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * TimelinePresenter is the presenter object for the Timeline module This is
+ * responsible for getting all the events from the server, firing changes across
+ * the event bus, if need be, repainting the timeline module, etc.
+ * 
+ * @author cjburrell
+ * 
+ */
+// TODO: timeline module needs refactoring quite a bit, since most of the logic
+// seems to be doing the view
+// as well, really ought to rewrite parts of it to remove the logic from the
+// display component
+public class TimelinePresenter extends WidgetPresenter<TimelinePresenter.Display> {
+	/**
+	 * the view contract for the timeline module
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public interface Display extends WidgetDisplay {
+
+		/**
+		 * @return the timeline module
+		 */
+		Timeline getTimeline();
+
+		/**
+		 * @return the zoom in Button
+		 */
+		HasClickHandlers getZoomIn();
+
+		/**
+		 * @return The zoom out button
+		 */
+		HasClickHandlers getZoomOut();
+	}
+
+	/**
+	 * The dispatcher for requests to the server
+	 */
+	private final DispatchAsync dispatcher;
+
+	/**
+	 * Constructor to set up the timeline module
+	 * 
+	 * @param display the view, passed in by Gin
+	 * @param eventBus the event bus, passed in by Gin
+	 * @param dispatcher the dispatcher, passed in by Gin
+	 */
+	@Inject
+	public TimelinePresenter(final Display display, final EventBus eventBus, final DispatchAsync dispatcher) {
+		super(display, eventBus);
+		this.dispatcher = dispatcher;
+
+		bind();
+	}
+
+	@Override
+	public Place getPlace() {
+		// TODO Auto-generated method stub
+		return null;
+	}
+
+	public void refreshDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void revealDisplay() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * registers interest in @see {@link ScriptureChangeEvent}
+	 */
+	private void addScriptureChangeHandler() {
+		eventBus.addHandler(ScriptureChangeEvent.TYPE, new ScriptureChangeEventHandler() {
+
+			public void onScriptureChange(final ScriptureChangeEvent event) {
+				Log.debug("Scripture Change event captured");
+
+				dispatcher.execute(new GetTimelineOriginForScriptureCommand(event.getNewReference()),
+						new DisplayCallback<GetTimelineOriginForScriptureResult>(display) {
+
+							@Override
+							protected void handleFailure(final Throwable e) {
+								Log.error("Failed to get timeline origin", e);
+							}
+
+							@Override
+							protected void handleSuccess(final GetTimelineOriginForScriptureResult value) {
+								if (!value.isEmpty()) {
+									final Timeline tl = display.getTimeline();
+									tl.repaint(value.getOriginDate(), value.getSuggestedTimeScale(), value
+											.getTimebandId());
+									// don't fire event to update list here,
+									// events haven't been requested yet!
+								}
+								// validation will be coped for elsewhere, in
+								// the relevant module, therefore do nothing at
+								// this stage
+							}
+
+						});
+
+				// so now we update the timeline, and we need to work out
+				// where to go.
+
+			}
+		});
+	}
+
+	/**
+	 * 
+	 */
+	private void addScrollHandler() {
+		eventBus.addHandler(TimelineScrollEvent.TYPE, new TimelineScrollEventHandler() {
+			public void onScroll(final TimelineScrollEvent event) {
+				dispatcher.execute(new GetEventsForDateRangeCommand(event.getTimebandVisibleDates()),
+						new DisplayCallback<GetEventsForDateRangeResult>(display) {
+							@Override
+							protected void handleFailure(final Throwable e) {
+								Log.error("An error occurred while tyring to get events for the timeline", e);
+							}
+
+							// TODO: push this down in to timeline component?
+							@Override
+							protected void handleSuccess(final GetEventsForDateRangeResult resultingEvents) {
+								Log.debug("Request for events came back succesfully!");
+								Log.debug("Request was for " + event.getTimebandVisibleDates().size()
+										+ " timebands.");
+
+								final List<TimelineEventBean> events = resultingEvents.getEvents();
+								final Timeline tl = getDisplay().getTimeline();
+
+								for (final TimelineEventBean ev : events) {
+									final int timebandId = ev.getTimelineId();
+
+									try {
+										final Timeband correctBand = tl.getBand(timebandId);
+										correctBand.addEvent(new TimeEvent(ev.getEventId(), ev.getName(), ev
+												.getFromDate(), ev.getToDate(), correctBand));
+									} catch (final TimeBandNotFoundException e) {
+										Log.debug("Could not find timeband");
+									}
+								}
+
+								// now that we've added something, we can notify
+								// the timebands that their minimum received
+								// windows are slightly more
+								// and also resize the bands too
+								for (final TimeBandVisibleDate tbvd : event.getTimebandVisibleDates()) {
+									try {
+										final Timeband tb = tl.getBand(tbvd.getTimebandId());
+										tb.adjustRequestedView(tbvd.getMinDate(), tbvd.getMaxDate());
+										tb.resizeBand();
+									} catch (final TimeBandNotFoundException e) {
+										// if for some reason the timeband has
+										// gone, we can but ignore
+										// the error
+										Log.error("Timeband " + tbvd.getTimebandId() + " cannot be found.");
+									}
+								}
+
+								eventBus.fireEvent(new TimebandListUpdateRequiredEvent(tl
+										.getCurrentBandStats()));
+							}
+						});
+			}
+		});
+	}
+
+	/**
+	 * Adds zoom in and out handlers to the timeline module
+	 */
+	private void addZoomHandlers() {
+		display.getZoomIn().addClickHandler(new ClickHandler() {
+
+			public void onClick(final ClickEvent event) {
+				// call zoom in on the timeline widget
+				display.getTimeline().zoomIn();
+			}
+		});
+
+		display.getZoomOut().addClickHandler(new ClickHandler() {
+
+			public void onClick(final ClickEvent event) {
+				// call zoom in on the timeline widget
+				display.getTimeline().zoomOut();
+			}
+		});
+	}
+
+	/**
+	 * calling the server for the initial data setup
+	 */
+	private void doInitialSetup() {
+		// TODO: this result can be cached quite successfully on the server
+		// (perhaps in the dispatch module
+		dispatcher.execute(new GetTimelineUISetupCommand(), new DisplayCallback<GetTimelineUISetupResult>(
+				display) {
+
+			@Override
+			protected void handleFailure(final Throwable e) {
+				Log.debug("Unable to initialise UI", e);
+			}
+
+			@Override
+			protected void handleSuccess(final GetTimelineUISetupResult setupData) {
+				Log.debug("Succesfully got timeline setup data");
+				setupTimeline(setupData);
+			}
+		});
+	}
+
+	@Override
+	protected void onBind() {
+		// TODO: all those anonymous classes make the code rather untidy... can
+		// we possible put all this somewhere else?
+		doInitialSetup();
+		addScrollHandler();
+		addZoomHandlers();
+		addScriptureChangeHandler();
+	}
+
+	@Override
+	protected void onPlaceRequest(final PlaceRequest request) {
+		// TODO Auto-generated method stub
+
+	}
+
+	@Override
+	protected void onUnbind() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * sets up the timeline view, height, intial timebands, etc.
+	 * 
+	 * @param setupData data returned from the server including all the
+	 *            timebands, and their units, etc.
+	 */
+	protected void setupTimeline(final GetTimelineUISetupResult setupData) {
+		final Timeline timeline = display.getTimeline();
+
+		// copy across to UI widget
+		// we could avoid the copying here, since the timline bean
+		// is essentially what is needed, but nice to have it decoupled.
+		// TODO: change TimelineBean to be a TimebandBean
+		for (final TimelineBean tb : setupData.getTimelines()) {
+			final Timeband band = new Timeband(timeline, tb.getTimelineId(), tb.getTimelineDescription());
+
+			band.setPixelsPerUnit(TimelineConstants.DEFAULT_PIXELS_PER_UNIT);
+			Log.debug("Unit of band is: " + tb.getUnit());
+			band.setOriginalUnit(Unit.valueOf(tb.getUnit()));
+			band.setCurrentDate(TimelineConstants.INITIAL_DATE);
+			band.setCurrentDateX(TimelineConstants.TIMELINE_WIDTH);
+			timeline.addBand(band);
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/eventbus/StepEventBusImpl.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/eventbus/StepEventBusImpl.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/eventbus/StepEventBusImpl.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,23 @@
+package com.tyndalehouse.step.web.client.service.eventbus;
+
+import net.customware.gwt.presenter.client.DefaultEventBus;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.shared.GwtEvent;
+
+/**
+ * Default Step event bus to be used. Provides extra logging and in flight
+ * monitoring capability later
+ * 
+ * @author cjburrell
+ * 
+ */
+public class StepEventBusImpl extends DefaultEventBus {
+
+	@Override
+	public void fireEvent(final GwtEvent<?> event) {
+		Log.debug("StepEventBus:: firing event " + event.toDebugString());
+		super.fireEvent(event);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleName.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleName.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleName.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,63 @@
+package com.tyndalehouse.step.web.client.service.refdata;
+
+/**
+ * Bean representing a module and its direct parent (if there is a hierarchy
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ModuleName {
+	/**
+	 * Module name
+	 */
+	private String moduleName;
+
+	/**
+	 * Parent if applicable of the module
+	 */
+	private String parent;
+
+	/**
+	 * Cosntructs a module with a given name and parent
+	 * 
+	 * @param moduleName module name
+	 * @param parent parent may be null
+	 */
+	public ModuleName(final String moduleName, final String parent) {
+		this.moduleName = moduleName;
+
+		if (parent == null) {
+			this.parent = "Module";
+		} else {
+			this.parent = parent;
+		}
+	}
+
+	/**
+	 * @return the moduleName
+	 */
+	public String getModuleName() {
+		return moduleName;
+	}
+
+	/**
+	 * @return the parent
+	 */
+	public String getParent() {
+		return parent;
+	}
+
+	/**
+	 * @param moduleName the moduleName to set
+	 */
+	public void setModuleName(final String moduleName) {
+		this.moduleName = moduleName;
+	}
+
+	/**
+	 * @param parent the parent to set
+	 */
+	public void setParent(final String parent) {
+		this.parent = parent;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleRefData.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleRefData.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/service/refdata/ModuleRefData.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,100 @@
+package com.tyndalehouse.step.web.client.service.refdata;
+
+import java.util.ArrayList;
+import java.util.List;
+
+//TODO: remove singleton pattern and use @Singleton and Gin instead.
+/**
+ * Client side service to serve the reference data to the user
+ */
+// TODO: Ginify the singleton pattern
+public final class ModuleRefData {
+	/**
+	 * This class is a singleton, so this is the unique private instance
+	 */
+	private static ModuleRefData instance;
+
+	/**
+	 * List of depths populating the Depth dropdown (level at which the user
+	 * wants to see articles)
+	 */
+	private final List<String> depths;
+
+	/**
+	 * List of module names to be displayed in the drop downs
+	 */
+	private final List<ModuleName> moduleNames;
+
+	/**
+	 * Private constructor setting up all modules, and their hierarchies For
+	 * e.g. People, Events and Eras come under History TODO: This needs
+	 * internationalising
+	 */
+	private ModuleRefData() {
+		moduleNames = new ArrayList<ModuleName>();
+
+		// no hashtable on client side...
+
+		// History Modules
+		moduleNames.add(new ModuleName("People", "History"));
+		moduleNames.add(new ModuleName("Events", "History"));
+		moduleNames.add(new ModuleName("Eras", "History"));
+
+		// Geography Modules
+		moduleNames.add(new ModuleName("Places", "Geography"));
+		moduleNames.add(new ModuleName("Maps", "Geography"));
+		moduleNames.add(new ModuleName("Google Maps", "Geography"));
+
+		// Main modules
+		// TODO: tidy up and send to paremeter files
+		moduleNames.add(new ModuleName("History", "Module"));
+		moduleNames.add(new ModuleName("Geography", "Module"));
+		moduleNames.add(new ModuleName("Language", "Module"));
+		moduleNames.add(new ModuleName("Parallels", "Module"));
+		moduleNames.add(new ModuleName("Translations", "Module"));
+		moduleNames.add(new ModuleName("Commentaries", "Module"));
+		moduleNames.add(new ModuleName("Publications", "Module"));
+		moduleNames.add(new ModuleName("Presentations", "Module"));
+
+		// DEPTHS
+		depths = new ArrayList<String>();
+		depths.add("Quick Look");
+		depths.add("Deep Study");
+		depths.add("Scholarly Details");
+	}
+
+	/**
+	 * @return the instance
+	 */
+	public static synchronized ModuleRefData getInstance() {
+		if (instance == null) {
+			instance = new ModuleRefData();
+		}
+
+		return instance;
+	}
+
+	/**
+	 * @return the depths
+	 */
+	public List<String> getDepths() {
+		return depths;
+	}
+
+	/**
+	 * Returns a list of modules given a parent module
+	 * 
+	 * @param parentModule parent module, or "Module" if none
+	 * @return the list of available modules
+	 */
+	public List<String> getListOfModules(final String parentModule) {
+		final List<String> subset = new ArrayList<String>();
+
+		for (final ModuleName mn : moduleNames) {
+			if (mn.getParent().equals(parentModule)) {
+				subset.add(mn.getModuleName());
+			}
+		}
+		return subset;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HasSource.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HasSource.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HasSource.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,24 @@
+package com.tyndalehouse.step.web.client.toolkit;
+
+/**
+ * Indicates that the view (generally) has got a source, a dropdown list for
+ * e.g.) and can be set
+ * 
+ * @author cjburrell
+ * 
+ * @param <T> The type of data it is expecting
+ */
+public interface HasSource<T> {
+	/**
+	 * Clears the source, i.e. resets to an empty list
+	 */
+	void clearSource();
+
+	/**
+	 * Settings the data
+	 * 
+	 * @param source source of the data
+	 */
+	void setSource(T source);
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HtmlList.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HtmlList.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/HtmlList.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,114 @@
+package com.tyndalehouse.step.web.client.toolkit;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.dom.client.LIElement;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * A HTML list, taken partially from the web This can be ordered or unordered
+ * 
+ * @author cjburrell
+ */
+public class HtmlList extends Widget {
+	/**
+	 * Two types of list, ordered or undered
+	 * 
+	 * @author cjburrell
+	 * 
+	 */
+	public static enum ListType {
+		/**
+		 * An ordered list
+		 */
+		ORDERED {
+			/**
+			 * Creates an UL element on the DOM
+			 * 
+			 * @return the element created
+			 */
+			@Override
+			public Element createElement() {
+				return Document.get().createOLElement();
+			}
+		},
+		/**
+		 * An unordered list
+		 */
+		UNORDERED {
+			/**
+			 * Creates an UL element on the DOM
+			 * 
+			 * @return the element created
+			 */
+			@Override
+			public Element createElement() {
+				return Document.get().createULElement();
+			}
+		};
+
+		/**
+		 * Creates an UL element on the DOM
+		 * 
+		 * @return the element created
+		 */
+		public abstract Element createElement();
+	}
+
+	/**
+	 * list of items to be mapped in the list. And whether they should launch
+	 * Commands on selected
+	 */
+	private final Map<Element, Command> listItems = new HashMap<Element, Command>();
+
+	/**
+	 * Constructor to create a HTML unordered or ordered list
+	 * 
+	 * @param listType whether an ordered or unordered list should be created
+	 */
+	public HtmlList(final ListType listType) {
+		setElement(listType.createElement());
+		setStylePrimaryName("html-list");
+	}
+
+	/**
+	 * Adds an item to the HtmlList
+	 * 
+	 * @param text the text next to the bullet/numbered point
+	 * @param command the command to be executed if a user clicks on it
+	 */
+	public void addItem(final String text, final Command command) {
+		final LIElement liElement = Document.get().createLIElement();
+		liElement.setInnerText(text);
+		getElement().appendChild(liElement);
+
+		listItems.put(liElement, command);
+
+		// All the events we're interested in
+		sinkEvents(Event.ONMOUSEOVER | Event.ONMOUSEOUT | Event.ONCLICK);
+	}
+	//	
+	// @Override
+	// public void onBrowserEvent(Event event) {
+	// switch(event.getTypeInt()) {
+	// case Event.ONCLICK:
+	// Element target = event.getTarget();
+	// if (listItems.containsKey(target))
+	// DeferredCommand.addCommand(listItems.get(target));
+	//
+	// break;
+	// case Event.ONMOUSEOUT:
+	// event.getTarget().setClassName(null);
+	// break;
+	//				
+	// case Event.ONMOUSEOVER:
+	// event.getTarget().setClassName("highlightOn");
+	// break;
+	// }
+	// }
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SimpleListBox.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SimpleListBox.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SimpleListBox.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,27 @@
+package com.tyndalehouse.step.web.client.toolkit;
+
+import java.util.List;
+
+import com.google.gwt.user.client.ui.ListBox;
+
+/**
+ * An extension to the GWT ListBox, mainly to allow the setSource method
+ * exposure, and hide implementation details of the ListBox from the presenter
+ * 
+ * @author cjburrell
+ * 
+ */
+public class SimpleListBox extends ListBox implements HasSource<List<String>> {
+
+	public void clearSource() {
+		this.clear();
+
+	}
+
+	public void setSource(final List<String> source) {
+		clearSource();
+		for (final String key : source) {
+			addItem(key);
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SourceListBox.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SourceListBox.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/SourceListBox.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,28 @@
+package com.tyndalehouse.step.web.client.toolkit;
+
+import java.util.SortedMap;
+import java.util.Map.Entry;
+
+import com.google.gwt.user.client.ui.ListBox;
+
+/**
+ * Similar to @see {@link SimpleListBox}, but the source is given as a HashMap
+ * 
+ * @author cjburrell
+ * 
+ */
+public class SourceListBox extends ListBox implements HasSource<SortedMap<String, String>> {
+
+	public void clearSource() {
+		this.clear();
+
+	}
+
+	public void setSource(final SortedMap<String, String> source) {
+		clearSource();
+		for (final Entry<String, String> entry : source.entrySet()) {
+			addItem(entry.getValue(), entry.getKey());
+		}
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/ScriptureDisplayConstants.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/ScriptureDisplayConstants.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/ScriptureDisplayConstants.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.web.client.toolkit.scripture;
+
+/**
+ * Scripture display module constants
+ * 
+ * @author cjburrell
+ * 
+ */
+public final class ScriptureDisplayConstants {
+
+	/**
+	 * To emphasis text in the module, for e.g. when a user clicks on a word
+	 */
+	public static final String EMPHASISE = "scripture-emphasise";
+
+	/**
+	 * making constructor private
+	 */
+	private ScriptureDisplayConstants() {
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/VerseLabel.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/VerseLabel.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/scripture/VerseLabel.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,132 @@
+package com.tyndalehouse.step.web.client.toolkit.scripture;
+
+import java.util.List;
+
+import net.customware.gwt.presenter.client.EventBus;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Label;
+import com.tyndalehouse.step.web.client.event.LemmaClickedEvent;
+
+/**
+ * Composite wrapper around a portion of scriptural text. The wrapper contains
+ * data retrieved from the server such as lemmas (Strong numbers), morphological
+ * data and an alternative word in the case of an interlinear
+ * 
+ * @author cjburrell
+ * 
+ */
+public class VerseLabel extends Composite {
+	/**
+	 * if there is an interlinear, then this is where the alternative word is
+	 * stored
+	 */
+	private Label alternativeWord;
+
+	/**
+	 * TODO: this should be removed into the presenter the event bus to fire off
+	 * events
+	 */
+	private final EventBus eventBus;
+
+	/**
+	 * Flow panel for display
+	 */
+	private final FlowPanel fp;
+
+	/**
+	 * List of Strong numbers associated to this portion of text
+	 */
+	private List<String> lemmas;
+
+	/**
+	 * The main word(s) to be displayed
+	 */
+	private final Label mainWord;
+
+	/**
+	 * list of morphs associated to this wrapper of text
+	 */
+	private List<String> morphs;
+
+	/**
+	 * This constructors initialises an instance of the composite wrapper and
+	 * sets up the panel, css, etc.
+	 * 
+	 * @param text the text to be wrapped
+	 * @param eventBus the event bus if events are to be fired
+	 */
+	public VerseLabel(final String text, final EventBus eventBus) {
+		fp = new FlowPanel();
+
+		// TODO: store all strings to do with css somewhere central
+		fp.setStyleName("scripture-interlinear");
+		initWidget(fp);
+
+		// main word display (from the version selected)
+		mainWord = new Label(text);
+		fp.add(mainWord);
+
+		this.eventBus = eventBus;
+	}
+
+	/**
+	 * @return the lemma
+	 */
+	public List<String> getLemma() {
+		return lemmas;
+	}
+
+	/**
+	 * @return the morph
+	 */
+	public List<String> getMorph() {
+		return morphs;
+	}
+
+	/**
+	 * sets the alternative word. This could be a Hebrew word, but for a classic
+	 * interlinear it could also be a English word, where the main word is the
+	 * Hebrew
+	 * 
+	 * @param originalWord an original word (for e.g. a hebrew translation)
+	 */
+	public void setAlternativeWord(final String originalWord) {
+		if (alternativeWord != null) {
+			alternativeWord.setText(originalWord);
+			return;
+		}
+
+		alternativeWord = new Label(originalWord);
+		fp.add(alternativeWord);
+	}
+
+	/**
+	 * @param lemma the lemma to set
+	 */
+	public void setLemmas(final List<String> lemma) {
+		this.lemmas = lemma;
+
+		if (lemma != null) {
+			// add a click listener
+			mainWord.addClickHandler(new ClickHandler() {
+
+				public void onClick(final ClickEvent event) {
+					Log.debug("Firing event");
+					eventBus.fireEvent(new LemmaClickedEvent(lemma));
+				}
+			});
+		}
+	}
+
+	/**
+	 * @param morph the morph to set
+	 */
+	public void setMorphs(final List<String> morph) {
+		this.morphs = morph;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TapeTrack.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TapeTrack.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TapeTrack.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,111 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * A tape track is the track on which events are painted. The events are
+ * contained by the TimeBand as that's where they logically reside. However,
+ * they are painted on the timetracks.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TapeTrack extends Widget {
+	/**
+	 * The following variable defines the earliest spot at which an event can be
+	 * painted
+	 */
+	private int earliestPaintOpportunity;
+
+	/**
+	 * Determines whether the Tape Track is part of the DOM yet
+	 */
+	private boolean isRendered;
+
+	/**
+	 * The following spot defines the latest spot at which an event needs to be
+	 * finished if it is to be painted on this track
+	 */
+	private int latestPaintOpportunity;
+
+	/**
+	 * Element on the DOM that is the track
+	 */
+	private final Element track;
+
+	/**
+	 * The default constructor initialises in memory a tape track. This includes
+	 * setting up the div outside of the DOM, and setting the default earliest
+	 * and latest opportunities for painting as Max and Min Integers hence
+	 * allowing everything to be painted
+	 */
+	public TapeTrack() {
+		isRendered = false;
+		track = DOM.createDiv();
+		track.setClassName("step-tape-track");
+		earliestPaintOpportunity = Integer.MAX_VALUE;
+		latestPaintOpportunity = Integer.MIN_VALUE;
+
+		setElement(track);
+	}
+
+	/**
+	 * Checks and then adds an event to the timetrack Logically it is still
+	 * added to the band, but it is painted on the timetrack
+	 * 
+	 * @param event even to be painted
+	 * @return whether the event has been painted
+	 */
+	public boolean addEvent(final TimeEvent event) {
+		if (canPaintAt(event.getLeftPixelPosition(), event.getTotalWidth())) {
+			// Log.debug(event.getDescription() +
+			// " can be painted on timetrack");
+			event.paint(this);
+
+			// now update the available bands
+			// Log.debug("Old latest and earliest times were: " +
+			// latestPaintOpportunity + "," + earliestPaintOpportunity);
+			latestPaintOpportunity = Math.max(latestPaintOpportunity, event.getLeftPixelPosition()
+					+ event.getTotalWidth());
+			earliestPaintOpportunity = Math.min(earliestPaintOpportunity, event.getLeftPixelPosition());
+			// Log.debug("New latest and earliest times were: " +
+			// latestPaintOpportunity + "," + earliestPaintOpportunity);
+			return true;
+		}
+		return false;
+	}
+
+	/**
+	 * The events need to be added in order, otherwise the time taping will not
+	 * be efficient Returns whether an event of width width can be painted at
+	 * position pixel
+	 * 
+	 * @param pixel pixel position at which to be painted
+	 * @param width width of the event
+	 * @return true if the event can be painted
+	 */
+	public boolean canPaintAt(final int pixel, final int width) {
+		return pixel > latestPaintOpportunity || (pixel + width + 1) < earliestPaintOpportunity;
+	}
+
+	/**
+	 * @return the track
+	 */
+	public Element getTrack() {
+		return track;
+	}
+
+	/**
+	 * paints the timetrack on to the timeband
+	 * 
+	 * @param band the band to be painteds
+	 */
+	public void paint(final Timeband band) {
+		if (!isRendered) {
+			band.getBandDiv().appendChild(track);
+			isRendered = true;
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEvent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEvent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEvent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,396 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import com.extjs.gxt.ui.client.core.El;
+import com.extjs.gxt.ui.client.util.TextMetrics;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimelineConstants;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.TimeConversionUtil;
+
+/**
+ * A time event, to be positioned on the screen
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimeEvent {
+
+	/**
+	 * events can move from one timeband to another
+	 */
+	private final Timeband currentTimeband;
+
+	/**
+	 * description of the event
+	 */
+	private String description;
+
+	/**
+	 * If this event is a duration, this captures the width to be displayed
+	 */
+	private int durationWidth;
+
+	/**
+	 * The master div containing all the relevant DOM elements representing it
+	 */
+	private Element eventDiv;
+
+	/**
+	 * default to a standard event or duration we will drive this from the
+	 * database
+	 */
+	private String eventType;
+
+	/**
+	 * The picture if appropriate, displaying the type of event
+	 */
+	private Element icon;
+	/**
+	 * id of the event
+	 */
+	private int id;
+
+	/**
+	 * whether the time event has been rendered on to the DOM yet
+	 */
+	private boolean isRendered = false;
+
+	/**
+	 * The label containing the text going with the event
+	 */
+	private Element label;
+
+	/**
+	 * The left-most position at which the event is located, in relation to the
+	 * timeband
+	 */
+	private int leftPixelPosition;
+	/**
+	 * the end date of a duration event
+	 */
+	private Long maxDate;
+
+	/**
+	 * the date of the event, and if a duration, the start date
+	 * 
+	 */
+	private Long minDate;
+
+	/**
+	 * Show event text
+	 */
+	private boolean showText;
+
+	/**
+	 * A representation of the total width occupied by the event, including the
+	 * text next to it. This is particularly important for events that are
+	 * single point in time, where the text will be much wider than the icon
+	 * 
+	 */
+	private int totalWidth;
+
+	/**
+	 * The
+	 * 
+	 * @param id id of the event
+	 * @param description a description to be displayed
+	 * @param minDate a minimum date
+	 * @param maxDate a maximum date, optional, in case of single point in time
+	 *            events
+	 * @param tb the timeband
+	 */
+	public TimeEvent(final int id, final String description, final Long minDate, final Long maxDate,
+			final Timeband tb) {
+		this.id = id;
+		this.description = description;
+		this.minDate = minDate;
+		this.maxDate = maxDate;
+		this.currentTimeband = tb;
+
+		setupEventSpecificOptions();
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	@Override
+	public boolean equals(final Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+		if (getClass() != obj.getClass()) {
+			return false;
+		}
+		final TimeEvent other = (TimeEvent) obj;
+		if (id != other.getId()) {
+			return false;
+		}
+		return true;
+	}
+
+	/**
+	 * @return the description
+	 */
+	public String getDescription() {
+		return description;
+	}
+
+	/**
+	 * returns the event div that is shown on the screen
+	 * 
+	 * @return the eventDiv
+	 */
+	public Element getEventDiv() {
+		return eventDiv;
+	}
+
+	/**
+	 * @return the eventType
+	 */
+	public String getEventType() {
+		return eventType;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public int getId() {
+		return id;
+	}
+
+	/**
+	 * @return the leftPixelPosition
+	 */
+	public int getLeftPixelPosition() {
+		return leftPixelPosition;
+	}
+
+	/**
+	 * @return the maxDate
+	 */
+	public Long getMaxDate() {
+		return maxDate;
+	}
+
+	/**
+	 * @return the minDate
+	 */
+	public long getMinDate() {
+		return minDate;
+	}
+
+	/**
+	 * @return the totalWidth
+	 */
+	public int getTotalWidth() {
+		return totalWidth;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#hashCode()
+	 */
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + id;
+		return result;
+	}
+
+	/**
+	 * returns whether this event is a duration or point in time event
+	 * 
+	 * @return true if this is a duration event
+	 */
+	public boolean isDuration() {
+		return maxDate == null;
+	}
+
+	/**
+	 * @return the isRendered
+	 */
+	public boolean isRendered() {
+		return isRendered;
+	}
+
+	/**
+	 * @return the showText
+	 */
+	public boolean isShowText() {
+		return showText;
+	}
+
+	/**
+	 * the main responsible culprit for painting events on the timeband
+	 * 
+	 * @param track the track on which the event will be painted
+	 */
+	public void paint(final TapeTrack track) {
+		// all we do is attach it to the parent if need be.
+		if (!isRendered) {
+			setupDivProperties();
+			track.getTrack().appendChild(eventDiv);
+			isRendered = true;
+		}
+	}
+
+	/**
+	 * ensures the event gets rendered next time paint() is called
+	 */
+	public void reset() {
+		isRendered = false;
+
+		// also recalculate the times and dates of the events (perhaps this is
+		// not always necessary)
+		setupEventSpecificOptions(); // a few extra bits in there, but nothing
+		// that takes time
+	}
+
+	/**
+	 * @param description the description to set
+	 */
+	public void setDescription(final String description) {
+		this.description = description;
+	}
+
+	/**
+	 * @param eventType the eventType to set
+	 */
+	public void setEventType(final String eventType) {
+		this.eventType = eventType;
+	}
+
+	/**
+	 * @param id the id to set
+	 */
+	public void setId(final int id) {
+		this.id = id;
+	}
+
+	/**
+	 * @param leftPixelPosition the leftPixelPosition to set
+	 */
+	public void setLeftPixelPosition(final int leftPixelPosition) {
+		this.leftPixelPosition = leftPixelPosition;
+	}
+
+	/**
+	 * @param maxDate the maxDate to set
+	 */
+	public void setMaxDate(final long maxDate) {
+		this.maxDate = maxDate;
+	}
+
+	/**
+	 * @param maxDate the maxDate to set
+	 */
+	public void setMaxDate(final Long maxDate) {
+		this.maxDate = maxDate;
+	}
+
+	/**
+	 * @param minDate the minDate to set
+	 */
+	public void setMinDate(final long minDate) {
+		this.minDate = minDate;
+	}
+
+	/**
+	 * @param minDate the minDate to set
+	 */
+	public void setMinDate(final Long minDate) {
+		this.minDate = minDate;
+	}
+
+	/**
+	 * @param showText the showText to set
+	 */
+	public void setShowText(final boolean showText) {
+		this.showText = showText;
+	}
+
+	/**
+	 * Creates all the elements/styles/etc.
+	 */
+	private void setupDivProperties() {
+		eventDiv = DOM.createDiv();
+		icon = DOM.createDiv();
+		label = DOM.createDiv();
+		final El gxtEvent = new El(eventDiv);
+		final El gxtLabel = new El(label);
+
+		// setup div hierarchy
+		eventDiv.appendChild(icon);
+		eventDiv.appendChild(label);
+
+		// setup CSS properties
+		eventDiv.setClassName(TimelineConstants.EVENT);
+
+		// setup positioning
+		gxtEvent.setLeft(leftPixelPosition);
+
+		// setup values
+		label.setInnerText(description);
+
+		// specific properties
+		if (maxDate != null) {
+			setupDurationProperties();
+		} else {
+			setupPointInTimeProperties();
+		}
+
+		// all css is setup, take measurement of label element:
+
+		final TextMetrics ruler = TextMetrics.get();
+		ruler.bind(new El(label));
+		final int labelWidth = ruler.getWidth(description);
+		gxtLabel.setWidth(labelWidth);
+
+		// set up width: if event, then labelWidth, otherwise
+		// max(duration,label)
+		totalWidth = maxDate == null ? labelWidth : Math.max(durationWidth, labelWidth);
+		gxtEvent.setWidth(totalWidth);
+	}
+
+	/**
+	 * Sets up duration properties
+	 */
+	private void setupDurationProperties() {
+		final El gxtIcon = new El(icon);
+		final El gxtLabel = new El(label);
+		gxtIcon.setWidth(durationWidth);
+		gxtIcon.setStyleName(eventType, true);
+		gxtLabel.setStyleName(TimelineConstants.DURATION_LABEL, true);
+	}
+
+	/**
+	 * Sets up properties and fields that depend on the type of event
+	 */
+	private void setupEventSpecificOptions() {
+		this.leftPixelPosition = TimeConversionUtil.timeToPixel(minDate.longValue(), currentTimeband);
+		if (maxDate == null) {
+			// then it's a point in time
+			eventType = TimelineConstants.POINT_IN_TIME_EVENT;
+		} else {
+			eventType = TimelineConstants.DURATION;
+			durationWidth = Math.max(TimelineConstants.EVENT_MIN_WIDTH, TimeConversionUtil.timeToPixel(
+					maxDate.longValue(), currentTimeband)
+					- leftPixelPosition);
+		}
+	}
+
+	/**
+	 * Sets up point in time properties
+	 */
+	private void setupPointInTimeProperties() {
+		final El gxtLabel = new El(label);
+		gxtLabel.setStyleName(TimelineConstants.POINT_IN_TIME_LABEL, true);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEventDescriptor.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEventDescriptor.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeEventDescriptor.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,82 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import com.extjs.gxt.ui.client.core.El;
+import com.google.gwt.event.dom.client.MouseEvent;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimelineConstants;
+
+/**
+ * There is only one TimeEvent descriptor for the timeline module. This is the
+ * hover over the time event on the timeline module. For e.g. a user might over
+ * a point in time event, and get a description of what/when it represents
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimeEventDescriptor {
+
+	/**
+	 * DOM Element containing the time event description
+	 */
+	private final Element div;
+
+	/**
+	 * a wrapper (div) around the main element
+	 */
+	private final El divWrapper;
+
+	/**
+	 * The timeline component on which to draw the popup
+	 */
+	private final Timeline timeline;
+
+	/**
+	 * public constructor initialising the descriptor
+	 * 
+	 * @param timeline the timeline on which the popup is to be displayed
+	 */
+	public TimeEventDescriptor(final Timeline timeline) {
+		this.timeline = timeline;
+		div = DOM.createDiv();
+		divWrapper = new El(div);
+
+		divWrapper.setStyleName("step-timeline-time-event-descriptor");
+		divWrapper.setDisplayed(false);
+
+		// append to timeline component
+		timeline.getElement().appendChild(div);
+	}
+
+	/**
+	 * @return the divWrapper
+	 */
+	public El getDivWrapper() {
+		return divWrapper;
+	}
+
+	/**
+	 * Hides the timeline
+	 */
+	public void hide() {
+		getDivWrapper().setDisplayed(false);
+	}
+
+	/**
+	 * Given a timed event, this shows the description in a div
+	 * 
+	 * @param te the TimeEvent to be displayed
+	 * @param me the mouse event that was triggered, contains details of pixel
+	 *            positions
+	 */
+	public void show(final TimeEvent te, final MouseEvent<?> me) {
+		final El divWrapper = getDivWrapper();
+		divWrapper.setInnerHtml(te.getId() + " - " + te.getDescription());
+		divWrapper.setDisplayed(true);
+		// Log.debug("x: " + me.getX());
+		// Log.debug("y: " + me.getY());
+
+		divWrapper.setLeft(timeline.getAbsoluteLeft() + me.getX());
+		divWrapper.setTop(timeline.getAbsoluteTop() + me.getY() - TimelineConstants.SPACE_BELOW_POPUP);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeScale.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeScale.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/TimeScale.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,164 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import java.util.HashMap;
+
+import com.extjs.gxt.ui.client.core.El;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.TimeConversionUtil;
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * time scale, in charge of drawing the different columns on the timeband at
+ * various lengths, dependant on the uni of the timeband
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimeScale {
+	/**
+	 * timeband on which the TimeScale resides
+	 */
+	private final Timeband band;
+
+	/**
+	 * true if time scale rendered
+	 */
+	private boolean isRendered = false;
+
+	/**
+	 * Maps of all timescales that have been drawn on the timeband
+	 */
+	private final HashMap<Integer, Element> paintedTimescaleBands;
+
+	/**
+	 * DOM element containing the scale columns
+	 */
+	private Element scaleBand;
+
+	/**
+	 * A timescale is attached to a timeband
+	 * 
+	 * @param band timeband to attach the scale on
+	 */
+	public TimeScale(final Timeband band) {
+		this.band = band;
+		paintedTimescaleBands = new HashMap<Integer, Element>();
+	}
+
+	/**
+	 * this paints the timescale band on those bits that need painting...
+	 */
+	public void paint() {
+		// check band is rendered, otherwise this is a waste of time
+		if (!band.isRendered()) {
+			return;
+		}
+
+		// if rendered already? skip!
+		if (!isRendered) {
+			scaleBand = DOM.createDiv();
+			paintedTimescaleBands.clear(); // reset in case we're in a zoom
+
+			final El gxtScaleBand = new El(scaleBand);
+			band.getBandDiv().appendChild(scaleBand);
+			gxtScaleBand.setStyleName("step-scale-band", true);
+			isRendered = true;
+		}
+
+		// finally render those bits that are visible only
+		paintVisibleScale();
+	}
+
+	/**
+	 * The easy way is to get rid of everything and repaint The slightly more
+	 * clever way is to actually repaint the existing dom elements. It uses more
+	 * memory though, however, we can try both eventually if need be.
+	 */
+	public void repaint() {
+		// remove oneself first
+		reset();
+		paint();
+	}
+
+	/**
+	 * resets to redraw
+	 */
+	public void reset() {
+		isRendered = false;
+	}
+
+	/**
+	 * draws the segments on the TimeScale DOM element
+	 * 
+	 * @param firstVisibleSegmentPixel first visible pixel, left most, of the
+	 *            band
+	 * @param numberOfVisibleSegments number of segments to draw
+	 */
+	private synchronized void drawSegments(final long firstVisibleSegmentPixel,
+			final long numberOfVisibleSegments) {
+		final El gxtScaleBand = new El(scaleBand);
+		final int pixelsPerUnit = band.getPixelsPerUnit();
+		int relativeLeft = (int) firstVisibleSegmentPixel;
+		// Log.debug("Drawing segments");
+		for (long ii = 0; ii < numberOfVisibleSegments + 1; ii++) {
+			// check segment not already drawn...
+			final Integer key = Integer.valueOf(relativeLeft);
+			final Integer keyMinus1 = Integer.valueOf(relativeLeft - 1);
+			final Integer keyPlus1 = Integer.valueOf(relativeLeft + 1);
+
+			// due to rounding errors, we need to check 1 below key and 1 above
+			// too
+			// TODO: instead of relying on time for drawing these, draw the
+			// first one,
+			// then rely on intervals. Saves computations for storage.
+			if (!paintedTimescaleBands.containsKey(key) && !paintedTimescaleBands.containsKey(keyPlus1)
+					&& !paintedTimescaleBands.containsKey(keyMinus1)) {
+				final Element un = DOM.createDiv();
+				final El gxtUn = new El(un);
+				gxtUn.setWidth(pixelsPerUnit);
+
+				un.setInnerText(TimeConversionUtil.formatPixelToTime(relativeLeft, band));
+				gxtScaleBand.appendChild(un);
+
+				// set left position:
+				gxtUn.setLeft(relativeLeft);
+				gxtUn.setTop(0); // if this is laid out after events, then 0
+				// makes sure it lines up to the top
+				gxtUn.setHeight("100%");
+
+				paintedTimescaleBands.put(key, un);
+			}
+			// else {
+			// TODO: log should come in next
+			// Log.debug("Segment not drawn as already painted");
+			// }
+			relativeLeft += pixelsPerUnit;
+		}
+	}
+
+	/**
+	 * paints the visible segments (columns) on to the band This method mainly
+	 * sets up all the relevant mathematics, and passes down
+	 */
+	private void paintVisibleScale() {
+		final long visibleLeft = band.getMinVisibleDate();
+		final long visibleRight = band.getMaxVisibleDate();
+
+		final Unit unit = band.getUnit();
+
+		// We do not want to generate all the time scale segments,
+		// the number of visible segments is number of time 'unit' is in the
+		// visible section
+		final long numberOfVisibleSegments = (visibleRight - visibleLeft) / unit.getMilliseconds();
+
+		// first visible segment is going to be located at
+		final long firstVisibleSegmentPixel = TimeConversionUtil.timeToPixel(visibleLeft
+				- (visibleLeft % unit.getMilliseconds()), band);
+
+		// TODO: uncomment all the debug statements and change global logging
+		// level to info
+		// Log.debug("Drawing segments for timeband" + band.getId());
+		drawSegments(firstVisibleSegmentPixel, numberOfVisibleSegments);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeband.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeband.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeband.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,952 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.TreeMap;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.extjs.gxt.ui.client.core.El;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.ui.Widget;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimebandRequestWindow;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimelineConstants;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.CannotDeleteEventException;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.IncapableOfCalculatingRequestWindowException;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.TimeConversionUtil;
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * The TimeBand object represents a section of the timeline that contains the
+ * events. There are many timebands on the timeline. Timebands contain
+ * TimeScales representing units as well as TapeTracks which contain the events
+ * The events are logically held on the Timeband, but painted on the time track.
+ * 
+ * @author CJBurrell
+ */
+public class Timeband extends Widget {
+	/**
+	 * The DOM element containing all timeband elements
+	 */
+	private Element bandDiv;
+
+	/**
+	 * The current date that is shown
+	 */
+	private long currentDate;
+
+	/**
+	 * The current pixel on the timeband representing the current date (above)
+	 */
+	private long currentDateX = 0;
+
+	/**
+	 * when this is set to true, then we can use the request window object to
+	 * determine whether or not we are showing all the events we are able to If
+	 * events can be deleted or moved to other timebands, it becomes difficult
+	 * to work out what the request window should be.
+	 */
+	private boolean deletionsDisabled = true;
+
+	/**
+	 * The timeband description
+	 */
+	private String description;
+
+	/**
+	 * this contains all the events on the time band
+	 */
+	private final TreeMap<Integer, TimeEvent> events;
+
+	/**
+	 * Id of the timeband
+	 */
+	private int id;
+
+	/**
+	 * This indicates whether the band has been painted and is showing
+	 */
+	private boolean isRendered = false;
+
+	/**
+	 * whether the user is interested in this timeband or not
+	 */
+	private boolean isUserInterested;
+
+	/**
+	 * Max date that the timeband is expected to paint
+	 */
+	private long maxDate;
+
+	/**
+	 * Min date that the timeband is expected to paint
+	 */
+	private long minDate;
+
+	/**
+	 * The last recorded mouse position on the mouse down event
+	 */
+	private int mouseDownScrollLeft;
+
+	/**
+	 * original unit as set up before it was rendered for the first time This is
+	 * used so that we can revert back to the original, recommended unit at
+	 * point in time
+	 */
+	private Unit originalUnit = null;
+
+	// TODO:Derive this from a properties file? somehow? or database?
+	/**
+	 * this describes how much of a unit needs to be visible before calling back
+	 * to the server
+	 */
+	private double outstandingUnitFactor = TimelineConstants.MINIMUM_UNIT_PORTION_BEFORE_SERVER_CALL;
+
+	/**
+	 * this is the parent widget Timeline object
+	 */
+	private final Timeline parent;
+
+	/**
+	 * Number of pixels to be shown per unit
+	 */
+	private int pixelsPerUnit;
+
+	/**
+	 * Each timeband is given a request window. This object is responsible of
+	 * working out how much to request from the server, so as not to flood it
+	 * with requests of stuff it already has
+	 */
+	private TimebandRequestWindow requestWindow = null;
+
+	/**
+	 * Whether or not to show the scale band
+	 */
+	private boolean showScale = true;
+
+	/**
+	 * The list of tape tracks on this timeband.
+	 */
+	private final List<TapeTrack> tapeTracks;
+
+	/**
+	 * The timeband container which contains the bandDiv
+	 */
+	private final Element timebandContainer;
+
+	/**
+	 * label of the timeband
+	 */
+	private Element timebandLabel;
+
+	/**
+	 * This is the timescale visible on the timeband drawing lines across the
+	 * timebands for each unit
+	 */
+	private TimeScale timescale;
+
+	/**
+	 * Determines the unit of the timeband and how to convert from/to
+	 * time/pixels
+	 */
+	private Unit unit;
+
+	/**
+	 * This determines how much of a zoom is applied. For example a factor of
+	 * 0.25 changes the scale of 50 pixels per decade to (1 + 0.25) * 50 = 75
+	 * pixels
+	 */
+	private double zoomFactor = TimelineConstants.ZOOM_FACTOR;
+
+	/**
+	 * To create a new timeband on the timeline
+	 * 
+	 * @param parent the timeline on which it is to be created
+	 * @param id the id of the timeband
+	 * @param description its description
+	 */
+	public Timeband(final Timeline parent, final int id, final String description) {
+		this.parent = parent;
+		this.id = id;
+		this.description = description;
+
+		// set up collections
+		events = new TreeMap<Integer, TimeEvent>();
+		tapeTracks = new ArrayList<TapeTrack>();
+
+		// set up page properties
+		bandDiv = DOM.createDiv();
+		timebandContainer = DOM.createDiv();
+		bandDiv.setClassName("step-timeband");
+		setElement(timebandContainer);
+	}
+
+	/**
+	 * Adds an event to the timeband, and therefore on to a random timetack. The
+	 * first available spot to minimize the space required. In particular this
+	 * delegates to addEventToTapeTrack after checking the event is not already
+	 * in our list of events
+	 * 
+	 * @param event event to be added
+	 */
+	public void addEvent(final TimeEvent event) {
+		// need to check the event isn't already in our list:
+		if (!events.containsKey(event.getId())) {
+			events.put(event.getId(), event);
+			addEventToTapeTrack(event);
+
+			// TODO: analyse this, but it is likely that it is not possible
+			// that the bit in the middle is redundant
+			if (isEventInVisibleSection(event)) {
+				Log.debug("Adding event to hidden band: " + event.getDescription());
+				addEventToTapeTrack(event);
+			}
+			// otherwise, autoHide is set to false, so leave hidden
+		}
+	}
+
+	/**
+	 * This method is used to tell the Timeband that it now has all events
+	 * within the section: (x1,x2). We can then use this to ensure subsequent
+	 * requests don't request the same thing from the server, hence reducing
+	 * load between the server and the client and also reducing the load on the
+	 * server
+	 * 
+	 * @param minDateRequested the minimum date that was requested and retrieved
+	 *            from the back-end
+	 * @param maxDateRequested the maximum date that was requested and retrieved
+	 *            from the back-end
+	 */
+	public void adjustRequestedView(final long minDateRequested, final long maxDateRequested) {
+		if (requestWindow == null) {
+			requestWindow = new TimebandRequestWindow(minDateRequested, maxDateRequested);
+		} else {
+			requestWindow.adjustRange(minDateRequested, maxDateRequested);
+		}
+	}
+
+	/**
+	 * when a mousedown event has been captured, update the position at which
+	 * the mouse was
+	 * 
+	 * @param e the mousedown event
+	 */
+	public void captureScrollLeft(final MouseDownEvent e) {
+		this.mouseDownScrollLeft = timebandContainer.getScrollLeft();
+	}
+
+	/**
+	 * @return the bandDiv
+	 */
+	public Element getBandDiv() {
+		return bandDiv;
+	}
+
+	/**
+	 * @return the currentDate
+	 */
+	public long getCurrentDate() {
+		return currentDate;
+	}
+
+	/**
+	 * @return the currentDateX
+	 */
+	public long getCurrentDateX() {
+		return currentDateX;
+	}
+
+	/**
+	 * @return the description
+	 */
+	public String getDescription() {
+		return description;
+	}
+
+	/**
+	 * @return the events
+	 */
+	public TreeMap<Integer, TimeEvent> getEvents() {
+		return events;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public int getId() {
+		return id;
+	}
+
+	/**
+	 * @return the maxDate
+	 */
+	public long getMaxDate() {
+		return maxDate;
+	}
+
+	/**
+	 * returns the current maximum visible date on the band
+	 * 
+	 * @return the maximum date visible on the band
+	 */
+	public long getMaxVisibleDate() {
+		int realClientWidth = timebandContainer.getClientWidth();
+		// if this is not rendered properly yet, then we have no width:
+		if (realClientWidth == 0) {
+			// use the timeline width, perhaps we can take the parent width
+			// instead...
+			// this is important as it it could that the timline doesn't take
+			// the full width
+			realClientWidth = Window.getClientWidth();
+		}
+
+		return TimeConversionUtil.pixelToTime(timebandContainer.getScrollLeft() + realClientWidth, this);
+	}
+
+	/**
+	 * @return the minDate, in pixels
+	 */
+	public long getMinDate() {
+		return minDate;
+	}
+
+	/**
+	 * returns the current minimum visible date on the band
+	 * 
+	 * @return the minimum date visible on the band
+	 */
+	public long getMinVisibleDate() {
+		return TimeConversionUtil.pixelToTime(timebandContainer.getScrollLeft(), this);
+	}
+
+	/**
+	 * Could this be optimized by organising the events in time order, and on
+	 * scroll recording which events have popped off?
+	 * 
+	 * @return the number of visible events in the band
+	 */
+	public int getNumberOfVisibleEvents() {
+		int count = 0;
+		for (final TimeEvent te : events.values()) {
+			if (isEventInVisibleSection(te)) {
+				count++;
+			}
+		}
+		return count;
+	}
+
+	/**
+	 * Works out how much of the timeband is to be requested Ideally we should
+	 * TODO: this somewhere else.
+	 * 
+	 * @return the visible section of the timeband
+	 * @throws IncapableOfCalculatingRequestWindowException thrown if we are not
+	 *             in a position to calculate what the remaining section is.
+	 */
+	public TimeBandVisibleDate getOustandingTimebandPeriod()
+			throws IncapableOfCalculatingRequestWindowException {
+		final long minVisibleDate = getMinVisibleDate();
+		final long maxVisibleDate = getMaxVisibleDate();
+		final long minimumDifference = (long) (unit.getMilliseconds() * outstandingUnitFactor);
+
+		// the new requested bit depends on our request window
+		if (requestWindow == null) {
+			return new TimeBandVisibleDate(id, minVisibleDate, maxVisibleDate);
+		} else {
+			// return only the portion that has changed (probably only one pixel
+			// worth)!
+			// -------|--------$------|-----$--------------------
+			// mvd mrd Mvd Mrd
+			final long minReceivedDate = requestWindow.getMinDate();
+			final long maxReceivedDate = requestWindow.getMaxDate();
+			final boolean shiftedLeft = minVisibleDate < minReceivedDate;
+			final boolean shiftedRight = maxVisibleDate > maxReceivedDate;
+
+			if (!shiftedLeft && !shiftedRight) {
+				return TimeBandVisibleDate.getNoRequest();
+			} else if (shiftedLeft && shiftedRight) {
+				// in this case, it was probably a zoom, and so we need to
+				// request both parts
+				return new TimeBandVisibleDate(id, minVisibleDate, maxVisibleDate);
+			} else if (shiftedLeft) {
+				// window could potentially have jumped, so there may be a gap
+				// between maxVisibleDate and min, so take so check that first:
+				if (maxVisibleDate < minReceivedDate) {
+					// we have issues here, as we're either going to have to
+					// remember about all the already painted stuff. this would
+					// potentially be troublesome
+					// as with units and zooming, we're going to have to
+					// eventually repaint huge amounts of stuff
+					// so reset to 0
+					requestWindow = null;
+
+					// TODO: investigate whether we want to clear the band down!
+					return new TimeBandVisibleDate(id, minVisibleDate, maxVisibleDate);
+				} else {
+					// the max is greater than the minimum so we return
+					if (minReceivedDate - minVisibleDate > minimumDifference) {
+						return new TimeBandVisibleDate(id, minVisibleDate, minReceivedDate);
+					} else {
+						return TimeBandVisibleDate.getNoRequest();
+					}
+				}
+			} else if (shiftedRight) {
+				// same problem as above if
+				if (minVisibleDate > maxReceivedDate) {
+					requestWindow = null;
+					return new TimeBandVisibleDate(id, minVisibleDate, maxVisibleDate);
+				} else {
+					// in particular check that the gap between maxReceivedDate
+					// and maxVisibleDate is enough
+					if (maxVisibleDate - maxReceivedDate > minimumDifference) {
+						return new TimeBandVisibleDate(id, maxReceivedDate, maxVisibleDate);
+					} else {
+						return TimeBandVisibleDate.getNoRequest();
+					}
+				}
+			} else {
+				throw new IncapableOfCalculatingRequestWindowException(minVisibleDate, maxVisibleDate,
+						minReceivedDate, maxReceivedDate);
+			}
+		}
+	}
+
+	/**
+	 * @return the outstandingUnitFactor
+	 */
+	public double getOutstandingUnitFactor() {
+		return outstandingUnitFactor;
+	}
+
+	/**
+	 * @return the pixelsPerUnit
+	 */
+	public int getPixelsPerUnit() {
+		return pixelsPerUnit;
+	}
+
+	/**
+	 * returns a single event contained on the timeband
+	 * 
+	 * @param eventId event id of the event
+	 * @return the TimeEvent
+	 */
+	public TimeEvent getSingleEvent(final String eventId) {
+		final Integer key = Integer.parseInt(eventId);
+		return events.get(key);
+	}
+
+	/**
+	 * current number of tape tracks on the band. Also remember that one tape
+	 * track is allocated at the top of the timeband to allow for dates to be
+	 * displayed
+	 * 
+	 * @return the numbers of tracks on the band
+	 */
+	public int getSizeTapeTracks() {
+		return tapeTracks.size();
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public Unit getUnit() {
+		return unit;
+	}
+
+	/**
+	 * @return the zoomFactor
+	 */
+	public double getZoomFactor() {
+		return zoomFactor;
+	}
+
+	/**
+	 * Hides by setting the height of the band to 0
+	 */
+	public void hideFromUser() {
+		// set height to 0 by default, and we'll add something later TODO: to
+		// see which bands have got events...
+		new El(timebandContainer).setHeight(0);
+	}
+
+	/**
+	 * @return the deletionsDisabled
+	 */
+	public boolean isDeletionsDisabled() {
+		return deletionsDisabled;
+	}
+
+	/**
+	 * indicates whether the band has been rendered or not
+	 * 
+	 * @return true if the band has been rendered
+	 */
+	public boolean isRendered() {
+		return isRendered;
+	}
+
+	/**
+	 * @return the showScale
+	 */
+	public boolean isShowScale() {
+		return showScale;
+	}
+
+	/**
+	 * @return the isUserInterested
+	 */
+	public boolean isUserInterested() {
+		return isUserInterested;
+	}
+
+	/**
+	 * Does not delete the events but redraws everything else.
+	 */
+	public void redrawBand() {
+		tapeTracks.clear();
+
+		// use El to remove all children
+		new El(bandDiv).removeChildren();
+		resetAllEvents();
+
+		timescale.repaint();
+
+		requestWindow = null;
+
+		drawEvents();
+	}
+
+	/**
+	 * Resets the timeband and redraws it
+	 */
+	public void redrawEmptyBand() {
+		events.clear();
+		redrawBand();
+	}
+
+	/**
+	 * true if the band is targetted from user input
+	 * 
+	 * @param isUserInterested identifies whether a user is interested in the
+	 *            band
+	 */
+	public void registerUserInterest(final boolean isUserInterested) {
+		this.isUserInterested = isUserInterested;
+	}
+
+	/**
+	 * Removes an event from the band
+	 * 
+	 * @param id the id of the event to be removed.
+	 * @throws CannotDeleteEventException An event cannot be removed from a
+	 *             timeband.
+	 */
+	public void removeEvent(final int id) throws CannotDeleteEventException {
+		if (deletionsDisabled) {
+			throw new CannotDeleteEventException("The event you are trying to delete (" + id
+					+ ") is on band set on" + "deletionsDisabled = true");
+		}
+
+		events.remove(id);
+		// TODO: refresh the timeline dom
+	}
+
+	/**
+	 * resets the band to use the original unit
+	 */
+	public void resetOriginalUnit() {
+		setUnit(originalUnit);
+	}
+
+	/**
+	 * Resizes bands dependant on how many bands are present.
+	 */
+	public void resizeBand() {
+		if (isUserInterested) {
+			// resize the timeband to take account of the number of timetracks
+			new El(timebandContainer).setHeight(tapeTracks.size() * TimelineConstants.TAPE_TRACK_HEIGHT);
+		}
+	}
+
+	/**
+	 * Gets the band to scroll to the current date
+	 */
+	public void scrollToCurrentDate() {
+		Log.debug("Client width /2 : " + (timebandContainer.getClientWidth() / 2));
+		new El(timebandContainer)
+				.setScrollLeft((int) currentDateX - (timebandContainer.getClientWidth() / 2));
+		displayTimebandLabel();
+	}
+
+	/**
+	 * @param bandDiv the bandDiv to set
+	 */
+	public final void setBandDiv(final Element bandDiv) {
+		this.bandDiv = bandDiv;
+	}
+
+	/**
+	 * resetting the current date...
+	 * 
+	 * @param currentDate the date on which the timeband is rooted
+	 */
+	public void setCurrentDate(final long currentDate) {
+		this.currentDate = currentDate;
+
+		// if we're changing the date, then everything on the band is going to
+		// be wrong, so
+		// get rid of it...
+
+	}
+
+	/**
+	 * @param currentDateX the currentDateX to set
+	 */
+	public void setCurrentDateX(final long currentDateX) {
+		this.currentDateX = currentDateX;
+	}
+
+	/**
+	 * @param deletionsDisabled the deletionsDisabled to set
+	 */
+	public void setDeletionsDisabled(final boolean deletionsDisabled) {
+		this.deletionsDisabled = deletionsDisabled;
+	}
+
+	/**
+	 * @param description the description to set
+	 */
+	public void setDescription(final String description) {
+		this.description = description;
+	}
+
+	/**
+	 * @param id the id to set
+	 */
+	public void setId(final int id) {
+		this.id = id;
+	}
+
+	/**
+	 * @param maxDate the maxDate to set
+	 */
+	public void setMaxDate(final long maxDate) {
+		this.maxDate = maxDate;
+	}
+
+	/**
+	 * @param minDate the minDate to set
+	 */
+	public void setMinDate(final long minDate) {
+		this.minDate = minDate;
+	}
+
+	/**
+	 * Usuall, the first call ever to set the unit of the timeband. The original
+	 * unit gets cached in the originalUnit field For other uses, use @see
+	 * {@link Timeband.setUnit} If not set, then it gets set. Otherwise a
+	 * warning if produced
+	 * 
+	 * @param unit unit to be associated with the timeband
+	 */
+	public void setOriginalUnit(final Unit unit) {
+		if (originalUnit == null) {
+			originalUnit = unit;
+		} else {
+			Log.warn("Original unit is already set. Please use resetOriginalUnit instead");
+		}
+		resetOriginalUnit();
+	}
+
+	/**
+	 * @param outstandingUnitFactor the outstandingUnitFactor to set
+	 */
+	public void setOutstandingUnitFactor(final double outstandingUnitFactor) {
+		this.outstandingUnitFactor = outstandingUnitFactor;
+	}
+
+	/**
+	 * @param pixelsPerUnit the pixelsPerUnit to set
+	 */
+	public void setPixelsPerUnit(final int pixelsPerUnit) {
+		this.pixelsPerUnit = pixelsPerUnit;
+	}
+
+	/**
+	 * sets the new position of the window, when the user is moving it
+	 * 
+	 * @param previousClientX the previousPosition on the x axis
+	 * @param newClientX the new position where it should be moved
+	 * @param defaultUnit the default unit which should be used to calculate the
+	 *            time difference
+	 * @param defaultPixelsPerUnit the default number of pixels per unit
+	 */
+	public void setScrollLeft(final int previousClientX, final int newClientX, final Unit defaultUnit,
+			final int defaultPixelsPerUnit) {
+		// we scroll, but we calculate the unit/scale factor first
+		// say default is 1 Year
+		// this one is 10 years
+		// unit Factor = 0.1 so we scroll 10 times less pixels
+		final double unitFactor = (double) defaultUnit.getMilliseconds() / (double) unit.getMilliseconds();
+
+		// now say instead unit factor is 1, ie. the same unit, but different
+		// number of pixels
+		// default is 50 pixels per year, this one is 25 pixels a year
+		// so we want to scroll half
+		final double pixelFactor = (double) pixelsPerUnit / (double) defaultPixelsPerUnit;
+		final double xAxisDiff = (previousClientX - newClientX) * (unitFactor * pixelFactor);
+		final int newScrollLeft = (int) (mouseDownScrollLeft + xAxisDiff);
+		this.timebandContainer.setScrollLeft(newScrollLeft);
+		displayTimebandLabel();
+	}
+
+	/**
+	 * @param showScale the showScale to set
+	 */
+	public void setShowScale(final boolean showScale) {
+		this.showScale = showScale;
+	}
+
+	/**
+	 * @param unit the unit to set
+	 */
+	public void setUnit(final Unit unit) {
+		this.unit = unit;
+	}
+
+	/**
+	 * @param zoomFactor the zoomFactor to set
+	 */
+	public void setZoomFactor(final double zoomFactor) {
+		this.zoomFactor = zoomFactor;
+	}
+
+	/**
+	 * Zooms in
+	 */
+	public void zoomIn() {
+		zoom(1 + zoomFactor);
+	}
+
+	/**
+	 * The way zooming works is that we recalculate the positions of all events
+	 * on the timeline
+	 */
+	public void zoomOut() {
+		// first change the zoom factor, then repaint events, and the timescale
+		// lets just assume a default zoom factor for now
+		// TODO: zoom in factor to be parameterised
+		zoom(1 - zoomFactor);
+
+	}
+
+	/**
+	 * Adds an event to the tape track. This ensures that the event has not
+	 * already been rendered If so, then it is present somewhere, perhaps not on
+	 * this band though. Then, iterates through the tape tracks trying to add
+	 * the event (i.e. asking each track whether there is space for the icon and
+	 * the text to be added)
+	 * 
+	 * @param event event to be added to the tape track
+	 */
+	private void addEventToTapeTrack(final TimeEvent event) {
+		int startIndex = showScale ? 1 : 0; // leaving room for the scale band
+
+		// if event is added already, then exit
+		if (event.isRendered()) {
+			return;
+		}
+
+		while (startIndex < tapeTracks.size()) {
+			// Log.debug("Trying to add " + event.getDescription() +
+			// " to track " + startIndex);
+			// try and add event to track
+			if (tapeTracks.get(startIndex).addEvent(event)) {
+				return;
+			}
+			startIndex++;
+		}
+
+		// Log.debug("Going to create a new tape track");
+
+		// check that the event was added, otherwise add timetrack
+		if (startIndex >= tapeTracks.size()) {
+			// did not manage to add it to tracks. therefore, let's add another
+			// one:
+			final TapeTrack t = addNewTapeTrack();
+			t.addEvent(event);
+		}
+	}
+
+	/**
+	 * Adds the timeband label to the band
+	 */
+	private void addLabelToBand() {
+		timebandLabel = DOM.createDiv();
+		final El gxtTimebandLabel = new El(timebandLabel);
+		gxtTimebandLabel.setStyleName("step-timeband-label", true);
+		gxtTimebandLabel.setLeft(getElement().getScrollLeft());
+		timebandLabel.setInnerText(description + "(" + id + ")");
+		timebandContainer.appendChild(timebandLabel);
+
+	}
+
+	/**
+	 * adds a new tape track to the timeband. The TapeTrack gets rendered at the
+	 * same time
+	 * 
+	 * @return the TapeTrack that was added
+	 */
+	private TapeTrack addNewTapeTrack() {
+		final TapeTrack t = new TapeTrack();
+		tapeTracks.add(t);
+		t.paint(this);
+		return t;
+	}
+
+	/**
+	 * TODO: The idea is to adjust depending on how many pixels constitutes a
+	 * unit so that we can easily zoom in and out and have the units repainted
+	 * properly
+	 */
+	private void adjustUnit() {
+
+	}
+
+	/**
+	 * Displays the timeband label on the timeband, with the description of it
+	 */
+	private void displayTimebandLabel() {
+		new El(timebandLabel).setLeft(getElement().getScrollLeft());
+	}
+
+	/**
+	 * Draws event onto the band
+	 */
+	private void drawEvents() {
+		// get the events to paint themselves (they will decide whether or not
+		// to
+		// paint if they are already showing...
+		for (final TimeEvent te : events.values()) {
+			addEventToTapeTrack(te);
+		}
+	}
+
+	/**
+	 * Tells the caller whether the event is in the visible section of the div
+	 * on the browser.
+	 * 
+	 * @param event the event to be tested
+	 * @return true if the event is in the visible section
+	 */
+	private boolean isEventInVisibleSection(final TimeEvent event) {
+		final Long eventMinDate = event.getMinDate();
+		final Long eventMaxDate = event.getMaxDate(); // eventMaxDate can be
+		// null
+		final long minVisibleDate = getMinVisibleDate();
+		final long maxVisibleDate = getMaxVisibleDate();
+
+		// output compare option:
+		// DateTimeFormat dtf = DateTimeFormat.getFormat("yyyy G");
+
+		// Log.debug("Comparing ev(" +
+		// dtf.format(new Date(eventMinDate)) + "," +
+		// dtf.format(new Date(eventMaxDate)) + ") " +
+		// "to band(" +
+		// dtf.format(new Date(minVisibleDate)) + "," +
+		// dtf.format(new Date(maxVisibleDate)) + ")");
+
+		if ((eventMinDate >= minVisibleDate && eventMinDate <= maxVisibleDate)
+				|| (eventMaxDate != null && eventMaxDate >= minVisibleDate && eventMaxDate <= maxVisibleDate)
+				|| (eventMaxDate != null && eventMinDate <= minVisibleDate && eventMaxDate >= maxVisibleDate)) {
+			return true;
+		}
+
+		return false;
+	}
+
+	/**
+	 * Resets the rendered status on all events
+	 */
+	private void resetAllEvents() {
+		for (final TimeEvent te : events.values()) {
+			te.reset();
+		}
+	}
+
+	/**
+	 * Zooms out given a ratio
+	 * 
+	 * @param zoomRatio the given ratio to zoom in and out
+	 */
+	private void zoom(final double zoomRatio) {
+		// TODO: somehow start with those events in the window (although for
+		// zoomout, won't make a different
+		// first change the scale
+		pixelsPerUnit *= zoomRatio;
+		adjustUnit();
+		redrawBand();
+	}
+
+	/**
+	 * adds the band to the DOM
+	 */
+	protected void addBandToUI() {
+		final El el = new El(timebandContainer);
+		final El gxtBandDiv = new El(bandDiv);
+
+		// set display options, ie. auto hide
+		// if (autoHide && !hasVisibleEvents()) {
+		// el.setDisplayed(false);
+		// }
+
+		parent.getTimelineContainer().appendChild(timebandContainer);
+		timebandContainer.appendChild(bandDiv);
+		addLabelToBand();
+
+		el.setStyleName("step-timeband-container");
+		gxtBandDiv.setHeight("100%");
+		gxtBandDiv.setTop(0);
+	}
+
+	/**
+	 * Repaints the timeband
+	 * 
+	 * @param top
+	 */
+	protected void paint() {
+		// Log.debug("Request to paint band id:" + getId() + " Current date: " +
+		// getCurrentDate() + " Desc:" + getDescription());
+		if (!isRendered) {
+			addBandToUI();
+			isRendered = true;
+		}
+
+		// show scale band?
+		if (showScale) {
+			// check if default time track has been added and add if not
+			if (tapeTracks.size() == 0) {
+				addNewTapeTrack();
+			}
+
+			if (timescale == null) {
+				timescale = new TimeScale(this);
+			}
+			timescale.paint();
+		}
+
+		drawEvents();
+
+		if (isUserInterested) {
+			// after adding events, call the resizing function.
+			// It decides whether or not the band needs resizing, so no overhead
+			resizeBand();
+		} else {
+			hideFromUser();
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeline.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeline.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/Timeline.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,564 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.customware.gwt.presenter.client.EventBus;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.extjs.gxt.ui.client.core.El;
+import com.google.gwt.dom.client.EventTarget;
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseEvent;
+import com.google.gwt.event.dom.client.MouseMoveEvent;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseUpEvent;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.ui.Widget;
+import com.tyndalehouse.step.web.client.event.TimebandListUpdateRequiredEvent;
+import com.tyndalehouse.step.web.client.event.TimelineScrollEvent;
+import com.tyndalehouse.step.web.client.event.UserInterestInBandEvent;
+import com.tyndalehouse.step.web.client.eventhandler.UserInterestInBandEventHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.components.TimelineConstants;
+import com.tyndalehouse.step.web.client.toolkit.timeline.events.TimelineMouseHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.IncapableOfCalculatingRequestWindowException;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.TimeBandNotFoundException;
+import com.tyndalehouse.step.web.client.toolkit.timeline.exceptions.UnknownFiredElement;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.CurrentBandStats;
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * FEATURE: Add uncertain times from database as dotted events/bands FEATURE:
+ * Add red line down the middle as current Sync line that tells user where bands
+ * are sunk FEATURE: Proper descriptions appearing in hover popups FEATURE: Add
+ * support for timetagging, history links, so that user can copy and paste url
+ * BUG: Fix obvious units that are wrong BUG: Timeline doesn't render properly
+ * when stuff is cached
+ * 
+ * 
+ * div .step-timeline (step-grab step-letgo) | | - div .step-timeline-container
+ * | | - div .step-timeband-container | | - div .step-timeband | | - div .
+ * step-scale-band
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class Timeline extends Widget {
+
+	/**
+	 * Client X records the last X-axis mouse position
+	 */
+	private int clientX;
+
+	/**
+	 * Map of hover over popups that describe an event
+	 */
+	private final TimeEventDescriptor descriptor;
+
+	/**
+	 * keeps track of whether the mouse button is up or down
+	 */
+	private boolean downStatus;
+
+	/**
+	 * The event bus on which to fire events
+	 */
+	private final EventBus eventBus;
+
+	/**
+	 * the current height of the timeline module
+	 */
+	private int height;
+
+	/**
+	 * whether the timeline is displayed horizontally or vertically (vertically
+	 * is not currently supported)
+	 */
+	private boolean isHorizontal;
+
+	/**
+	 * whether the timeline module has been rendered
+	 */
+	private boolean isRendered = false;
+
+	/**
+	 * The list of timebands
+	 */
+	private final List<Timeband> timebands;
+
+	/**
+	 * The container for the timeline module, a DOM element wrapping the whole
+	 * lot this is for styling and makes it easier
+	 */
+	private final Element timelineContainer;
+
+	/**
+	 * the timeline div, in which everything gets done.
+	 */
+	private final Element timelineDiv;
+
+	/**
+	 * The current width of the timeline module when rendered
+	 */
+	private int width;
+
+	/**
+	 * Default constructor
+	 * 
+	 * @param eventBus the event bus to fire events on
+	 */
+	public Timeline(final EventBus eventBus) {
+		this.eventBus = eventBus;
+		timebands = new ArrayList<Timeband>();
+
+		timelineContainer = DOM.createDiv();
+		timelineContainer.setClassName("step-timeline-container");
+
+		timelineDiv = DOM.createDiv();
+		timelineDiv.setClassName("step-timeline");
+		setElement(timelineDiv);
+
+		// set up hover over
+		descriptor = new TimeEventDescriptor(this);
+
+		paint();
+		addEventHandlers(eventBus);
+		disableSelection(getElement());
+	}
+
+	/**
+	 * Adds a band to a timeline module
+	 * 
+	 * @param band the timeband to be added
+	 */
+	public synchronized void addBand(final Timeband band) {
+		timebands.add(band);
+		band.paint();
+	}
+
+	/**
+	 * Both on load and on scroll we are doing an awful lot of looping to
+	 * repaint just in case TODO: change this perhaps with a stack of repainting
+	 * needed to ensure that we only repaint those timebands that think they
+	 * need repainting. for example, we don't need to be repainting the whole
+	 * band for one event etc.
+	 */
+	public void fireTimelineScrollEvent() {
+		final TimelineScrollEvent tse = new TimelineScrollEvent();
+
+		// calculate only those bits that need requesting! but at the same time
+		// we don't need to wait for the server to redraw timebands
+		for (final Timeband tb : timebands) {
+			try {
+				tb.paint(); // the timeband is rendered, and there are no new
+				// events,
+				// so apart from looping through the events which are already
+				// rendered
+				// we are only repainting the timescale
+
+				final TimeBandVisibleDate tvd = tb.getOustandingTimebandPeriod();
+				Log.debug("firing scroll " + tb.getDescription() + " " + tvd.getMinDate() + ","
+						+ tvd.getMaxDate());
+				tse.addTimebandVisibleDate(tvd);
+			} catch (final IncapableOfCalculatingRequestWindowException e) {
+				Log.error("Incapable of calculating request window", e);
+			}
+		}
+
+		// check we have something to fire
+		if (tse.getTimebandVisibleDates().size() != 0) {
+			eventBus.fireEvent(tse);
+		} else {
+			// this is fired after the scroll has got the events,
+			// but in this case we're not event firing
+			// the event, so should update the stats, since the visible view has
+			// changed
+			eventBus.fireEvent(new TimebandListUpdateRequiredEvent(getCurrentBandStats()));
+		}
+	}
+
+	/**
+	 * returns a band to the caller based on the band id
+	 * 
+	 * @param bandId the band id of the band to be returned
+	 * @return the relevant timeband
+	 * @throws TimeBandNotFoundException thrown if bandId is not part of this
+	 *             timeline module
+	 */
+	public Timeband getBand(final int bandId) throws TimeBandNotFoundException {
+		// do a linear search - we're not going to have lots of timebands
+		for (final Timeband t : timebands) {
+			if (t.getId() == bandId) {
+				return t;
+			}
+		}
+
+		throw new TimeBandNotFoundException("Timeband " + bandId + " was not found.");
+	}
+
+	/**
+	 * Returns the number of bands to the caller
+	 * 
+	 * @return the number of bands on the timeline module
+	 */
+	public int getBandCount() {
+		return timebands.size();
+	}
+
+	/**
+	 * returns the list of the timeband. This is rather dangerous, and probably
+	 * should be protected
+	 * 
+	 * @return the list of timebands
+	 */
+	public List<Timeband> getBands() {
+		return timebands;
+	}
+
+	/**
+	 * returns the stats for all timebands to the caller
+	 * 
+	 * @return a list containing lots of @see {@link CurrentBandStats}
+	 */
+	public List<CurrentBandStats> getCurrentBandStats() {
+		final List<CurrentBandStats> stats = new ArrayList<CurrentBandStats>();
+		for (final Timeband band : timebands) {
+
+			final CurrentBandStats bandStats = new CurrentBandStats(band.getId(), band.getDescription(), band
+					.getEvents().size(), band.getNumberOfVisibleEvents(), band.isUserInterested());
+			stats.add(bandStats);
+		}
+
+		return stats;
+	}
+
+	/**
+	 * @return the height
+	 */
+	public int getHeight() {
+		return height;
+	}
+
+	/**
+	 * @return the timelineContainer
+	 */
+	public Element getTimelineContainer() {
+		return timelineContainer;
+	}
+
+	/**
+	 * @return the width
+	 */
+	public int getWidth() {
+		return width;
+	}
+
+	/**
+	 * handles the mouse event, by alerting all the various bands to capture the
+	 * position of the mouse on them
+	 * 
+	 * @param e mouse event
+	 */
+	public void handle(final MouseDownEvent e) {
+		downStatus = true;
+		clientX = e.getClientX();
+
+		// capture scrollLeft on every timeband
+		for (final Timeband tb : timebands) {
+			tb.captureScrollLeft(e);
+		}
+
+		// Log.debug("ClientX " + clientX);
+
+		// change cursor to hand grab
+		new El(timelineDiv).setStyleName("step-grab", true);
+
+		// cursor: hand; /* ? */ TODO
+	}
+
+	/**
+	 * handles a move of the mouse, Ensures we know what timeband has been fired
+	 * then if the mouse is down, then tells timebands to move across else,
+	 * perhaps we're mouse hovering over something, and a popup needs to be
+	 * shown
+	 * 
+	 * @param e the mouse move event
+	 */
+	public void handle(final MouseMoveEvent e) {
+		if (timebands.size() != 0) {
+			Timeband firedBand;
+			try {
+				firedBand = getFiredBand(e);
+			} catch (final UnknownFiredElement e1) {
+				Log.warn("Unknown element was fired");
+				firedBand = timebands.get(0);
+			}
+
+			final Unit unit = firedBand.getUnit();
+			final int pixelsPerUnit = firedBand.getPixelsPerUnit();
+
+			if (downStatus) {
+				// mouse is down so move the scroll bars on each timeband
+				// for each timeband, scroll a certain amount... This amount
+				// though
+				// is relative to the scales
+				// at the same time we want to add some new scroll visible event
+				// to
+				// allow service layer to update
+				// the events shown if necessary on each timeband
+				for (final Timeband tb : timebands) {
+					tb.setScrollLeft(clientX, e.getClientX(), unit, pixelsPerUnit);
+					// Log.debug("About to scroll: " + (clientX -
+					// e.getClientX()));
+				}
+
+				// fire the event and let presenter decide how much of the event
+				// needs to be passed back to the server...
+				// TODO: this needs to be fired also in the case of window
+				// resizing events
+				fireTimelineScrollEvent();
+			} else {
+				handleMouseOverTimeEvent(e);
+			}
+		}
+		// ignore if no timebands, as it is not fully rendered
+	}
+
+	/**
+	 * Sets the down status to false, simulating a mouse up, recording whether
+	 * the mouse is up or down, to false
+	 * 
+	 * @param event mouse out event
+	 */
+	public void handle(final MouseOutEvent event) {
+		downStatus = false;
+	}
+
+	/**
+	 * on mouse over event, we call handleMouseOverTimeEvent to work out which
+	 * TimeEvent fired the event if at all
+	 * 
+	 * @param e mouse over event
+	 */
+	public void handle(final MouseOverEvent e) {
+		handleMouseOverTimeEvent(e);
+	}
+
+	/**
+	 * on mouse up, we set the down status to false, and update the mouse icon
+	 * 
+	 * @param e mouse up event
+	 */
+	public void handle(final MouseUpEvent e) {
+		downStatus = false;
+		new El(timelineDiv).setStyleName("step-letgo", true);
+	}
+
+	/**
+	 * handles the display or remove of the popup An awful lot of events are
+	 * going to fired and captured and discarded and one wonders if this is
+	 * really the best way to do it
+	 * 
+	 * @param e move over event
+	 */
+	public void handleMouseOverTimeEvent(final MouseEvent<?> e) {
+		final EventTarget et = e.getNativeEvent().getEventTarget();
+		final Element targetElement = et.cast();
+
+		// find out if moved over event:
+		// Log.debug("Scanning " + timebands.size() + " timebands");
+		for (final Timeband band : timebands) {
+			// Log.debug("Scanning " + band.getEvents().size());
+			for (final TimeEvent te : band.getEvents().values()) {
+				if (te.getEventDiv().isOrHasChild(targetElement)) {
+					// Log.debug("Found event:" + te.getId() + " " +
+					// te.getDescription());
+					this.descriptor.show(te, e);
+					return;
+				}
+			}
+		}
+
+		// if no events found, then hide description:
+		this.descriptor.hide();
+	}
+
+	/**
+	 * @return the isHorizontal
+	 */
+	public boolean isHorizontal() {
+		return isHorizontal;
+	}
+
+	/**
+	 * call this when you want to force a repaint
+	 */
+	public synchronized void paint() {
+		if (!isRendered) {
+			timelineDiv.appendChild(timelineContainer);
+
+			int relativeTop = 0;
+			for (final Timeband tb : timebands) {
+				tb.paint();
+				relativeTop += tb.getSizeTapeTracks() * TimelineConstants.TAPE_TRACK_HEIGHT;
+			}
+
+			// the total relative at this stage is the total height of the
+			// timeline
+			new El(timelineDiv).setHeight(relativeTop);
+			isRendered = true;
+		}
+	}
+
+	/**
+	 * Repaints a particular timeband
+	 * 
+	 * @param originDate date at which to start
+	 * @param unit unit to be used on the timeband
+	 * @param timebandId the timeband id
+	 */
+	public void repaint(final Long originDate, final Unit unit, final int timebandId) {
+		// remove all the timebands from the timeline widget
+		// TODO: HERE all we want to do is set the corect timeband with that
+		// unit, not all of them, right?
+		// what if we have several timebands in the origin, is that possible?
+		// events on different timebands with the same scripture references
+
+		// TODO: set other timbands back to their original scales
+
+		for (final Timeband band : timebands) {
+			setUserInterestOnBand(band, timebandId, unit);
+			band.setCurrentDate(originDate);
+			band.setCurrentDateX(TimelineConstants.TIMELINE_WIDTH + timelineDiv.getClientWidth() / 2);
+			band.scrollToCurrentDate();
+			band.redrawEmptyBand();
+		}
+
+		fireTimelineScrollEvent();
+	}
+
+	/**
+	 * @param height the height to set
+	 */
+	public void setHeight(final int height) {
+		this.height = height;
+	}
+
+	/**
+	 * @param isHorizontal the isHorizontal to set
+	 */
+	public void setHorizontal(final boolean isHorizontal) {
+		this.isHorizontal = isHorizontal;
+	}
+
+	/**
+	 * @param width the width to set
+	 */
+	public void setWidth(final int width) {
+		this.width = width;
+	}
+
+	/**
+	 * Zooming is done on a band level, so delegate to timebands
+	 */
+	public void zoomIn() {
+		for (final Timeband tb : timebands) {
+			tb.zoomIn();
+		}
+	}
+
+	/**
+	 * Zooming is done on a band level, so delegate to timebands
+	 */
+	public void zoomOut() {
+		for (final Timeband tb : timebands) {
+			tb.zoomOut();
+		}
+	}
+
+	/**
+	 * adds event handlers to capture mouse movements, clicks, etc
+	 * 
+	 * @param eventBus event bus on which to register some handlers
+	 */
+	// TODO: investigate pushing the handlers in to the handler!!!
+	private void addEventHandlers(final EventBus eventBus) {
+		final TimelineMouseHandler tmh = new TimelineMouseHandler(this);
+		addDomHandler(tmh, MouseMoveEvent.getType());
+		addDomHandler(tmh, MouseUpEvent.getType());
+		addDomHandler(tmh, MouseDownEvent.getType());
+		addDomHandler(tmh, MouseOutEvent.getType());
+		addDomHandler(tmh, MouseOverEvent.getType());
+
+		eventBus.addHandler(UserInterestInBandEvent.TYPE, new UserInterestInBandEventHandler() {
+
+			public void onUserInterestedInBand(final UserInterestInBandEvent userInterestInBandEvent) {
+				try {
+					final Timeband band = getBand(userInterestInBandEvent.getBandId());
+					band.registerUserInterest(userInterestInBandEvent.isOfInterest());
+					band.paint();
+				} catch (final TimeBandNotFoundException e) {
+					Log.warn("The user request a band that no longer exists.");
+				}
+			}
+		});
+
+		// TODO: add window handler
+
+	}
+
+	/**
+	 * Disables the user selection on the timeline widget, to ensure the user
+	 * gets a good experience
+	 * 
+	 * @param e the DOM element on which to perform these javascript operations
+	 */
+	private native void disableSelection(final Element e) /*-{
+		e.ondrag = function() { return false; };
+		e.onselectstart = function() { return false; };
+		e.style.MozUserSelect = "none";
+	}-*/;
+
+	/**
+	 * returns the fired timeband band, given a mouse move event
+	 * 
+	 * @param e the mouse band
+	 * @return the timeband that was fired
+	 * @throws UnknownFiredElement thrown if we do not know which timeband was
+	 *             fired
+	 */
+	private Timeband getFiredBand(final MouseMoveEvent e) throws UnknownFiredElement {
+		final EventTarget et = e.getNativeEvent().getEventTarget();
+		final Element targetElement = et.cast();
+
+		for (final Timeband b : timebands) {
+			if (b.getBandDiv().isOrHasChild(targetElement)) {
+				return b;
+			}
+		}
+
+		throw new UnknownFiredElement();
+	}
+
+	/**
+	 * if the band corresponds to the correct timeband id, then set unit,
+	 * otherwise revert back to the original state...
+	 * 
+	 * @param band band
+	 * @param timebandId timebandId
+	 * @param unit unit
+	 */
+	private void setUserInterestOnBand(final Timeband band, final int timebandId, final Unit unit) {
+		if (band.getId() == timebandId) {
+			band.setUnit(unit);
+			band.registerUserInterest(true);
+		} else {
+			band.resetOriginalUnit();
+			band.registerUserInterest(false);
+		}
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/Orientation.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/Orientation.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/Orientation.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,21 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.components;
+
+/**
+ * This determines whether to render the timeband horizontally or vertically. At
+ * the moment only HORIZONTAL is supported.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum Orientation {
+	/**
+	 * Render the timeband horizontally
+	 */
+	HORIZONTAL,
+
+	/**
+	 * Render the timeband vertically
+	 */
+	VERTICAL,
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimebandRequestWindow.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimebandRequestWindow.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimebandRequestWindow.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,82 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.components;
+
+/**
+ * This window identifies what is already displayed on the timeline Perhaps
+ * later we send this back to the server, and let the server work out which bits
+ * and pieces each timebands are interested in. So still send the full view
+ * coordinates, but send that as well.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimebandRequestWindow {
+	/** max date requested so far */
+	private long maxDate;
+
+	/** min date requested so far */
+	private long minDate;
+
+	/**
+	 * timeband request window, when created takes the intial window (min, max)
+	 * 
+	 * @param initialMin initial minimum, usually the left most visible pixel of
+	 *            the timeband
+	 * @param initialMax initial maximum, usually the right most visible pixel
+	 *            of the timeband
+	 */
+	public TimebandRequestWindow(final long initialMin, final long initialMax) {
+		minDate = initialMin;
+		maxDate = initialMax;
+	}
+
+	/**
+	 * Enlarges the minimum window on the left hand-side
+	 * 
+	 * @param minDateRequested the new minDate that the band has received
+	 * @param maxDateRequested the new maxDate that the band has received
+	 */
+	public void adjustRange(final long minDateRequested, final long maxDateRequested) {
+		// Log.debug("Adjusting minimum of received/requested window");
+
+		// adjust minimum: as long as the minimum is before, but the max within
+		// range, we're fine to adjust
+		// --------------------<-------$-----<-------$------------------
+		// mdr md Mdr MD
+		if (minDateRequested < minDate && maxDateRequested >= minDate) {
+			minDate = minDateRequested;
+		}
+
+		// do the same for the maximum:
+		if (maxDateRequested > maxDate && minDateRequested <= maxDate) {
+			maxDate = maxDateRequested;
+		}
+	}
+
+	/**
+	 * @return the maxDate
+	 */
+	public long getMaxDate() {
+		return maxDate;
+	}
+
+	/**
+	 * @return the minDate
+	 */
+	public long getMinDate() {
+		return minDate;
+	}
+
+	/**
+	 * @param maxDate the maxDate to set
+	 */
+	public void setMaxDate(final long maxDate) {
+		this.maxDate = maxDate;
+	}
+
+	/**
+	 * @param minDate the minDate to set
+	 */
+	public void setMinDate(final long minDate) {
+		this.minDate = minDate;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimelineConstants.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimelineConstants.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/components/TimelineConstants.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,85 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.components;
+
+/**
+ * Timeline constants to be used in the timeline module
+ * 
+ * @author CJBurrell
+ * 
+ */
+public final class TimelineConstants {
+
+	/**
+	 * This is the setting defining how many pixels represent 1 unit
+	 */
+	public static final int DEFAULT_PIXELS_PER_UNIT = 100;
+	/**
+	 * for a duration event, the css class
+	 */
+	public static final String DURATION = "step-timeline-duration";
+	/**
+	 * css class for a label of a duration event
+	 */
+	public static final String DURATION_LABEL = "step-time-duration-label";
+	/**
+	 * step time event css
+	 */
+	public static final String EVENT = "step-time-event";
+	/**
+	 * the minimum width of an event
+	 */
+	public static final int EVENT_MIN_WIDTH = 2;
+
+	/**
+	 * The initial date for the timeline, the date of birth of Jesus
+	 */
+	public static final long INITIAL_DATE = -61183987174853L;
+	/**
+	 * this describes how much of a unit needs to be visible before calling back
+	 * to the server
+	 */
+	public static final double MINIMUM_UNIT_PORTION_BEFORE_SERVER_CALL = 0.5;
+	/**
+	 * css of a point in time event
+	 */
+	public static final String POINT_IN_TIME_EVENT = "step-timeline-pointInTime";
+
+	/**
+	 * css for the label of a point in time event label
+	 */
+	public static final String POINT_IN_TIME_LABEL = "step-time-point-in-time-label";
+
+	/**
+	 * space between the icon and the text
+	 */
+	public static final int POINT_IN_TIME_WIDTH_SPACE = 15;
+
+	/**
+	 * space between the popup and the mouse
+	 */
+	public static final int SPACE_BELOW_POPUP = 20;
+
+	/**
+	 * height of each tape track
+	 * 
+	 */
+	public static final int TAPE_TRACK_HEIGHT = 21;
+
+	/**
+	 * total width of timeline width, hardcoded at the moment
+	 */
+	// TODO: parameterize this depending on the length of the band
+	public static final int TIMELINE_WIDTH = 32000;
+
+	/**
+	 * The initial zoom factor. This determines how much of a zoom is applied.
+	 * For example a factor of 0.25 changes the scale of 50 pixels per decade to
+	 * (1 + 0.25) * 50 = 75 pixels
+	 */
+	public static final double ZOOM_FACTOR = 0.25;
+
+	/**
+	 * prevent intialisation
+	 */
+	private TimelineConstants() {
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/events/TimelineMouseHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/events/TimelineMouseHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/events/TimelineMouseHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,58 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.events;
+
+import com.google.gwt.event.dom.client.MouseDownEvent;
+import com.google.gwt.event.dom.client.MouseDownHandler;
+import com.google.gwt.event.dom.client.MouseMoveEvent;
+import com.google.gwt.event.dom.client.MouseMoveHandler;
+import com.google.gwt.event.dom.client.MouseOutEvent;
+import com.google.gwt.event.dom.client.MouseOutHandler;
+import com.google.gwt.event.dom.client.MouseOverEvent;
+import com.google.gwt.event.dom.client.MouseOverHandler;
+import com.google.gwt.event.dom.client.MouseUpEvent;
+import com.google.gwt.event.dom.client.MouseUpHandler;
+import com.tyndalehouse.step.web.client.toolkit.timeline.Timeline;
+
+/**
+ * timeline mouse handler to re-delegate events to the timeline component this
+ * is used mainly for the scrolling functionality on the timeline
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimelineMouseHandler implements MouseMoveHandler, MouseUpHandler, MouseDownHandler,
+		MouseOutHandler, MouseOverHandler {
+	/**
+	 * The timeline component
+	 */
+	private final Timeline timeline;
+
+	/**
+	 * constructor takes the timeline component
+	 * 
+	 * @param timeline the timeline component.
+	 */
+	public TimelineMouseHandler(final Timeline timeline) {
+		this.timeline = timeline;
+	}
+
+	public void onMouseDown(final MouseDownEvent event) {
+		timeline.handle(event);
+	}
+
+	public void onMouseMove(final MouseMoveEvent event) {
+		timeline.handle(event);
+	}
+
+	public void onMouseOut(final MouseOutEvent event) {
+		timeline.handle(event);
+	}
+
+	public void onMouseOver(final MouseOverEvent event) {
+		timeline.handle(event);
+
+	}
+
+	public void onMouseUp(final MouseUpEvent event) {
+		timeline.handle(event);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/CannotDeleteEventException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/CannotDeleteEventException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/CannotDeleteEventException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,27 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.exceptions;
+
+/**
+ * The request to delete an event has failed. The message should explain why
+ * this has happened.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class CannotDeleteEventException extends Exception {
+
+	/**
+	 * The default constructor with the explanatory message
+	 * 
+	 * @param message
+	 *            The message for the exception
+	 */
+	public CannotDeleteEventException(final String message) {
+		super(message);
+	}
+
+	/**
+	 * Serialisation id
+	 */
+	private static final long serialVersionUID = -9221252482310063155L;
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/IncapableOfCalculatingRequestWindowException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/IncapableOfCalculatingRequestWindowException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/IncapableOfCalculatingRequestWindowException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,32 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.exceptions;
+
+/**
+ * The request window is the window of pixels (start/end) that gets send to the
+ * server indicating the client wants to get events that are in that time
+ * section There are certain situations where it is impossible to calculate how
+ * the user has moved, for example when the browser moves so quickly that the
+ * whole screen shifts 1 screen-wide of pixels
+ * 
+ * @author CJBurrell
+ */
+public class IncapableOfCalculatingRequestWindowException extends Exception {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 1866493907904681758L;
+
+	/**
+	 * The client is unable to calculate which bit to request from the server
+	 * 
+	 * @param minVisibleDate the minimum visible date from the client
+	 * @param maxVisibleDate the maximum visible date from the client
+	 * @param minReceivedDate the minimum date the client has ever seen
+	 * @param maxReceivedDate the maximum date the client has ever seen
+	 */
+	public IncapableOfCalculatingRequestWindowException(final long minVisibleDate, final long maxVisibleDate,
+			final long minReceivedDate, final long maxReceivedDate) {
+		super("Unable to calculate request window for: " + minReceivedDate + " / " + maxReceivedDate
+				+ ". Visible section is: " + minVisibleDate + " / " + maxVisibleDate);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/TimeBandNotFoundException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/TimeBandNotFoundException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/TimeBandNotFoundException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,25 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.exceptions;
+
+/**
+ * While trying to lookup the timeband, it was not found
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimeBandNotFoundException extends Exception {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 6234571991235670035L;
+
+	/**
+	 * Constructor specifying the error message
+	 * 
+	 * @param message message indicating which band was not found
+	 */
+	public TimeBandNotFoundException(final String message) {
+		super(message);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/UnknownFiredElement.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/UnknownFiredElement.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/exceptions/UnknownFiredElement.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,17 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.exceptions;
+
+/**
+ * Thrown if an DOM element contained in the timeline is fired but it is not
+ * recognised by the timeline element
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class UnknownFiredElement extends Exception {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -726869406002130223L;
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/CurrentBandStats.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/CurrentBandStats.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/CurrentBandStats.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,87 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.helpers;
+
+/**
+ * Contains the current statistics of how many events are present on a
+ * particular timeband This bean is band specific
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class CurrentBandStats {
+	/**
+	 * description of the band to be displayed on the screen
+	 */
+	private final String bandDescription;
+
+	/**
+	 * timeband id
+	 */
+	private final int bandId;
+
+	/**
+	 * ticked or not, whether the user is interested in this
+	 */
+	private final boolean isUserInterested;
+
+	/**
+	 * number of elements on the timeband
+	 */
+	private final int numElements;
+
+	/**
+	 * number of elements currently visible
+	 */
+	private final int numVisibleElements;
+
+	/**
+	 * 
+	 * @param bandId the id of the band
+	 * @param numElements the number of events on the band
+	 * @param numVisibleElements the number of visible events in the frame
+	 * @param bandDescription description to be displayed on the view
+	 * @param isUserInterested whether the user is interested in the band
+	 */
+	public CurrentBandStats(final int bandId, final String bandDescription, final int numElements,
+			final int numVisibleElements, final boolean isUserInterested) {
+		this.bandId = bandId;
+		this.bandDescription = bandDescription;
+		this.numElements = numElements;
+		this.numVisibleElements = numVisibleElements;
+		this.isUserInterested = isUserInterested;
+	}
+
+	/**
+	 * @return the bandDescription
+	 */
+	public String getBandDescription() {
+		return bandDescription;
+	}
+
+	/**
+	 * @return the bandId
+	 */
+	public int getBandId() {
+		return bandId;
+	}
+
+	/**
+	 * @return the numElements
+	 */
+	public int getNumElements() {
+		return numElements;
+	}
+
+	/**
+	 * @return the numVisibleElements
+	 */
+	public int getNumVisibleElements() {
+		return numVisibleElements;
+	}
+
+	/**
+	 * @return the isUserInterested
+	 */
+	public boolean isUserInterested() {
+		return isUserInterested;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/TimeConversionUtil.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/TimeConversionUtil.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/toolkit/timeline/helpers/TimeConversionUtil.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,92 @@
+package com.tyndalehouse.step.web.client.toolkit.timeline.helpers;
+
+import java.util.Date;
+
+import com.google.gwt.i18n.client.DateTimeFormat;
+import com.tyndalehouse.step.web.client.toolkit.timeline.Timeband;
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * Util class to convert time to date and vice versa
+ * 
+ * @author CJBurrell
+ * 
+ */
+public final class TimeConversionUtil {
+	/**
+	 * converts a pixel position to its date using the format associated to the
+	 * unit of the timeband
+	 * 
+	 * @param pixelPosition pixel position to be converted
+	 * @param timeband current timeband (this contains the current viewing
+	 *            location, and unit
+	 * @return the date as a formatted string
+	 */
+	public static String formatPixelToTime(final long pixelPosition, final Timeband timeband) {
+		return formatTime(pixelToTime(pixelPosition, timeband), timeband);
+	}
+
+	/**
+	 * formats the given time using the unit described in the timeband
+	 * 
+	 * @param timeband the timeband containing the current view, unit, etc.
+	 * @param eventDate date to be formatted
+	 * @return the string representation of the date
+	 */
+	public static String formatTime(final long eventDate, final Timeband timeband) {
+		final Date date = new Date(eventDate);
+		final String formatForBand = timeband.getUnit().getFormat();
+		final DateTimeFormat format = DateTimeFormat.getFormat(formatForBand);
+		return format.format(date);
+	}
+
+	/**
+	 * This takes a pixel position and returns the equivalent time
+	 * 
+	 * @param pixelPosition the pixel position that we are trying to convert
+	 * @param timeband the timeband which contains the relevant information
+	 *            (current view, unit) to calculate the time from the pixel
+	 *            position
+	 * @return the time of pixelPosition
+	 */
+	public static long pixelToTime(final long pixelPosition, final Timeband timeband) {
+		final long currentDateX = timeband.getCurrentDateX();
+		final long currentDate = timeband.getCurrentDate();
+		final Unit unit = timeband.getUnit();
+		final long pixelsPerUnit = timeband.getPixelsPerUnit();
+
+		final long differenceWithOrigin = pixelPosition - currentDateX;
+		final long date = currentDate + (differenceWithOrigin * unit.getMilliseconds() / pixelsPerUnit);
+		return date;
+	}
+
+	/**
+	 * A date is always calculated within a time band.
+	 * 
+	 * @param eventDate the date to be converted
+	 * @param currentTimeband reference timeband (including current view, unit,
+	 *            etc).
+	 * @return the pixel position on the timeband for the passed in time
+	 */
+	public static int timeToPixel(final long eventDate, final Timeband currentTimeband) {
+		// here's what we start from
+		final long millisecondPerUnit = currentTimeband.getUnit().getMilliseconds();
+		final long pixelsPerUnit = currentTimeband.getPixelsPerUnit();
+		final long currentOriginDate = currentTimeband.getCurrentDate();
+		final long currentOriginXPixel = currentTimeband.getCurrentDateX();
+
+		// what's one pixel in milliseconds?
+		final double onePixelInMs = (double) millisecondPerUnit / pixelsPerUnit;
+
+		// calculate difference with current position on timeband
+		final long differenceWithEvent = eventDate - currentOriginDate;
+		final long pixelValueOnBand = currentOriginXPixel + (long) (differenceWithEvent / onePixelInMs);
+		return (int) pixelValueOnBand;
+	}
+
+	/**
+	 * making the constructor invisible to outsiders
+	 */
+	private TimeConversionUtil() {
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/HistoryModuleView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/HistoryModuleView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/HistoryModuleView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,87 @@
+package com.tyndalehouse.step.web.client.view;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.tyndalehouse.step.web.client.presenter.HistoryModulePresenter;
+import com.tyndalehouse.step.web.client.toolkit.HtmlList;
+import com.tyndalehouse.step.web.client.toolkit.HtmlList.ListType;
+
+/**
+ * The history module TODO: revamp this completely
+ * 
+ * @author cjburrell
+ * 
+ */
+public class HistoryModuleView extends Composite implements HistoryModulePresenter.Display {
+
+	/**
+	 * an article
+	 */
+	private final HTML article;
+
+	/**
+	 * A contents page to choose from
+	 */
+	private final HtmlList contentsTable;
+
+	/**
+	 * default constructor
+	 */
+	public HistoryModuleView() {
+		final VerticalPanel vp = new VerticalPanel();
+		initWidget(vp);
+		article = new HTML();
+
+		article.setHTML("Abija Aviyam: \"Father of the sea\" or \"my father "
+				+ "is the sea\" or \"my father is Yah\") was the fourth king "
+				+ "of the House of David and the second of the Kingdom of "
+				+ "Judah. He was the son of Rehoboam, the grandson of Solomon "
+				+ "and the great-grandson of David. The Chronicler refers to "
+				+ "him as \"Abijah (Hebrew, \"my father is The LORD\"). "
+				+ "William F. Albright has dated his reign to 915 BC - 913 "
+				+ "BC, while E. R. Thiele offers the dates 914/913 - 911/910 BC. "
+				+ "[1] As explained in the Rehoboam article, Thiele's chronology for "
+				+ "the first kings of Judah contained an internal inconsistency "
+				+ "that later scholars corrected by dating these kings "
+				+ "one year earlier, so that Abijah's dates are taken as 915/914 "
+				+ "to 912/911 BC in the present article. The Hebrew Bible gives "
+				+ "his reign length as three years. His mother's name was Maacah, "
+				+ "or Micaiah, the granddaughter of the infamous Abishalom (Absalom). "
+				+ "Abijah married fourteen wives, and had 22 sons and 16 daughters. " + "[2]");
+
+		// contents at the top
+		contentsTable = new HtmlList(ListType.UNORDERED);
+		contentsTable.addItem("Abijah, Yah is my father", null);
+		contentsTable.addItem("Abijam, father of the sea", null);
+		contentsTable.addItem("Abilene, the father of mourning", null);
+
+		vp.add(contentsTable);
+		vp.add(article);
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	/**
+	 * Sets the current article
+	 * 
+	 * @param articleText the text of the article to be viewed
+	 */
+	public void setArticle(final String articleText) {
+		article.setHTML(articleText);
+	}
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ModuleSelectorView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ModuleSelectorView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ModuleSelectorView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,133 @@
+package com.tyndalehouse.step.web.client.view;
+
+import java.util.List;
+
+import com.google.gwt.event.dom.client.HasChangeHandlers;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.tyndalehouse.step.web.client.presenter.ModuleSelectorPresenter;
+import com.tyndalehouse.step.web.client.toolkit.HasSource;
+import com.tyndalehouse.step.web.client.toolkit.SimpleListBox;
+
+/**
+ * The module selector view, displaying three levels of study
+ * <p />
+ * The module: History, Geography, etc. <br />
+ * <p />
+ * The sub-module: Genealogies,
+ * <p />
+ * 
+ * The depth: the depth at which people want to study (scholarly, light etc.)
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ModuleSelectorView extends Composite implements ModuleSelectorPresenter.Display {
+	/**
+	 * a list of modules
+	 */
+	private final SimpleListBox module;
+
+	/**
+	 * a list of depths
+	 */
+	private final SimpleListBox moduleDepth;
+
+	/**
+	 * a list of sub modules, correlated to the list of modules
+	 */
+	private final SimpleListBox subModule;
+
+	/**
+	 * The default constructor
+	 */
+	public ModuleSelectorView() {
+		final FlowPanel p = new FlowPanel();
+		initWidget(p);
+
+		module = new SimpleListBox();
+		moduleDepth = new SimpleListBox();
+		subModule = new SimpleListBox();
+
+		p.add(module);
+		p.add(moduleDepth);
+		p.add(subModule);
+	}
+
+	public String getSelectedModule() {
+		// check that the module has been populated already!
+		if (module.getItemCount() == 0) {
+			return null;
+		}
+		
+		return module.getValue(module.getSelectedIndex());
+	}
+	
+	public void setSelectedModule(final String value) {
+		// simple linear search
+		for (int ii = 0; ii < module.getItemCount(); ii++) {
+			if (value.equals(module.getValue(ii))) {
+				module.setSelectedIndex(ii);
+				return;
+			}
+		}	
+	}
+	
+	
+	public String getSelectedSubModule() {
+		if (subModule.getItemCount() == 0) {
+			return null;
+		}
+		return subModule.getValue(subModule.getSelectedIndex());
+	}
+	
+	public Widget asWidget() {
+		return this;
+	}
+
+	public HasChangeHandlers getModuleChangeHandlers() {
+		return module;
+	}
+
+	public HasChangeHandlers getModuleDepthChangeHandlers() {
+		return moduleDepth;
+	}
+
+	public HasSource<List<String>> getModuleDepthSource() {
+		return moduleDepth;
+	}
+
+	public HasSource<List<String>> getModuleSource() {
+		return module;
+	}
+
+	public String getSelectedDepth() {
+		if (moduleDepth.getItemCount() == 0) {
+			return null;
+		}
+		return moduleDepth.getValue(moduleDepth.getSelectedIndex());
+	}
+
+
+
+	public HasChangeHandlers getSubModuleChangeHandlers() {
+		return subModule;
+	}
+
+	public HasSource<List<String>> getSubModuleSource() {
+		return subModule;
+	}
+
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureSelectorView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureSelectorView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureSelectorView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,95 @@
+package com.tyndalehouse.step.web.client.view;
+
+import java.util.Collection;
+
+import com.allen_sauer.gwt.log.client.Log;
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HasValue;
+import com.google.gwt.user.client.ui.MultiWordSuggestOracle;
+import com.google.gwt.user.client.ui.SuggestBox;
+import com.google.gwt.user.client.ui.Widget;
+import com.tyndalehouse.step.web.client.presenter.ScriptureSelectorPresenter;
+
+/**
+ * This view provides the user with a way to select a portion of scripture. It
+ * therefore contains a textbox and a button to fire the event. The textbox is
+ * an auto-complete textbox
+ * 
+ * @author cjburrell
+ */
+public class ScriptureSelectorView extends Composite implements ScriptureSelectorPresenter.Display {
+	/**
+	 * the source of the auto comlete textbox
+	 */
+	private final MultiWordSuggestOracle oracle;
+
+	/**
+	 * the auto complete text box
+	 */
+	private final SuggestBox reference;
+
+	/**
+	 * the button fired to search
+	 */
+	private final Button search;
+
+	/**
+	 * the default constructor to render the view
+	 */
+	public ScriptureSelectorView() {
+		final FlowPanel p = new FlowPanel();
+		initWidget(p);
+
+		oracle = new MultiWordSuggestOracle();
+		reference = new SuggestBox(oracle);
+		p.add(reference);
+
+		// TODO: localise this
+		search = new Button("Lookup");
+		p.add(search);
+
+		Log.debug("== Scripture Selector View initialiased");
+	}
+
+	public void addSuggestion(final String suggestion) {
+		oracle.add(suggestion);
+	}
+
+	public void addSuggestions(final Collection<String> suggestions) {
+		oracle.addAll(suggestions);
+
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	/**
+	 * @return the unvalidated biblical reference that is currently in the
+	 *         textbox
+	 */
+	public HasValue<String> getReference() {
+		return reference;
+	}
+
+	/**
+	 * @return the search button on which to append listeners
+	 */
+	public HasClickHandlers getSearch() {
+		return search;
+	}
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/ScriptureView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,207 @@
+package com.tyndalehouse.step.web.client.view;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedMap;
+
+import net.customware.gwt.presenter.client.EventBus;
+
+import com.google.gwt.event.dom.client.HasChangeHandlers;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HTML;
+import com.google.gwt.user.client.ui.InlineLabel;
+import com.google.gwt.user.client.ui.Panel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.presenter.ScripturePresenter;
+import com.tyndalehouse.step.web.client.toolkit.HasSource;
+import com.tyndalehouse.step.web.client.toolkit.SourceListBox;
+import com.tyndalehouse.step.web.client.toolkit.scripture.ScriptureDisplayConstants;
+import com.tyndalehouse.step.web.client.toolkit.scripture.VerseLabel;
+import com.tyndalehouse.step.web.shared.scripture.Passage;
+import com.tyndalehouse.step.web.shared.scripture.TextualElement;
+import com.tyndalehouse.step.web.shared.scripture.Title;
+import com.tyndalehouse.step.web.shared.scripture.Verse;
+import com.tyndalehouse.step.web.shared.scripture.VerseContent;
+import com.tyndalehouse.step.web.shared.scripture.Word;
+
+/**
+ * This view aims to show Scripture to the user. In order to do this, the user
+ * can select a version from a dropdown. The
+ * 
+ * TODO: remove the eventBus from the view.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ScriptureView extends Composite implements ScripturePresenter.Display {
+
+	/**
+	 * the auto list of bible versions
+	 */
+	private final SourceListBox bibleVersions;
+
+	// TODO: to be removed into the presenter
+	/**
+	 * the default event bus
+	 */
+	private final EventBus eventBus;
+
+	/**
+	 * a list of VerseLabel (wrappers of bible text) that are currently being
+	 * displayed and contain lemmas
+	 */
+	private final List<VerseLabel> lemmaWords;
+
+	/**
+	 * a list of VerseLabel (wrappers of bible text) that are currently being
+	 * displayed and contain morphs
+	 */
+	private final List<VerseLabel> morphs;
+
+	/**
+	 * a logical display of scripture, in that events can be attached to each of
+	 * the elements on this panel
+	 */
+	private final Panel scriptureHolder;
+
+	/**
+	 * a simple display of scripture as text
+	 */
+	private final HTML scriptureHTML;
+
+	/**
+	 * The default constructor
+	 * 
+	 * @param eventBus eventBus - //TODO: remove this
+	 */
+	@Inject
+	public ScriptureView(final EventBus eventBus) {
+		this.eventBus = eventBus;
+		final VerticalPanel vp = new VerticalPanel();
+		scriptureHolder = new FlowPanel();
+		lemmaWords = new ArrayList<VerseLabel>();
+		morphs = new ArrayList<VerseLabel>();
+
+		initWidget(vp);
+
+		bibleVersions = new SourceListBox();
+		bibleVersions.setStylePrimaryName("bibleVersionsDropDown");
+
+		// adding the dropdown with the bible versions
+		vp.add(bibleVersions);
+
+		// adding the html display of scripture
+		// TODO : Localise this here.
+		scriptureHTML = new HTML("Please lookup a reference");
+		vp.add(scriptureHTML);
+		vp.add(scriptureHolder);
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	public HasChangeHandlers getChangeHandlers() {
+		return bibleVersions;
+	}
+
+	public String getSelectedBibleVersion() {
+		return bibleVersions.getValue(bibleVersions.getSelectedIndex());
+	}
+
+	public HasSource<SortedMap<String, String>> getSource() {
+		return bibleVersions;
+	}
+
+	public void highlight(final List<String> lemmaList) {
+		for (final VerseLabel vl : lemmaWords) {
+			for (final String l : lemmaList) {
+				if (vl.getLemma().contains(l)) {
+					vl.setStyleName(ScriptureDisplayConstants.EMPHASISE);
+				} else {
+					vl.removeStyleName(ScriptureDisplayConstants.EMPHASISE);
+				}
+			}
+		}
+	}
+
+	public void setPassage(final Passage passage) {
+		final List<VerseContent> verseContent = passage.getVerseContent();
+
+		// clear current text:
+		scriptureHolder.clear();
+
+		for (final VerseContent v : verseContent) {
+			if (v instanceof Title) {
+				doTitle((Title) v);
+			} else if (v instanceof Verse) {
+				doVerse((Verse) v);
+			}
+		}
+
+	}
+
+	// TODO: probably remove the following function, and ensure the service is
+	// removed at the same time
+	public void setPassage(final String text) {
+		scriptureHTML.setHTML(text);
+	}
+
+	public void startProcessing() {
+	}
+
+	public void stopProcessing() {
+		// TODO: to be completed
+	}
+
+	/**
+	 * Create an element to display a title
+	 * 
+	 * @param v the logical representation of a title
+	 */
+	private void doTitle(final Title v) {
+		final InlineLabel il = new InlineLabel(v.getText());
+		scriptureHolder.add(il);
+	}
+
+	/**
+	 * Create a display for the verse
+	 * 
+	 * @param v the logical representation of the verse
+	 */
+	private void doVerse(final Verse v) {
+		VerseLabel vl;
+
+		for (final TextualElement text : v.getVerseContent()) {
+			// check that text is not nullable
+			if (text.getText() != null) {
+				vl = new VerseLabel(text.getText(), eventBus);
+				scriptureHolder.add(vl);
+
+				// then do specifics
+				if (text instanceof Word) {
+					final Word w = (Word) text;
+					// if there's an alternative, then we ensure that we set
+					// that up
+					// eventually UI design will mean changes here
+					vl.setAlternativeWord(w.getAlternativeWord());
+
+					final List<String> lemma = w.getLemma();
+					if (lemma != null) {
+						lemmaWords.add(vl);
+						vl.setLemmas(lemma);
+					}
+
+					final List<String> morph = w.getMorph();
+					if (morph != null) {
+						vl.setMorphs(morph);
+						morphs.add(vl);
+					}
+				}
+			}
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/StepView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/StepView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/StepView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,116 @@
+package com.tyndalehouse.step.web.client.view;
+
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.DockPanel;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.HorizontalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.presenter.HistoryModulePresenter;
+import com.tyndalehouse.step.web.client.presenter.ModuleSelectorPresenter;
+import com.tyndalehouse.step.web.client.presenter.ScripturePresenter;
+import com.tyndalehouse.step.web.client.presenter.ScriptureSelectorPresenter;
+import com.tyndalehouse.step.web.client.presenter.StepPresenter;
+import com.tyndalehouse.step.web.client.presenter.TimebandListPresenter;
+import com.tyndalehouse.step.web.client.presenter.TimelinePresenter;
+
+/**
+ * This View sets up the many different views and the layout of the Step
+ * Application
+ * 
+ * @author cjburrell
+ * 
+ */
+public class StepView extends Composite implements StepPresenter.Display {
+
+	/**
+	 * This is the panel on which you display scripture side by side.
+	 */
+	private final DockPanel dp;
+
+	// TODO: i should be able to pass in the ScriptureSelectorPresenter as
+	// opposed to the display directly
+	// we want one that is attached. that would remove the need for
+
+	/**
+	 * 
+	 * Default constructor inputting most presenters, which initialises the
+	 * views via Gin
+	 * 
+	 * @param scriptureSelector a view allowing the user to key in a biblical
+	 *            reference
+	 * @param scripture a view showing scripture
+	 * @param scripture2 a second view showing scripture
+	 * @param moduleSelector a view allowing the user to select his module of
+	 *            interest (history, geography, etc.)
+	 * @param module the view display the various different modules (history,
+	 *            geography, etc.)
+	 * @param timelinePresenter a view allowing the user to show
+	 * @param timebandListPresenter a view showing the current numbers of events
+	 *            displayed on the timeline
+	 *            <p>
+	 *            TODO: experiment if these can be passed in using just the
+	 *            View, but their interface definition for e.g.
+	 *            ScripturePresenter.Display
+	 */
+	@Inject
+	public StepView(final ScriptureSelectorPresenter scriptureSelector,
+		final ScripturePresenter scripture, final ScripturePresenter scripture2,
+		final ModuleSelectorPresenter moduleSelector, final HistoryModulePresenter module,
+		final TimelinePresenter timelinePresenter, final TimebandListPresenter timebandListPresenter) {
+
+		final FlowPanel flow = new FlowPanel();
+
+		dp = new DockPanel();
+		flow.add(dp);
+		initWidget(flow);
+
+		final HorizontalPanel northPanel = new HorizontalPanel();
+
+		dp.add(northPanel, DockPanel.NORTH);
+		northPanel.add(scriptureSelector.getDisplay().asWidget());
+		northPanel.add(moduleSelector.getDisplay().asWidget());
+
+		// scripturePanels = new HorizontalPanel();
+		// dp.add(scripturePanels, DockPanel.WEST);
+		addScriptureDisplay(scripture);
+		addScriptureDisplay(scripture2);
+
+		// starts here hardcoded, each of the scripture panel takes 25%, but
+		// eventually, they
+		// should try and work this out for themselves
+		// TODO: see above
+		scripture.getDisplay().asWidget();
+		scripture2.getDisplay().asWidget();
+
+		dp.add(module.getDisplay().asWidget(), DockPanel.CENTER);
+		flow.add(timelinePresenter.getDisplay().asWidget());
+
+		// for the moment, adding it to the flow
+		dp.add(timebandListPresenter.getDisplay().asWidget(), DockPanel.SOUTH);
+	}
+
+	/**
+	 * adds a scripture display component to the page
+	 * 
+	 * @param scripture scripture "view"
+	 */
+	public void addScriptureDisplay(final ScripturePresenter scripture) {
+		dp.add(scripture.getDisplay().asWidget(), DockPanel.WEST);
+		// scripturePanels.add(scripture.getDisplay().asWidget());
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimebandListView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimebandListView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimebandListView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,99 @@
+package com.tyndalehouse.step.web.client.view;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.customware.gwt.presenter.client.EventBus;
+
+import com.google.gwt.event.logical.shared.ValueChangeEvent;
+import com.google.gwt.event.logical.shared.ValueChangeHandler;
+import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.event.UserInterestInBandEvent;
+import com.tyndalehouse.step.web.client.presenter.TimebandListPresenter;
+import com.tyndalehouse.step.web.client.toolkit.timeline.helpers.CurrentBandStats;
+
+/**
+ * The timeband list view is a list of timebands. The list includes numbers of
+ * events currently on the timeband and the number of events that could be
+ * shown, in the visible section, of the timeband should the user express
+ * interest
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimebandListView extends Composite implements TimebandListPresenter.Display {
+	/**
+	 * the map of checkboxes displayed on the page
+	 */
+	private final Map<Integer, CheckBox> checkboxes = new HashMap<Integer, CheckBox>();
+
+	/**
+	 * TODO: remove this event bus
+	 */
+	private final EventBus eventBus;
+
+	/**
+	 * the vertical panel on which the checkboxes are added
+	 */
+	private final VerticalPanel fp = new VerticalPanel();
+
+	/**
+	 * The default constructor
+	 * 
+	 * @param eventBus TODO: TO BE REMOVED
+	 */
+	@Inject
+	public TimebandListView(final EventBus eventBus) {
+		this.eventBus = eventBus;
+		initWidget(fp);
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	/**
+	 * method called to update the list of timebands with the latest statistics
+	 * 
+	 * @param stats is a list of current numbers of events (total/visible) on
+	 *            each timeband
+	 */
+	// TODO: should the event adding somehow be moved into the presenter?
+	public void updateList(final List<CurrentBandStats> stats) {
+		for (final CurrentBandStats band : stats) {
+			CheckBox cb = checkboxes.get(band.getBandId());
+			if (cb == null) {
+				cb = new CheckBox();
+				fp.add(cb);
+				cb.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
+					public void onValueChange(final ValueChangeEvent<Boolean> event) {
+						eventBus.fireEvent(new UserInterestInBandEvent(band.getBandId(), event.getValue()));
+					}
+
+				});
+			}
+
+			final int numEventsInBand = band.getNumVisibleElements();
+			cb.setText(band.getBandDescription() + " (" + numEventsInBand + ")");
+			cb.setTitle("Click here to show " + numEventsInBand + " more events.");
+			cb.setValue(band.isUserInterested(), false);
+			checkboxes.put(band.getBandId(), cb);
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimelineView.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimelineView.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/client/view/TimelineView.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,104 @@
+package com.tyndalehouse.step.web.client.view;
+
+import net.customware.gwt.presenter.client.EventBus;
+
+import com.google.gwt.event.dom.client.HasClickHandlers;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
+import com.google.gwt.user.client.ui.Widget;
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.client.presenter.TimelinePresenter;
+import com.tyndalehouse.step.web.client.toolkit.timeline.Timeline;
+
+/**
+ * the timeline view is a wrapper around the whole timeline component used for
+ * displaying events stored in the database. These events can be point-in-time
+ * or in duration.
+ * 
+ * A timeline is split into a timebands, which are then split in to time tracks.
+ * The events are added to a timetrack
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimelineView extends Composite implements TimelinePresenter.Display {
+
+	/**
+	 * The timeline component
+	 */
+	private final Timeline timeline;
+
+	/**
+	 * The zoom in button
+	 */
+	private final Button zoomIn;
+
+	/**
+	 * The zoom out button
+	 */
+	private final Button zoomOut;
+
+	/**
+	 * Default constructor TODO: remove eventBus
+	 * 
+	 * @param eventBus remove event bus from here
+	 */
+	@Inject
+	public TimelineView(final EventBus eventBus) {
+		// to do a custom timeline for testing
+		// TODO: change to a provider, lookup Gin/Guice manual to do this...
+		timeline = new Timeline(eventBus);
+
+		final VerticalPanel vp = new VerticalPanel();
+		final FlowPanel fp = new FlowPanel();
+		vp.add(fp);
+		vp.setWidth("100%");
+
+		zoomIn = new Button("+");
+		zoomOut = new Button("-");
+		zoomIn.setStyleName("step-timeline-control");
+		zoomOut.setStyleName("step-timeline-control");
+
+		fp.add(zoomIn);
+		fp.add(zoomOut);
+		vp.add(timeline);
+		initWidget(vp);
+	}
+
+	public Widget asWidget() {
+		return this;
+	}
+
+	/**
+	 * @return the timeline
+	 */
+	public Timeline getTimeline() {
+		return timeline;
+	}
+
+	/**
+	 * @return A click handler on which to register an event for zooming in
+	 */
+	public HasClickHandlers getZoomIn() {
+		return zoomIn;
+	}
+
+	/**
+	 * @return A click handler on which to register an event for zooming out
+	 */
+	public HasClickHandlers getZoomOut() {
+		return zoomOut;
+	}
+
+	public void startProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+
+	public void stopProcessing() {
+		// TODO Auto-generated method stub
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/AbstractStepHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/AbstractStepHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/AbstractStepHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,44 @@
+package com.tyndalehouse.step.web.server.common;
+
+import java.lang.reflect.ParameterizedType;
+
+import net.customware.gwt.dispatch.server.ActionHandler;
+import net.customware.gwt.dispatch.shared.Action;
+import net.customware.gwt.dispatch.shared.Result;
+
+import org.apache.log4j.Logger;
+
+/**
+ * To abstract away the need for declaring getActionType every time.
+ * 
+ * @author CJBurrell
+ * 
+ * @param <A> the action in question
+ * @param <R> the response to be sent back to the client
+ */
+public abstract class AbstractStepHandler<A extends Action<R>, R extends Result> implements
+	ActionHandler<A, R> {
+
+	/**
+	 * Logger for a particular instance of a handler
+	 */
+	private final Logger logger = Logger.getLogger(this.getClass());
+
+	@SuppressWarnings("unchecked")
+	/*
+	 * returns the type of the action
+	 * 
+	 * @return the type of the action
+	 */
+	public final Class<A> getActionType() {
+		final ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
+		return (Class<A>) pt.getActualTypeArguments()[0];
+	}
+
+	/**
+	 * @return the logger
+	 */
+	protected final Logger getLogger() {
+		return logger;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigNotLoadedException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigNotLoadedException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigNotLoadedException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,28 @@
+package com.tyndalehouse.step.web.server.common;
+
+/**
+ * an exceptoin to indicate that the configuration properties have not been
+ * loaded
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class ConfigNotLoadedException extends Exception {
+
+	/**
+	 * serial id for serialization
+	 */
+	private static final long serialVersionUID = 1644291687028980017L;
+
+	/**
+	 * public constructor an exceptoin to indicate that the configuration
+	 * properties have not been loaded
+	 * 
+	 * @param e
+	 *            the base exception
+	 */
+	public ConfigNotLoadedException(final Exception e) {
+		super("The configuration files could not be loaded", e);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigProvider.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigProvider.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/ConfigProvider.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,85 @@
+package com.tyndalehouse.step.web.server.common;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Properties;
+
+/**
+ * Config Provider for Step. 
+ * TODO: Possibly should be rewritten to have a Guice element to it, with @Singleton tag 
+ * @author CJBurrell
+ *
+ */
+public final class ConfigProvider {
+	/**
+	 * internal static provider
+	 */
+	private static ConfigProvider pr;
+		
+	/**
+	 * Internal properties object
+	 */
+	private Properties p = new Properties();
+
+	/**
+	 * private constructor to prevent initialisation.
+	 * @throws ConfigNotLoadedException exception should it fail to look up the parameter name
+	 */
+	private ConfigProvider() throws ConfigNotLoadedException {
+		load();
+	}
+
+	/**
+	 * Loads or reloads a properties file from the classpath.
+	 * TODO: investigate issue with concurrency here, since we might access p before it's fully loaded...
+	 * @throws ConfigNotLoadedException  exception should it fail to look up the parameter name
+	 */
+	public void load() throws ConfigNotLoadedException {
+		ClassLoader loader = Thread.currentThread().getContextClassLoader();
+		URL url = loader.getResource("com/tyndalehouse/step/web/server/config/environment.properties");
+		try {
+			p.load(url.openStream());
+		} catch (IOException e) {
+			throw new ConfigNotLoadedException(e);
+		}
+	}
+
+	/**
+	 * Gets the value of a param.
+	 * @param name the name of the param
+	 * @return the value of the param
+	 * @throws ConfigNotLoadedException A problem occured during loading of the config
+	 */
+	public synchronized static String get(final String name) throws ConfigNotLoadedException {
+		if (pr == null) {
+			pr = new ConfigProvider();
+		}
+		
+		String value = System.getProperty(name);
+		if(value == null) {
+			value = pr.readProperty(name);
+		}
+		
+		return value;
+		
+	}
+
+	/**
+	 * reads a property on the properties object.
+	 * @param name name of the property
+	 * @return the value
+	 */
+	private String readProperty(final String name) {
+		return p.getProperty(name);
+	}
+
+	/**
+	 * returns an integer corresponding to the name of the parameter.
+	 * @param paramName the name of the parameter
+	 * @return an integer value for paramName
+	 * @throws ConfigNotLoadedException exception should it fail to look up the parameter name
+	 */
+	public static int getInt(final String paramName) throws ConfigNotLoadedException {
+		return Integer.parseInt(get(paramName));
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/JSwordConstants.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/JSwordConstants.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/common/JSwordConstants.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,50 @@
+package com.tyndalehouse.step.web.server.common;
+
+/**
+ * Constants to map back to the correct JSword modules, index entries
+ * @author CJBurrell
+ *
+ */
+public final class JSwordConstants {
+	/**
+	 * the pattern with which strong references in OSIS start
+	 */
+	public static final String STRONG_PATTERN_START = "strong:";
+	
+	/**
+	 * a greek marker for strong numbers, e.g. strong:Gxxxx
+	 */
+	public static final char STRONG_GREEK_MARKER = 'G';
+	
+	/**
+	 * Strong hebrew marker, for e.g. strong:Hxxxx
+	 */
+	public static final char STRONG_HEBREW_MARKER = 'H';
+	
+	/**
+	 * Initials of default Hebrew JSword module to use for lookup of dictionary definitions
+	 */
+	public static final String STRONG_HEBREW_DICTIONARY_INITIALS = "StrongsHebrew";
+	
+	/**
+	 * Initials of default Strong JSword greek dictionary module for lookup of dictionary definitions
+	 */
+	public static final String STRONG_GREEK_DICTIONARY_INITIALS = "StrongsGreek";
+	
+	/**
+	 * Default hebrew text for interlinear purposes
+	 */
+	public static final String DEFAULT_HEBREW_INTERLINEAR_TEXT = "LXX";
+
+	//TODO:This gives us greek!
+	/**
+	 * Default Greek text for interlinear purposes
+	 */
+	public static final String DEFAULT_GREEK_INTERLINEAR_TEXT = "BYZ";
+
+	/**
+	 * hiding default constructor
+	 */
+	private JSwordConstants() {
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/MalformedStepQueryException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/MalformedStepQueryException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/MalformedStepQueryException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,39 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+/**
+ * Query to be thrown if the query file cannot be parsed by our framework.
+ * @author CJBurrell
+ *
+ */
+public class MalformedStepQueryException extends Exception {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -3607780460262284122L;
+
+	/**
+	 * to instantiate the exception when a particular parameter name is incorrect
+	 * @param paramName parameter name that is incorrect
+	 * @param sql sql in which parameter name was incorrect
+	 */
+	public MalformedStepQueryException(final String paramName, final String sql) {
+		super(String.format("The argument %s was not recognised in query:\n %s", paramName, sql));
+	}
+
+	/**
+	 * @param message the message
+	 * @param ex base exception to be passed up to the super class
+	 */
+	public MalformedStepQueryException(final String message, final Exception ex) {
+		super(message, ex);
+	}
+
+	/**
+	 * 
+	 * @param message simple message to instantiate the default exception
+	 */
+	public MalformedStepQueryException(final String message) {
+		super(message);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/Query.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/Query.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/Query.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,20 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+/**
+ * The interface for any enum describing the queries to be run
+ * @author CJBurrell
+ *
+ */
+public interface Query {
+	/**
+	 * @return the component name
+	 */
+	String getComponent();
+
+	/**
+	 * returns the name of the enum
+	 * 
+	 * @return the name of the query
+	 */
+	String name();
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/QueryImpl.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/QueryImpl.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/QueryImpl.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,50 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+/**
+ * List of queries to be executed against DB
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum QueryImpl implements Query {
+	/**
+	 * gets events for a particular date range
+	 */
+	GET_EVENTS_FOR_DATE_RANGE("timeline"),
+
+	/**
+	 * gets timeline description data
+	 */
+	GET_TIMELINE_SETUP_DATA("timeline"),
+
+	/**
+	 * looks up which is the closest event, and on which timeline a given
+	 * scripture passage is
+	 */
+	LOOKUP_TIMELINE_ORIGIN("timeline");
+
+	/**
+	 * component (folder) in which the component can be found
+	 */
+	private final String component;
+
+	/**
+	 * default constructor for this enum
+	 * 
+	 * @param component component/folder where the query resides
+	 */
+	QueryImpl(final String component) {
+		this.component = component;
+	}
+
+	/**
+	 * (non-Javadoc)
+	 * 
+	 * @see com.tyndalehouse.step.web.server.db.framework.Query#getComponent()
+	 * @return component/folder where the query resides
+	 */
+	public String getComponent() {
+		return component;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/ResultSetProcessor.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/ResultSetProcessor.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/ResultSetProcessor.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,43 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+
+/**
+ * @author CJBurrell This is used by the query runner to process result sets
+ * @param <T> the type of bean to be returned
+ */
+public interface ResultSetProcessor<T> {
+	/**
+	 * returns the parameters. Typically this would only be called by the query
+	 * framework
+	 * 
+	 * @return a map, mapping the parameter name to the object to be passed into
+	 *         the query (generally native types or Strings)
+	 */
+	Map<String, Object> getParameters();
+
+	/**
+	 * Returns the enum defining which query should be executed.
+	 * 
+	 * @return the query to be executed.
+	 */
+	Query getQuery();
+
+	/**
+	 * This method will be called after a query has been run by the query
+	 * framework. It returns a list of beans to the caller
+	 * 
+	 * @param rs ResultSet to be processed
+	 * @return a list of beans to the UI of type T
+	 * @throws MalformedStepQueryException the query run was malformed
+	 * @throws ConfigNotLoadedException an error occured during the loading of
+	 *             the database config
+	 * @throws SQLException a SQL exception occurred
+	 */
+	List<T> process(ResultSet rs) throws MalformedStepQueryException, ConfigNotLoadedException, SQLException;
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQuery.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQuery.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQuery.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,158 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Step Query to be executed against the database. This this is then given to
+ * the StepQueryRunner and executed It contains the list of arguments, the types
+ * of those parameters and the sql statement to be executed
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class StepQuery {
+	/**
+	 * list of expected arguments
+	 */
+	private final List<String> arguments;
+
+	/**
+	 * the types of the expected parameters
+	 */
+	private final Map<String, Integer> paramTypes;
+
+	/**
+	 * the SQL statements
+	 */
+	private String sql;
+
+	/**
+	 * public constructor which initialises the arguments and parameters.
+	 */
+	public StepQuery() {
+		arguments = new ArrayList<String>();
+		paramTypes = new HashMap<String, Integer>();
+	}
+
+	/**
+	 * adding an argument as found in the query definition: e.g. <code>
+	 * select 1 from table where value = #paramName#
+	 * </code>
+	 * 
+	 * @param paramName param name to be added to the query definition
+	 * 
+	 */
+	public void addArgument(final String paramName) {
+		arguments.add(paramName);
+	}
+
+	/**
+	 * addings a mapping from the definitions at the top of the file
+	 * 
+	 * @param paramName parameter name
+	 * @param type type of the parameter
+	 */
+	public void addParamTypeMapping(final String paramName, final Integer type) {
+		paramTypes.put(paramName, type);
+	}
+
+	/**
+	 * returns the SQL that gets executed
+	 * 
+	 * @return the SQL query
+	 */
+	public String getSQLText() {
+		return sql;
+	}
+
+	/**
+	 * Sets the sql for the step query to be run
+	 * 
+	 * @param sql sql representing the query to be run
+	 */
+	public void setSQLText(final String sql) {
+		this.sql = sql;
+	}
+
+	/**
+	 * Sets up the prepared statement arguments in the correct order.
+	 * 
+	 * @param ps the prepared statement
+	 * @param passedArguments the map of named arguments
+	 * @throws SQLException this is thrown if the passed in arguments do not
+	 *             match the expected parameters as loaded from disk
+	 * 
+	 */
+	public void setupParameters(final PreparedStatement ps, final Map<String, Object> passedArguments)
+			throws SQLException {
+		int argIndex = 1;
+		for (final String argName : arguments) {
+			setArgument(ps, paramTypes.get(argName), passedArguments.get(argName), argIndex++);
+		}
+	}
+
+	/**
+	 * Validates the query loaded, to ensure that the number of arguments found
+	 * in the query match the number of arguments found in the declarations
+	 * 
+	 * @throws MalformedStepQueryException this is thrown if the validation
+	 *             fails
+	 */
+	public void validate() throws MalformedStepQueryException {
+		for (final String arg : arguments) {
+			if (!paramTypes.containsKey(arg)) {
+				throw new MalformedStepQueryException(arg, sql);
+			}
+		}
+
+		// TODO: optimize by compiling prepared statement here!
+	}
+
+	/**
+	 * Sets up the parameter into the prepared statement
+	 * 
+	 * @param ps prepared statement
+	 * @param sqlType the type of the parameter
+	 * @param value the value of the parameter
+	 * @param argIndex the position at which the parameter is to be placed in
+	 *            the prepared statement
+	 * @throws SQLException an exception thrown in case something goes wrong
+	 */
+	private void setArgument(final PreparedStatement ps, final int sqlType, final Object value,
+			final int argIndex) throws SQLException {
+		// check for null first
+		if (value == null) {
+			ps.setNull(argIndex, sqlType);
+			return;
+		}
+
+		// at this stage, we do not need to worry about null variables
+		switch (sqlType) {
+		case Types.INTEGER:
+			ps.setInt(argIndex, (Integer) value);
+			break;
+		case Types.VARCHAR:
+			ps.setString(argIndex, (String) value);
+			break;
+		case Types.BIGINT:
+			ps.setLong(argIndex, (Long) value);
+			break;
+		case Types.SMALLINT:
+			ps.setShort(argIndex, (Short) value);
+			break;
+		case Types.LONGVARCHAR:
+			ps.setString(argIndex, (String) value);
+			break;
+		default:
+			throw new SQLException(String.format(
+					"The STEP query framework does not yet support this type/value (%d, %s)", sqlType, value
+							.toString()));
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunner.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunner.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunner.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,35 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+import java.util.List;
+
+/**
+ * StepQueryRunner interface defining what should be present for the clients to
+ * use this as a library
+ * 
+ * @author CJBurrell
+ * 
+ */
+public interface StepQueryRunner {
+
+	/**
+	 * Clears the cache of parsed queries that are currently in the query runner
+	 */
+	void clearCache();
+
+	/**
+	 * Tears down the database pool and starts it up again
+	 */
+	void restartDatasourcePool();
+
+	/**
+	 * To run a query in the database
+	 * 
+	 * @param <T> Type of bean to be returned
+	 * @param processor Processor to be invoked: @see {@link ResultSetProcessor}
+	 * @return a list of beans of type T
+	 * @throws UnableToRunQueryException if the configuration was not loaded or
+	 *             a sql exception during parsing or execution of the call
+	 */
+	<T> List<T> run(final ResultSetProcessor<T> processor) throws UnableToRunQueryException;
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunnerImpl.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunnerImpl.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/StepQueryRunnerImpl.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,356 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.sql.DataSource;
+
+import org.apache.commons.dbcp.BasicDataSource;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.logging.Log;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+import com.tyndalehouse.step.web.server.common.ConfigProvider;
+
+/**
+ * This class is the crux of the database access. An enum identifies the SQL
+ * file to be loaded. Arguments get defined in the query file as define
+ * variableName as sqlType A map can be passed in that ensures all arguments are
+ * mapped to the correct location in the prepared statement
+ * 
+ * @author CJBurrell
+ */
+ at Singleton
+public class StepQueryRunnerImpl implements StepQueryRunner {
+	/**
+	 * query to indicate whether to cache prepared statements. Currently doesn't
+	 * work well with Apache Derby
+	 */
+	private static final Object CACHE_QUERY_PROPERTY = "query.runner.cache";
+
+	/**
+	 * Datasource object which gets loaded through a conection pool
+	 */
+	private static DataSource datasource = null;
+
+	/**
+	 * pattern definition of a declaration of argument at the top of a SQL file
+	 */
+	private static final String DEFINITION_PATTERN = "define (\\w+) as (\\w+)";
+
+	/**
+	 * the HASH character
+	 */
+	private static final String HASH = "#";
+
+	/**
+	 * the hashmap containing the cache of all queries
+	 */
+	private static HashMap<Query, StepQuery> queries = new HashMap<Query, StepQuery>();
+
+	/**
+	 * the ?, QUESTION MARK character
+	 */
+	private static final String QUESTION_MARK = "?";
+
+	/**
+	 * a pointer to the Log4J log
+	 */
+	private final Log log;
+
+	/**
+	 * prevent instantiation
+	 * 
+	 * @param log default logger to use throughout implementation
+	 */
+	@Inject
+	public StepQueryRunnerImpl(final Log log) {
+		this.log = log;
+	}
+
+	public void clearCache() {
+		queries.clear();
+	}
+
+	public void restartDatasourcePool() {
+		// TODO: feature is to kill off all connections, and reload it.
+
+	}
+
+	/**
+	 * returns a list of beans of type T
+	 * 
+	 * @param processor processor to be used
+	 * @param <T> the type of the bean to be returned
+	 * @return list of beans of type T
+	 * @throws UnableToRunQueryException unable to run the query for various
+	 *             reasons
+	 * @see com.tyndalehouse.step.web.server.db.StepQueryRunner#run(com.tyndalehouse
+	 *      .step.web.server.db.ResultSetProcessor)
+	 */
+	public <T> List<T> run(final ResultSetProcessor<T> processor) throws UnableToRunQueryException {
+		ResultSet rs;
+		Connection connection = null;
+		PreparedStatement ps = null;
+
+		// check for null
+		if (processor == null) {
+			log.error("The passed in ResultSetProcessor was null.");
+			throw new UnableToRunQueryException(new NullPointerException());
+		}
+
+		final long tInit = System.currentTimeMillis();
+		StepQuery stepQuery = null;
+		try {
+			stepQuery = prepareStepQuery(processor.getQuery());
+
+			final long tAfterLoad = System.currentTimeMillis();
+			connection = datasource.getConnection();
+			ps = connection.prepareStatement(stepQuery.getSQLText());
+
+			final long tAfterParse = System.currentTimeMillis();
+			stepQuery.setupParameters(ps, processor.getParameters());
+
+			logStepQuery(processor, stepQuery);
+			final long tAfterLog = System.currentTimeMillis();
+
+			// TODO: not returning anything!
+			rs = ps.executeQuery();
+			final long tAfterExecute = System.currentTimeMillis();
+
+			final List<T> results = processor.process(rs);
+			final long tAfterParseResults = System.currentTimeMillis();
+
+			if (log.isInfoEnabled()) {
+				log.info(String.format("StepQueryRunner (load, parse, execute, return) = (%d, %d, %d, %d)",
+						tAfterLoad - tInit, tAfterParse - tAfterLoad, tAfterExecute - tAfterLog,
+						tAfterParseResults - tAfterExecute));
+			}
+
+			return results;
+		} catch (final ConfigNotLoadedException e) {
+			log.error("Unable to load the configuration file to set up datasource.");
+			throw new UnableToRunQueryException(e, stepQuery);
+		} catch (final MalformedStepQueryException e) {
+			log.error("An exception occured during the execution of the sql query");
+			throw new UnableToRunQueryException(e, stepQuery);
+		} catch (final SQLException e) {
+			log.error("An exception occured file trying to locate the file.");
+			throw new UnableToRunQueryException(e, stepQuery);
+		} finally {
+			// close the statement
+			if (ps != null) {
+				try {
+					ps.close();
+				} catch (final SQLException exception) {
+					log.error("Error finalising connection", exception);
+				}
+			}
+
+			// close the connection
+			if (connection != null) {
+				try {
+					connection.close();
+				} catch (final SQLException exception) {
+					log.error("Error finalising connection", exception);
+				}
+			}
+		}
+	}
+
+	/**
+	 * if logging is enabled at trace level, then the query is output, with all
+	 * its parameters
+	 * 
+	 * @param processor processor to process results of the query, which
+	 *            contains the parameters
+	 * @param stepQuery the query to be logged
+	 */
+	private void logStepQuery(final ResultSetProcessor<?> processor, final StepQuery stepQuery) {
+		if (log.isTraceEnabled()) {
+			final StringBuffer logOutput = new StringBuffer();
+			logOutput.append("Query is: ");
+			logOutput.append(stepQuery.getSQLText());
+
+			for (final String paramName : processor.getParameters().keySet()) {
+				logOutput.append(' ');
+				logOutput.append(paramName);
+				logOutput.append('=');
+				logOutput.append(processor.getParameters().get(paramName));
+				logOutput.append(", ");
+			}
+			log.trace(logOutput.toString());
+		}
+	}
+
+	/**
+	 * Faster than a regexp, so use this , in which we expect that there are
+	 * arguments to be parsed These would be defined as #query-param# within the
+	 * sql text. The function works by looking for a open and then a closed #
+	 * Unfortunately, it is not perfect and will have TODO; be rewritten to
+	 * ensure that the programmer can use the charact # in his query
+	 * 
+	 * @param q is the query
+	 * @return a object of type {@link StepQuery}
+	 */
+	private StepQuery parseArguments(final StringBuffer q) {
+		final StepQuery query = new StepQuery();
+
+		int openingHash = 0;
+		while ((openingHash = q.indexOf(HASH)) != -1) {
+			final int endingHash = q.indexOf(HASH, openingHash + 1);
+			final String paramName = q.substring(openingHash + 1, endingHash);
+			query.addArgument(paramName);
+			q.replace(openingHash, endingHash + 1, QUESTION_MARK);
+		}
+
+		return query;
+	}
+
+	/**
+	 * Look for all lines containing the pattern define variable_name as type
+	 * Then removes those into a map before continuing
+	 * 
+	 * @param queryText sql text as loaded from disk
+	 * @param q query text to look through
+	 * @return a object of type {@link StepQuery}
+	 * @throws MalformedStepQueryException an exception is thrown to indicate an
+	 */
+	private StepQuery parseDefinitions(final StringBuffer queryText, final StepQuery q)
+			throws MalformedStepQueryException {
+		// all sql files with parameters will have definitions for their
+		// parameters at the top.
+		final Pattern p = Pattern.compile(DEFINITION_PATTERN);
+		final Matcher m = p.matcher(queryText);
+
+		// iterate through definitions that have been found
+		while (m.find()) {
+			final String paramName = m.group(1);
+			final String paramType = m.group(2);
+
+			try {
+				final Integer type = Types.class.getField(paramType.toUpperCase()).getInt(null);
+				q.addParamTypeMapping(paramName, type);
+			} catch (final IllegalArgumentException e) {
+				throw new MalformedStepQueryException(String.format("Could not parse argument type: %s",
+						paramType), e);
+			} catch (final SecurityException e) {
+				throw new MalformedStepQueryException(String.format("Could not parse argument type: %s",
+						paramType), e);
+			} catch (final IllegalAccessException e) {
+				throw new MalformedStepQueryException(String.format("Could not parse argument type: %s",
+						paramType), e);
+			} catch (final NoSuchFieldException e) {
+				throw new MalformedStepQueryException(String.format("Could not parse argument type: %s",
+						paramType), e);
+			}
+		}
+
+		q.setSQLText(m.replaceAll(""));
+		return q;
+	}
+
+	/**
+	 * @param query query to be executed. If already cached, then this query is
+	 *            returned otherwise, it is loaded from disk
+	 * @return a object of type {@link StepQuery}
+	 * @throws ConfigNotLoadedException if an issue occured during loading of
+	 *             the configuration for STEP
+	 * @throws MalformedStepQueryException an exception is thrown to indicate an
+	 *             issue with the sql file that could not be parsed
+	 */
+	private StepQuery prepareStepQuery(final Query query) throws ConfigNotLoadedException,
+			MalformedStepQueryException {
+		StepQuery stepQuery = queries.get(query);
+		// check whether query is in cache
+		if (stepQuery == null) {
+			stepQuery = readQueryFromFile(query);
+		}
+
+		// now check if datasource is null
+		if (datasource == null) {
+			datasource = setupDatasource();
+		}
+		return stepQuery;
+	}
+
+	/**
+	 * Reads a query from the file
+	 * 
+	 * @param query query to be loaded
+	 * @return returns a loaded {@link StepQuery} object
+	 * @throws ConfigNotLoadedException failed to load the configuration
+	 * @throws MalformedStepQueryException thrown if arguments found don't match
+	 *             a declaration
+	 */
+	private StepQuery readQueryFromFile(final Query query) throws ConfigNotLoadedException,
+			MalformedStepQueryException {
+		// get base path from file
+		final String basePath = ConfigProvider.get("query.repository.path");
+		final String baseComponent = query.getComponent();
+		final String filenameBase = query.name();
+
+		// read query from file
+		final ClassLoader loader = Thread.currentThread().getContextClassLoader();
+		final String filename = String.format("%s%s/%s.sql", basePath, baseComponent, filenameBase
+				.toLowerCase());
+		final URL fileLocation = loader.getResource(filename);
+		StepQuery stepQuery = null;
+		StringBuffer q;
+
+		// check file location is non null:
+		if (fileLocation == null) {
+			throw new MalformedStepQueryException(String.format("The filename %s does not exist.", filename));
+		}
+
+		try {
+			q = new StringBuffer(FileUtils.readFileToString(new File(fileLocation.getFile())));
+			stepQuery = parseDefinitions(q, parseArguments(q));
+			stepQuery.validate();
+
+			// check whether or not to cache the query:
+			if (ConfigProvider.get("query.runner.cache").equals(CACHE_QUERY_PROPERTY)) {
+				queries.put(query, stepQuery);
+			}
+		} catch (final IOException e) {
+			throw new MalformedStepQueryException(
+					String.format("Error reading query file: %s", filenameBase), e);
+		}
+
+		return stepQuery;
+	}
+
+	/**
+	 * sets up the datasource from properties
+	 * 
+	 * @return the datasource properly configured
+	 * @throws ConfigNotLoadedException throws if properties aren't found
+	 */
+	private DataSource setupDatasource() throws ConfigNotLoadedException {
+		final BasicDataSource ds = new BasicDataSource();
+		ds.setDriverClassName(ConfigProvider.get("db.driver"));
+		ds.setUsername(ConfigProvider.get("db.user"));
+		ds.setPassword(ConfigProvider.get("db.password"));
+		ds.setUrl(ConfigProvider.get("connection.string"));
+		ds.setInitialSize(ConfigProvider.getInt("db.pool.initialSize"));
+		ds.setMaxActive(ConfigProvider.getInt("db.pool.maxSize"));
+		// ds.setValidationQuery(ConfigProvider.get("db.pool.validation.query"));
+		// ds.setPoolPreparedStatements(true); //NOT Supported by java DB :(
+		ds.setMaxOpenPreparedStatements(ConfigProvider.getInt("db.pool.prepared.size"));
+		ds.setDefaultAutoCommit(false);
+
+		return ds;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/UnableToRunQueryException.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/UnableToRunQueryException.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/framework/UnableToRunQueryException.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,56 @@
+package com.tyndalehouse.step.web.server.db.framework;
+
+/**
+ * An issue occurred during the parsing or running of a query
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class UnableToRunQueryException extends Exception {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -7810594097160119720L;
+
+	/**
+	 * The StepQuery at the origin of the exception
+	 */
+	private StepQuery stepQuery;
+
+	/**
+	 * Pass in the root cause of the exception
+	 * 
+	 * @param e the root exception
+	 */
+	public UnableToRunQueryException(final Exception e) {
+		super(e);
+	}
+
+	/**
+	 * Unable to run a query exception, with the stepQuery itself, and the root
+	 * exception
+	 * 
+	 * @param e the exception to be wrapped
+	 * @param stepQuery a step query that was attempted to be executed
+	 */
+	public UnableToRunQueryException(final Exception e, final StepQuery stepQuery) {
+		this(e);
+		this.stepQuery = stepQuery;
+	}
+
+	/**
+	 * @return the stepQuery
+	 */
+	public final StepQuery getStepQuery() {
+		return stepQuery;
+	}
+
+	/**
+	 * @param stepQuery the stepQuery to set
+	 */
+	public final void setStepQuery(final StepQuery stepQuery) {
+		this.stepQuery = stepQuery;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimeBandVisibleDateProcessor.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimeBandVisibleDateProcessor.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimeBandVisibleDateProcessor.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,134 @@
+package com.tyndalehouse.step.web.server.db.timeline;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+import com.tyndalehouse.step.web.server.db.framework.MalformedStepQueryException;
+import com.tyndalehouse.step.web.server.db.framework.Query;
+import com.tyndalehouse.step.web.server.db.framework.QueryImpl;
+import com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineEventBean;
+
+/**
+ * Processes a list of timebands from the database
+ * @author CJBurrell cjburrell
+ *
+ */
+public class TimeBandVisibleDateProcessor implements ResultSetProcessor<TimelineEventBean> {
+
+	/**
+	 * event type id
+	 */
+	private static final String EVENT_TYPE_ID = "event_type_id";
+	/**
+	 * certainty
+	 */
+	private static final String CERTAINTY = "certainty";
+	/**
+	 * importance if
+	 */
+	private static final String IMPORTANCE_ID = "importance_id";
+	/**
+	 * timeband id
+	 */
+	private static final String TIMEBAND_ID = "timeband_id";
+	/**
+	 * name
+	 */
+	private static final String NAME = "name";
+	/**
+	 * to precision
+	 */
+	private static final String TO_PRECISION = "to_precision";
+	/**
+	 * from precision
+	 */
+	private static final String FROM_PRECISION = "from_precision";
+	/**
+	 * to date
+	 */
+	private static final String TO_DATE = "to_date";
+	/**
+	 * from date
+	 */
+	private static final String FROM_DATE = "from_date";
+	/**
+	 * event id
+	 */
+	private static final String EVENT_ID = "event_id";
+	/**
+	 * min date
+	 */
+	private static final String MIN_DATE = "min_date";
+	/**
+	 * max date 
+	 */
+	private static final String MAX_DATE = "max_date";
+	/**
+	 * params to be passed in to the query
+	 */
+	private Map<String, Object> params;
+
+	/**
+	 * public constructor to create the processor with default parameters
+	 * @param minDate min date to be passed to the query
+	 * @param maxDate max date to be passed to the query
+	 * @param timebandId the timeband id to be looked up
+	 */
+	public TimeBandVisibleDateProcessor(final long minDate, final long maxDate, final int timebandId) {
+		params = new HashMap<String, Object>();
+		params.put(MIN_DATE, minDate);
+		params.put(MAX_DATE, maxDate);
+		params.put(TIMEBAND_ID, timebandId);
+	}
+
+
+	/**
+	 * @see {@link ResultSetProcessor}
+	 * @return the map of parameters
+	 */
+	public final Map<String, Object> getParameters() {
+		return params;
+	}
+
+	
+	/**
+	 * @see {@link ResultSetProcessor}
+	 * @return the query to be executed
+	 */
+	public final Query getQuery() {
+		return QueryImpl.GET_EVENTS_FOR_DATE_RANGE;
+	}
+
+	/**
+	 * 
+	 * @param rs result set to be processed
+	 * @see com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor#process(java.sql.ResultSet)
+	 * @return a list of {@link TimelineEventBean} returned by the query
+	 * @exception MalformedStepQueryException an error occurred during the execution of the query
+	 * @exception ConfigNotLoadedException an error occurred during the loading of the configuration
+	 * @exception SQLException an runtime SQL exception occurred
+	 */
+	public final List<TimelineEventBean> process(final ResultSet rs) 
+		throws MalformedStepQueryException, ConfigNotLoadedException, SQLException {
+		// TODO: parse the event in some object, as opposed to just fields like
+		// that!
+		// in particular the precision type
+		List<TimelineEventBean> events = new ArrayList<TimelineEventBean>();
+		while (rs.next()) {
+			Long toDate = rs.getObject(TO_DATE) == null ? null : rs.getLong(TO_DATE);
+			TimelineEventBean teb = new TimelineEventBean(rs.getInt(EVENT_ID), rs.getLong(FROM_DATE), 
+					toDate, 
+					rs.getString(FROM_PRECISION), rs.getString(TO_PRECISION), 
+					rs.getString(NAME), rs.getInt(TIMEBAND_ID), rs.getInt(IMPORTANCE_ID), 
+					rs.getString(CERTAINTY), rs.getInt(EVENT_TYPE_ID));
+			events.add(teb);
+		}
+		return events;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginDbBean.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginDbBean.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginDbBean.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,75 @@
+package com.tyndalehouse.step.web.server.db.timeline;
+
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * Timeline Origin DB Bean, containing the default configuration for each timeband
+ * @author CJBurrell
+ *
+ */
+public class TimelineOriginDbBean {
+
+	
+	/**
+	 * origin in time (milli seconds since epoch)
+	 */
+	private long origin;
+	/**
+	 * recommended time unit to be displayed
+	 */
+	private Unit unit;
+	
+	/**
+	 * timeband id to be looked up 
+	 */
+	private int timebandId;
+
+	/**
+	 * @return the origin
+	 */
+	public final long getOrigin() {
+		return origin;
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public final Unit getUnit() {
+		return unit;
+	}
+
+	/**
+	 * Sets the origin field
+	 * @param origin value in ms for oring
+	 */
+	public final void setOrigin(final long origin) {
+		this.origin = origin;
+	}
+
+	/**
+	 * Sets the unit for the bean
+	 * 
+	 * @param unit
+	 *            unit that should be shown on screen
+	 */
+	public final void setUnit(final String unit) {
+		this.unit = Unit.valueOf(unit);
+	}
+
+	/**
+	 * returns the timeband id
+	 * @return timeband id
+	 */
+	public final int getTimebandId() {
+		return timebandId;
+	}
+
+	/**
+	 * @param timebandId
+	 *            the timebandId to set
+	 */
+	public final void setTimebandId(final int timebandId) {
+		this.timebandId = timebandId;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginProcessor.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginProcessor.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineOriginProcessor.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,77 @@
+package com.tyndalehouse.step.web.server.db.timeline;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+import com.tyndalehouse.step.web.server.db.framework.MalformedStepQueryException;
+import com.tyndalehouse.step.web.server.db.framework.Query;
+import com.tyndalehouse.step.web.server.db.framework.QueryImpl;
+import com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor;
+
+/**
+ * Step Processor to retrieve the origin event, given a scripture passage
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimelineOriginProcessor implements ResultSetProcessor<TimelineOriginDbBean> {
+	/** result column origin */
+	private static final String ORIGIN = "origin";
+
+	/** input qry end,, verse no for which to restrict the query */
+	private static final String QRY_END = "qry_end";
+
+	/** input qry start, verse no for which to restrict the query */
+	private static final String QRY_START = "qry_start";
+
+	/** result column timeband id */
+	private static final String TIMEBAND = "timeband_id";
+
+	// TODO: move to enum
+	/** result column unit */
+	private static final String UNIT = "unit";
+
+	/** parameters to pass in to the query */
+	private final Map<String, Object> params;
+
+	/**
+	 * Given a scripture range, it
+	 * 
+	 * @param qryStart minimum verse no to restrict range lookup
+	 * @param qryEnd maximum verse no to restrict range lookup
+	 */
+	public TimelineOriginProcessor(final int qryStart, final int qryEnd) {
+		params = new HashMap<String, Object>();
+		params.put(QRY_START, qryStart);
+		params.put(QRY_END, qryEnd);
+	}
+
+	public Map<String, Object> getParameters() {
+		return params;
+
+	}
+
+	public Query getQuery() {
+		return QueryImpl.LOOKUP_TIMELINE_ORIGIN;
+	}
+
+	public List<TimelineOriginDbBean> process(final ResultSet rs) throws MalformedStepQueryException,
+			ConfigNotLoadedException, SQLException {
+		final List<TimelineOriginDbBean> origins = new ArrayList<TimelineOriginDbBean>();
+
+		while (rs.next()) {
+			final TimelineOriginDbBean bean = new TimelineOriginDbBean();
+			bean.setOrigin(rs.getLong(ORIGIN));
+			bean.setUnit(rs.getString(UNIT));
+			bean.setTimebandId(rs.getInt(TIMEBAND));
+			origins.add(bean);
+		}
+		return origins;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineSetupDataProcessor.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineSetupDataProcessor.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/db/timeline/TimelineSetupDataProcessor.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,69 @@
+package com.tyndalehouse.step.web.server.db.timeline;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+import com.tyndalehouse.step.web.server.db.framework.MalformedStepQueryException;
+import com.tyndalehouse.step.web.server.db.framework.Query;
+import com.tyndalehouse.step.web.server.db.framework.QueryImpl;
+import com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineBean;
+
+/**
+ * Data processor for the Step Query framework, to parse results from the
+ * timeline setup sql query
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimelineSetupDataProcessor implements ResultSetProcessor<TimelineBean> {
+	/**
+	 * the result column timeband_description
+	 */
+	private static final String TIMEBAND_DESCRIPTION = "timeband_description";
+
+	/** the result column timeband_id */
+	private static final String TIMEBAND_ID = "timeband_id";
+
+	/** the result column timeband unit */
+	private static final String TIMEBAND_UNIT = "timeband_unit";
+
+	/** the parameters to pass in to the query */
+	private final Map<String, Object> params;
+
+	/**
+	 * public constructor
+	 */
+	public TimelineSetupDataProcessor() {
+		params = new HashMap<String, Object>();
+	}
+
+	public Map<String, Object> getParameters() {
+		return params;
+
+	}
+
+	public Query getQuery() {
+		return QueryImpl.GET_TIMELINE_SETUP_DATA;
+	}
+
+	public List<TimelineBean> process(final ResultSet rs) throws MalformedStepQueryException,
+			ConfigNotLoadedException, SQLException {
+		final List<TimelineBean> timelines = new ArrayList<TimelineBean>();
+
+		while (rs.next()) {
+			final TimelineBean bean = new TimelineBean();
+			bean.setTimelineId(rs.getInt(TIMEBAND_ID));
+			bean.setTimelineDescription(rs.getString(TIMEBAND_DESCRIPTION));
+			bean.setUnit(rs.getString(TIMEBAND_UNIT));
+			timelines.add(bean);
+		}
+		return timelines;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/CustomDispatchServiceServlet.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/CustomDispatchServiceServlet.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/CustomDispatchServiceServlet.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,47 @@
+package com.tyndalehouse.step.web.server.guice;
+
+import net.customware.gwt.dispatch.server.Dispatch;
+import net.customware.gwt.dispatch.server.service.DispatchServiceServlet;
+
+import org.apache.commons.logging.Log;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+/**
+ * Step dispatch servlet to use for the dispatchin of queries
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at Singleton
+public class CustomDispatchServiceServlet extends DispatchServiceServlet {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -6063357416925075136L;
+
+	/**
+	 * default logger
+	 */
+	private final Log logger;
+
+	/**
+	 * normal constructor
+	 * 
+	 * @param dispatch dispath object
+	 * @param logger logger to be provided
+	 */
+	@Inject
+	public CustomDispatchServiceServlet(final Dispatch dispatch, final Log logger) {
+		super(dispatch);
+		this.logger = logger;
+	};
+
+	@Override
+	protected void doUnexpectedFailure(final Throwable e) {
+		logger.error("An unexpected error happened on the bridge between server and client", e);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/DispatchServletModule.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/DispatchServletModule.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/DispatchServletModule.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,20 @@
+package com.tyndalehouse.step.web.server.guice;
+
+import com.google.inject.servlet.ServletModule;
+
+/**
+ * Servlet module for the Jetty/Tomcat server
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class DispatchServletModule extends ServletModule {
+
+	@Override
+	public void configureServlets() {
+		// NOTE: the servlet context will probably need changing
+
+		serve("/step/dispatch").with(CustomDispatchServiceServlet.class);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/LogProvider.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/LogProvider.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/LogProvider.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,43 @@
+package com.tyndalehouse.step.web.server.guice;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.impl.Log4JLogger;
+
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+/**
+ * A Gin provider for logging purposes.
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at Singleton
+public class LogProvider implements Provider<Log> {
+	// enforce singleton to allow static methods to get to the same log
+	/**
+	 * TODO: there should be a logger per class really. All appending to the
+	 * same file, but so that we can turn them on and off
+	 * 
+	 */
+	private static Log logger = new Log4JLogger("step.jetty");
+
+	/**
+	 * The static equivalent of the above, so that static contexts can log as
+	 * well
+	 * 
+	 * @return the log to use
+	 */
+	public static Log getLogger() {
+		return logger;
+	}
+
+	/**
+	 * The instantiated log to be returned
+	 * 
+	 * @return the Log file to be used
+	 */
+	public Log get() {
+		return logger;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/MyGuiceServletConfig.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/MyGuiceServletConfig.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/MyGuiceServletConfig.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,19 @@
+package com.tyndalehouse.step.web.server.guice;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.servlet.GuiceServletContextListener;
+
+/**
+ * The servlet configuraiton for Guice, which creates an injector
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class MyGuiceServletConfig extends GuiceServletContextListener {
+
+	@Override
+	protected Injector getInjector() {
+		return Guice.createInjector(new ServerModule(), new DispatchServletModule());
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/ServerModule.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/ServerModule.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/guice/ServerModule.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,37 @@
+package com.tyndalehouse.step.web.server.guice;
+
+import net.customware.gwt.dispatch.server.guice.ActionHandlerModule;
+
+import org.apache.commons.logging.Log;
+
+import com.google.inject.Singleton;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunnerImpl;
+import com.tyndalehouse.step.web.server.handler.GetAvailableBibleVersionsHandler;
+import com.tyndalehouse.step.web.server.handler.GetBibleBooksHandler;
+import com.tyndalehouse.step.web.server.handler.GetCurrentBibleTextHandler;
+import com.tyndalehouse.step.web.server.handler.GetDictionaryDefinitionHandler;
+import com.tyndalehouse.step.web.server.handler.GetEventsForDateRangeHandler;
+import com.tyndalehouse.step.web.server.handler.GetTimelineOriginForScriptureHandler;
+import com.tyndalehouse.step.web.server.handler.GetTimelineUISetupHandler;
+
+/**
+ * Module which binds the handlers and configurations
+ * 
+ */
+public class ServerModule extends ActionHandlerModule {
+
+	@Override
+	protected void configureHandlers() {
+		bindHandler(GetAvailableBibleVersionsHandler.class);
+		bind(Log.class).toProvider(LogProvider.class).in(Singleton.class);
+		bindHandler(GetBibleBooksHandler.class);
+		bindHandler(GetCurrentBibleTextHandler.class);
+		bindHandler(GetEventsForDateRangeHandler.class);
+		bindHandler(GetTimelineUISetupHandler.class);
+		bindHandler(GetTimelineOriginForScriptureHandler.class);
+		bindHandler(GetDictionaryDefinitionHandler.class);
+
+		bind(StepQueryRunner.class).to(StepQueryRunnerImpl.class).in(Singleton.class);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetAvailableBibleVersionsHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetAvailableBibleVersionsHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetAvailableBibleVersionsHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,63 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.List;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookCategory;
+import org.crosswire.jsword.book.Books;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.shared.command.GetAvailableBibleVersionsCommand;
+import com.tyndalehouse.step.web.shared.result.GetAvailableBibleVersionsResult;
+
+/**
+ * Command handler returning all available bible versions
+ * 
+ * @author CJBurrell TODO: add logging to this class
+ */
+public class GetAvailableBibleVersionsHandler extends
+	AbstractStepHandler<GetAvailableBibleVersionsCommand, GetAvailableBibleVersionsResult> {
+	/**
+	 * Default logger
+	 */
+	private final Log logger;
+
+	/**
+	 * normal constructor
+	 * 
+	 * @param logger provided by Gin
+	 */
+	@Inject
+	public GetAvailableBibleVersionsHandler(final Log logger) {
+		this.logger = logger;
+	}
+
+	public GetAvailableBibleVersionsResult execute(final GetAvailableBibleVersionsCommand cmd,
+		final ExecutionContext arg1) throws ActionException {
+		// TODO: add handling of different types of book: bibles, commentaries,
+		// versions, etc.
+		@SuppressWarnings("unchecked")
+		final List<Book> books = Books.installed().getBooks();
+		final SortedMap<String, String> map = new TreeMap<String, String>();
+		for (final Book b : books) {
+			if (b.getBookCategory() == BookCategory.BIBLE) {
+				map.put(b.getInitials(), b.getName());
+			}
+		}
+		return new GetAvailableBibleVersionsResult(map);
+	}
+
+	public void rollback(final GetAvailableBibleVersionsCommand arg0,
+		final GetAvailableBibleVersionsResult arg1, final ExecutionContext arg2)
+		throws ActionException {
+		logger.error("Rolling back GetAvailableBibleVersions");
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetBibleBooksHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetBibleBooksHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetBibleBooksHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,70 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.ArrayList;
+import java.util.Locale;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.crosswire.jsword.passage.NoSuchVerseException;
+import org.crosswire.jsword.versification.BibleInfo;
+import org.crosswire.jsword.versification.BibleNames;
+import org.crosswire.jsword.versification.BookName;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.shared.command.GetBibleBooksCommand;
+import com.tyndalehouse.step.web.shared.result.GetBibleBooksCommandResult;
+
+/**
+ * Command handler for retrieving the different names of the books in a
+ * particular version TODO: only currently works for KJV
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetBibleBooksHandler extends
+	AbstractStepHandler<GetBibleBooksCommand, GetBibleBooksCommandResult> {
+	/**
+	 * public constructor
+	 */
+	@Inject
+	public GetBibleBooksHandler() {
+	}
+
+
+	public GetBibleBooksCommandResult execute(final GetBibleBooksCommand command,
+		final ExecutionContext arg1) throws ActionException {
+
+		getLogger().debug("GetBibleBooksCommandResult has been called...");
+
+		// TODO: on start up, we should check a whole load of things: jsword
+		// installed, database can be started, database has got data
+
+		// find selection of books and then add stuff to the suggestbox.
+		final ArrayList<String> suggestions = new ArrayList<String>();
+
+		// http://www.crosswire.org/jsword/java2html/org/crosswire/jsword/bridge/BibleScope.java.html
+		// TODO: currently based on KJV versification, when better to base it on
+		// preferred version
+		// of the bible...
+		try {
+			final int booksInBible = BibleInfo.booksInBible();
+			BookName bn;
+			final BibleNames all = new BibleNames(Locale.getDefault());
+			for (int ii = 1; ii <= booksInBible; ii++) {
+				bn = all.getName(ii);
+				suggestions.add(bn.getPreferredName());
+			}
+		} catch (final NoSuchVerseException e) {
+			getLogger().error("Failed to generate list of bible books", e);
+		}
+
+		return new GetBibleBooksCommandResult(suggestions);
+	}
+
+	public void rollback(final GetBibleBooksCommand arg0, final GetBibleBooksCommandResult arg1,
+		final ExecutionContext context) throws ActionException {
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetCurrentBibleTextHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,514 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.lang.StringUtils;
+import org.crosswire.common.util.Reporter;
+import org.crosswire.common.xml.SAXEventProvider;
+import org.crosswire.common.xml.TransformingSAXEventProvider;
+import org.crosswire.common.xml.XMLUtil;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookData;
+import org.crosswire.jsword.book.BookException;
+import org.crosswire.jsword.book.BookMetaData;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.book.OSISUtil;
+import org.crosswire.jsword.passage.NoSuchKeyException;
+import org.jdom.Attribute;
+import org.jdom.Content;
+import org.jdom.Element;
+import org.jdom.Text;
+import org.jdom.filter.Filter;
+import org.xml.sax.SAXException;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.common.JSwordConstants;
+import com.tyndalehouse.step.web.server.handler.util.passage.StrongMorphMap;
+import com.tyndalehouse.step.web.server.jsword.ConfigurableHTMLConverter;
+import com.tyndalehouse.step.web.shared.command.GetCurrentBibleTextCommand;
+import com.tyndalehouse.step.web.shared.result.GetCurrentBibleTextResult;
+import com.tyndalehouse.step.web.shared.scripture.Milestone;
+import com.tyndalehouse.step.web.shared.scripture.Note;
+import com.tyndalehouse.step.web.shared.scripture.OSISConstants;
+import com.tyndalehouse.step.web.shared.scripture.Passage;
+import com.tyndalehouse.step.web.shared.scripture.TextualElement;
+import com.tyndalehouse.step.web.shared.scripture.Title;
+import com.tyndalehouse.step.web.shared.scripture.TransChange;
+import com.tyndalehouse.step.web.shared.scripture.Verse;
+import com.tyndalehouse.step.web.shared.scripture.VerseContent;
+import com.tyndalehouse.step.web.shared.scripture.Word;
+
+/**
+ * Command handler returning a portion of scripture in different formats
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetCurrentBibleTextHandler extends
+	AbstractStepHandler<GetCurrentBibleTextCommand, GetCurrentBibleTextResult> {
+
+	/**
+	 * default constructor with the getLogger
+	 * 
+	 */
+	@Inject
+	public GetCurrentBibleTextHandler() {
+
+	}
+
+
+	public GetCurrentBibleTextResult execute(final GetCurrentBibleTextCommand command,
+		final ExecutionContext arg1) throws ActionException {
+		final String version = command.getVersion();
+		final String reference = command.getReference();
+
+		// check information has been passed in
+		// TODO: ensure error handling is handled properly
+		if (StringUtils.isEmpty(version)) {
+			throw new ActionException("Version was not provided");
+		}
+		if (StringUtils.isEmpty(reference)) {
+			throw new ActionException("Reference was not provided");
+		}
+
+		final GetCurrentBibleTextResult result = new GetCurrentBibleTextResult();
+
+		final BookData data = getBookData(version, reference);
+
+		switch (command.getTypeOfLookup()) {
+		case CLASSIC_INTERLINEAR:
+			addClassicInterlinear(result.getPassage(), reference);
+			break;
+		case LOGICAL:
+			addLogicalLookup(result, data);
+			break;
+		case PLAIN_TEXT:
+			try {
+				result.setPassageText(OSISUtil.getCanonicalText(data.getOsis()));
+			} catch (final BookException e) {
+				throw new ActionException("Unable to get simple canonical text from book", e);
+			}
+			break;
+		case REVERSE_INTERLINEAR:
+			addLogicalLookup(result, data);
+			addReverseInterlinear(result.getPassage(), reference);
+			break;
+		case XSLT:
+			result.setXsltedText(doXslt(data));
+			break;
+		default:
+			// do nothing since nothing was requested
+			break;
+		}
+		return result;
+	}
+
+	public void rollback(final GetCurrentBibleTextCommand arg0,
+		final GetCurrentBibleTextResult arg1, final ExecutionContext arg2) throws ActionException {
+		getLogger().error("Get Current Bible Text rolling back");
+
+	}
+
+	/**
+	 * does a classic interlinear and populates the Passage
+	 * 
+	 * @param p the logical passage to be populated
+	 * @param reference the reference
+	 */
+	private void addClassicInterlinear(final Passage p, final String reference) {
+		// TODO: feature
+		// identify the hebrew/greek version of the text, and get book data for
+		// the appropriate version
+		// final VerseRange vrf = VerseRangeFactory.fromString(reference);
+		// TODO updgrade to latest jsword version
+
+		// VerseRange.remainder(vrf, null);
+
+		// getBookData(version, reference);
+	}
+
+	/**
+	 * adds a logical lookup to the result objet
+	 * 
+	 * @param result the result object to populate
+	 * @param data the data to base the lookup upon
+	 * @throws ActionException an exception thrown if the parsing or lookup goes
+	 *             bad
+	 */
+	private void addLogicalLookup(final GetCurrentBibleTextResult result, final BookData data)
+		throws ActionException {
+		final Passage p = parseForGwt(data);
+		result.setPassage(p);
+	}
+
+	/**
+	 * doing a reverse interlinear
+	 * 
+	 * @param translatedText the passage as looked up in an non-original version
+	 * @param reference the reference of the text so we can add the original
+	 *            text onto it
+	 * @throws ActionException action exception thrown during execution of the
+	 *             reverse interlinear process
+	 */
+	private void addReverseInterlinear(final Passage translatedText, final String reference)
+		throws ActionException {
+		// first lookup passage from LXX or TODO user chosen version
+		// TODO: cope with Hebrew
+		String versionToUse;
+		StrongMorphMap strongMorphMap;
+
+		if (isGreek(translatedText)) {
+			versionToUse = JSwordConstants.DEFAULT_GREEK_INTERLINEAR_TEXT;
+		} else {
+			// assume Hebrew
+			versionToUse = JSwordConstants.DEFAULT_HEBREW_INTERLINEAR_TEXT;
+		}
+
+		// TODO: we need to do something different here,
+		// we don't need to parse through the whole lot, and probably JDom
+		// allows us to use filters to get all children of a certain kind,
+		// we want to end up with a keyed map, looking like [strong, morph?] ->
+		// word
+		try {
+			strongMorphMap = getStrongMorphMap(getBookData(versionToUse, reference));
+		} catch (final BookException e) {
+			throw new ActionException("Unable to lookup source text and parse to StrongMorphMap", e);
+		}
+
+		mergePassages(translatedText, strongMorphMap);
+	}
+
+	/**
+	 * parsing a milestone into a logical element
+	 * 
+	 * @param verseContent the Content on which to append the logical element
+	 * @param v the verse
+	 */
+	private void doMilestone(final Element verseContent, final Verse v) {
+		final Milestone m = new Milestone();
+		m.setMarker(verseContent.getAttributeValue(OSISConstants.MARKER));
+		m.setType(verseContent.getAttributeValue(OSISUtil.OSIS_ATTR_TYPE));
+		v.addTextualElement(m);
+	}
+
+	/**
+	 * parsing a note into a logical element
+	 * 
+	 * @param verseContent the Content on which to append the logical element
+	 * @param v the verse
+	 */
+	private void doNote(final Element verseContent, final Verse v) {
+		final Note n = new Note();
+		n.setType(verseContent.getAttributeValue(OSISUtil.OSIS_ATTR_TYPE));
+		n.setText(verseContent.getText());
+		v.addTextualElement(n);
+	}
+
+	/**
+	 * parses a title
+	 * 
+	 * @param titleElement the xml title element
+	 * @param passage the passage to be parsed into
+	 */
+	private void doTitle(final Element titleElement, final Passage passage) {
+		final Title title = new Title();
+		title.setType(titleElement.getAttributeValue(OSISUtil.OSIS_ATTR_TYPE));
+		title.setText(titleElement.getText());
+		passage.addPassageElement(title);
+	}
+
+	/**
+	 * parses a TransChange element
+	 * 
+	 * @param verseContent the trans change element
+	 * @param v the verse to be parsed into
+	 */
+	private void doTransChange(final Element verseContent, final Verse v) {
+		final TransChange t = new TransChange();
+		t.setType(verseContent.getAttributeValue(OSISUtil.OSIS_ATTR_TYPE));
+		t.setText(verseContent.getText());
+		v.addTextualElement(t);
+	}
+
+	/**
+	 * parses a verse xml element
+	 * 
+	 * @param e the verse element
+	 * @param passage the passage to be parsed into
+	 */
+	private void doVerse(final Element e, final Passage passage) {
+		final List<Content> verseWords = e.getContent();
+		final Verse v = new Verse();
+		v.setOsisID(e.getAttributeValue(OSISUtil.OSIS_ATTR_OSISID));
+		passage.addPassageElement(v);
+
+		for (final Content c : verseWords) {
+			if (c instanceof Element) {
+				final Element verseContent = (Element) c;
+				final String tagName = verseContent.getName();
+				if (tagName.equals(OSISUtil.OSIS_ELEMENT_W)) {
+					doWord(verseContent, v);
+				} else if (tagName.equals(OSISUtil.OSIS_ELEMENT_NOTE)) {
+					doNote(verseContent, v);
+				} else if (tagName.equals(OSISConstants.MILESTONE)) {
+					doMilestone(verseContent, v);
+				} else if (tagName.equals(OSISConstants.TRANS_CHANGE)) {
+					doTransChange(verseContent, v);
+				} else {
+					getLogger().warn(String.format("Unexpected element %s", tagName));
+				}
+			} else if (c instanceof Text) {
+				final Text textElement = (Text) c;
+				final com.tyndalehouse.step.web.shared.scripture.Text t = new com.tyndalehouse.step.web.shared.scripture.Text(
+					textElement.getText());
+				v.addTextualElement(t);
+			} else {
+				// we're in trouble
+				getLogger().warn("Content c is not recognised: " + c.getClass().getCanonicalName());
+			}
+		}
+	}
+
+	/**
+	 * processes a word from the bible text passed in as XML
+	 * 
+	 * @param verseContent verseContent in XML
+	 * @param v the object version of this word
+	 */
+	private void doWord(final Element verseContent, final Verse v) {
+		final Word w = new Word();
+
+		final String lemmas = verseContent.getAttributeValue(OSISUtil.ATTRIBUTE_W_LEMMA);
+		final String morphs = verseContent.getAttributeValue(OSISUtil.ATTRIBUTE_W_MORPH);
+
+		// TODO: make a constant
+		if (lemmas != null) {
+			w.addLemmas(lemmas.split(" "));
+		}
+		if (morphs != null) {
+			w.addMorphs(morphs.split(" "));
+		}
+		w.setText(verseContent.getText());
+		v.addTextualElement(w);
+	}
+
+	/**
+	 * does an xslt transformation on some OSIS text
+	 * 
+	 * @param data data of the book to use and the key in the book.
+	 * @return the passage xslted version
+	 */
+	private String doXslt(final BookData data) {
+		if (data == null) {
+			return "";
+		}
+
+		// Make sure Hebrew displays from Right to Left
+		final BookMetaData bmd = data.getFirstBook().getBookMetaData();
+		if (bmd == null) {
+			return "";
+		}
+
+		try {
+			final SAXEventProvider osissep = data.getSAXEventProvider();
+
+			final TransformingSAXEventProvider htmlsep = (TransformingSAXEventProvider) new ConfigurableHTMLConverter()
+				.convert(osissep);
+			final String text = XMLUtil.writeToString(htmlsep);
+			return text;
+		} catch (final SAXException e) {
+			Reporter.informUser(this, e);
+		} catch (final BookException e) {
+			Reporter.informUser(this, e);
+		} catch (final TransformerException e) {
+			Reporter.informUser(this, e);
+		}
+		return "";
+	}
+
+	/**
+	 * returns the book data using the JSword API
+	 * 
+	 * @param version version to be looked up
+	 * @param reference reference of the passage
+	 * @return the JSword BookData object
+	 * @throws ActionException an exception should an problem happen
+	 */
+	private BookData getBookData(final String version, final String reference)
+		throws ActionException {
+		try {
+			final Book currentBook = Books.installed().getBook(version);
+			final BookData data = new BookData(currentBook, currentBook.getKey(reference));
+			return data;
+		} catch (final NoSuchKeyException e) {
+			getLogger().error("An error occurred looking up the passage", e);
+			throw new ActionException(e);
+		}
+	}
+
+	/**
+	 * given a book data (referencing a biblical reference + a book), retrieves
+	 * the morphs and the Strong numbers (lemmas) in the passage to help in the
+	 * interlinear processing
+	 * 
+	 * @param bookData the bookData from JSword specialised for the reference
+	 *            and bible book
+	 * @return a map of strong numbers and morphs
+	 * @throws BookException an exception occuring during parsing of the OSIS
+	 *             XML
+	 */
+	@SuppressWarnings("unchecked")
+	private StrongMorphMap getStrongMorphMap(final BookData bookData) throws BookException {
+		final Element osis = bookData.getOsisFragment();
+		final StrongMorphMap strongMorphMap = new StrongMorphMap();
+		final Iterator<Element> it = osis.getDescendants(new Filter() {
+			/**
+			 * serial id
+			 */
+			private static final long serialVersionUID = 4171956787222841308L;
+
+			public boolean matches(final Object obj) {
+				return obj instanceof Element
+					&& ((Element) obj).getName().equals(OSISUtil.OSIS_ELEMENT_W);
+			}
+
+		});
+
+		while (it.hasNext()) {
+			final Element word = it.next();
+			final Attribute lemmaAttribute = word.getAttribute(OSISUtil.ATTRIBUTE_W_LEMMA);
+			final Attribute morphAttribute = word.getAttribute(OSISUtil.ATTRIBUTE_W_MORPH);
+
+			if (lemmaAttribute != null) {
+				if (morphAttribute != null) {
+					strongMorphMap.addWord(lemmaAttribute.getValue(), morphAttribute.getValue(),
+						word.getValue());
+				} else {
+					strongMorphMap.addWord(lemmaAttribute.getValue(), word.getValue());
+				}
+			}
+		}
+
+		return strongMorphMap;
+	}
+
+	/**
+	 * Look at the first word with a lemma and return lemma[0] == 'G'
+	 * 
+	 * @param p passage to be looked up
+	 * @return true if the word with the first lemma is in Greek
+	 */
+	private boolean isGreek(final Passage p) {
+		for (final VerseContent vc : p.getVerseContent()) {
+			if (vc instanceof Verse) {
+				final Verse v = (Verse) vc;
+				for (final TextualElement te : v.getVerseContent()) {
+					if (te instanceof Word) {
+						final Word w = (Word) te;
+						if (w.getLemma() != null) {
+							return w.getLemma().get(0).charAt(
+								JSwordConstants.STRONG_PATTERN_START.length()) == JSwordConstants.STRONG_GREEK_MARKER;
+						}
+					}
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Iterates through the master passage and incorporates into it, the text
+	 * given and mapped in the strongMorphMap
+	 * 
+	 * @param masterPassage the passage to be enriched
+	 * @param strongMorphMap the map containing the links.
+	 */
+	// TODO: tidy up all the different iterator approaches, widely using
+	// instanceof
+	private void mergePassages(final Passage masterPassage, final StrongMorphMap strongMorphMap) {
+		// iterate through the masterPassage, and lookup the strong morph map
+		final List<VerseContent> verseContent = masterPassage.getVerseContent();
+		List<String> lemma, morph;
+		for (final VerseContent vc : verseContent) {
+			if (vc instanceof Verse) {
+				final Verse v = (Verse) vc;
+				for (final TextualElement te : v.getVerseContent()) {
+					if (te instanceof Word) {
+						final Word w = (Word) te;
+
+						// we have several lemmas for each word, and therefore,
+						// we need to loop round them
+						lemma = w.getLemma();
+						morph = w.getMorph();
+
+						final StringBuffer alternativeWording = new StringBuffer(64);
+
+						// we iterate through each lemma, knowing that we may
+						// not have morphs at all (Hebrew text)
+						// we cannot use the morph without the lemma, although
+						// TODO: check what we're supposed to do
+						// when we only have one morphology for several lemmas
+						// always 0 or equal to number of lemmas
+						for (int ii = 0; ii < lemma.size(); ii++) {
+							final String l = lemma.get(ii);
+							final String m = ii < morph.size() ? morph.get(ii) : null;
+							final String text = strongMorphMap.get(l, m);
+							if (text != null) {
+								alternativeWording.append(text);
+								alternativeWording.append(' ');
+							}
+							w.setAlternativeWord(alternativeWording.toString());
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * parsing an element
+	 * 
+	 * @param data the book data to used as a basis for parsing
+	 * @return the passage once parsed, et al.
+	 * @throws ActionException an exception to bubble up to the web UI
+	 */
+	@SuppressWarnings("unchecked")
+	// TODO: upgrade to latest JSword version for generics
+	private Passage parseForGwt(final BookData data) throws ActionException {
+		Element osisFragment;
+		try {
+			osisFragment = data.getOsisFragment();
+		} catch (final BookException e1) {
+			throw new ActionException("Unable to get OSIS Fragment from selected version");
+		}
+
+		final List<Content> l = osisFragment.getContent();
+		final Passage passage = new Passage();
+
+		// First level can be title or verse
+		for (final Content el : l) {
+			// check whether we've just got text, or a verse or something
+			if (el instanceof Element) {
+				final Element e = (Element) el;
+
+				if (e.getName().equals(OSISUtil.OSIS_ELEMENT_TITLE)) {
+					doTitle(e, passage);
+				} else if (e.getName().equals(OSISUtil.OSIS_ELEMENT_VERSE)) {
+					doVerse(e, passage);
+				}
+			} else {
+				// this shouldn't happen
+				getLogger().warn("Unexpected text while parsing gwt");
+			}
+		}
+
+		return passage;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetDictionaryDefinitionHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetDictionaryDefinitionHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetDictionaryDefinitionHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,175 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.List;
+
+import javax.xml.transform.TransformerException;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.lang.StringUtils;
+import org.crosswire.common.util.Reporter;
+import org.crosswire.common.xml.SAXEventProvider;
+import org.crosswire.common.xml.TransformingSAXEventProvider;
+import org.crosswire.common.xml.XMLUtil;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookData;
+import org.crosswire.jsword.book.BookException;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.passage.NoSuchKeyException;
+import org.jdom.Element;
+import org.xml.sax.SAXException;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.common.JSwordConstants;
+import com.tyndalehouse.step.web.server.jsword.ConfigurableHTMLConverter;
+import com.tyndalehouse.step.web.shared.command.GetDictionaryDefinitionCommand;
+import com.tyndalehouse.step.web.shared.result.GetDictionaryDefinitionResult;
+
+/**
+ * Looks up the dictionary definition in a JSword module and returns it to the
+ * client
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetDictionaryDefinitionHandler extends
+	AbstractStepHandler<GetDictionaryDefinitionCommand, GetDictionaryDefinitionResult> {
+
+	/**
+	 * The dictionary definition handler's constructor
+	 */
+	@Inject
+	public GetDictionaryDefinitionHandler() {
+	}
+
+
+
+	public GetDictionaryDefinitionResult execute(final GetDictionaryDefinitionCommand command,
+		final ExecutionContext arg1) throws ActionException {
+		final List<String> referenceList = command.getLookupReferencce();
+		final GetDictionaryDefinitionResult result = new GetDictionaryDefinitionResult();
+
+		final StringBuffer definitions = new StringBuffer(300);
+		// for each definition: TODO : probably want to pass back a list of
+		// definitions, and tab them
+		// on the popup!
+		for (final String reference : referenceList) {
+			definitions.append(lookUpDefinition(reference));
+			definitions.append("<hr />");
+
+		}
+		result.setDefinition(definitions.toString());
+		return result;
+	}
+
+	
+	public void rollback(final GetDictionaryDefinitionCommand arg0,
+		final GetDictionaryDefinitionResult arg1, final ExecutionContext arg2)
+		throws ActionException {
+		getLogger().error("Get Dictionary definition Text rolling back");
+
+	}
+
+	/**
+	 * does a simple xslt transformation to show the definition on the screen
+	 * 
+	 * @param data data to be shown
+	 * @param osisFragment osisFragment to transform
+	 * @return the xslted definition ready to be displayed on the user's screen
+	 */
+	private String doXslt(final BookData data, final Element osisFragment) {
+		if (data == null) {
+			return "";
+		}
+
+		try {
+			final SAXEventProvider osissep = data.getSAXEventProvider();
+			// TODO: do some work on the XSLT definition
+			final TransformingSAXEventProvider htmlsep = (TransformingSAXEventProvider) new ConfigurableHTMLConverter()
+				.convert(osissep);
+			final String text = XMLUtil.writeToString(htmlsep);
+			return text;
+		} catch (final SAXException e) {
+			Reporter.informUser(this, e);
+		} catch (final BookException e) {
+			Reporter.informUser(this, e);
+		} catch (final TransformerException e) {
+			Reporter.informUser(this, e);
+		}
+		return "";
+	}
+
+	/**
+	 * dependant on the reference, we return a different module to lookup the
+	 * definition. For e.g. we use a Greek dictionary to lookup a reference
+	 * starting strong:Gxxxxx
+	 * 
+	 * @param reference reference to be looked up
+	 * @return the module initials to use for the dictionary lookup
+	 * @throws ActionException an exception to be thrown if the reference is not
+	 *             recognised
+	 */
+	private String getInitialsFromReference(final String reference) throws ActionException {
+		if (reference.toLowerCase().startsWith(JSwordConstants.STRONG_PATTERN_START)) {
+			final int charPosition = JSwordConstants.STRONG_PATTERN_START.length();
+			if (reference.charAt(charPosition) == JSwordConstants.STRONG_HEBREW_MARKER) {
+				return JSwordConstants.STRONG_HEBREW_DICTIONARY_INITIALS;
+			} else if (reference.charAt(charPosition) == JSwordConstants.STRONG_GREEK_MARKER) {
+				return JSwordConstants.STRONG_GREEK_DICTIONARY_INITIALS;
+			}
+			// continuing will throw exception
+		}
+		throw new ActionException(String.format("Dictionary reference not recognised: %s",
+			reference));
+	}
+
+	/**
+	 * returns the actual reference, removing the strong pattern + first
+	 * initial. For e.g. removes strong:H from "strong:H00002"
+	 * 
+	 * @param reference reference to parse
+	 * @return the key in the dictionary to be used for lookup purposes
+	 * @throws ActionException the action exception
+	 */
+	private String getLookupKeyFromReference(final String reference) throws ActionException {
+		if (reference.toLowerCase().startsWith(JSwordConstants.STRONG_PATTERN_START)) {
+			// remove strong:H or strong:G
+			return reference.substring(JSwordConstants.STRONG_PATTERN_START.length() + 1);
+		}
+		throw new ActionException(String.format("Lookup key not recognised: %s", reference));
+	}
+
+	/**
+	 * Looks up a definition given a reference in the default JSword module
+	 * 
+	 * @param reference reference, for e.g. a Strong number
+	 * @return the definition
+	 * @throws ActionException an exception occurring if the reference is
+	 *             invalid
+	 */
+	private String lookUpDefinition(final String reference) throws ActionException {
+		if (StringUtils.isEmpty(reference)) {
+			throw new ActionException("Reference was not provided");
+		}
+		getLogger().error("definition lookup command");
+		final String initials = getInitialsFromReference(reference);
+		final String lookupKey = getLookupKeyFromReference(reference);
+
+		try {
+			// TODO: ensure a lookup key exists!
+			// TODO: make a common adapter api to access JSword
+			final Book currentBook = Books.installed().getBook(initials);
+			final BookData data = new BookData(currentBook, currentBook.getKey(lookupKey));
+			final String xsltedDefinition = doXslt(data, data.getOsisFragment());
+			return xsltedDefinition;
+		} catch (final NoSuchKeyException e) {
+			getLogger().error("An error occurred looking up the passage", e);
+			throw new ActionException(e);
+		} catch (final BookException e) {
+			getLogger().error("A book exception has occurred whilte looking up the passage", e);
+			throw new ActionException(e);
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetEventsForDateRangeHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetEventsForDateRangeHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetEventsForDateRangeHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,104 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.server.db.framework.UnableToRunQueryException;
+import com.tyndalehouse.step.web.server.db.timeline.TimeBandVisibleDateProcessor;
+import com.tyndalehouse.step.web.shared.command.GetEventsForDateRangeCommand;
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineEventBean;
+import com.tyndalehouse.step.web.shared.result.GetEventsForDateRangeResult;
+
+/**
+ * Command that gets relevant events on a date range. Currently this executes
+ * multiple queries against the database
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetEventsForDateRangeHandler extends
+	AbstractStepHandler<GetEventsForDateRangeCommand, GetEventsForDateRangeResult> {
+
+	/**
+	 * The step query runner to run queries against the database
+	 */
+	private final StepQueryRunner queryRunner;
+
+	/**
+	 * public constructor for this handler
+	 * 
+	 * @param queryRunner the query runner object to use for executing the query
+	 */
+	@Inject
+	public GetEventsForDateRangeHandler(final StepQueryRunner queryRunner) {
+		this.queryRunner = queryRunner;
+	}
+
+
+	// TODO: this needs to change to take into account the three different types
+	// of date precision but for now,
+	// let's get something working
+	public GetEventsForDateRangeResult execute(final GetEventsForDateRangeCommand event,
+		final ExecutionContext arg1) throws ActionException {
+		final GetEventsForDateRangeResult result = new GetEventsForDateRangeResult();
+		final List<TimeBandVisibleDate> timebands = event.getVisbleDates();
+		try {
+			for (final TimeBandVisibleDate tvd : timebands) {
+				List<TimelineEventBean> events;
+				events = queryRunner.run(new TimeBandVisibleDateProcessor(tvd.getMinDate(), tvd
+					.getMaxDate(), tvd.getTimebandId()));
+				result.getEvents().addAll(events);
+			}
+		} catch (final UnableToRunQueryException e) {
+			getLogger().error(
+				"An error occured while trying to retrieve new events from the datbase", e);
+			throw new ActionException(e);
+		}
+
+		logEventsRetrieved(result.getEvents());
+		return result;
+	}
+
+	public void rollback(final GetEventsForDateRangeCommand arg0,
+		final GetEventsForDateRangeResult arg1, final ExecutionContext arg2) throws ActionException {
+
+	}
+
+	/**
+	 * Logs which events have been retrieved in trace mode
+	 * 
+	 * @param events events to be traced
+	 */
+	private void logEventsRetrieved(final List<TimelineEventBean> events) {
+		final SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy G");
+
+		if (getLogger().isTraceEnabled()) {
+			for (final TimelineEventBean teb : events) {
+				if (teb.getFromDate() != null && teb.getToDate() != null) {
+					getLogger().trace(
+						String.format("returning: %s %s-%s (tb_id: %d)", teb.getName(), sdf
+							.format(new Date(teb.getFromDate())), sdf.format(new Date(teb
+							.getToDate())), teb.getTimelineId()));
+
+				} else if (teb.getFromDate() != null) {
+					getLogger().trace(
+						String.format("returning: %s %s (tb_id: %d)", teb.getName(), sdf
+							.format(new Date(teb.getFromDate())), teb.getTimelineId()));
+				} else {
+					getLogger().trace(
+						String.format("returning: %s (tb_id: %d)", teb.getName(), teb
+							.getTimelineId()));
+				}
+			}
+		}
+		getLogger().trace(String.format("Returning %d events to the client", events.size()));
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetLocationsHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetLocationsHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetLocationsHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,51 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.shared.command.GetLocationsCommand;
+import com.tyndalehouse.step.web.shared.result.GetLocationsResult;
+
+/**
+ * The GetLocations command gets geographical locations from the server
+ * datasources and sends them back to the client
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetLocationsHandler extends
+	AbstractStepHandler<GetLocationsCommand, GetLocationsResult> {
+
+	/**
+	 * Default constructor
+	 * 
+	 * @param queryRunner a query runner
+	 */
+	@Inject
+	public GetLocationsHandler(final StepQueryRunner queryRunner) {
+//		this.queryRunner = queryRunner;
+	}
+
+
+	public GetLocationsResult execute(final GetLocationsCommand arg0, final ExecutionContext arg1)
+		throws ActionException {
+		// try {
+		// final List<GeoLoc> timelines = queryRunner.run(new
+		// TimelineSetupDataProcessor());
+		final GetLocationsResult r = new GetLocationsResult();
+		return r;
+		// } catch (final UnableToRunQueryException e) {
+		// getLogger().error("An error occured while loading the config for the query",
+		// e);
+		// throw new ActionException(e);
+		// }
+	}
+
+	public void rollback(final GetLocationsCommand arg0, final GetLocationsResult arg1,
+		final ExecutionContext arg2) throws ActionException {
+		getLogger().error("Get Locations Handler rolling back");
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineOriginForScriptureHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineOriginForScriptureHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineOriginForScriptureHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,121 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.crosswire.jsword.passage.Key;
+import org.crosswire.jsword.passage.KeyFactory;
+import org.crosswire.jsword.passage.NoSuchKeyException;
+import org.crosswire.jsword.passage.PassageKeyFactory;
+import org.crosswire.jsword.passage.RestrictionType;
+import org.crosswire.jsword.passage.RocketPassage;
+import org.crosswire.jsword.passage.VerseRange;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.server.db.framework.UnableToRunQueryException;
+import com.tyndalehouse.step.web.server.db.timeline.TimelineOriginDbBean;
+import com.tyndalehouse.step.web.server.db.timeline.TimelineOriginProcessor;
+import com.tyndalehouse.step.web.shared.command.GetTimelineOriginForScriptureCommand;
+import com.tyndalehouse.step.web.shared.result.GetTimelineOriginForScriptureResult;
+
+/**
+ * returns the timeline origin, i.e the best (closest in time) event for a given
+ * verse range.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetTimelineOriginForScriptureHandler extends
+	AbstractStepHandler<GetTimelineOriginForScriptureCommand, GetTimelineOriginForScriptureResult> {
+	/**
+	 * The step query runner to run queries against the database
+	 */
+	private final StepQueryRunner queryRunner;
+
+	/**
+	 * constructor for this handler
+	 * 
+	 * @param queryRunner the query runner framework
+	 */
+	@Inject
+	public GetTimelineOriginForScriptureHandler(final StepQueryRunner queryRunner) {
+		this.queryRunner = queryRunner;
+	}
+
+
+	// TODO: build a proper sql statement to query all time bands in one go
+	// TODO: this needs to change to take into account the three different types
+	// of date precision but for now,
+	// let's get something working
+	public GetTimelineOriginForScriptureResult execute(
+		final GetTimelineOriginForScriptureCommand event, final ExecutionContext arg1)
+		throws ActionException {
+		try {
+			// TODO: this is bad - look at JSword to work out how to properly
+			// get the verserange out
+			final RocketPassage passage = (RocketPassage) resolveScriptureToVerseNumbers(event
+				.getScriptureReference());
+
+			if (passage.isEmpty()) {
+				getLogger().warn("No passage was requested");
+			} else {
+
+				// TODO: we're doing only the first range - ignoring others...
+				// What would we do with several ranges? Interesting question -
+				// perhaps we could use as min/max
+				final VerseRange range = passage.getRangeAt(0, RestrictionType.NONE);
+				final int startVerseNo = range.getStart().getOrdinal();
+				final int endVerseNo = range.getEnd().getOrdinal();
+
+				final ResultSetProcessor<TimelineOriginDbBean> originProcessor = new TimelineOriginProcessor(
+					startVerseNo, endVerseNo);
+
+				// TODO: should be able to ensure this is implied, rather having
+				// to cast directly
+				final List<TimelineOriginDbBean> originList = queryRunner.run(originProcessor);
+
+				if (originList.size() != 0) {
+					final TimelineOriginDbBean origin = originList.get(0);
+					return new GetTimelineOriginForScriptureResult(origin.getOrigin(), origin
+						.getUnit(), origin.getTimebandId());
+				} // else {
+				// // TODO: work out the nearest passage and redo this...
+				// }
+			}
+		} catch (final NoSuchKeyException e) {
+			getLogger().warn("Could not resolve verse number", e);
+			// TODO: return a proper exception and show error message on the UI
+			return new GetTimelineOriginForScriptureResult(true);
+		} catch (final UnableToRunQueryException e) {
+			getLogger().error("An error occured while loading the config for the query", e);
+			throw new ActionException(e);
+		}
+		return new GetTimelineOriginForScriptureResult(true);
+	}
+
+	public void rollback(final GetTimelineOriginForScriptureCommand arg0,
+		final GetTimelineOriginForScriptureResult arg1, final ExecutionContext arg2)
+		throws ActionException {
+
+	}
+
+	/**
+	 * resolves a string to a range of verses
+	 * 
+	 * @return the OSIS key to use to look up a particular scripture reference
+	 *         in a JSword module
+	 * @throws NoSuchKeyException thrown if the passed in reference cannot be
+	 *             parsed //TODO: make into seperate util classes
+	 */
+	private Key resolveScriptureToVerseNumbers(final String scriptureReference)
+		throws NoSuchKeyException {
+		final KeyFactory keyFactory = PassageKeyFactory.instance();
+		return keyFactory.getKey(scriptureReference);
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineUISetupHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineUISetupHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/GetTimelineUISetupHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,66 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.server.db.framework.UnableToRunQueryException;
+import com.tyndalehouse.step.web.server.db.timeline.TimelineSetupDataProcessor;
+import com.tyndalehouse.step.web.shared.command.GetTimelineUISetupCommand;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineBean;
+import com.tyndalehouse.step.web.shared.result.GetTimelineUISetupResult;
+
+/**
+ * the timeline UI setup handler, which returns the initial set of data for the
+ * timeline module including the different bands, their recommended scales, etc.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetTimelineUISetupHandler extends
+	AbstractStepHandler<GetTimelineUISetupCommand, GetTimelineUISetupResult> {
+	/**
+	 * The step query runner to run queries against the database
+	 */
+	private final StepQueryRunner queryRunner;
+
+	/**
+	 * Default constructor
+	 * 
+	 * @param queryRunner a query runner
+	 */
+	@Inject
+	public GetTimelineUISetupHandler(final StepQueryRunner queryRunner) {
+		this.queryRunner = queryRunner;
+	}
+
+	// TODO: this can be cached quite succesfully on the server
+
+	public GetTimelineUISetupResult execute(final GetTimelineUISetupCommand cmd,
+		final ExecutionContext arg1) throws ActionException {
+		try {
+			final List<TimelineBean> timelines = queryRunner.run(new TimelineSetupDataProcessor());
+			final GetTimelineUISetupResult r = new GetTimelineUISetupResult();
+			r.setTimelines(timelines);
+
+			if (getLogger().isDebugEnabled()) {
+				getLogger().debug(
+					String.format("Returning %d timebands to the client.", timelines.size()));
+			}
+			return r;
+		} catch (final UnableToRunQueryException e) {
+			getLogger().error("An error occured while loading the config for the query", e);
+			throw new ActionException(e);
+		}
+	}
+
+	public void rollback(final GetTimelineUISetupCommand arg0, final GetTimelineUISetupResult arg1,
+		final ExecutionContext arg2) throws ActionException {
+		getLogger().error("Get Timeline UI Setup Handler rolling back");
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/InstallJswordModuleHandler.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/InstallJswordModuleHandler.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/InstallJswordModuleHandler.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,150 @@
+package com.tyndalehouse.step.web.server.handler;
+
+import java.util.Set;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.crosswire.common.progress.JobManager;
+import org.crosswire.common.progress.Progress;
+import org.crosswire.jsword.book.Book;
+import org.crosswire.jsword.book.BookException;
+import org.crosswire.jsword.book.Books;
+import org.crosswire.jsword.book.install.sword.HttpSwordInstaller;
+
+import com.google.inject.Inject;
+import com.tyndalehouse.step.web.server.common.AbstractStepHandler;
+import com.tyndalehouse.step.web.shared.command.InstallJswordModuleCommand;
+import com.tyndalehouse.step.web.shared.result.InstallJswordModuleResult;
+
+/**
+ * Handler that installs a JSword module (bible, etc.) on to the server (perhaps
+ * a localhost server)
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class InstallJswordModuleHandler extends
+	AbstractStepHandler<InstallJswordModuleCommand, InstallJswordModuleResult> {
+
+	// TODO: move the lookup to properties file
+	/**
+	 * proxy to use to access the internet from step
+	 */
+	private static final String PROXY_HOST = "step.proxy.host";
+
+	/**
+	 * proxy port to use for accessing the internet form step
+	 */
+	private static final String PROXY_PORT = "step.proxy.port";
+
+	/**
+	 * the time to wait for installer to kick in, so that we can then wait for
+	 * it
+	 */
+	private static final int WAIT_TIME_FOR_INSTALLER = 2000;
+
+	/**
+	 * constructor to create this handler, usually via Guice
+	 */
+	@Inject
+	public InstallJswordModuleHandler() {
+	}
+
+
+
+	public InstallJswordModuleResult execute(final InstallJswordModuleCommand cmd,
+		final ExecutionContext context) throws ActionException {
+
+		final String initials = cmd.getInitials();
+		if (initials == null) {
+			throw new ActionException("Module initials provided was null");
+		}
+
+		try {
+			final HttpSwordInstaller newCustomInstaller = getNewCustomInstaller();
+
+			// remove if already installed
+			final Book installed = Books.installed().getBook(initials);
+			if (installed != null) {
+				// remove first
+				// Books.installed().removeBook(installed);
+				installed.getDriver().delete(installed);
+				getLogger().debug(
+					String.format("%s (%s) is already installed, so removing first", initials,
+						installed.getName()));
+			}
+
+			// now kick off install
+			final Book bookToBeInstalled = newCustomInstaller.getBook(initials);
+			newCustomInstaller.install(bookToBeInstalled);
+
+			getLogger().debug(String.format("Installing %s", initials));
+
+			// finally wait for install to finish
+			// hack to wait for the thread to register with the manager
+			// TODO: check with jsword community
+			// TODO: use a timer instead...
+			Thread.sleep(WAIT_TIME_FOR_INSTALLER);
+
+			@SuppressWarnings("unchecked")
+			final Set<Progress> jswordJobs = JobManager.getJobs();
+			for (final Progress p : jswordJobs) {
+				if (p.getJobName().equals("Installing book: " + bookToBeInstalled.getName())) {
+					// TODO: expose join on the thread and wait for it to exit
+					// this will depend on the JSword community
+					while (!p.isFinished()) {
+						// sleep
+						Thread.sleep(WAIT_TIME_FOR_INSTALLER);
+					}
+				}
+			}
+		} catch (final BookException e) {
+			getLogger().error("An error occured during the installation of the book", e);
+		} catch (final InterruptedException e) {
+			getLogger().error("An error occurred during the downloading of the book", e);
+		}
+
+		// wait for module to be completed
+
+		return new InstallJswordModuleResult(true);
+	}
+
+	public void rollback(final InstallJswordModuleCommand arg0,
+		final InstallJswordModuleResult arg1, final ExecutionContext arg2) throws ActionException {
+		getLogger().error("Rolling back InstallJswordModule");
+	}
+
+	/**
+	 * TODO: needs redoing to ensure we take all the installers provided by
+	 * JSword
+	 * 
+	 * @return a custom installer configured with the crosswire proxy
+	 */
+	private HttpSwordInstaller getNewCustomInstaller() {
+		getLogger().info("Creating new installer for JSword");
+		final HttpSwordInstaller resourceInstaller = new HttpSwordInstaller();
+
+		getLogger().info("Currently hardcoded installer host to:" + "www.crosswire.org");
+		getLogger().info("Currently hardcoded property names for step");
+		final String host = "www.crosswire.org";
+		final String proxyHost = System.getProperty(PROXY_HOST);
+		final String proxyPort = System.getProperty(PROXY_PORT);
+		getLogger().info(
+			String.format("Setting to (%1$s via %2$s:%3$s)", "www.crosswire.org", proxyHost,
+				proxyPort));
+
+		resourceInstaller.setHost(host);
+		if (proxyHost != null) {
+			resourceInstaller.setProxyHost(proxyHost);
+		}
+		if (proxyPort != null) {
+			resourceInstaller.setProxyPort(Integer.parseInt(proxyPort));
+		}
+
+		getLogger().info("Setting package and catalog directories");
+		resourceInstaller.setPackageDirectory("/ftpmirror/pub/sword/packages/rawzip");
+		resourceInstaller.setCatalogDirectory("/ftpmirror/pub/sword/raw");
+		return resourceInstaller;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/passage/StrongMorphMap.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/passage/StrongMorphMap.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/handler/util/passage/StrongMorphMap.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,119 @@
+package com.tyndalehouse.step.web.server.handler.util.passage;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * This map will store the mapping for strong,morph to the word However
+ * sometimes the morphology of the word is not present in the passage and since
+ * we still want to be able to render some sort of interlinear, it would be best
+ * to match just on the word as a result each entity will have the the three
+ * values associated to it text (what the word is) the strong number the
+ * morphology (optional) The map is keyed my strong number.
+ * 
+ * In order to ensure rapid lookup, we will use the following way of mapping
+ * elements Strong numbers will map either directly to the word when no morph is
+ * available, or through a morph to the word
+ * 
+ * TODO: It is assumed that given a strong and morph the text is unique TODO:
+ * change this, since there are multiple morphs per lemma and word strong
+ * ---------> morph --------> word (1) or strong ------------------------> word
+ * (2) A mapping (2) will not be stored if (1) is available, and therefore
+ * lookups lookup the morph first as this is prefered.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class StrongMorphMap {
+	// lemmas morphs word
+	/**
+	 * this map maps strong numbers to morphs. it is the first level of
+	 * indirection to the map of morphs which maps to a word
+	 */
+	private final Map<String, Map<String, String>> strongToMorph;
+
+	/**
+	 * this map maps the strong number ot the word directly
+	 */
+	private final Map<String, String> strongToWord;
+
+	/**
+	 * Default constructor that initialises the two maps
+	 */
+	public StrongMorphMap() {
+		strongToMorph = new HashMap<String, Map<String, String>>();
+		strongToWord = new HashMap<String, String>();
+	}
+
+	/**
+	 * only to be used if no morph is available
+	 * 
+	 * @param strong the strong number or lemma
+	 * @param word the word to be stored
+	 */
+	public final void addWord(final String strong, final String word) {
+		strongToWord.put(strong, word);
+	}
+
+	/**
+	 * adds a word to the map
+	 * 
+	 * @param strong the lemma/strong number
+	 * @param morph the morph / indicating morphology
+	 * @param word the word
+	 */
+	public final void addWord(final String strong, final String morph, final String word) {
+		if (morph == null) {
+			addWord(strong, word);
+			return;
+		}
+
+		Map<String, String> morphsToWords = strongToMorph.get(strong);
+		if (morphsToWords == null) {
+			morphsToWords = new HashMap<String, String>();
+			strongToMorph.put(strong, morphsToWords);
+		}
+
+		// guaranteed non-null map
+		morphsToWords.put(morph, word);
+	}
+
+	/**
+	 * Looks up the (lemma, morph) key in the map. If morph is null, lookup is
+	 * done solely on strong number, and takes the first of the morphs
+	 * 
+	 * @param lemma lemma associated to a a word
+	 * @param morph morph, can be passed in null, refering to the grammar of a
+	 *            word in a language
+	 * @return the word associated in the map to the (lemma, morph) combination
+	 */
+	// TODO: check for nulls on lemma
+	public final String get(final String lemma, final String morph) {
+		final Map<String, String> morphToWord = strongToMorph.get(lemma);
+
+		if (morphToWord != null) {
+			if (morph != null) {
+				// use the chain from morphs to word
+				final String word = morphToWord.get(morph);
+				if (word != null) {
+					return word;
+				} else {
+					// well we didn't find our morph, so the best option is to
+					// return another morph for the same strong number
+					final Collection<String> words = morphToWord.values();
+					final Iterator<String> wordsIterator = words.iterator();
+					if (wordsIterator.hasNext()) {
+						return wordsIterator.next();
+					}
+				}
+			}
+		}
+
+		// if we get here, there is nothing valuable in the map going through
+		// the morphs
+		// therefore, let's just return something from the other map
+		return strongToWord.get(lemma);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/ConfigurableHTMLConverter.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/ConfigurableHTMLConverter.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/ConfigurableHTMLConverter.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,170 @@
+/**
+ * Distribution License:
+ * BibleDesktop is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 2 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/gpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: ConfigurableSwingConverter.java 1583 2007-07-30 17:04:04Z dmsmith $
+ */
+package com.tyndalehouse.step.web.server.jsword;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.MissingResourceException;
+
+import javax.xml.transform.TransformerException;
+
+import org.crosswire.common.util.FileUtil;
+import org.crosswire.common.util.NetUtil;
+import org.crosswire.common.util.ResourceUtil;
+import org.crosswire.common.util.URIFilter;
+import org.crosswire.common.xml.Converter;
+import org.crosswire.common.xml.SAXEventProvider;
+import org.crosswire.common.xml.TransformingSAXEventProvider;
+
+/**
+ * Turn XML from a Bible into HTML according to a Display style.
+ * 
+ * @see gnu.gpl.License for license details. The copyright to this program is
+ *      held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+ */
+public class ConfigurableHTMLConverter implements Converter {
+	/**
+     *
+     */
+	static final class XSLTFilter implements URIFilter {
+
+		public boolean accept(final String name) {
+			return name.endsWith(FileUtil.EXTENSION_XSLT);
+		}
+	}
+
+	/**
+	 * The font to be used in OSIS->HTML generation
+	 */
+	private static String font = "Serif-PLAIN-14"; //$NON-NLS-1$
+
+	/**
+	 * The stylesheet we are transforming using
+	 */
+	private static String style = "simple.xsl"; //$NON-NLS-1$
+
+	/**
+	 * ripped off JSWord: TODO: needs to be down properly
+	 */
+	public ConfigurableHTMLConverter() {
+
+	}
+
+	//
+	// /**
+	// * Accessor for the stylesheet we are transforming using
+	// */
+	// public static Font toFont()
+	// {
+	// return null;
+	// //return GuiConvert.string2Font(font);
+	// }
+
+	// /**
+	// * Accessor for the stylesheet we are transforming using
+	// */
+	// public static void setFont(String font)
+	// {
+	// ConfigurableHTMLConverter.font = font;
+	// XSLTProperty.FONT.setState(font);
+	// }
+
+	/**
+	 * Accessor for the stylesheet we are transforming using
+	 * 
+	 * @return the font
+	 */
+	public static String getFont() {
+		return font;
+	}
+
+	/**
+	 * Accessor for the stylesheet we are transforming using
+	 * 
+	 * @return the resource name
+	 */
+	public static String getResourceName() {
+		return style;
+	}
+
+	/**
+	 * Accessor for the stylesheet we are transforming using
+	 * 
+	 * @param style returns the resource name given a style
+	 */
+	public static void setResourceName(final String style) {
+		ConfigurableHTMLConverter.style = style;
+	}
+
+	/**
+	 * 
+	 * 
+	 * @see org.crosswire.common.xml.Converter#convert(org.crosswire.common.xml.
+	 *      SAXEventProvider)
+	 * @param xmlsep the sax event provider
+	 * @return the converted SAX event provider
+	 * @throws TransformerException thrown if something bad happens during the
+	 *             transformation of the xml
+	 */
+	public SAXEventProvider convert(final SAXEventProvider xmlsep) throws TransformerException {
+		try {
+			final String path = "xsl/cswing/" + style; //$NON-NLS-1$
+			final URL xslurl = ResourceUtil.getResource(path);
+
+			final TransformingSAXEventProvider tsep = new TransformingSAXEventProvider(NetUtil.toURI(xslurl),
+					xmlsep);
+			// We used to do:
+			// tsep.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+			// however for various reasons, now we don't but nothing seems to be
+			// broken ...
+			return tsep;
+		} catch (final MissingResourceException ex) {
+			throw new TransformerException(ex);
+		}
+	}
+
+	/**
+	 * Get an array of the available style names for a given subject. Different
+	 * subjects are available for different contexts. For example - for
+	 * insertion into a web page we might want to use a set that had complex
+	 * HTML, or IE/NS specific HTML, where as a JFC HTMLDocument needs simpler
+	 * HTML - and special tags like the starting &lt;HTML> tags.
+	 * <p>
+	 * If the protocol of the URL of the current directory is not file then we
+	 * can't use File.list to get the contents of the directory. This will
+	 * happen if this is being run as an applet. When we start doing that then
+	 * we will need to think up something smarter here. Until then we just
+	 * return a zero length array.
+	 * 
+	 * @return An array of available style names
+	 */
+	public String[] getStyles() {
+		try {
+			final String search = "xsl/cswing/" + NetUtil.INDEX_FILE; //$NON-NLS-1$
+			final URL index = ResourceUtil.getResource(search);
+			return NetUtil.listByIndexFile(NetUtil.toURI(index), new XSLTFilter());
+		} catch (final IOException ex) {
+			return new String[0];
+		}
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/XSLTProperty.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/XSLTProperty.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/server/jsword/XSLTProperty.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,321 @@
+/**
+ * Distribution License:
+ * BibleDesktop is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, version 2 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/gpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: XSLTProperty.java 1583 2007-07-30 17:04:04Z dmsmith $
+ */
+package com.tyndalehouse.step.web.server.jsword;
+
+import java.io.File;
+import java.io.Serializable;
+import java.net.MalformedURLException;
+
+import org.crosswire.common.util.NetUtil;
+import org.crosswire.common.util.Reporter;
+import org.crosswire.common.xml.TransformingSAXEventProvider;
+
+/* TODO: redo this class properly to behave as per where it cam from!
+ * 
+ */
+
+/**
+ * Defines properties that control the behavior of translating OSIS to HTML.
+ * 
+ * @see gnu.gpl.License for license details. The copyright to this program is
+ *      held by it's authors.
+ * @author DM Smith [ dmsmith555 at yahoo dot com]
+ */
+ at SuppressWarnings(value = {})
+public final class XSLTProperty implements Serializable {
+	/**
+	 * What is the base of the current document. Note this needs to be set each
+	 * time the document is shown.
+	 */
+	public static final XSLTProperty BASE_URL = new XSLTProperty("baseURL", "", true); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/**
+	 * Show book, chapter and verse numbers.
+	 */
+	public static final XSLTProperty BCV = new XSLTProperty("BCVNum", false); //$NON-NLS-1$
+
+	/**
+	 * What is the base of the current document.
+	 */
+	public static final XSLTProperty CSS = new XSLTProperty("css", "", true); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/**
+	 * Show chapter and verse numbers.
+	 */
+	public static final XSLTProperty CV = new XSLTProperty("CVNum", false); //$NON-NLS-1$
+
+	/**
+	 * What is the base of the current document. Note this needs to be set each
+	 * time the document is shown.
+	 */
+	public static final XSLTProperty DIRECTION = new XSLTProperty("direction", ""); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/**
+	 * What is the base of the current document. Note this needs to be set each
+	 * time the font changes.
+	 */
+	public static final XSLTProperty FONT = new XSLTProperty("font", "Serif-PLAIN-14"); //$NON-NLS-1$ //$NON-NLS-2$
+
+	/**
+	 * Should headings be shown
+	 */
+	public static final XSLTProperty HEADINGS = new XSLTProperty("Headings", true); //$NON-NLS-1$
+
+	/**
+	 * Determines whether Word Morphology (e.g. Robinson) should show
+	 */
+	public static final XSLTProperty MORPH = new XSLTProperty("Morph", false); //$NON-NLS-1$
+
+	/**
+	 * Show no verse numbers
+	 */
+	public static final XSLTProperty NO_VERSE_NUMBERS = new XSLTProperty("NoVNum", false); //$NON-NLS-1$
+
+	/**
+	 * Should notes be shown
+	 */
+	public static final XSLTProperty NOTES = new XSLTProperty("Notes", true); //$NON-NLS-1$
+
+	/**
+	 * Determines whether verses should start on a new line.
+	 */
+	public static final XSLTProperty START_VERSE_ON_NEWLINE = new XSLTProperty("VLine", false); //$NON-NLS-1$
+
+	/**
+	 * Determines whether Strong's Numbers should show
+	 */
+	public static final XSLTProperty STRONGS_NUMBERS = new XSLTProperty("Strongs", false); //$NON-NLS-1$
+
+	/**
+	 * Show verse numbers as a superscript.
+	 */
+	public static final XSLTProperty TINY_VERSE_NUMBERS = new XSLTProperty("TinyVNum", true); //$NON-NLS-1$
+
+	/**
+	 * Show verse numbers
+	 */
+	public static final XSLTProperty VERSE_NUMBERS = new XSLTProperty("VNum", true); //$NON-NLS-1$
+
+	/**
+	 * Should cross references be shown
+	 */
+	public static final XSLTProperty XREF = new XSLTProperty("XRef", true); //$NON-NLS-1$
+
+	/**
+	 * Support for serialization
+	 * 
+	 */
+	private static int nextObj;
+
+	/**
+	 * Serialization ID
+	 */
+	private static final long serialVersionUID = 3257567325749326905L;
+
+	/**
+	 * list of xslt properties
+	 */
+	private static final XSLTProperty[] VALUES = { STRONGS_NUMBERS, MORPH, START_VERSE_ON_NEWLINE,
+			VERSE_NUMBERS, CV, BCV, NO_VERSE_NUMBERS, TINY_VERSE_NUMBERS, HEADINGS, NOTES, XREF, BASE_URL,
+			DIRECTION, FONT, CSS, };
+
+	/**
+	 * Whether the string state should be converted to an URL when setting the
+	 * property.
+	 */
+	private final boolean asURL;
+
+	/**
+	 * The default state of the XSLTProperty
+	 */
+	private final String defaultState;
+
+	/**
+	 * The name of the XSLTProperty
+	 */
+	private final String name;
+
+	/**
+	 * TODO: don't know what this does, this class is a copy from JSword which
+	 * needs revamping
+	 */
+	private final int obj = nextObj++;
+
+	/**
+	 * The current state of the XSLTProperty
+	 */
+	private String state;
+
+	/**
+	 * @param name The name of this property
+	 * @param defaultState The initial state of the property.
+	 */
+	private XSLTProperty(final String name, final boolean defaultState) {
+		this(name, Boolean.toString(defaultState));
+	}
+
+	/**
+	 * @param name The name of this property
+	 * @param defaultState The initial state of the property.
+	 */
+	private XSLTProperty(final String name, final String defaultState) {
+		this(name, defaultState, false);
+	}
+
+	/**
+	 * @param name The name of this property
+	 * @param defaultState The initial state of the property.
+	 * @param asURL whether it is a uRl?
+	 */
+	private XSLTProperty(final String name, final String defaultState, final boolean asURL) {
+		this.name = name;
+		this.defaultState = defaultState;
+		this.state = defaultState;
+		this.asURL = asURL;
+	}
+
+	/**
+	 * Lookup method to convert from an integer
+	 * 
+	 * @param i gets a particular xslt property
+	 * @return the XSLT property matching the index
+	 */
+	public static XSLTProperty fromInteger(final int i) {
+		return VALUES[i];
+	}
+
+	/**
+	 * Lookup method to convert from a String
+	 * 
+	 * @param name a linear search for a property and returns the XSLT property
+	 * @return a XSLT property
+	 */
+	public static XSLTProperty fromString(final String name) {
+		for (int i = 0; i < VALUES.length; i++) {
+			final XSLTProperty o = VALUES[i];
+			if (o.name.equalsIgnoreCase(name)) {
+				return o;
+			}
+		}
+		assert false;
+		return null;
+	}
+
+	/**
+	 * 
+	 * @param provider sets the SAX provider
+	 */
+	public static void setProperties(final TransformingSAXEventProvider provider) {
+		for (int i = 0; i < VALUES.length; i++) {
+			VALUES[i].setProperty(provider);
+		}
+	}
+
+	/**
+	 * 
+	 * @return default state
+	 */
+	public boolean getDefaultState() {
+		return Boolean.valueOf(defaultState).booleanValue();
+	}
+
+	/**
+	 * 
+	 * @return default state as a string
+	 */
+	public String getDefaultStringState() {
+		return defaultState;
+	}
+
+	/**
+	 * @return the name of the property
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return the state
+	 */
+	public boolean getState() {
+		return Boolean.valueOf(state).booleanValue();
+	}
+
+	/**
+	 * 
+	 * @return state as a string
+	 */
+	public String getStringState() {
+		return state;
+	}
+
+	/**
+	 * 
+	 * @param provider a SAX provider
+	 */
+	public void setProperty(final TransformingSAXEventProvider provider) {
+		if (state != null && state.length() > 0) {
+			String theState = state;
+			if (asURL) {
+				try {
+					theState = NetUtil.getURI(new File(state)).toURL().toString();
+				} catch (final MalformedURLException ex) {
+					Reporter.informUser(this, ex);
+				}
+			}
+			provider.setParameter(name, theState);
+		}
+	}
+
+	/**
+	 * @param newState sets the state to newState
+	 */
+	public void setState(final boolean newState) {
+		state = Boolean.toString(newState);
+	}
+
+	/**
+	 * @param newState sets the state to newState
+	 */
+	public void setState(final String newState) {
+		state = newState;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see java.lang.Object#toString()
+	 */
+	@Override
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * TODO: redo this whole class
+	 * 
+	 * @return an object
+	 */
+	Object readResolve() {
+		return VALUES[obj];
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/BooksRequiredType.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/BooksRequiredType.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/BooksRequiredType.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,14 @@
+package com.tyndalehouse.step.web.shared.command;
+
+/**
+ * Describing what kind of book to be displayed
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum BooksRequiredType {
+	/**
+	 * only retrieve bibles
+	 */
+	BIBLE,
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetAvailableBibleVersionsCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetAvailableBibleVersionsCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetAvailableBibleVersionsCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,46 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetAvailableBibleVersionsResult;
+
+/**
+ * Commmand to get available set of books, that are installed on the server
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetAvailableBibleVersionsCommand implements Action<GetAvailableBibleVersionsResult> {
+	/**
+	 * serial id.
+	 */
+	private static final long serialVersionUID = 5781027650600417430L;
+
+	// TODO: later change that to list modules, bibles, etc.
+	/**
+	 * Describes which types of modules are required to be returned.
+	 */
+	private BooksRequiredType booksRequired = BooksRequiredType.BIBLE;
+
+	/**
+	 * Default constructor needs to be available for GWT it seems.
+	 */
+	public GetAvailableBibleVersionsCommand() {
+
+	}
+
+	/**
+	 * @return the booksRequired
+	 */
+	public BooksRequiredType getBooksRequired() {
+		return booksRequired;
+	}
+
+	/**
+	 * @param booksRequired the booksRequired to set
+	 */
+	public void setBooksRequired(final BooksRequiredType booksRequired) {
+		this.booksRequired = booksRequired;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetBibleBooksCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetBibleBooksCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetBibleBooksCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,40 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetBibleBooksCommandResult;
+
+/**
+ * This is currently based on the KJV and ensures that all bible books are
+ * returned to the UI.
+ * 
+ * @author CJBurrell
+ * 
+ */
+
+public class GetBibleBooksCommand implements Action<GetBibleBooksCommandResult> {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 2749008090105331922L;
+
+	/**
+	 * Initials of version to use to lookup bible
+	 */
+	private String initials;
+
+	/**
+	 * @return the initials
+	 */
+	public final String getInitials() {
+		return initials;
+	}
+
+	/**
+	 * @param initials the initials to set
+	 */
+	public final void setInitials(final String initials) {
+		this.initials = initials;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetCurrentBibleTextCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetCurrentBibleTextCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetCurrentBibleTextCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,107 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.common.scripturelookup.BibleTextLookupType;
+import com.tyndalehouse.step.web.shared.result.GetCurrentBibleTextResult;
+
+/**
+ * Contains the details of a request for biblical text. Such details include
+ * whether to use a plain text, a standard XSLT, or a logical form
+ * <p>
+ * For logical form (represented in Bean form) we allow the use of interlinears
+ * as well.
+ * <p>
+ * A classic interlinear is where the original text is the master copy of the
+ * text, and the translated (English, French, etc.) text is lined up underneath
+ * <p>
+ * A reverse interlinear is where the the English/French text is on top, and the
+ * original (Hebrew or Greek) is lined up underneath.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class GetCurrentBibleTextCommand implements Action<GetCurrentBibleTextResult> {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -6828956918275592036L;
+
+	/**
+	 * the biblical reference, for e.g. Gen 1:1
+	 */
+	private String reference;
+
+	/**
+	 * type of lookup to make
+	 */
+	private BibleTextLookupType typeOfLookup;
+
+	// TODO: add validation to the handler/client to ensure that
+	// version/interlinear matches correctly
+	/**
+	 * the version of the bible to use.
+	 */
+	private String version;
+
+	/**
+	 * default constructor TODO: can this be made private? I think so
+	 */
+	public GetCurrentBibleTextCommand() {
+
+	}
+
+	/**
+	 * constructor for a version,reference combo
+	 * 
+	 * @param version version to be used in the lookup (intials)
+	 * @param reference reference to be used in the lookup (for e.g. Gen 1:1)
+	 */
+	public GetCurrentBibleTextCommand(final String version, final String reference) {
+		this.version = version;
+		this.reference = reference;
+	}
+
+	/**
+	 * @return the biblical reference (Gen 1:1-5 for example)
+	 */
+	public String getReference() {
+		return reference;
+	}
+
+	/**
+	 * @return the typeOfLookup
+	 */
+	public final BibleTextLookupType getTypeOfLookup() {
+		return typeOfLookup;
+	}
+
+	/**
+	 * @return the initials of the version to be used in the lookup
+	 */
+	public String getVersion() {
+		return version;
+	}
+
+	/**
+	 * @param reference the reference to set
+	 */
+	public void setReference(final String reference) {
+		this.reference = reference;
+	}
+
+	/**
+	 * @param typeOfLookup the typeOfLookup to set
+	 */
+	public final void setTypeOfLookup(final BibleTextLookupType typeOfLookup) {
+		this.typeOfLookup = typeOfLookup;
+	}
+
+	/**
+	 * @param version the version to set
+	 */
+	public void setVersion(final String version) {
+		this.version = version;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetDictionaryDefinitionCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetDictionaryDefinitionCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetDictionaryDefinitionCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,46 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetDictionaryDefinitionResult;
+
+/**
+ * dictionary definition command, contains the references to lookup
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetDictionaryDefinitionCommand implements Action<GetDictionaryDefinitionResult> {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -6139208624046856543L;
+
+	/**
+	 * references to be looked up
+	 */
+	private List<String> lookupReferencce;
+
+	/**
+	 * the public constructor
+	 */
+	public GetDictionaryDefinitionCommand() {
+
+	}
+
+	/**
+	 * @return the lookupReferencce
+	 */
+	public List<String> getLookupReferencce() {
+		return lookupReferencce;
+	}
+
+	/**
+	 * @param lookupReferences the list lookupReferencce to set
+	 */
+	public void setLookupReference(final List<String> lookupReferences) {
+		this.lookupReferencce = lookupReferences;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetEventsForDateRangeCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetEventsForDateRangeCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetEventsForDateRangeCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,78 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.common.timeline.TimeBandVisibleDate;
+import com.tyndalehouse.step.web.shared.result.GetEventsForDateRangeResult;
+
+/**
+ * Contains the details of a request for events within a particular date range.
+ * This contains a list of @see {@link TimeBandVisibleDate}, which records the
+ * portion of time to be requested from the server
+ * 
+ * @author cjburrell
+ * 
+ */
+public class GetEventsForDateRangeCommand implements Action<GetEventsForDateRangeResult> {
+	/**
+	 * default uid
+	 */
+	private static final long serialVersionUID = 5781027650600417430L;
+
+	/**
+	 * whether to retrieve durations (this is a DEBUG flag really)
+	 */
+	private boolean showDuration = true;
+
+	/**
+	 * the list of timebands and the times that are currently showing
+	 */
+	private List<TimeBandVisibleDate> visbleDates;
+
+	/**
+	 * Used for serialization
+	 */
+	public GetEventsForDateRangeCommand() {
+
+	}
+
+	/**
+	 * default constructor that should be used
+	 * 
+	 * @param visbleDates list of date ranges encapsulated in a
+	 *            TimeBandVisibleDate object
+	 */
+	public GetEventsForDateRangeCommand(final List<TimeBandVisibleDate> visbleDates) {
+		this.visbleDates = visbleDates;
+	}
+
+	/**
+	 * @return the visbleDates
+	 */
+	public List<TimeBandVisibleDate> getVisbleDates() {
+		return visbleDates;
+	}
+
+	/**
+	 * @return the showDuration
+	 */
+	public boolean isShowDuration() {
+		return showDuration;
+	}
+
+	/**
+	 * @param showDuration the showDuration to set
+	 */
+	public void setShowDuration(final boolean showDuration) {
+		this.showDuration = showDuration;
+	}
+
+	/**
+	 * @param visbleDates the visbleDates to set
+	 */
+	public void setVisbleDates(final List<TimeBandVisibleDate> visbleDates) {
+		this.visbleDates = visbleDates;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetLocationsCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetLocationsCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetLocationsCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,21 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetLocationsResult;
+
+/**
+ * This command captures the input to the handler to query the server for all
+ * locations pertaining to a particular passage
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetLocationsCommand implements Action<GetLocationsResult> {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -4636855791737543490L;
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineOriginForScriptureCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineOriginForScriptureCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineOriginForScriptureCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,54 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetTimelineOriginForScriptureResult;
+
+/**
+ * The command to retrieve the best event given a verse range
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetTimelineOriginForScriptureCommand implements Action<GetTimelineOriginForScriptureResult> {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -6454957611866927920L;
+	/**
+	 * default uid
+	 */
+
+	private String scriptureReference;
+
+	/**
+	 * default constructor that should be used
+	 * 
+	 * @param scriptureReference the biblical reference/range to be looked up
+	 */
+	public GetTimelineOriginForScriptureCommand(final String scriptureReference) {
+		this.scriptureReference = scriptureReference;
+	}
+
+	/**
+	 * Used for serialization
+	 */
+	@SuppressWarnings("unused")
+	private GetTimelineOriginForScriptureCommand() {
+
+	}
+
+	/**
+	 * @return the scriptureReference
+	 */
+	public String getScriptureReference() {
+		return scriptureReference;
+	}
+
+	/**
+	 * @param scriptureReference the scriptureReference to set
+	 */
+	public void setScriptureReference(final String scriptureReference) {
+		this.scriptureReference = scriptureReference;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineUISetupCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineUISetupCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/GetTimelineUISetupCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,27 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.GetTimelineUISetupResult;
+
+/**
+ * command to request all the initial information useful to set up a timeline
+ * component, including the list of timebands, their recommended units, etc.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetTimelineUISetupCommand implements Action<GetTimelineUISetupResult> {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 7813083800240239846L;
+
+	/**
+	 * public constructor
+	 */
+	public GetTimelineUISetupCommand() {
+
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/InstallJswordModuleCommand.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/InstallJswordModuleCommand.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/command/InstallJswordModuleCommand.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,45 @@
+package com.tyndalehouse.step.web.shared.command;
+
+import net.customware.gwt.dispatch.shared.Action;
+
+import com.tyndalehouse.step.web.shared.result.InstallJswordModuleResult;
+
+/**
+ * Requests the server (or local server) to install a bible version
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class InstallJswordModuleCommand implements Action<InstallJswordModuleResult> {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 3416377875572322721L;
+
+	/**
+	 * the initials to be used to check/install the book
+	 */
+	private String initials;
+
+	/**
+	 * the install jsword module command constructor
+	 */
+	public InstallJswordModuleCommand() {
+
+	}
+
+	/**
+	 * @return the initials of module to be installed
+	 */
+	public String getInitials() {
+		return initials;
+	}
+
+	/**
+	 * @param initials the initials of the module to set
+	 */
+	public void setInitials(final String initials) {
+		this.initials = initials;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocation.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocation.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocation.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,140 @@
+package com.tyndalehouse.step.web.shared.common.maps;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Serialisable POJO containing all the data pertaining to displaying the
+ * location on the screen
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GeoLocation implements Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -2429722523530262993L;
+
+	/**
+	 * description of the location
+	 */
+	private String description;
+
+	/**
+	 * value of the latitude
+	 */
+	private long latitude;
+
+	/**
+	 * List of lat longs
+	 */
+	private List<LatLong> latlongs;
+
+	/**
+	 * type of location, for e.g. a city, a memorial, a fountain, etc.
+	 */
+	private GeoLocationType locationType;
+
+	/**
+	 * value of the longitude
+	 */
+	private long longitude;
+
+	/**
+	 * Name of the place, for e.g. Golgotha
+	 */
+	private String placeName;
+
+	/**
+	 * default constructor
+	 */
+	public GeoLocation() {
+		latlongs = new ArrayList<LatLong>();
+	}
+
+	/**
+	 * @return the description
+	 */
+	public final String getDescription() {
+		return description;
+	}
+
+	/**
+	 * @return the latitude
+	 */
+	public final long getLatitude() {
+		return latitude;
+	}
+
+	/**
+	 * @return the latlongs
+	 */
+	public final List<LatLong> getLatlongs() {
+		return latlongs;
+	}
+
+	/**
+	 * @return the locationType
+	 */
+	public final GeoLocationType getLocationType() {
+		return locationType;
+	}
+
+	/**
+	 * @return the longitude
+	 */
+	public final long getLongitude() {
+		return longitude;
+	}
+
+	/**
+	 * @return the placeName
+	 */
+	public final String getPlaceName() {
+		return placeName;
+	}
+
+	/**
+	 * @param description the description to set
+	 */
+	public final void setDescription(final String description) {
+		this.description = description;
+	}
+
+	/**
+	 * @param latitude the latitude to set
+	 */
+	public final void setLatitude(final long latitude) {
+		this.latitude = latitude;
+	}
+
+	/**
+	 * @param latlongs the latlongs to set
+	 */
+	public final void setLatlongs(final List<LatLong> latlongs) {
+		this.latlongs = latlongs;
+	}
+
+	/**
+	 * @param locationType the locationType to set
+	 */
+	public final void setLocationType(final GeoLocationType locationType) {
+		this.locationType = locationType;
+	}
+
+	/**
+	 * @param longitude the longitude to set
+	 */
+	public final void setLongitude(final long longitude) {
+		this.longitude = longitude;
+	}
+
+	/**
+	 * @param placeName the placeName to set
+	 */
+	public final void setPlaceName(final String placeName) {
+		this.placeName = placeName;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocationType.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocationType.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/GeoLocationType.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,18 @@
+package com.tyndalehouse.step.web.shared.common.maps;
+
+/**
+ * Type of location, indicating whether the location is a city, a wall, a
+ * region, etc.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum GeoLocationType {
+	/** CITY */
+	CITY,
+	/** A FOUNTAIN */
+	FOUNTAIN,
+	/** A REGION */
+	REGION,
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/LatLong.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/LatLong.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/maps/LatLong.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,47 @@
+package com.tyndalehouse.step.web.shared.common.maps;
+
+/**
+ * LatLong POJO containg the latitude and longitude of a point on a map
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class LatLong {
+	/**
+	 * latitude of the point
+	 */
+	private long latitude;
+
+	/**
+	 * longitude of the point
+	 */
+	private long longitude;
+
+	/**
+	 * @return the latitude
+	 */
+	public final long getLatitude() {
+		return latitude;
+	}
+
+	/**
+	 * @return the longitude
+	 */
+	public final long getLongitude() {
+		return longitude;
+	}
+
+	/**
+	 * @param latitude the latitude to set
+	 */
+	public final void setLatitude(final long latitude) {
+		this.latitude = latitude;
+	}
+
+	/**
+	 * @param longitude the longitude to set
+	 */
+	public final void setLongitude(final long longitude) {
+		this.longitude = longitude;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/scripturelookup/BibleTextLookupType.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/scripturelookup/BibleTextLookupType.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/scripturelookup/BibleTextLookupType.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,20 @@
+package com.tyndalehouse.step.web.shared.common.scripturelookup;
+
+/**
+ * This enum indicates what kind of lookup is required from the server
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum BibleTextLookupType {
+	/** a classic interlinear is required */
+	CLASSIC_INTERLINEAR,
+	/** a logical form, POJO form of the text is required */
+	LOGICAL,
+	/** only the text is required */
+	PLAIN_TEXT,
+	/** a reverse interlinear is required */
+	REVERSE_INTERLINEAR,
+	/** the text, using a default xslt is required */
+	XSLT,
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimeBandVisibleDate.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimeBandVisibleDate.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimeBandVisibleDate.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,136 @@
+package com.tyndalehouse.step.web.shared.common.timeline;
+
+import java.io.Serializable;
+
+/**
+ * This object acts as a container of the current display window on an ether.
+ * timebandId identifies the timeband and is associated with a minimum and a
+ * maximum date which are generally used to request things off the database.
+ * 
+ * TODO: harmonize capital letters to be TimebandVisibleDate
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimeBandVisibleDate implements Serializable {
+
+	/**
+	 * default serial id
+	 */
+	private static final long serialVersionUID = -7384255321830177509L;
+
+	/**
+	 * max date visible on the timeband
+	 */
+	private long maxDate;
+
+	/**
+	 * min date visible on the time band
+	 */
+	private long minDate;
+
+	/**
+	 * true indicates no request is required on the server
+	 */
+	private boolean noRequest;
+
+	/**
+	 * time band id
+	 */
+	private int timebandId;
+
+	/**
+	 * so that
+	 * 
+	 * @param timebandId the timebandId referred to in the module
+	 * @param minDate minDate in the range of dates to ask the server
+	 * @param maxDate maxDate in the range of dates to the ask the server
+	 */
+	public TimeBandVisibleDate(final int timebandId, final long minDate, final long maxDate) {
+		this.timebandId = timebandId;
+		this.minDate = minDate;
+		this.maxDate = maxDate;
+		noRequest = false;
+	}
+
+	/**
+	 * removing default constructor from view of other callers. Only accessible
+	 * through reflection, and therefore GWT
+	 */
+	private TimeBandVisibleDate() {
+	}
+
+	/**
+	 * returns a TimeBandVisibleDate object tagged to indicate no request is
+	 * required on the server
+	 * 
+	 * @return a marked TimeBandVisibleDate object, marked with a flag saying no
+	 *         request is required
+	 */
+	public static TimeBandVisibleDate getNoRequest() {
+		final TimeBandVisibleDate tvd = new TimeBandVisibleDate();
+		tvd.setNoRequest(true);
+		return tvd;
+	}
+
+	/**
+	 * @return the maxDate
+	 */
+	public long getMaxDate() {
+		return maxDate;
+	}
+
+	/**
+	 * @return the minDate
+	 */
+	public long getMinDate() {
+		return minDate;
+	}
+
+	/**
+	 * @return the timebandId
+	 */
+	public int getTimebandId() {
+		return timebandId;
+	}
+
+	/**
+	 * NoRequest determines whether the values in here should be sent back.
+	 * Perhaps we've got everything we need already, so we don't need to send
+	 * anything back to the server
+	 * 
+	 * @return the noRequest
+	 */
+	public boolean isNoRequest() {
+		return noRequest;
+	}
+
+	/**
+	 * @param maxDate the maxDate to set
+	 */
+	public void setMaxDate(final long maxDate) {
+		this.maxDate = maxDate;
+	}
+
+	/**
+	 * @param minDate the minDate to set
+	 */
+	public void setMinDate(final long minDate) {
+		this.minDate = minDate;
+	}
+
+	/**
+	 * @param noRequest the noRequest to set
+	 */
+	public void setNoRequest(final boolean noRequest) {
+		this.noRequest = noRequest;
+	}
+
+	/**
+	 * @param timebandId the timebandId to set
+	 */
+	public void setTimebandId(final int timebandId) {
+		this.timebandId = timebandId;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineBean.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineBean.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineBean.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,130 @@
+package com.tyndalehouse.step.web.shared.common.timeline;
+
+import java.io.Serializable;
+
+/**
+ * Timeline bean represents the different timelines on which events can be
+ * found... TODO: should this be renamed timeband?
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TimelineBean implements Serializable {
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -1734142151232501392L;
+
+	/**
+	 * Timeline description from the server layer
+	 */
+	private String timelineDescription;
+
+	/**
+	 * timeline id sent across the wire
+	 */
+	private int timelineId;
+
+	/**
+	 * unit to be used when first display the timeband
+	 */
+	private String unit;
+
+	/**
+	 * default constructor made public
+	 */
+	public TimelineBean() {
+
+	}
+
+	/**
+	 * @return the timelineDescription
+	 */
+	public String getTimelineDescription() {
+		return timelineDescription;
+	}
+
+	/**
+	 * @return the timelineId
+	 */
+	public int getTimelineId() {
+		return timelineId;
+	}
+
+	/**
+	 * @return the unit
+	 */
+	public String getUnit() {
+		return unit;
+	}
+
+	/**
+	 * @param timelineDescription the timelineDescription to set
+	 */
+	public void setTimelineDescription(final String timelineDescription) {
+		this.timelineDescription = timelineDescription;
+	}
+
+	/**
+	 * @param timelineId the timelineId to set
+	 */
+	public void setTimelineId(final int timelineId) {
+		this.timelineId = timelineId;
+	}
+
+	/**
+	 * sets the unit field
+	 * 
+	 * @param unit the unit to be set
+	 */
+	public void setUnit(final String unit) {
+		this.unit = unit;
+
+	}
+
+	// /**
+	// * @return the minDate
+	// */
+	// public long getMinDate() {
+	// return minDate;
+	// }
+	//
+	// /**
+	// * @param minDate the minDate to set
+	// */
+	// public void setMinDate(long minDate) {
+	// this.minDate = minDate;
+	// }
+	//
+	// /**
+	// * @return the maxDate
+	// */
+	// public long getMaxDate() {
+	// return maxDate;
+	// }
+	//
+	// /**
+	// * @param maxDate the maxDate to set
+	// */
+	// public void setMaxDate(long maxDate) {
+	// this.maxDate = maxDate;
+	// }
+
+	// /**
+	// * @return the timelineCode
+	// */
+	// public String getTimelineCode() {
+	// return timelineCode;
+	// }
+	//
+	// public void setEventCount(int eventCount) {
+	// this.eventCount = eventCount;
+	// }
+	//
+	// /**
+	// * @return the eventCount
+	// */
+	// public int getEventCount() {
+	// return eventCount;
+	// }
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineEventBean.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineEventBean.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/common/timeline/TimelineEventBean.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,235 @@
+package com.tyndalehouse.step.web.shared.common.timeline;
+
+import java.io.Serializable;
+
+/**
+ * An Time Event bean, containing all the relevant fields passed from the server
+ * to the client. For e.g. the description of the event, its id, the dates, etc.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TimelineEventBean implements Serializable {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -7664806988001700477L;
+
+	/**
+	 * The certainty of dating, as provided in input CSV files
+	 */
+	private String certainty;
+
+	/**
+	 * the event id
+	 */
+	private int eventId;
+
+	/**
+	 * the type of the event, where we distinguish battles, from births, etc.
+	 * (TODO: still to be done)
+	 */
+	private int eventTypeId;
+
+	/**
+	 * the from date
+	 */
+	private Long fromDate;
+
+	/**
+	 * how precise the date is, whether to the day, month, etc. see schema
+	 * definition for details
+	 */
+	private String fromPrecision;
+
+	/**
+	 * Name/Description of the event
+	 */
+	private String name;
+
+	/**
+	 * The timeband/timeline on which the event should be displayed
+	 */
+	private int timelineId;
+
+	/**
+	 * the to-date in the case of a duration
+	 */
+	private Long toDate;
+
+	/**
+	 * the precision of the "to-date", whether to the day, month, etc. see
+	 * schema definition for details
+	 */
+	private String toPrecision;
+
+	/**
+	 * making public
+	 */
+	public TimelineEventBean() {
+
+	}
+
+	/**
+	 * a constructor to set up everything in one go
+	 * 
+	 * @param eventId the event id from the database
+	 * @param fromDate the from date, at which the event starts/is
+	 * @param toDate the to date, if the date is a duratio
+	 * @param fromPrecision how precise the from date is (see schema for more
+	 *            details)
+	 * @param toPrecision how precise the to date is (see schema for more
+	 *            details)
+	 * @param name the description of the event
+	 * @param timelineId the timeband on which to be located
+	 * @param importanceId the importance id as defined in the input files
+	 * @param certainty the certainty as defined in the input files
+	 * @param eventTypeId the event type, describing different types, and
+	 *            therefore different representations of the event on the UI
+	 * 
+	 */
+	// CHECKSTYLE:OFF
+	public TimelineEventBean(final int eventId, final Long fromDate, final Long toDate,
+			final String fromPrecision, final String toPrecision, final String name, final int timelineId,
+			final int importanceId, final String certainty, final int eventTypeId) {
+		// CHECKSTYLE:ON
+		this.eventId = eventId;
+		this.fromDate = fromDate;
+		this.toDate = toDate;
+		this.fromPrecision = fromPrecision;
+		this.toPrecision = toPrecision;
+		this.timelineId = timelineId;
+		this.certainty = certainty;
+		this.eventTypeId = eventTypeId;
+		this.name = name;
+	}
+
+	/**
+	 * @return the certainty
+	 */
+	public String getCertainty() {
+		return certainty;
+	}
+
+	/**
+	 * @return the eventId
+	 */
+	public int getEventId() {
+		return eventId;
+	}
+
+	/**
+	 * @return the eventTypeId
+	 */
+	public int getEventTypeId() {
+		return eventTypeId;
+	}
+
+	/**
+	 * @return the fromDate
+	 */
+	public Long getFromDate() {
+		return fromDate;
+	}
+
+	/**
+	 * @return the fromPrecision
+	 */
+	public String getFromPrecision() {
+		return fromPrecision;
+	}
+
+	/**
+	 * returns the name/description of the event
+	 * 
+	 * @return the description of the event
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return the timelineId
+	 */
+	public int getTimelineId() {
+		return timelineId;
+	}
+
+	/**
+	 * @return the toDate
+	 */
+	public Long getToDate() {
+		return toDate;
+	}
+
+	/**
+	 * @return the toPrecision
+	 */
+	public String getToPrecision() {
+		return toPrecision;
+	}
+
+	/**
+	 * @param certainty the certainty to set
+	 */
+	public void setCertainty(final String certainty) {
+		this.certainty = certainty;
+	}
+
+	/**
+	 * @param eventId the eventId to set
+	 */
+	public void setEventId(final int eventId) {
+		this.eventId = eventId;
+	}
+
+	/**
+	 * @param eventTypeId the eventTypeId to set
+	 */
+	public void setEventTypeId(final int eventTypeId) {
+		this.eventTypeId = eventTypeId;
+	}
+
+	/**
+	 * @param fromDate the fromDate to set
+	 */
+	public void setFromDate(final Long fromDate) {
+		this.fromDate = fromDate;
+	}
+
+	/**
+	 * @param fromPrecision the fromPrecision to set
+	 */
+	public void setFromPrecision(final String fromPrecision) {
+		this.fromPrecision = fromPrecision;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	public void setName(final String name) {
+		this.name = name;
+	}
+
+	/**
+	 * @param timelineId the timelineId to set
+	 */
+	public void setTimelineId(final int timelineId) {
+		this.timelineId = timelineId;
+	}
+
+	/**
+	 * @param toDate the toDate to set
+	 */
+	public void setToDate(final Long toDate) {
+		this.toDate = toDate;
+	}
+
+	/**
+	 * @param toPrecision the toPrecision to set
+	 */
+	public void setToPrecision(final String toPrecision) {
+		this.toPrecision = toPrecision;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetAvailableBibleVersionsResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetAvailableBibleVersionsResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetAvailableBibleVersionsResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,54 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import java.util.Collections;
+import java.util.SortedMap;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+/**
+ * This is in response to a @see
+ * {@link com.tyndalehouse.step.web.share.command.GetAvailableBibleVersionsCommand}
+ * In essence, this contains a sorted map of books to be displayed on the UI.
+ * The intials are the key into JSword and should be used at all times when sent
+ * back to the server.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class GetAvailableBibleVersionsResult implements Result {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 1441380470741483969L;
+
+	/**
+	 * a map keyed from the initials (link into JSword) to the name of the book
+	 */
+	private SortedMap<String, String> books;
+
+	/**
+	 * constructor passing in the map of available bible versions
+	 * 
+	 * @param map map containing combinations of (key, book name)
+	 */
+	public GetAvailableBibleVersionsResult(final SortedMap<String, String> map) {
+		this.books = map;
+	}
+
+	/**
+	 * used for reflection
+	 */
+	@SuppressWarnings("unused")
+	private GetAvailableBibleVersionsResult() {
+
+	}
+
+	/**
+	 * the map of available books
+	 * 
+	 * @return the map of available books
+	 */
+	public SortedMap<String, String> getBooks() {
+		return Collections.unmodifiableSortedMap(books);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetBibleBooksCommandResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetBibleBooksCommandResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetBibleBooksCommandResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,52 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+/**
+ * Result from the GetBibleBooksCommand which contains the list of books
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetBibleBooksCommandResult implements Result {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -26170538247007172L;
+
+	/**
+	 * the list of books
+	 */
+	private List<String> books;
+
+	/**
+	 * the list of bible books provided to the constructor
+	 * 
+	 * @param books the list of books
+	 */
+	public GetBibleBooksCommandResult(final List<String> books) {
+		this.books = books;
+	}
+
+	/**
+	 * this constructor is used for reflection and must be present
+	 */
+	@SuppressWarnings("unused")
+	private GetBibleBooksCommandResult() {
+
+	}
+
+	/**
+	 * returns a list of books
+	 * 
+	 * @return the list of books
+	 */
+	public Collection<String> getBooks() {
+		return Collections.unmodifiableList(books);
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetCurrentBibleTextResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetCurrentBibleTextResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetCurrentBibleTextResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,83 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.tyndalehouse.step.web.shared.scripture.Passage;
+
+/**
+ * Result from a command, representing a biblical text
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetCurrentBibleTextResult implements Result {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -5781394877510591218L;
+
+	/**
+	 * the passage in logical form
+	 */
+	private Passage passage;
+
+	/**
+	 * the passage text
+	 */
+	private String passageText;
+
+	/**
+	 * The xslted text
+	 */
+	private String xsltedText;
+
+	/**
+	 * returns the logical form passage
+	 * 
+	 * @return the logical form of the passage
+	 */
+	public Passage getPassage() {
+		return passage;
+	}
+
+	/**
+	 * returns the passage text
+	 * 
+	 * @return the passage text
+	 */
+	public String getPassageText() {
+		return passageText;
+	}
+
+	/**
+	 * @return the xsltedText
+	 */
+	public String getXsltedText() {
+		return xsltedText;
+	}
+
+	/**
+	 * sets the logical form of the passage
+	 * 
+	 * @param p passage
+	 */
+	public void setPassage(final Passage p) {
+		this.passage = p;
+	}
+
+	/**
+	 * @param passageText the passageText to set
+	 */
+	public void setPassageText(final String passageText) {
+		this.passageText = passageText;
+	}
+
+	/**
+	 * @param xsltedText the xsltedText to set
+	 */
+	public void setXsltedText(final String xsltedText) {
+		this.xsltedText = xsltedText;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetDictionaryDefinitionResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetDictionaryDefinitionResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetDictionaryDefinitionResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,53 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+/**
+ * The dictionary definition that was looked up from the
+ * GetDictionaryDefinitionCommand
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetDictionaryDefinitionResult implements Result {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 3121326970467885008L;
+
+	/**
+	 * the xslted definition of the definition that was looked up
+	 */
+	private String xsltedDefinition;
+
+	/**
+	 * Default constructor
+	 */
+	public GetDictionaryDefinitionResult() {
+
+	}
+
+	/**
+	 * @return the xsltedDefinition
+	 */
+	public String getXsltedDefinition() {
+		return xsltedDefinition;
+	}
+
+	/**
+	 * sets the definition
+	 * 
+	 * @param xsltedDefinition the definition to be set
+	 */
+	public void setDefinition(final String xsltedDefinition) {
+		this.xsltedDefinition = xsltedDefinition;
+	}
+
+	/**
+	 * @param xsltedDefinition the xsltedDefinition to set
+	 */
+	public void setXsltedDefinition(final String xsltedDefinition) {
+		this.xsltedDefinition = xsltedDefinition;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetEventsForDateRangeResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetEventsForDateRangeResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetEventsForDateRangeResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,56 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineEventBean;
+
+/**
+ * Result containing all events requested within a particular date range.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetEventsForDateRangeResult implements Result {
+
+	/**
+	 * default serial id
+	 */
+	private static final long serialVersionUID = 7118668612721569823L;
+
+	/** list of events */
+	private List<TimelineEventBean> events = new ArrayList<TimelineEventBean>();
+
+	/**
+	 * public constructor
+	 */
+	public GetEventsForDateRangeResult() {
+
+	}
+
+	/**
+	 * Adds a new Event in Tim to the response
+	 * 
+	 * @param teb the event to add to the response
+	 */
+	public void add(final TimelineEventBean teb) {
+		getEvents().add(teb);
+
+	}
+
+	/**
+	 * @return a list of events within a specified date range
+	 */
+	public List<TimelineEventBean> getEvents() {
+		return events;
+	}
+
+	/**
+	 * @param events the events to set
+	 */
+	public void setEvents(final List<TimelineEventBean> events) {
+		this.events = events;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetLocationsResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetLocationsResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetLocationsResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,50 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.tyndalehouse.step.web.shared.common.maps.GeoLocation;
+
+/**
+ * This object contains the result from a geographical location, containing
+ * enough data to display a marker on the screen, and a hover over.
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetLocationsResult implements Result {
+
+	/**
+	 * serial id for serialisation
+	 */
+	private static final long serialVersionUID = 1516648078862839012L;
+
+	/**
+	 * list of locations
+	 */
+	private List<GeoLocation> locations;
+
+	/**
+	 * default constructor
+	 */
+	public GetLocationsResult() {
+		locations = new ArrayList<GeoLocation>();
+	}
+
+	/**
+	 * @return the locations
+	 */
+	public final List<GeoLocation> getLocations() {
+		return locations;
+	}
+
+	/**
+	 * @param locations the locations to set
+	 */
+	public final void setLocations(final List<GeoLocation> locations) {
+		this.locations = locations;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineOriginForScriptureResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineOriginForScriptureResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineOriginForScriptureResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,131 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.tyndalehouse.step.web.shared.timeline.Unit;
+
+/**
+ * Result from querying the server for the best event to use as the origin of
+ * the timeline. This event is the one that best suits the verse range provided
+ * by the user
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class GetTimelineOriginForScriptureResult implements Result {
+	/**
+	 * generated serial version id
+	 */
+	private static final long serialVersionUID = 4256230588330550554L;
+
+	/**
+	 * whether no data was returned, because no events matched the biblical
+	 * reference
+	 */
+	private boolean isEmpty;
+
+	/**
+	 * the date of the recommended
+	 */
+	private Long originDate;
+
+	/**
+	 * the suggested timescale the UI should use
+	 */
+	private Unit suggestedTimeScale;
+
+	/**
+	 * the timeband id on which this date should be used
+	 */
+	private int timebandId;
+
+	/**
+	 * public constructor for this result object
+	 * 
+	 * @param isEmpty true if no data was found
+	 */
+	public GetTimelineOriginForScriptureResult(final boolean isEmpty) {
+		this.isEmpty = isEmpty;
+	}
+
+	/**
+	 * another constructor to provide the correct origin information, including
+	 * 
+	 * @param originDate the date at which the timeline should be positioned
+	 * @param unit the unit that should be used for this timeband
+	 * @param timebandId the timeband id
+	 */
+	public GetTimelineOriginForScriptureResult(final Long originDate, final Unit unit, final int timebandId) {
+		this.originDate = originDate;
+		this.suggestedTimeScale = unit;
+		this.timebandId = timebandId;
+		isEmpty = false;
+	}
+
+	/**
+	 * private constructor, used by GWT serialisation
+	 */
+	@SuppressWarnings("unused")
+	private GetTimelineOriginForScriptureResult() {
+
+	}
+
+	/**
+	 * @return the originDate
+	 */
+	public Long getOriginDate() {
+		return originDate;
+	}
+
+	/**
+	 * @return the suggestedTimeScale
+	 */
+	public Unit getSuggestedTimeScale() {
+		return suggestedTimeScale;
+	}
+
+	/**
+	 * gets the timeband id
+	 * 
+	 * @return timebandId
+	 */
+	public int getTimebandId() {
+		return timebandId;
+	}
+
+	/**
+	 * @return the isEmpty
+	 */
+	public boolean isEmpty() {
+		return isEmpty;
+	}
+
+	/**
+	 * @param isEmpty the isEmpty to set
+	 */
+	public void setEmpty(final boolean isEmpty) {
+		this.isEmpty = isEmpty;
+	}
+
+	/**
+	 * @param originDate the originDate to set
+	 */
+	public void setOriginDate(final Long originDate) {
+		this.originDate = originDate;
+	}
+
+	/**
+	 * @param unit the suggestedTimeScale to set
+	 */
+	public void setSuggestedTimeScale(final Unit unit) {
+		this.suggestedTimeScale = unit;
+	}
+
+	/**
+	 * @param timebandId the timebandId to set
+	 */
+	public void setTimebandId(final int timebandId) {
+		this.timebandId = timebandId;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineUISetupResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineUISetupResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/GetTimelineUISetupResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,53 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import java.util.List;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineBean;
+
+/**
+ * Response from a @see
+ * {@link com.tyndalehouse.step.web.shared.command.GetTimelineUISetupCommand}
+ * This contains details on how to set up each timeband, their units, etc.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class GetTimelineUISetupResult implements Result {
+
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -566447989637280143L;
+
+	/**
+	 * A list of timebands
+	 */
+	private List<TimelineBean> tlb;
+
+	/**
+	 * Default constructor made public
+	 */
+	public GetTimelineUISetupResult() {
+
+	}
+
+	/**
+	 * returns a list of timebands
+	 * 
+	 * @return a list of timeband beans
+	 */
+	public List<TimelineBean> getTimelines() {
+		return tlb;
+	}
+
+	/**
+	 * sets the list. made available for reflection
+	 * 
+	 * @param tlb the list of timeline beans
+	 */
+	public void setTimelines(final List<TimelineBean> tlb) {
+		this.tlb = tlb;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/InstallJswordModuleResult.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/InstallJswordModuleResult.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/result/InstallJswordModuleResult.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,54 @@
+package com.tyndalehouse.step.web.shared.result;
+
+import net.customware.gwt.dispatch.shared.Result;
+
+/**
+ * Response from a @see
+ * {@link com.tyndalehouse.step.web.shared.command.InstallJswordModuleCommand}
+ * indicating whether the installation was succesful
+ * 
+ * @author cjburrell
+ * 
+ */
+public class InstallJswordModuleResult implements Result {
+	/**
+	 * generated serial id
+	 */
+	private static final long serialVersionUID = -5063510082176727310L;
+
+	/**
+	 * true if installation was successful
+	 */
+	private boolean successful;
+
+	/**
+	 * Default constructor made public
+	 */
+	public InstallJswordModuleResult() {
+
+	}
+
+	/**
+	 * Constructor with the success flag passed in
+	 * 
+	 * @param successful true to indicate success
+	 */
+	public InstallJswordModuleResult(final boolean successful) {
+		this.successful = successful;
+
+	}
+
+	/**
+	 * @return the successful
+	 */
+	public boolean isSuccessful() {
+		return successful;
+	}
+
+	/**
+	 * @param successful the successful to set
+	 */
+	public void setSuccessful(final boolean successful) {
+		this.successful = successful;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Milestone.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Milestone.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Milestone.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,61 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+
+/**
+ * A marker in the OSIS xml to indicate a break in the normal flow of text.
+ * Usually editors layouts, I believe.
+ * 
+ * @author cjburrell
+ * 
+ */
+public class Milestone extends Text implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 6444472622836494795L;
+
+	/**
+	 * optional marker
+	 */
+	private String marker;
+
+	/**
+	 * Type of milestone, see OSIS details for clarifications
+	 */
+	private String type;
+
+	/**
+	 * Default constructor made public
+	 */
+	public Milestone() {
+	}
+
+	/**
+	 * @return the marker
+	 */
+	public String getMarker() {
+		return marker;
+	}
+
+	/**
+	 * @return the type
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * @param marker the marker to set
+	 */
+	public void setMarker(final String marker) {
+		this.marker = marker;
+	}
+
+	/**
+	 * @param type the type to set
+	 */
+	public void setType(final String type) {
+		this.type = type;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Note.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Note.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Note.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,42 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+
+/**
+ * A logical representation of some OSIS xml. This bean is serialised and passed
+ * over the wire
+ * 
+ * @author cjburrell
+ * 
+ */
+public class Note extends Text implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 4592986819523938392L;
+
+	/**
+	 * The type of note
+	 */
+	private String type;
+
+	/**
+	 * Default constructor made public
+	 */
+	public Note() {
+	}
+
+	/**
+	 * @return the type
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * @param type the type to set
+	 */
+	public void setType(final String type) {
+		this.type = type;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/OSISConstants.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/OSISConstants.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/OSISConstants.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,43 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+/**
+ * Some constants not defined in JSword
+ * 
+ * @author cjburrell
+ * 
+ */
+public final class OSISConstants {
+	/**
+	 * A marker in the text, for formatting purposes: TODO: check this and the
+	 * other two with online people
+	 */
+	public static final String MARKER = "marker";
+
+	/**
+	 * A milestone, between two portions of scripture
+	 */
+	public static final String MILESTONE = "milestone";
+
+	/**
+	 * A decision by the translator to make a change?
+	 */
+	public static final String TRANS_CHANGE = "transChange";
+
+	// public static final String LEMMA = "lemma";
+	// public static final String MORPH = "morph";
+	// public static final Object NOTE = "note";
+	// public static final String OSISID = "osisID";
+	// public static final String TITLE = "title";
+
+	// public static final String TYPE = "type";
+	// public static final String VERSE = "verse";
+	// public static final String WORD = "w";
+
+	/**
+	 * Making the constructor private
+	 */
+	private OSISConstants() {
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Passage.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,74 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Logical form of a passage
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class Passage implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -3926440372519158967L;
+
+	/**
+	 * List of verses/title throughout the passage
+	 */
+	private List<VerseContent> verseContent;
+
+	/**
+	 * making the constructor public and initialising list
+	 */
+	public Passage() {
+		verseContent = new ArrayList<VerseContent>();
+	}
+
+	/**
+	 * Adding a passage element, such as a {@link Verse} or a {@link Title}
+	 * 
+	 * @param vc a verse or a title
+	 */
+	public void addPassageElement(final VerseContent vc) {
+		verseContent.add(vc);
+	}
+
+	/**
+	 * returns the text representation of a passage. This is NOT performance
+	 * optimized and therefore should not be used more than once.
+	 * Non-optimization is due to the fact that we won't to reduce traffic over
+	 * the wire
+	 * 
+	 *TODO: this could be further optimized by not relying on strings in
+	 * versecontent being returned as strings
+	 * 
+	 * @return the passage in a string form.
+	 */
+	public String getText() {
+		final StringBuffer text = new StringBuffer(1024);
+		for (final VerseContent vc : verseContent) {
+			if (!(vc instanceof Title)) {
+				text.append(vc.getText());
+			}
+		}
+		return text.toString();
+	}
+
+	/**
+	 * @return the verseContent list of a combination of verses and titles
+	 */
+	public List<VerseContent> getVerseContent() {
+		return verseContent;
+	}
+
+	/**
+	 * @param verseContent the verseContent to set
+	 */
+	public void setVerseContent(final List<VerseContent> verseContent) {
+		this.verseContent = verseContent;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Text.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Text.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Text.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,51 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+
+/**
+ * The Text class, a wrapper for String
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class Text implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -7068301858306124428L;
+
+	/**
+	 * the string representing the portion of scripture for each OSIS element
+	 */
+	private String text;
+
+	/**
+	 * A simple text, default constructor made public
+	 */
+	public Text() {
+	}
+
+	/**
+	 * Initialising a text with a String
+	 * 
+	 * @param text text is the string representation of the #text element
+	 */
+	public Text(final String text) {
+		this.text = text;
+	}
+
+	/**
+	 * @return the text
+	 */
+	public String getText() {
+		return text;
+	}
+
+	/**
+	 * @param text the text to set
+	 */
+	public void setText(final String text) {
+		this.text = text;
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TextualElement.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TextualElement.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TextualElement.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,18 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+/**
+ * Interface being applied to anything that can contains text (directly or
+ * indirectly)
+ * 
+ * @author CJBurrell
+ * 
+ */
+public interface TextualElement {
+
+	/**
+	 * returns the text
+	 * 
+	 * @return text to be returned
+	 */
+	String getText();
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Title.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Title.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Title.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,43 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+/**
+ * Title element in the OSIS as a POJO
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class Title extends Text implements VerseContent {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -4362500737203594954L;
+
+	/**
+	 * Type of title as defined in OSIS spec
+	 */
+	private String type;
+
+	/**
+	 * Making default constructor public
+	 */
+	public Title() {
+	}
+
+	/**
+	 * @return the type
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * type of title
+	 * 
+	 * @param type title
+	 */
+	public void setType(final String type) {
+		this.type = type;
+
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TransChange.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TransChange.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/TransChange.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,41 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+
+/**
+ * TODO: check OSIS details and update documentation
+ * 
+ * @author cjburrell
+ * 
+ */
+public class TransChange extends Text implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = 4557607388014222750L;
+
+	/**
+	 * Type of trans change
+	 */
+	private String type;
+
+	/**
+	 * Default constructor made public
+	 */
+	public TransChange() {
+	}
+
+	/**
+	 * @return the type
+	 */
+	public String getType() {
+		return type;
+	}
+
+	/**
+	 * @param type the type to set
+	 */
+	public void setType(final String type) {
+		this.type = type;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Verse.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Verse.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Verse.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,92 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Logical representation of a verse from the OSIS
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class Verse implements VerseContent, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -7000973434382091156L;
+
+	/**
+	 * the OSIS key, for e.g. gen 1:1
+	 */
+	private String osisID;
+
+	/**
+	 * list of textual elements that are contained in this verse
+	 */
+	private List<TextualElement> verseContent;
+
+	/**
+	 * public constructor to create a logical form of a verse
+	 */
+	public Verse() {
+		verseContent = new ArrayList<TextualElement>();
+	}
+
+	/**
+	 * adds a textual element to the verse
+	 * 
+	 * @param te textual element
+	 */
+	public void addTextualElement(final TextualElement te) {
+		this.verseContent.add(te);
+	}
+
+	/**
+	 * @return the osisID
+	 */
+	public String getOsisID() {
+		return osisID;
+	}
+
+	/**
+	 * This method is not optimized for performance. It iterates through the
+	 * list each time it is required. The reason it is not optimized, is that it
+	 * should not be used except to display the text once.
+	 * 
+	 * Not storing the result of the concatenation enables us to have shorted
+	 * messages going across the wire
+	 * 
+	 * @return the concatenated text
+	 */
+	public String getText() {
+		final StringBuilder sb = new StringBuilder(128);
+		for (final TextualElement te : verseContent) {
+			if (!(te instanceof Note)) {
+				sb.append(te.getText());
+			}
+		}
+		return sb.toString();
+	}
+
+	/**
+	 * @return the text
+	 */
+	public List<TextualElement> getVerseContent() {
+		return verseContent;
+	}
+
+	/**
+	 * @param osisID the osisID to set
+	 */
+	public void setOsisID(final String osisID) {
+		this.osisID = osisID;
+	}
+
+	/**
+	 * @param text the text to set
+	 */
+	public void setVerseContent(final List<TextualElement> text) {
+		this.verseContent = text;
+	}
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/VerseContent.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/VerseContent.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/VerseContent.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,12 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+/**
+ * This interfaces marks a verse or a title which are direct children of a
+ * passage
+ * 
+ * @author CJBurrell
+ * 
+ */
+public interface VerseContent extends TextualElement {
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Word.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Word.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/scripture/Word.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,137 @@
+package com.tyndalehouse.step.web.shared.scripture;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A Word is a portion of a verse from the Bible. It can be several words or
+ * just one. In some versions it is associated with a list of lemmas (strong
+ * numbers which link to the Strong Hebrew or Greek Dictionary), as well as a
+ * morphological code (morph) which is a coded form of the morphology of the
+ * word/set of words (i.e. grammar form and usage in the sentence)
+ * 
+ * @author cjburrell
+ * 
+ */
+public class Word extends Text implements TextualElement, Serializable {
+	/**
+	 * serial id
+	 */
+	private static final long serialVersionUID = -5750252359953024623L;
+
+	/**
+	 * An alternative word, such as a different language
+	 */
+	private String alternativeWord;
+
+	// TODO: FIX: this is a bug, we can have several lemmas or morphologies for
+	// one translated word
+	/**
+	 * a list of lemmas referring to a portion of text
+	 */
+	private List<String> lemma;
+
+	/**
+	 * A list of morphs referring to a portion of text. A morph is a coded
+	 * string indicating the grammar and form of the original word
+	 */
+	private List<String> morph;
+
+	/**
+	 * default constructor initialises internal lists
+	 */
+	public Word() {
+		lemma = new ArrayList<String>();
+		morph = new ArrayList<String>();
+	}
+
+	/**
+	 * Adds a new lemma to the Word
+	 * 
+	 * @param newLemma the lemma to set
+	 */
+	public void addLemma(final String newLemma) {
+		lemma.add(newLemma);
+	}
+
+	/**
+	 * Adds an array of lemmas to the Word
+	 * 
+	 * @param lemmas a list of lemmas
+	 */
+	public void addLemmas(final String[] lemmas) {
+		for (final String l : lemmas) {
+			this.lemma.add(l);
+		}
+	}
+
+	/**
+	 * Adds an array of morphs to the Word
+	 * 
+	 * @param morphs array of morphs to be associated with the Word (portion of
+	 *            a verse)
+	 */
+	public void addMorphs(final String[] morphs) {
+		for (final String m : morphs) {
+			this.morph.add(m);
+		}
+
+	}
+
+	/**
+	 * @return the alternativeWord
+	 */
+	public String getAlternativeWord() {
+		return alternativeWord;
+	}
+
+	/**
+	 * @return the lemma
+	 */
+	public List<String> getLemma() {
+		return lemma;
+	}
+
+	/**
+	 * @return the morph
+	 */
+	public List<String> getMorph() {
+		return morph;
+	}
+
+	/**
+	 * sets an alternative word (such as a hebrew original word)
+	 * 
+	 * @param alternativeWord a word equivalent, different language. For e.g.
+	 *            Hebrew word
+	 * 
+	 */
+	public void setAlternativeWord(final String alternativeWord) {
+		this.alternativeWord = alternativeWord;
+	}
+
+	/**
+	 * @param lemma the lemma to set
+	 */
+	public void setLemma(final List<String> lemma) {
+		this.lemma = lemma;
+	}
+
+	/**
+	 * @param morph the morph to set
+	 */
+	public void setMorph(final List<String> morph) {
+		this.morph = morph;
+	}
+
+	/**
+	 * Adding a morph to the Word
+	 * 
+	 * @param newMorph the morph to set
+	 */
+	public void setMorph(final String newMorph) {
+		morph.add(newMorph);
+	}
+
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/timeline/Unit.java
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/timeline/Unit.java	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/shared/timeline/Unit.java	2010-04-14 22:11:51 UTC (rev 120)
@@ -0,0 +1,100 @@
+package com.tyndalehouse.step.web.shared.timeline;
+
+/**
+ * Unit as used both on the server and on the ui This makes the correspondance
+ * between dates in milliseconds and their actual real dates
+ * 
+ * @author CJBurrell
+ * 
+ */
+public enum Unit {
+	/**
+	 * century
+	 */
+	CENTURY(10L * 10L * 365L * 24 * 3600 * 1000L, "yyyy G"),
+	/**
+	 * day
+	 */
+	DAY(24L * 3600L * 1000L, "dd MMM yyyy G"),
+	/**
+	 * decade
+	 */
+	DECADE(10L * 365L * 24 * 3600 * 1000L, "yyyy G"),
+	/**
+	 * hour
+	 */
+	HOUR(3600L * 1000L),
+	/**
+	 * 1000 years
+	 */
+	MILLENIUM(10L * 10L * 10L * 365L * 24 * 3600 * 1000L, "yyyy G"),
+	/**
+	 * a minute
+	 */
+	MINUTE(60L * 1000L),
+	/**
+	 * a month
+	 */
+	// CHECKSTYLE:OFF
+	MONTH((365L * 24L * 3600L * 1000L) / 12, "MMM yyyy G"),
+	// CHECKSTYLE:ON
+	/**
+	 * a second
+	 */
+	SECOND(1000L),
+	/**
+	 * a week
+	 * 
+	 */
+	WEEK(7L * 24L * 3600L * 1000L, "dd MMM yyyy G"),
+	/**
+	 * a year
+	 */
+	YEAR(365L * 24 * 3600 * 1000L, "yyyy G");
+
+	/**
+	 * format to be applied when displaying
+	 */
+	private final String format;
+	/**
+	 * length of unit in milliseconds
+	 */
+	private final long milliseconds;
+
+	/**
+	 * constructor to create a unit, with a default format of dd MMM YYYY G
+	 * 
+	 * @param milliseconds length of unit in milliseconds
+	 */
+	Unit(final long milliseconds) {
+		this(milliseconds, "dd MMM YYYY G");
+	}
+
+	/**
+	 * creates a unit enum
+	 * 
+	 * @param milliseconds length of unit in milliseconds
+	 * @param format format to be applied if different to default one of dd MMM
+	 *            YYYY G
+	 */
+	Unit(final long milliseconds, final String format) {
+		this.format = format;
+		this.milliseconds = milliseconds;
+	}
+
+	/**
+	 * returns the format to be used for the unit
+	 * 
+	 * @return the format format
+	 */
+	public String getFormat() {
+		return format;
+	}
+
+	/**
+	 * @return the value In Milliseconds of the length of the unit
+	 */
+	public long getMilliseconds() {
+		return milliseconds;
+	}
+}



From ChrisBurrell at crosswire.org  Wed Apr 14 15:14:14 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 22:14:14 -0000
Subject: [Tynstep-svn] r121 - in
	trunk/step-web-app/src/main/java/com/tyndalehouse/step/web: .
	public public/css public/gwtext public/gwtext/css public/step
	public/step/images
Message-ID: <E1O2Aqc-0003xw-IX@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:14:14 -0700 (Wed, 14 Apr 2010)
New Revision: 121

Added:
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/Step.html
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/css/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/css/step.css
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-all.css
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-gray.css
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/blue-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-arrow.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left-arrow.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right-arrow.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-arrow.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/close-button.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright-vertical.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-blue-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-green-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-red-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-blue-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-green-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-red-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/gray-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/green-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-left.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-right.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/progress-running.gif
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/red-circle.png
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/top-bubble.png
Log:
committing resources from gwt java folder

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/Step.html
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/Step.html	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/Step.html	2010-04-14 22:14:14 UTC (rev 121)
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<!-- The HTML 4.01 Transitional DOCTYPE declaration-->
+<!-- above set at the top of the file will set     -->
+<!-- the browser's rendering engine into           -->
+<!-- "Quirks Mode". Replacing this declaration     -->
+<!-- with a "Standards Mode" doctype is supported, -->
+<!-- but may lead to some differences in layout.   -->
+
+<html>
+  <head>
+    <!-- TODO: Wonder if we need to set this to unicode -->
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+        
+    <!--                                           -->
+    <!-- Any title is fine                         -->
+    <!--                                           -->
+    <title>STEP :: Scripture Tools for Every Pastor</title>
+    
+    <!--                                           -->
+    <!-- This script loads your compiled module.   -->
+    <!-- If you add any GWT meta tags, they must   -->
+    <!-- be added before this line.                -->
+    <!--                                           -->
+    <script type="text/javascript" language="javascript" src="step.nocache.js"></script>
+
+    <!--                                                               -->
+    <!-- Consider inlining CSS to reduce the number of requested files -->
+	<link rel="stylesheet" href="css/step.css" />
+
+  </head>
+
+  <!--                                           -->
+  <!-- The body can have arbitrary html, or      -->
+  <!-- you can leave the body empty if you want  -->
+  <!-- to create a completely dynamic UI.        -->
+  <!--                                           -->
+  <body>
+
+    <!-- OPTIONAL: include this if you want history support -->
+    <iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
+
+	<div id="main_panel"></div>
+
+  </body>
+</html>

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/css/step.css
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/css/step.css	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/css/step.css	2010-04-14 22:14:14 UTC (rev 121)
@@ -0,0 +1,161 @@
+.bibleVersionsDropDown {
+	width: 250px;
+}
+
+.scripture-interlinear {
+	display: inline;
+	float: left;
+	padding: 0 0.5em 0.5em 0;
+}
+
+/****************************************************************************
+* Scripture display component
+*****************************************************************************/
+.scripture-emphasise {
+	font-weight: bold;	
+}
+
+
+/****************************************************************************
+ * TIMELINE WIDGET
+ ****************************************************************************/
+.step-timeline {
+	clear:both;
+	/* border: 1px solid green; */
+	font-size: 10px;
+	font-family: Tahoma;
+	 
+	cursor: hand;
+}
+
+
+.step-timeline-container {
+	width: 100%;
+	position: relative;
+	/* height: 100%; */
+}
+
+.step-timeband-container {
+	width: 100%;
+	background-color: AliceBlue;
+	overflow: hidden;
+	position: relative;
+	/* border: 1px solid red; */
+	
+}
+
+.step-timeband {
+	width: 64000px;
+	clear:both;
+	border: 1px solid darkgrey;
+	border-top: 2px solid lightgrey;
+	background-color: transparent;
+	position: absolute;
+	display: list-item;
+	list-style-type: none;
+	z-index: 100;
+	
+	/* height: 100%; */
+
+}
+.step-timeband-label {
+	position: absolute;
+	left: 0px;
+	bottom: 0px;
+}
+
+
+.step-time-event {
+	/* background-color: gold; */
+	position: relative;
+	/* border-style: dashed; */
+	display: absolute;
+	padding: 0px;
+	margin: 0px;
+}
+
+/** for all children of the the time band **/
+.step-time-event div {
+	margin-top: 1px;
+	margin-right: 0px;
+	margin-left: 0px;
+	margin-bottom: 1px;
+	list-style-type: none;
+	position: absolute;
+}
+
+.step-timeline-pointInTime {
+	display:inline;
+	background-image: url("../step/step/images/blue-circle.png");
+	width: 10px;
+	border: none;
+	background-repeat: no-repeat;
+	background-position: left;
+}
+
+.step-time-point-in-time-label {
+	background-image: url("../step/step/images/blue-circle.png");
+	display:inline;
+	background-repeat: no-repeat;
+	background-position: left;
+	padding-left: 15px;
+}
+
+
+.step-timeline-duration {
+	background-color: 99CCFF;
+	border-style: none;
+	border-width: 1px;
+	/* overflow: visible; */
+	height: 4px;
+}
+
+.step-time-duration-label {
+	display: inline;
+	margin-top: 5px;
+	padding-top:4px;	
+}
+
+.step-scale-band div {
+	border-left: none;
+	border-top: none;
+	border-bottom: none;
+	border-right: 1px dotted gray;
+	margin-right: -1px;
+	/* float: left; */
+	height: 100%;
+	display: inline;
+	position: absolute;
+	text-align: left;
+}
+
+.step-grab {
+	cursor: hand;
+	cursor: grabbing;
+	cursor: -moz-grabbing;
+}
+
+.step-letgo {
+	cursor: hand; /* ? */	
+}
+
+
+.step-tape-track {
+	display: block;
+	height: 20px; /* TODO: to shove in properties file if they are possible? */
+	width: 100%;
+	position: relative;
+	/* border-bottom: 1px solid red; DEBUG */
+	z-index: 110;
+}
+
+.step-timeline-control {
+	z-index: 120;
+}
+
+.step-timeline-time-event-descriptor {
+	position: absolute;
+	border: 1px dashed blue;
+	background-color: white;
+	z-index: 130;
+}
\ No newline at end of file

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-all.css
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-all.css	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-all.css	2010-04-14 22:14:14 UTC (rev 121)
@@ -0,0 +1,6839 @@
+/*
+ * Ext GWT Library 2.0.1
+ * Copyright(c) 2006-2009, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://extjs.com/license
+ */
+html,body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,p,blockquote,th,td{margin:0;padding:0;}img,body,html{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}ol,ul {list-style:none;}caption,th {text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';}
+.ext-el-mask {
+    z-index: 100;
+    position: absolute;
+    top:0;
+    left:0;
+    -moz-opacity: 0.5;
+    opacity: .50;
+    filter: alpha(opacity=50);
+    width: 100%;
+    height: 100%;
+    zoom: 1;
+}
+.ext-el-mask-msg {
+    z-index: 101;
+    position: absolute;
+    top: 0;
+    left: 0;
+    border:1px solid;
+    background:repeat-x 0 -16px;
+    padding:2px;
+}
+.ext-el-mask-msg div {
+    padding:5px 10px 5px 10px;
+    border:1px solid;
+    cursor:wait;
+}
+.ext-webkit *:focus{
+    outline: none !important;
+}
+.ext-shim {
+    position:absolute;
+    visibility:hidden;
+    left:0;
+    top:0;
+    overflow:hidden;
+}
+.ext-ie .ext-shim {
+    filter: alpha(opacity=0);
+}
+.ext-ie6 .ext-shim {
+    margin-left: 5px;
+    margin-top: 3px;
+}
+.x-mask-loading div {
+    padding:5px 10px 5px 25px;
+    background:no-repeat 5px 5px;
+    line-height:16px;
+}
+.x-hidden, .x-hide-offsets {
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+}
+.x-hide-display {
+    display:none !important;
+}
+.x-hide-visibility {
+    visibility:hidden !important;
+}
+.x-masked {
+    overflow: hidden !important;
+}
+.x-masked-relative {
+    position: relative !important;
+}
+.x-masked select, .x-masked object, .x-masked embed {
+    visibility: hidden;
+}
+.x-layer {
+    visibility: hidden;
+}
+.x-unselectable, .x-unselectable * {
+    -moz-user-select: none;
+    -khtml-user-select: none;
+    -webkit-user-select: ignore;
+}
+.x-repaint {
+    zoom: 1;
+    background-color: transparent;
+    -moz-outline: none;
+}
+.x-item-disabled {
+    cursor: default;
+    opacity: .6;
+    -moz-opacity: .6;
+    filter: alpha(opacity=60);
+}
+.x-item-disabled * {
+	cursor: default !important;
+}
+.x-splitbar-proxy {
+    position: absolute;
+    visibility: hidden;
+    z-index: 20001;
+    zoom: 1;
+    line-height: 1px;
+    font-size: 1px;
+    overflow: hidden;
+}
+.x-splitbar-h, .x-splitbar-proxy-h {
+    cursor: e-resize;
+    cursor: col-resize;
+}
+.x-splitbar-v, .x-splitbar-proxy-v {
+    cursor: s-resize;
+    cursor: row-resize;
+}
+.x-color-palette {
+    width: 150px;
+    height: 92px;
+    cursor: pointer;
+}
+.x-color-palette a {
+    border: 1px solid;
+    float: left;
+    padding: 2px;
+    text-decoration: none;
+    -moz-outline: 0 none;
+    outline: 0 none;
+    cursor: pointer;
+}
+.x-color-palette a.x-color-palette-hover, .x-color-palette a.x-color-palette-sel {
+    border: 1px solid;
+}
+.x-color-palette em {
+    display: block;
+    border: 1px solid;
+}
+.x-color-palette em span {
+    cursor: pointer;
+    display: block;
+    height: 10px;
+    line-height: 10px;
+    width: 10px;
+}
+.x-ie-shadow {
+    display: none;
+    position: absolute;
+    overflow: hidden;
+    left:0;
+    top:0;
+    zoom:1;
+}
+.x-shadow {
+    display: none;
+    position: absolute;
+    overflow: hidden;
+    left:0;
+    top:0;
+}
+.x-shadow * {
+    overflow: hidden;
+}
+.x-shadow * {
+    padding: 0;
+    border: 0;
+    margin: 0;
+    clear: none;
+    zoom: 1;
+}
+.x-shadow .xstc, .x-shadow .xsbc {
+    height: 6px;
+    float: left;
+}
+.x-shadow .xstl, .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbr {
+    width: 6px;
+    height: 6px;
+    float: left;
+}
+.x-shadow .xsc {
+    width: 100%;
+}
+.x-shadow .xsml, .x-shadow .xsmr {
+    width: 6px;
+    float: left;
+    height: 100%;
+}
+.x-shadow .xsmc {
+    float: left;
+    height: 100%;
+    background: transparent;
+}
+.x-shadow .xst, .x-shadow .xsb {
+    height: 6px;
+    overflow: hidden;
+    width: 100%;
+}
+.x-shadow .xsml {
+    background: transparent repeat-y 0 0;
+}
+.x-shadow .xsmr {
+    background: transparent repeat-y -6px 0;
+}
+.x-shadow .xstl {
+    background: transparent no-repeat 0 0;
+}
+.x-shadow .xstc {
+    background: transparent repeat-x 0 -30px;
+}
+.x-shadow .xstr {
+    background: transparent repeat-x 0 -18px;
+}
+.x-shadow .xsbl {
+    background: transparent no-repeat 0 -12px;
+}
+.x-shadow .xsbc {
+    background: transparent repeat-x 0 -36px;
+}
+.x-shadow .xsbr {
+    background: transparent repeat-x 0 -6px;
+}
+.loading-indicator {
+    background: no-repeat left;
+    padding-left: 20px;
+    line-height: 16px;
+    margin: 3px;
+}
+.x-text-resize {
+    position: absolute;
+    left: -1000px;
+    top: -1000px;
+    visibility: hidden;
+    zoom: 1;
+}
+.x-drag-overlay {
+    width: 100%;
+    height: 100%;
+    display: none;
+    position: absolute;
+    left: 0;
+    top: 0;
+    background-image:url(../images/default/s.gif);
+    z-index: 20000;
+}
+.x-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+.x-spotlight {
+    z-index: 8999;
+    position: absolute;
+    top:0;
+    left:0;
+    -moz-opacity: 0.5;
+    opacity: .50;
+    filter: alpha(opacity=50);
+    width:0;
+    height:0;
+    zoom: 1;
+}
+#x-history-frame {
+    position:absolute;
+    top:-1px;
+    left:0;
+	width:1px;
+    height:1px;
+    visibility:hidden;
+}
+#x-history-field {
+    position:absolute;
+    top:0;
+    left:-1px;
+	width:1px;
+    height:1px;
+    visibility:hidden;
+}
+
+.x-portlet {
+  margin-bottom: 10px;
+}
+
+.ext-ie .x-btn-icon .x-btn-center .x-btn-text {
+  height: auto;
+}
+
+.icon-wait {
+  background: url(../images/gxt/icons/wait.gif) no-repeat !important;
+}
+
+.x-portal-insert div {
+  height: 4px;
+  font-size: 0px;
+  border: 2px dotted blue;
+}
+
+.x-panel-icon {
+  padding-left: 20px !important;
+}
+
+.x-icon-btn {
+  width: 16px;
+  height: 16px;
+  overflow: hidden;
+  background-repeat: no-repeat;
+  cursor: pointer;
+}
+
+.x-panel-inline-icon {
+  margin-top: 0;
+}
+
+.x-modal {
+  position: absolute;
+  z-index: 10;
+  background-color: black;
+  filter: alpha(opacity =                     10);
+  opacity: .1;
+  left: 0px;
+  top: 0px;
+}
+
+.x-progress {
+  font-family: tahoma, arial, helvetica, sans-serif;
+}
+
+.x-float-right {
+  float: right;
+}
+
+.x-toolbar .x-float-right {
+  margin-right: 4px;
+}
+
+.x-border {
+  border: 1px solid #99BBE8;
+}
+
+.x-border-top {
+  border-top: 1px solid #99BBE8;
+}
+
+.x-layout-popup {
+  background-color: #DFE8F6;
+  border: 1px solid #7CA4D9;
+}
+
+.x-panel-popup-body {
+  border-top: 1px solid #99BBE8;
+}
+
+.x-layout-collapsed .x-panel-header {
+  border-left: none;
+  border-right: none;
+  border-top: none;
+}
+
+.x-layout-collapsed .x-panel-header .x-tool {
+  margin: 0 0 0 -4px;
+  padding: 0px;
+}
+
+.x-layout-collapsed {
+  position: absolute;
+  visibility: hidden;
+  background-color: #d2e0f2;
+  width: 20px;
+  height: 20px;
+  overflow: hidden;
+  border: 1px solid #98c0f4;
+  z-index: 20;
+}
+
+.ext-border-box .x-layout-collapsed {
+  width: 22px;
+  height: 22px;
+}
+
+.x-layout-collapsed-over {
+  cursor: pointer;
+  background-color: #d9e8fb;
+}
+
+.x-layout-collapsed-west .x-layout-collapsed-tools,.x-layout-collapsed-east .x-layout-collapsed-tools {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 20px;
+  height: 20px;
+}
+
+.x-panel-toolbar {
+  float: right;
+}
+
+.x-cursor-row-resize {
+  cursor: n-resize;
+  cursor: row-resize;
+}
+
+.x-drag-proxy {
+  border: 1px dashed #3b5a82;
+  background-color: #EDEDED;
+  filter: alpha(opacity =                         50);
+  opacity: .5;
+  background-color: #c3daf9;
+  z-index: 20000;
+  overflow: hidden;
+  position: absolute;
+  left: 0;;
+  top: 0;
+}
+
+.x-date-picker,.x-date-picker a {
+  font-size: 11px;
+}
+
+.x-date-days {
+  table-layout: fixed;
+  width: 100%;
+}
+
+.x-date-days td {
+  width: 25px;
+  border: none;
+}
+
+.x-date-days td span {
+  display: block;
+  padding: 2px 7px 2px 2px;
+}
+
+.x-date-days td {
+  background: #DFECFB url(../images/default/shared/glass-bg.gif) repeat-x scroll left top;
+  border-bottom: 1px solid #A3BAD9;
+  border-collapse: separate;
+  color: #233D6D;
+  cursor: default;
+  font-family: arial, helvetica, tahoma, sans-serif;
+  font-size: 10px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  line-height: normal;
+  padding: 0pt;
+  text-align: right !important;
+}
+
+.x-date-picker .x-date-header {
+  background: url(../images/default/shared/hd-sprite.gif) repeat-x 0 -83px;
+  height: 22px;
+  left: 10px;
+  top: 10px;
+  width: 157px;
+}
+
+.x-date-header .x-btn .x-btn-text {
+  color: #fff;
+}
+
+.x-date-picker-footer {
+  width: 100%;
+}
+
+.x-date-picker-footer td {
+  text-align: center;
+}
+
+.x-date-left {
+  background: transparent url(../images/default/shared/hd-sprite.gif) repeat-x scroll 0pt -83px;
+  color: #FFFFFF;
+  font-family: "sans serif", tahoma, verdana, helvetica;
+  font-size: 11px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: bold;
+  line-height: normal;
+  overflow: hidden;
+}
+
+.x-modal {
+  position: absolute;
+  z-index: 10;
+  background-color: black;
+  filter: alpha(opacity =                     10);
+  opacity: .1;
+  left: 0px;
+  top: 0px;
+}
+
+.x-progress {
+  font-family: tahoma, arial, helvetica, sans-serif;
+}
+
+.x-float-right {
+  float: right;
+}
+
+.x-layout-popup {
+  background-color: #DFE8F6;
+  border: 1px solid #7CA4D9;
+}
+
+.x-layout-collapsed .x-panel-header .x-tool {
+  margin: 0 0 0 -4px;
+  padding: 0px;
+}
+
+.ext-border-box .x-layout-collapsed {
+  width: 22px;
+  height: 22px;
+}
+
+.x-layout-collapsed-over {
+  cursor: pointer;
+  background-color: #d9e8fb;
+}
+
+.x-layout-collapsed-west .x-layout-collapsed-tools,.x-layout-collapsed-east .x-layout-collapsed-tools {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 20px;
+  height: 20px;
+}
+
+.x-panel-toolbar {
+  float: right;
+}
+
+.x-cursor-col-resize {
+  cursor: e-resize;
+  cursor: col-resize;
+}
+
+.x-cursor-row-resize {
+  cursor: n-resize;
+  cursor: row-resize;
+}
+.x-drag-proxy {
+  border: 1px dashed #3b5a82;
+  background-color: #EDEDED;
+  filter: alpha(opacity=50);
+  opacity: .5;
+  background-color: #c3daf9;
+  z-index: 20000;
+  overflow: hidden;
+  position: absolute;
+  left: 0;;
+  top: 0;
+}.x-tab-panel {
+    overflow:hidden;
+  -moz-outline: none;
+}
+.x-tab-panel-header, .x-tab-panel-footer {
+	border: 1px solid;
+    overflow:hidden;
+    zoom:1;
+}
+.x-tab-panel-header {
+	border: 1px solid;
+	padding-bottom: 2px;
+}
+.x-tab-panel-footer {
+	border: 1px solid;
+	padding-top: 2px;
+}
+.x-tab-strip-wrap {
+	width:100%;
+    overflow:hidden;
+    position:relative;
+    zoom:1;
+}
+ul.x-tab-strip {
+	display:block;
+    width:5000px;
+    zoom:1;
+}
+ul.x-tab-strip-top{
+	padding-top: 1px;
+	background: repeat-x bottom;
+	border-bottom: 1px solid;
+}
+ul.x-tab-strip-bottom{
+	padding-bottom: 1px;
+	background: repeat-x top;
+	border-top: 1px solid;
+	border-bottom: 0 none;
+}
+.x-tab-panel-header-plain .x-tab-strip-top {
+    background:transparent !important;
+    padding-top:0 !important;
+}
+.x-tab-panel-header-plain {
+    background:transparent !important;
+    border-width:0 !important;
+    padding-bottom:0 !important;
+}
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+    border:1px solid;
+    height:2px;
+    font-size:1px;
+    line-height:1px;
+}
+.x-tab-panel-header-plain .x-tab-strip-spacer {
+    border-top: 0 none;
+}
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+    border-bottom: 0 none;
+}
+.x-tab-panel-footer-plain .x-tab-strip-bottom {
+    background:transparent !important;
+    padding-bottom:0 !important;
+}
+.x-tab-panel-footer-plain {
+    background:transparent !important;
+    border-width:0 !important;
+    padding-top:0 !important;
+}
+.ext-border-box .x-tab-panel-header-plain .x-tab-strip-spacer,
+.ext-border-box .x-tab-panel-footer-plain .x-tab-strip-spacer {
+    height:3px;
+}
+ul.x-tab-strip li {
+    float:left;
+    margin-left:2px;
+}
+ul.x-tab-strip li.x-tab-edge {
+    float:left;
+    margin:0 !important;
+    padding:0 !important;
+    border:0 none !important;
+    font-size:1px !important;
+    line-height:1px !important;
+    overflow:hidden;
+    zoom:1;
+    background:transparent !important;
+    width:1px;
+}
+.x-tab-strip a, .x-tab-strip span, .x-tab-strip em {
+	display:block;
+}
+.x-tab-strip a {
+	text-decoration:none !important;
+	-moz-outline: none;
+	outline: none;
+	cursor:pointer;
+}
+.x-tab-strip-inner {
+    overflow:hidden;
+	text-overflow: ellipsis;
+}
+.x-tab-strip span.x-tab-strip-text {
+	white-space: nowrap;
+	cursor:pointer;
+    padding:4px 0;
+}
+.x-tab-strip-top .x-tab-with-icon .x-tab-right {
+    padding-left:6px;
+}
+.x-tab-strip .x-tab-with-icon span.x-tab-strip-text {
+	padding-left:20px;
+    background-position: 0 3px;
+    background-repeat: no-repeat;
+}
+.x-tab-strip-active, .x-tab-strip-active a.x-tab-right {
+    cursor:default;
+}
+.x-tab-strip-active span.x-tab-strip-text {
+	cursor:default;
+}
+.x-tab-strip-disabled .x-tabs-text {
+	cursor:default;
+}
+.x-tab-panel-body {
+    overflow:hidden;
+}
+.x-tab-panel-bwrap {
+    overflow:hidden;
+}
+.ext-ie .x-tab-strip .x-tab-right {
+    position:relative;
+}
+.x-tab-strip-top .x-tab-strip-active .x-tab-right {
+    margin-bottom:-1px;
+}
+.x-tab-strip-top .x-tab-strip-active .x-tab-right span.x-tab-strip-text {
+    padding-bottom:5px;
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+    margin-top:-1px;
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right span.x-tab-strip-text {
+    padding-top:5px;
+}
+.x-tab-strip-top .x-tab-right {
+	background: transparent no-repeat 0 -51px;
+    padding-left:10px;
+}
+.x-tab-strip-top .x-tab-left {
+	background: transparent no-repeat right -351px;
+    padding-right:10px;
+}
+.x-tab-strip-top .x-tab-strip-inner {
+	background: transparent repeat-x 0 -201px;
+}
+.x-tab-strip-top .x-tab-strip-over .x-tab-right {
+	 background-position:0 -101px;
+}
+.x-tab-strip-top .x-tab-strip-over .x-tab-left {
+	 background-position:right -401px;
+}
+.x-tab-strip-top .x-tab-strip-over .x-tab-strip-inner {
+	 background-position:0 -251px;
+}
+.x-tab-strip-top .x-tab-strip-active .x-tab-right {
+	background-position: 0 0;
+}
+.x-tab-strip-top .x-tab-strip-active .x-tab-left {
+	background-position: right -301px;
+}
+.x-tab-strip-top .x-tab-strip-active .x-tab-strip-inner {
+	background-position: 0 -151px;
+}
+.x-tab-strip-bottom .x-tab-right {
+	background: no-repeat bottom right;
+}
+.x-tab-strip-bottom .x-tab-left {
+	background: no-repeat bottom left;
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+	background: no-repeat bottom left;
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+	background: no-repeat bottom right;
+}
+.x-tab-strip-bottom .x-tab-left {
+    padding:0 10px;
+}
+.x-tab-strip-bottom .x-tab-right {
+    padding:0;
+}
+.x-tab-strip .x-tab-strip-close {
+    display:none;
+}
+.x-tab-strip-closable {
+    position:relative;
+}
+.x-tab-strip-closable .x-tab-left {
+    padding-right:19px;
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+    opacity:.6;
+    -moz-opacity:.6;
+    background-repeat:no-repeat;
+    display:block;
+	width:11px;
+    height:11px;
+    position:absolute;
+    top:3px;
+    right:3px;
+    cursor:pointer;
+    z-index:2;
+}
+.x-tab-strip .x-tab-strip-active a.x-tab-strip-close {
+    opacity:.8;
+    -moz-opacity:.8;
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{
+    opacity:1;
+    -moz-opacity:1;
+}
+.x-tab-panel-body {
+    border: 1px solid;
+}
+.x-tab-panel-body-top {
+    border-top: 0 none;
+}
+.x-tab-panel-body-bottom {
+    border-bottom: 0 none;
+}
+.x-tab-scroller-left {
+    background: transparent no-repeat -18px 0;
+    border-bottom: 1px solid;
+    width:18px;
+    position:absolute;
+    left:0;
+    top:0;
+    z-index:10;
+    cursor:pointer;
+}
+.x-tab-scroller-left-over {
+    background-position: 0 0;
+}
+.x-tab-scroller-left-disabled {
+    background-position: -18px 0;
+    opacity:.5;
+    -moz-opacity:.5;
+    filter:alpha(opacity=50);
+    cursor:default;
+}
+.x-tab-scroller-right {
+    background: transparent no-repeat 0 0;
+    border-bottom: 1px solid;
+    width:18px;
+    position:absolute;
+    right:0;
+    top:0;
+    z-index:10;
+    cursor:pointer;
+}
+.x-tab-scroller-right-over {
+    background-position: -18px 0;
+}
+.x-tab-scroller-right-disabled {
+    background-position: 0 0;
+    opacity:.5;
+    -moz-opacity:.5;
+    filter:alpha(opacity=50);
+    cursor:default;
+}
+.x-tab-scrolling-bottom .x-tab-scroller-left, .x-tab-scrolling-bottom .x-tab-scroller-right{
+    margin-top: 1px;
+}
+.x-tab-scrolling .x-tab-strip-wrap {
+    margin-left:18px;
+    margin-right:18px;
+}
+.x-tab-scrolling {
+    position:relative;    
+}
+.x-tab-panel-bbar .x-toolbar {
+    border:1px solid;
+    border-top:0 none;
+    overflow:hidden;
+    padding:2px;
+}
+.x-tab-panel-tbar .x-toolbar {
+    border:1px solid;
+    border-top:0 none;
+    overflow:hidden;
+    padding:2px;
+}
+.x-form-field{
+    margin: 0;
+}
+.x-form-text, textarea.x-form-field{
+    padding:1px 3px;
+    background:repeat-x 0 0;
+    border:1px solid;
+}
+textarea.x-form-field {
+    padding:2px 3px;
+}
+.x-form-text, .ext-ie .x-form-file {
+    height:22px;
+    line-height:18px;
+    vertical-align:middle;
+}
+
+.ext-ie6 .x-form-text, .ext-ie7 .x-form-text {
+    margin: -1px 0;
+    height:22px; /* ie quirks */
+    line-height:18px;
+}
+.ext-ie8-compatibility .x-form-text {
+	margin: 0;
+}
+.x-form-field-wrap .x-form-text {
+	position: relative;
+}
+.ext-strict .x-form-text {
+    height:18px;
+}
+.ext-safari.ext-mac textarea.x-form-field {
+    margin-bottom:-2px;  
+}
+.ext-gecko .x-form-text, .ext-ie8 .x-form-text {
+    padding-top:2px;  
+    padding-bottom:0;
+}
+textarea {
+    resize: none;   
+}
+.x-form-select-one {
+    height:20px;
+    line-height:18px;
+    vertical-align:middle;
+    border: 1px solid;
+}
+.x-form-check-wrap {
+    line-height:18px;
+    height: 22px;
+}
+.x-editor .x-form-check-wrap {
+	border: 1px solid;
+	padding:2px;
+	height: 14px;
+}
+.x-editor .x-form-checkbox {
+    height:13px;
+}
+.x-form-check-group-label {
+    border-bottom: 1px solid;
+    margin-bottom: 5px;
+    padding-left: 3px !important;
+    float: none !important;
+}
+.x-form-field-wrap .x-form-trigger{
+    width:17px;
+    height:21px;
+    border:0;
+    background:transparent no-repeat 0 0;
+    cursor:pointer;
+    border-bottom: 1px solid;
+    position:absolute;
+    top:0;
+}
+.ext-safari .x-form-field-wrap .x-form-trigger{
+    height:21px;  
+}
+.x-form-field-wrap .x-form-date-trigger, .x-form-field-wrap .x-form-clear-trigger, .x-form-field-wrap .x-form-search-trigger{
+    cursor:pointer;
+}
+.ext-safari .x-form-field-wrap .x-form-trigger,.ext-gecko .x-form-field-wrap .x-form-trigger{
+    right:0;
+}
+.x-form-field-wrap .x-form-twin-triggers .x-form-trigger{
+    position:static;
+    top:auto;
+    vertical-align:top;
+}
+.x-form-field-wrap {
+    position:relative;
+    left:0;top:0;
+    zoom:1;
+    white-space: nowrap;
+}
+.x-form-field-wrap .x-form-trigger-over{
+    background-position:-17px 0;
+}
+.x-form-field-wrap .x-form-trigger-click{
+    background-position:-34px 0;
+}
+.x-trigger-wrap-focus .x-form-trigger{
+    background-position:-51px 0;
+}
+.x-trigger-wrap-focus .x-form-trigger-over{
+    background-position:-68px 0;
+}
+.x-trigger-wrap-focus .x-form-trigger-click{
+    background-position:-85px 0;
+}
+.x-trigger-wrap-focus .x-form-trigger{
+    border-bottom: 1px solid;
+}
+.x-item-disabled .x-form-trigger-over{
+    background-position:0 0 !important;
+    border-bottom: 1px solid;
+}
+.x-item-disabled .x-form-trigger-click{
+    background-position:0 0 !important;
+    border-bottom: 1px solid;
+}
+.x-form-focus, textarea.x-form-focus{
+	border: 1px solid;
+}
+.x-form-invalid, textarea.x-form-invalid{
+	background:repeat-x bottom;
+	border: 1px solid;
+}
+.ext-safari .x-form-invalid{
+	border: 1px solid;
+}
+.x-form-inner-invalid, textarea.x-form-inner-invalid{
+	background:repeat-x bottom;
+}
+.x-editor {
+    visibility:hidden;
+    padding:0;
+    margin:0;
+}
+.ext-ie .x-form-check-wrap input {
+    width:15px;
+    height:15px;
+}
+.x-form-grow-sizer {
+    left: -10000px;
+	padding: 8px 3px;
+    position: absolute;
+    visibility:hidden;
+    top: -10000px;
+	white-space: pre-wrap;
+    white-space: -moz-pre-wrap;
+    white-space: -pre-wrap;
+    white-space: -o-pre-wrap;
+    word-wrap: break-word;
+    zoom:1;
+}
+.x-form-grow-sizer p {
+    margin:0 !important;
+    border:0 none !important;
+    padding:0 !important;
+}
+.x-form-item {
+    display:block;
+    margin-bottom:4px;
+}
+.x-form-item label {
+    display:block;
+    float:left;
+    width:100px;
+    padding:3px;
+    padding-left:0;
+    clear:left;
+    z-index:2;
+    position:relative;
+}
+.x-form-element {
+    padding-left:105px;
+    position: relative;
+}
+.x-form-invalid-msg {
+    padding:2px;
+    padding-left:18px;
+    background: transparent no-repeat 0 2px;
+    line-height:16px;
+    width:200px;
+}
+.x-form-label-left label {
+   text-align:left;
+}
+.x-form-label-right label {
+   text-align:right;
+}
+.x-form-label-top .x-form-item label {
+    width:auto;
+    float:none;
+    clear:none;
+    display:inline;
+    margin-bottom:4px;
+    position:static;
+}
+.x-form-label-top .x-form-element {
+    padding-left:0;
+    padding-top:4px;
+}
+.x-form-label-top .x-form-item {
+    padding-bottom:4px;
+}
+.x-small-editor .x-form-text {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.ext-ie6 .x-small-editor .x-form-text, .ext-ie7 .x-small-editor .x-form-text {
+    height:20px !important;  
+    line-height:16px !important;
+}
+
+.ext-strict .x-small-editor .x-form-text {
+    height:16px !important;
+}
+
+.ext-border-box .x-small-editor .x-form-text {
+    height:20px;
+}
+.x-small-editor .x-form-select-one {
+    height:20px;
+    line-height:16px;
+    vertical-align:middle;
+}
+.x-small-editor .x-form-num-field {
+    text-align:right;
+}
+.x-small-editor .x-form-field-wrap .x-form-trigger{
+    height:19px;
+}
+.x-form-clear {
+    clear:both;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+.x-form-clear-left {
+    clear:left;
+    height:0;
+    overflow:hidden;
+    line-height:0;
+    font-size:0;
+}
+.x-form-cb-label {
+    width:auto !important;
+    float:none !important;
+    clear:none !important;
+    display:inline !important;
+    margin-left:4px;
+}
+.x-form-column {
+    float:left;
+    padding:0;
+    margin:0;
+    width:48%;
+    overflow:hidden;
+    zoom:1;
+}
+.x-form .x-form-btns-ct .x-btn{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns td {
+	border:0;
+	padding:0;
+}
+.x-form .x-form-btns-ct .x-form-btns-right table{
+	float:right;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-left table{
+	float:left;
+	clear:none;
+}
+.x-form .x-form-btns-ct .x-form-btns-center{
+	text-align:center;  
+}
+.x-form .x-form-btns-ct .x-form-btns-center table{
+	margin:0 auto;  
+}
+.x-form .x-form-btns-ct table td.x-form-btn-td{
+	padding:3px;
+}
+.x-form .x-form-btns-ct .x-btn-focus .x-btn-left{
+	background-position:0 -147px;
+}
+.x-form .x-form-btns-ct .x-btn-focus .x-btn-right{
+	background-position:0 -168px;
+}
+.x-form .x-form-btns-ct .x-btn-focus .x-btn-center{
+	background-position:0 -189px;
+}
+.x-form .x-form-btns-ct .x-btn-click .x-btn-center{
+	background-position:0 -126px;
+}
+.x-form .x-form-btns-ct .x-btn-click  .x-btn-right{
+	background-position:0 -84px;
+}
+.x-form .x-form-btns-ct .x-btn-click .x-btn-left{
+	background-position:0 -63px;
+}
+.x-form-invalid-icon {
+    width:16px;
+    height:18px;
+    position:absolute;
+    left:0;
+    top:0;
+    display:block;
+    background:transparent no-repeat 0 2px;
+}
+.x-fieldset {
+    border:1px solid;
+    padding:10px;
+    margin-bottom:10px;
+    display:block;  
+}
+.ext-ie .x-fieldset legend {
+    margin-bottom:10px;
+}
+.ext-ie .x-fieldset {
+    padding-top: 0;
+    padding-bottom:10px;
+}
+.x-fieldset legend .x-tool-toggle {
+    margin-right:3px;
+    margin-left:0;
+    float:left !important;
+}
+.x-fieldset legend input {
+    margin-right:3px;
+    float:left !important;
+    height:13px;
+    width:13px;
+}
+fieldset.x-panel-collapsed {
+    padding-bottom:0 !important;
+    border-width: 1px 1px 0 1px !important;
+    border-left-color: transparent;
+    border-right-color: transparent;
+}      
+.ext-ie6 fieldset.x-panel-collapsed{
+    padding-bottom:0 !important;
+    border-width: 1px 0 0 0 !important;
+    margin-left: 1px;
+    margin-right: 1px;
+}
+fieldset.x-panel-collapsed .x-fieldset-bwrap {
+    visibility:hidden;
+    position:absolute;
+    left:-1000px;
+    top:-1000px;
+}
+.ext-ie .x-fieldset-bwrap {
+    zoom:1;
+}
+.x-fieldset-noborder {
+    border:0px none transparent;
+}
+.x-fieldset-noborder legend {
+    margin-left:-3px;
+}
+.ext-ie .x-fieldset-noborder legend {
+    position: relative;
+    margin-bottom:23px;
+}
+.ext-ie .x-fieldset-noborder legend span {
+    position: absolute;
+    left:16px;
+}
+.ext-gecko .x-window-body .x-form-item {
+    -moz-outline: none;
+    overflow: auto;
+}
+.ext-gecko .x-form-item {
+    -moz-outline: none;
+}
+.x-hide-label label.x-form-item-label {
+     display:none;
+}
+.x-hide-label .x-form-element {
+     padding-left: 0 !important;
+}
+.x-fieldset {
+    overflow:hidden;
+}
+/* make top of checkbox/tools visible in webkit */
+.ext-webkit .x-fieldset-header {
+    padding-top: 1px;
+}
+.x-fieldset-bwrap {
+    overflow:hidden;
+    zoom:1;
+}
+.x-fieldset-body {
+    overflow:hidden;
+}
+
+.x-combo-list .x-combo-selected {
+  border-color: #a3bae9 !important;
+}
+
+.x-combo-list {
+  background-color: white !important;
+}
+
+.ext-gecko .x-form-file {
+  height: inherit !important;
+}
+
+.x-form-check {
+  background: none !important
+}
+
+.x-form-radio {
+  background: none !important
+}
+
+.x-form-label {
+  padding: 2px 3px 3px 0px;
+  font-size: 12px;
+}
+
+.x-form-label-top .x-form-item {
+  padding-bottom: 0px;
+  margin-bottom: 2px;
+}
+
+.ext-safari .x-form-text {
+  height: 22px; /* safari always same size */
+  padding: 0 3px; /* remove extra top/bottom padding */
+}
+
+.ext-safari .x-small-editor .x-form-text {
+  height: 20px;
+}
+
+.x-form-group .x-form-check-wrap {
+  float: left;
+  padding-right: 2px;
+}
+
+.x-form-group .x-form-check-wrap .x-form-group-label {
+  float: left;
+}
+
+.x-form-group .x-form-radio-wrap {
+  float: left;
+  padding-right: 2px;
+}
+
+.x-form-group-label,.x-form-cb-label {
+  font: normal 12px tahoma, arial, helvetica, sans-serif;
+  padding-right: 10px;
+}
+
+.x-form-list {
+  background: #FFFFFF url(../images/default/form/text-bg.gif) repeat-x scroll 0 0;
+  border: 1px solid #B5B8C8;
+}
+
+/*
+ * FileUploadField component styles
+ */
+.x-form-file-wrap {
+  height: 22px;
+}
+
+.ext-ie .x-form-file-wrap {
+  height: 20px;
+}
+
+
+.x-form-file-wrap .x-form-file {
+  position: absolute;
+  right: 0;
+  -moz-opacity: 0;
+  filter: alpha(opacity :     0);
+  opacity: 0;
+  z-index: 2;
+  height: 22px;
+}
+
+.x-form-file-wrap .x-form-file-btn {
+  position: absolute;
+  right: 0;
+  z-index: 1;
+}
+
+.x-form-file-wrap .x-form-file-text {
+  position: absolute;
+  left: 0;
+  z-index: 3;
+  color: #777;
+}
+
+.x-form-invalid-icon {
+  background-position: 0 0 !important;
+}
+
+.x-triggerfield-noedit{
+    cursor:pointer;
+}
+.x-btn{
+	cursor:pointer;
+	white-space: nowrap;
+}
+.x-btn button{
+    border:0 none;
+    background:transparent;
+    padding-left:3px;
+    padding-right:3px;
+    cursor:pointer;
+    margin:0;
+    overflow:visible;
+    width:auto;
+    -moz-outline:0 none;
+    outline:0 none;
+}
+* html .ext-ie .x-btn button {
+    width:1px;
+}
+.ext-ie .x-item-disabled .x-btn-mc img {
+	filter: alpha(opacity=60);
+}
+.ext-gecko .x-btn button,.ext-webkit .x-btn button {
+    padding-left:0;
+    padding-right:0;
+}
+.ext-gecko .x-btn button::-moz-focus-inner {
+    padding:0;
+}
+.ext-ie .x-btn button {
+    padding-top:2px;
+}
+.x-btn td {
+    padding:0 !important;
+}
+.x-btn-text {
+    cursor:pointer;
+	white-space: nowrap;
+    padding:0;
+}
+.x-btn-noicon .x-btn-small .x-btn-text{
+	height: 16px;
+}
+.x-btn-noicon .x-btn-medium .x-btn-text{
+    height: 24px;
+}
+.x-btn-noicon .x-btn-large .x-btn-text{
+    height: 32px;
+}
+.x-btn-icon .x-btn-text{
+    background-position: center;
+	background-repeat: no-repeat;
+}
+.x-btn-icon .x-btn-small .x-btn-text{
+	height: 16px;
+	width: 16px;
+}
+.x-btn-icon .x-btn-medium .x-btn-text{
+    height: 24px;
+	width: 24px;
+}
+.x-btn-icon .x-btn-large .x-btn-text{
+    height: 32px;
+	width: 32px;
+}
+.x-btn-text-icon .x-btn-icon-small-left .x-btn-text{
+    background-position: 0 center;
+	background-repeat: no-repeat;
+    padding-left:18px;
+    height:16px;
+}
+.x-btn-text-icon .x-btn-icon-medium-left .x-btn-text{
+    background-position: 0 center;
+	background-repeat: no-repeat;
+    padding-left:26px;
+    height:24px;
+}
+.x-btn-text-icon .x-btn-icon-large-left .x-btn-text{
+    background-position: 0 center;
+	background-repeat: no-repeat;
+    padding-left:34px;
+    height:32px;
+}
+.x-btn-text-icon .x-btn-icon-small-top .x-btn-text{
+    background-position: center 0;
+	background-repeat: no-repeat;
+    padding-top:18px;
+}
+.x-btn-text-icon .x-btn-icon-medium-top .x-btn-text{
+    background-position: center 0;
+	background-repeat: no-repeat;
+    padding-top:26px;
+}
+.x-btn-text-icon .x-btn-icon-large-top .x-btn-text{
+    background-position: center 0;
+	background-repeat: no-repeat;
+    padding-top:34px;
+}
+.x-btn-text-icon .x-btn-icon-small-right .x-btn-text{
+    background-position: right center;
+	background-repeat: no-repeat;
+    padding-right:18px;
+    height:16px;
+}
+.x-btn-text-icon .x-btn-icon-medium-right .x-btn-text{
+    background-position: right center;
+	background-repeat: no-repeat;
+    padding-right:26px;
+    height:24px;
+}
+.x-btn-text-icon .x-btn-icon-large-right .x-btn-text{
+    background-position: right center;
+	background-repeat: no-repeat;
+    padding-right:34px;
+    height:32px;
+}
+.x-btn-text-icon .x-btn-icon-small-bottom .x-btn-text{
+    background-position: center bottom;
+	background-repeat: no-repeat;
+    padding-bottom:18px;
+}
+.x-btn-text-icon .x-btn-icon-medium-bottom .x-btn-text{
+    background-position: center bottom;
+	background-repeat: no-repeat;
+    padding-bottom:26px;
+}
+.x-btn-text-icon .x-btn-icon-large-bottom .x-btn-text{
+    background-position: center bottom;
+	background-repeat: no-repeat;
+    padding-bottom:34px;
+}
+.x-btn-tr i, .x-btn-tl i, .x-btn-mr i, .x-btn-ml i, .x-btn-br i, .x-btn-bl i{
+	font-size:1px;
+    line-height:1px;
+    width:3px;
+    display:block;
+    overflow:hidden;
+}
+.x-btn-tr i, .x-btn-tl i, .x-btn-br i, .x-btn-bl i{
+	height:3px;
+}
+.x-btn-tl{
+	width:3px;
+	height:3px;
+	background:no-repeat 0 0;
+}
+.x-btn-tr{
+	width:3px;
+	height:3px;
+	background:no-repeat -3px 0;
+}
+.x-btn-tc{
+	height:3px;
+	background:repeat-x 0 -6px;
+}
+.x-btn-ml{
+	width:3px;
+	background:no-repeat 0 -24px;
+}
+.x-btn-mr{
+	width:3px;
+	background:no-repeat -3px -24px;
+}
+.x-btn-mc{
+	background:repeat-x 0 -1096px;
+    vertical-align: middle;
+	text-align:center;
+	padding:0 5px;
+	cursor:pointer;
+	white-space:nowrap;
+}
+.x-btn-bl{
+	width:3px;
+	height:3px;
+	background:no-repeat 0 -3px;
+}
+.x-btn-br{
+	width:3px;
+	height:3px;
+	background:no-repeat -3px -3px;
+}
+.x-btn-bc{
+	height:3px;
+	background:repeat-x 0 -15px;
+}
+.x-btn-over .x-btn-tl{
+	background-position: -6px 0;
+}
+.x-btn-over .x-btn-tr{
+	background-position: -9px 0;
+}
+.x-btn-over .x-btn-tc{
+	background-position: 0 -9px;
+}
+.x-btn-over .x-btn-ml{
+	background-position: -6px -24px;
+}
+.x-btn-over .x-btn-mr{
+	background-position: -9px -24px;
+}
+.x-btn-over .x-btn-mc{
+	background-position: 0 -2168px;
+}
+.x-btn-over .x-btn-bl{
+	background-position: -6px -3px;
+}
+.x-btn-over .x-btn-br{
+	background-position: -9px -3px;
+}
+.x-btn-over .x-btn-bc{
+	background-position: 0 -18px;
+}
+.x-btn-click .x-btn-tl, .x-btn-menu-active .x-btn-tl, .x-btn-pressed .x-btn-tl{
+	background-position: -12px 0;
+}
+.x-btn-click .x-btn-tr, .x-btn-menu-active .x-btn-tr, .x-btn-pressed .x-btn-tr{
+	background-position: -15px 0;
+}
+.x-btn-click .x-btn-tc, .x-btn-menu-active .x-btn-tc, .x-btn-pressed .x-btn-tc{
+	background-position: 0 -12px;
+}
+.x-btn-click .x-btn-ml, .x-btn-menu-active .x-btn-ml, .x-btn-pressed .x-btn-ml{
+	background-position: -12px -24px;
+}
+.x-btn-click .x-btn-mr, .x-btn-menu-active .x-btn-mr, .x-btn-pressed .x-btn-mr{
+	background-position: -15px -24px;
+}
+.x-btn-click .x-btn-mc, .x-btn-menu-active .x-btn-mc, .x-btn-pressed .x-btn-mc{
+	background-position: 0 -3240px;
+}
+.x-btn-click .x-btn-bl, .x-btn-menu-active .x-btn-bl, .x-btn-pressed .x-btn-bl{
+	background-position: -12px -3px;
+}
+.x-btn-click .x-btn-br, .x-btn-menu-active .x-btn-br, .x-btn-pressed .x-btn-br{
+	background-position: -15px -3px;
+}
+.x-btn-click .x-btn-bc, .x-btn-menu-active .x-btn-bc, .x-btn-pressed .x-btn-bc{
+	background-position: 0 -21px;
+}
+.x-btn-disabled *{
+	cursor:default !important;
+}
+.x-btn-mc em.x-btn-arrow {
+    display:block;
+    background:transparent no-repeat right center;
+	padding-right:10px;
+}
+.x-btn-mc em.x-btn-split {
+    display:block;
+    background:transparent no-repeat right center;
+	padding-right:14px;
+}
+.x-btn-mc em.x-btn-arrow-bottom {
+    display:block;
+    background:transparent no-repeat center bottom;
+	padding-bottom:14px;
+}
+.x-btn-mc em.x-btn-split-bottom {
+    display:block;
+    background:transparent no-repeat center bottom;
+	padding-bottom:14px;
+}
+.x-btn-as-arrow .x-btn-mc em {
+    display:block;
+    background:transparent;
+	padding-bottom:14px;
+}
+.x-btn-group {
+    padding:1px;
+}
+.x-btn-group-header {
+    padding:2px;
+    text-align:center;
+}
+.x-btn-group-tc {
+	background: transparent repeat-x 0 0;
+	overflow:hidden;
+}
+.x-btn-group-tl {
+	background: transparent no-repeat 0 0;
+	padding-left:3px;
+    zoom:1;
+}
+.x-btn-group-tr {
+	background: transparent no-repeat right 0;
+	zoom:1;
+    padding-right:3px;
+}
+.x-btn-group-bc {
+	background: transparent repeat-x 0 bottom;
+    zoom:1;
+}
+.x-btn-group-bc .x-panel-footer {
+    zoom:1;
+}
+.x-btn-group-bl {
+	background: transparent no-repeat 0 bottom;
+	padding-left:3px;
+    zoom:1;
+}
+.x-btn-group-br {
+	background: transparent no-repeat right bottom;
+	padding-right:3px;
+    zoom:1;
+}
+.x-btn-group-mc {
+    border:0 none;
+    padding:1px 0 0 0;
+    margin:0;
+}
+.x-btn-group-mc .x-btn-group-body {
+    background:transparent;
+    border: 0 none;
+}
+.x-btn-group-ml {
+	background: transparent repeat-y 0 0;
+	padding-left:3px;
+    zoom:1;
+}
+.x-btn-group-mr {
+	background: transparent repeat-y right 0;
+	padding-right:3px;
+    zoom:1;
+}
+.x-btn-group-bc .x-btn-group-footer {
+    padding-bottom:6px;
+}
+.x-panel-nofooter .x-btn-group-bc {
+	height:3px;
+    font-size:0;
+    line-height:0;
+}
+.x-btn-group-bwrap {
+    overflow:hidden;
+    zoom:1;
+}
+.x-btn-group-body {
+    overflow:hidden;
+    zoom:1;
+}
+.x-btn-group-notitle .x-btn-group-tc {
+	background: transparent repeat-x 0 0;
+	overflow:hidden;
+    height:2px;
+}
+.x-toolbar{
+    border-style:solid;
+    border-width:0 0 1px 0;
+    display: block;
+	padding:2px;
+    background:repeat-x top left;
+    position:relative;
+    left:0;
+    top:0;
+    zoom:1;
+    overflow:hidden;
+}
+.x-toolbar .x-item-disabled .x-btn-icon {
+    opacity: .35;
+    -moz-opacity: .35;
+    filter: alpha(opacity=35);
+}
+.x-toolbar td {
+	vertical-align:middle;
+}
+.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{
+	white-space: nowrap;
+}
+.x-toolbar .x-item-disabled {
+	cursor:default;
+	opacity:.6;
+	-moz-opacity:.6;
+	filter:alpha(opacity=60);
+}
+
+.x-toolbar .x-item-disabled *{
+	cursor:default;
+}
+
+.x-toolbar .x-toolbar-cell {
+    vertical-align:middle;
+}
+.x-toolbar .x-btn-tl, .x-toolbar .x-btn-tr, .x-toolbar .x-btn-tc, .x-toolbar .x-btn-ml, .x-toolbar .x-btn-mr, 
+.x-toolbar .x-btn-mc, .x-toolbar .x-btn-bl, .x-toolbar .x-btn-br, .x-toolbar .x-btn-bc
+{
+	background-position: 500px 500px;
+}
+.x-toolbar .x-btn-over .x-btn-tl{
+	background-position: -6px 0;
+}
+.x-toolbar .x-btn-over .x-btn-tr{
+	background-position: -9px 0;
+}
+.x-toolbar .x-btn-over .x-btn-tc{
+	background-position: 0 -9px;
+}
+.x-toolbar .x-btn-over .x-btn-ml{
+	background-position: -6px -24px;
+}
+.x-toolbar .x-btn-over .x-btn-mr{
+	background-position: -9px -24px;
+}
+.x-toolbar .x-btn-over .x-btn-mc{
+	background-position: 0 -2168px;
+}
+.x-toolbar .x-btn-over .x-btn-bl{
+	background-position: -6px -3px;
+}
+.x-toolbar .x-btn-over .x-btn-br{
+	background-position: -9px -3px;
+}
+.x-toolbar .x-btn-over .x-btn-bc{
+	background-position: 0 -18px;
+}
+.x-toolbar .x-btn-click .x-btn-tl, .x-toolbar .x-btn-menu-active .x-btn-tl, .x-toolbar .x-btn-pressed .x-btn-tl{
+	background-position: -12px 0;
+}
+.x-toolbar .x-btn-click .x-btn-tr, .x-toolbar .x-btn-menu-active .x-btn-tr, .x-toolbar .x-btn-pressed .x-btn-tr{
+	background-position: -15px 0;
+}
+.x-toolbar .x-btn-click .x-btn-tc, .x-toolbar .x-btn-menu-active .x-btn-tc, .x-toolbar .x-btn-pressed .x-btn-tc{
+	background-position: 0 -12px;
+}
+.x-toolbar .x-btn-click .x-btn-ml, .x-toolbar .x-btn-menu-active .x-btn-ml, .x-toolbar .x-btn-pressed .x-btn-ml{
+	background-position: -12px -24px;
+}
+.x-toolbar .x-btn-click .x-btn-mr, .x-toolbar .x-btn-menu-active .x-btn-mr, .x-toolbar .x-btn-pressed .x-btn-mr{
+	background-position: -15px -24px;
+}
+.x-toolbar .x-btn-click .x-btn-mc, .x-toolbar .x-btn-menu-active .x-btn-mc, .x-toolbar .x-btn-pressed .x-btn-mc{
+	background-position: 0 -3240px;
+}
+.x-toolbar .x-btn-click .x-btn-bl, .x-toolbar .x-btn-menu-active .x-btn-bl, .x-toolbar .x-btn-pressed .x-btn-bl{
+	background-position: -12px -3px;
+}
+.x-toolbar .x-btn-click .x-btn-br, .x-toolbar .x-btn-menu-active .x-btn-br, .x-toolbar .x-btn-pressed .x-btn-br{
+	background-position: -15px -3px;
+}
+.x-toolbar .x-btn-click .x-btn-bc, .x-toolbar .x-btn-menu-active .x-btn-bc, .x-toolbar .x-btn-pressed .x-btn-bc{
+	background-position: 0 -21px;
+}
+.x-toolbar div.xtb-text{
+    padding:2px 2px 0;
+    line-height:16px;
+    display:block;
+}
+.x-toolbar .xtb-sep {
+	background-position: center;
+	background-repeat: no-repeat;
+	display: block;
+	font-size: 1px;
+	height: 16px;
+	width:4px;
+	overflow: hidden;
+	cursor:default;
+	margin: 0 2px 0;
+	border:0;
+}
+.x-toolbar .xtb-spacer {
+    width:2px;
+}
+.x-tbar-page-number{
+	width:24px;
+	height:14px;
+}
+.x-paging-info {
+    position:absolute;
+    top:5px;
+    right: 8px;
+}
+.x-toolbar-ct {
+    width:100%;
+}
+.x-panel-tbar, .x-panel-bbar, .x-window-tbar, .x-window-bbar, .x-tab-panel-tbar, .x-tab-panel-bbar, .x-plain-tbar, .x-plain-bbar {
+    overflow:hidden;
+    zoom:1;
+}
+.x-toolbar-more .x-btn-small .x-btn-text{
+	height: 16px;
+	width: 12px;
+}
+.x-toolbar-more em.x-btn-arrow {
+    display:inline;
+    background:transparent;
+	padding-right:0;
+}
+.x-toolbar-more .x-btn-mc em.x-btn-arrow {
+    background-image: none;
+}
+div.x-toolbar-no-items {
+    color:gray !important;
+    padding:5px 10px !important;
+}.x-resizable-handle {
+    position:absolute;
+    z-index:100;
+    font-size:1px;
+    line-height:6px;
+    overflow:hidden;
+	filter:alpha(opacity=0);
+	opacity:0;
+	zoom:1;
+}
+.x-resizable-handle-east{
+    width:6px;
+    cursor:e-resize;
+    right:0;
+    top:0;
+    height:100%;
+}
+.ext-ie .x-resizable-handle-east {
+    margin-right:-1px;  
+}
+.x-resizable-handle-south{
+    width:100%;
+    cursor:s-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+}
+.ext-ie .x-resizable-handle-south {
+    margin-bottom:-1px;  
+}
+.x-resizable-handle-west{
+    width:6px;
+    cursor:w-resize;
+    left:0;
+    top:0;
+    height:100%;
+}
+.x-resizable-handle-north{
+    width:100%;
+    cursor:n-resize;
+    left:0;
+    top:0;
+    height:6px;
+}
+.x-resizable-handle-southeast{
+    width:6px;
+    cursor:se-resize;
+    right:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northwest{
+    width:6px;
+    cursor:nw-resize;
+    left:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-northeast{
+    width:6px;
+    cursor:ne-resize;
+    right:0;
+    top:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-handle-southwest{
+    width:6px;
+    cursor:sw-resize;
+    left:0;
+    bottom:0;
+    height:6px;
+    z-index:101;
+}
+.x-resizable-over .x-resizable-handle, .x-resizable-pinned .x-resizable-handle{
+    filter:alpha(opacity=100);
+	opacity:1;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east,
+.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west
+{
+	background-position: left;
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north
+{
+    background-position: top;
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background-position: top left;
+}
+.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{
+    background-position:bottom right;
+}
+.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{
+    background-position: bottom left;
+}
+.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{
+    background-position: top right;
+}
+.x-resizable-proxy{
+    border: 1px dashed;
+    position:absolute;
+    overflow:hidden;
+    display:none;
+	left:0;
+    top:0;
+    z-index:50000;
+}
+.x-resizable-overlay{
+    width:100%;
+	height:100%;
+	display:none;
+	position:absolute;
+	left:0;
+	top:0;
+	z-index:200000;
+	-moz-opacity: 0;
+    opacity:0;
+    filter: alpha(opacity=0);
+}
+.x-grid3 {
+  position: relative;
+  overflow: hidden;
+}
+
+.x-grid-panel .x-panel-body {
+  overflow: hidden !important;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+  border: 1px solid;
+}
+
+.x-grid3 .x-grid3-row-table {
+  table-layout: fixed;
+}
+
+.x-grid3-viewport {
+  overflow: hidden;
+}
+
+.x-grid3-hd-row .x-grid3-hd,.x-grid3-row .x-grid3-hd,.x-grid3-summary-row .x-grid3-hd {
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.x-grid3-row,.x-grid3-summary-row{
+  -moz-user-select: none;
+  -khtml-user-select: none;
+  -webkit-user-select: ignore;
+}
+
+.x-grid3-row td.x-grid3-cell,.x-grid3-summary-row td.x-grid3-cell {
+  line-height: 13px;
+  vertical-align: top;
+  padding-left: 1px;
+  padding-right: 1px;
+  -moz-outline: none;
+}
+
+.x-grid3-hd-row .x-grid3-hd {
+  line-height: 15px;
+  vertical-align: middle;
+  border-left: 1px solid;
+  border-right: 1px solid;
+}
+
+.x-grid3-hd-row .x-grid3-marker-hd {
+  padding: 3px;
+}
+
+.x-grid3-row .x-grid3-marker {
+  padding: 3px;
+}
+
+.x-grid3-cell-inner,.x-grid3-hd-inner {
+  overflow: hidden;
+  -o-text-overflow: ellipsis;
+  text-overflow: ellipsis;
+  padding: 3px 3px 3px 5px;
+  white-space: nowrap;
+}
+
+.x-grid3-hd-inner {
+  position: relative;
+  cursor: inherit;
+  padding: 4px 3px 4px 5px;
+  vertical-align: middle;
+}
+
+.ext-ie .x-grid3-hd-inner {
+  position: static;
+}
+
+.x-grid3-row-body {
+  white-space: normal;
+  font-size: 11px;
+}
+
+.x-grid3-body-cell {
+  -moz-outline: 0 none;
+  outline: 0 none;
+}
+
+.ext-ie .x-grid3-cell-inner,.ext-ie .x-grid3-hd-inner {
+  width: 100%;
+}
+
+.ext-strict .x-grid3-cell-inner,.ext-strict .x-grid3-hd-inner {
+  width: auto;
+}
+
+.x-grid-row-loading {
+  background: no-repeat center center;
+}
+
+.x-grid-page {
+  overflow: hidden;
+}
+
+.x-grid3-row {
+  cursor: default;
+  border: 1px solid;
+  width: 100%;
+}
+
+.x-grid3-row-over {
+  border: 1px solid;
+  background: repeat-x left top;
+}
+
+.x-grid3-resize-proxy {
+  width: 1px;
+  left: 0;
+  cursor: e-resize;
+  cursor: col-resize;
+  position: absolute;
+  top: 0;
+  height: 100px;
+  overflow: hidden;
+  visibility: hidden;
+  border: 0 none;
+  z-index: 7;
+}
+
+.x-grid3-resize-marker {
+  width: 1px;
+  left: 0;
+  position: absolute;
+  top: 0;
+  height: 100px;
+  overflow: hidden;
+  visibility: hidden;
+  border: 0 none;
+  z-index: 7;
+}
+
+.x-grid3-focus {
+  position: absolute;
+  left: 0;
+  top: 0;
+  width: 1px;
+  height: 1px;
+  line-height: 1px;
+  font-size: 1px;
+  -moz-outline: 0 none;
+  outline: 0 none;
+  -moz-user-select: text;
+  -khtml-user-select: text;
+  -webkit-user-select: ignore;
+}
+
+.x-grid3-header {
+  background: repeat-x 0 bottom;
+  cursor: default;
+  zoom: 1;
+  padding: 0px 0 0 0;
+}
+
+.x-grid3-header-pop {
+  border-left: 1px solid;
+  float: right;
+  clear: none;
+}
+
+.x-grid3-header-pop-inner {
+  border-left: 1px solid;
+  width: 14px;
+  height: 19px;
+  background: transparent no-repeat center center;
+}
+
+.ext-ie .x-grid3-header-pop-inner {
+  width: 15px;
+}
+
+.ext-strict .x-grid3-header-pop-inner {
+  width: 14px;
+}
+
+.x-grid3-header-inner {
+  overflow: hidden;
+  zoom: 1;
+  float: left;
+}
+
+.x-grid3-header-offset {
+  padding-left: 1px;
+}
+
+td.x-grid3-hd-over,td.sort-desc,td.sort-asc,td.x-grid3-hd-menu-open {
+  border-left: 1px solid;
+  border-right: 1px solid;
+}
+
+td.x-grid3-hd-over .x-grid3-hd-inner,td.sort-desc .x-grid3-hd-inner,td.sort-asc .x-grid3-hd-inner,td.x-grid3-hd-menu-open .x-grid3-hd-inner
+  {
+  background: repeat-x left bottom;
+}
+
+.x-grid3-sort-icon {
+  background-repeat: no-repeat;
+  display: none;
+  height: 4px;
+  width: 13px;
+  margin-left: 3px;
+  vertical-align: middle;
+}
+
+.sort-asc .x-grid3-sort-icon,.sort-desc .x-grid3-sort-icon {
+  display: inline;
+}
+
+.ext-strict .ext-ie .x-grid3-header-inner,.ext-strict .ext-ie6 .x-grid3-hd {
+  position: relative;
+}
+
+.ext-strict .ext-ie6 .x-grid3-hd-inner {
+  position: static;
+}
+
+.x-grid3-body {
+  zoom: 1;
+}
+
+.x-grid3-scroller {
+  overflow: auto;
+  zoom: 1;
+  position: relative;
+}
+
+.x-grid3-cell-text,.x-grid3-hd-text {
+  display: block;
+  padding: 3px 5px 3px 5px;
+}
+
+.x-grid3-split {
+  background-position: center;
+  background-repeat: no-repeat;
+  cursor: e-resize;
+  cursor: col-resize;
+  display: block;
+  font-size: 1px;
+  height: 16px;
+  overflow: hidden;
+  position: absolute;
+  top: 2px;
+  width: 6px;
+  z-index: 3;
+}
+
+.x-dd-drag-proxy .x-grid3-hd-inner {
+  background: repeat-x left bottom;
+  width: 120px;
+  padding: 3px;
+  border: 1px solid;
+  overflow: hidden;
+}
+
+.col-move-top,.col-move-bottom {
+  width: 9px;
+  height: 9px;
+  position: absolute;
+  top: 0;
+  line-height: 1px;
+  font-size: 1px;
+  overflow: hidden;
+  visibility: hidden;
+  z-index: 20000;
+  background: transparent no-repeat left top;
+}
+
+.x-grid3-row-selected {
+  border: 1px dotted;
+}
+
+.x-grid3-locked td.x-grid3-row-marker,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker
+  {
+  background: repeat-x 0 bottom !important;
+  vertical-align: middle !important;
+  padding: 0;
+  border-top: 1px solid;
+  border-bottom: none !important;
+  border-right: 1px solid !important;
+  text-align: center;
+}
+
+.x-grid3-locked td.x-grid3-row-marker div,.x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div
+  {
+  padding: 0 4px;
+  text-align: center;
+}
+
+.x-grid3-dirty-cell {
+  background: transparent no-repeat 0 0;
+}
+
+.x-grid3-topbar,.x-grid3-bottombar {
+  overflow: hidden;
+  display: none;
+  zoom: 1;
+  position: relative;
+}
+
+.x-grid3-topbar .x-toolbar {
+  border-right: 0 none;
+}
+
+.x-grid3-bottombar .x-toolbar {
+  border-right: 0 none;
+  border-bottom: 0 none;
+  border-top: 1px solid;
+}
+
+.x-props-grid .x-grid3-cell {
+  padding: 1px;
+}
+
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner {
+  background: transparent repeat-y -16px !important;
+  padding-left: 12px;
+}
+
+.x-props-grid .x-grid3-body .x-grid3-td-name {
+  padding: 1px;
+  padding-right: 0;
+  border: 0 none;
+  border-right: 1px solid;
+}
+
+.x-grid3-col-dd {
+  border: 0 none;
+  padding: 0;
+  background: transparent;
+}
+
+.x-dd-drag-ghost .x-grid3-dd-wrap {
+  padding: 1px 3px 3px 1px;
+}
+
+.x-grid3-hd {
+  -moz-user-select: none;
+  -khtml-user-select: none;
+  -webkit-user-select: ignore;
+}
+
+.x-grid3-hd-btn {
+  display: none;
+  position: absolute;
+  width: 14px;
+  background: no-repeat left center;
+  right: 0;
+  top: 0;
+  z-index: 2;
+  cursor: pointer;
+}
+
+.x-grid3-hd-over .x-grid3-hd-btn,.x-grid3-hd-menu-open .x-grid3-hd-btn {
+  display: block;
+}
+
+a.x-grid3-hd-btn:hover {
+  background-position: -14px center;
+}
+
+.x-grid3-body .x-grid3-td-expander {
+  background: transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-expander .x-grid3-cell-inner {
+  padding: 0 !important;
+  height: 100%;
+}
+
+.x-grid3-row-expander {
+  width: 100%;
+  height: 18px;
+  background-position: 4px 2px;
+  background-repeat: no-repeat;
+  background-color: transparent;
+}
+
+.x-grid3-row-collapsed .x-grid3-row-expander {
+  background-position: 4px 2px;
+}
+
+.x-grid3-row-expanded .x-grid3-row-expander {
+  background-position: -21px 2px;
+}
+
+.x-grid3-row-collapsed .x-grid3-row-body {
+  display: none !important;
+}
+
+.x-grid3-row-expanded .x-grid3-row-body {
+  display: block !important;
+}
+
+.x-grid3-body .x-grid3-td-checker {
+  background: transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-checker .x-grid3-cell-inner,.x-grid3-header .x-grid3-td-checker .x-grid3-hd-inner {
+  padding: 0 !important;
+  height: 100%;
+}
+
+.x-grid3-row-checker,.x-grid3-hd-checker {
+  width: 100%;
+  height: 18px;
+  background-position: 2px 2px;
+  background-repeat: no-repeat;
+  background-color: transparent;
+}
+.x-grid3-hd-checker {
+  padding-bottom: 0px !important; 
+}
+.x-grid3-row .x-grid3-row-checker {
+  background-position: 2px 2px;
+}
+
+.x-grid3-row-selected .x-grid3-row-checker,.x-grid3-hd-checker-on .x-grid3-hd-checker,.x-grid3-row-checked .x-grid3-row-checker
+  {
+  background-position: -23px 2px;
+}
+
+.x-grid3-hd-checker {
+  background-position: 2px 3px;
+}
+
+.x-grid3-hd-checker-on .x-grid3-hd-checker {
+  background-position: -23px 3px;
+}
+
+.x-grid3-body .x-grid3-td-numberer {
+  background: transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+  padding: 3px 5px 0 0 !important;
+  text-align: right;
+}
+
+.x-grid3-body .x-grid3-td-row-icon {
+  background: transparent repeat-y right;
+  vertical-align: top;
+  text-align: center;
+}
+
+.x-grid3-body .x-grid3-td-row-icon .x-grid3-cell-inner {
+  padding: 0 !important;
+  background-position: center center;
+  background-repeat: no-repeat;
+  width: 16px;
+  height: 16px;
+  margin-left: 2px;
+  margin-top: 3px;
+}
+
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander
+  {
+  background: transparent repeat-y right;
+}
+
+.x-grid3-body .x-grid3-check-col-td .x-grid3-cell-inner {
+  padding: 1px 0 0 0 !important;
+}
+
+.x-grid3-check-col {
+  width: 100%;
+  height: 16px;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-color: transparent;
+}
+
+.x-grid3-check-col-on {
+  width: 100%;
+  height: 16px;
+  background-position: center center;
+  background-repeat: no-repeat;
+  background-color: transparent;
+}
+
+.x-grid-group,.x-grid-group-body,.x-grid-group-hd {
+  zoom: 1;
+}
+
+.x-grid-group-hd {
+  border-bottom: 2px solid;
+  cursor: pointer;
+  padding-top: 6px;
+}
+
+.x-grid-group-hd div {
+  background: transparent no-repeat 3px -47px;
+  padding: 4px 4px 4px 17px;
+}
+
+.x-grid-group-collapsed .x-grid-group-hd div {
+  background-position: 3px 3px;
+}
+
+.x-grid-group-collapsed .x-grid-group-body {
+  display: none;
+}
+
+.x-grid-empty {
+  padding: 10px;
+}
+
+.ext-ie7 .x-grid-panel .x-panel-bbar {
+  position: relative;
+}
+
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+  padding-right: 0;
+  border-right: 1px solid;
+}
+
+.ext-ie6 .x-grid3-header {
+  position: relative;
+}
+
+.x-grid3-check-col-disabled {
+  width: 100%;
+  height: 16px;
+  background-position: center center;
+  background-repeat: no-repeat;
+}
+
+.x-row-editor-header {
+  height: 2px;
+  overflow: hidden;
+}
+.x-row-editor-footer {
+  height: 2px;
+  overflow: hidden;
+}
+
+.ext-ie8 .x-row-editor .x-form-field-wrap .x-form-text, .ext-ie8-compatibility .x-row-editor .x-form-field-wrap .x-form-text {
+  margin: -1px 0;
+}
+.ext-ie .x-row-editor-footer {
+  margin-top: -1px;
+}
+
+.x-row-editor-body {
+  overflow: hidden;
+  zoom: 1;
+  padding-top: 2px;
+}
+
+.x-row-editor .x-btns {
+  position: absolute;
+  top: 28px;
+  left: 20px;
+  padding-left: 5px;
+}
+
+.x-row-editor .x-btns .x-plain-bwrap {
+  padding-right: 5px;
+}
+
+.x-row-editor .x-btns .x-plain-body {
+  height: 31px;
+}
+
+.x-row-editor .x-btns .x-table-layout-cell {
+  padding: 3px;
+}
+
+.x-grid3-footer {
+  background: #f7f7f7 none repeat scroll 0 0;
+  border-top: 1px solid #DDDDDD;
+  border-bottom: 1px solid #DDDDDD;
+  display: block;
+  overflow: hidden;
+  position: relative;
+}
+
+.x-grid3-footer-row {
+  border-top: 1px solid #EEEEEE;
+  background-color: #f7f7f7;
+  -moz-user-select: none;
+  -khtml-user-select: none;
+  -webkit-user-select: ignore;
+}
+
+.x-grid3-footer-row td {
+  line-height: 13px;
+  vertical-align: top;
+  padding-left: 1px;
+  padding-right: 1px;
+  font: normal 11px arial, tahoma, helvetica, sans-serif;
+}.x-dd-drag-proxy{
+	position:absolute;
+	left:0;
+    top:0;
+	visibility:hidden;
+	z-index:15000;
+}
+.x-dd-drag-ghost{
+	-moz-opacity: 0.85;
+    opacity:.85;
+    filter: alpha(opacity=85);
+    border: 1px solid;
+	padding:3px;
+	padding-left:20px;
+	white-space:nowrap;
+}
+.x-dd-drag-repair .x-dd-drag-ghost{
+	-moz-opacity: 0.4;
+    opacity:.4;
+    filter: alpha(opacity=40);
+	border:0 none;
+	padding:0;
+	background-color:transparent;
+}
+.x-dd-drag-repair .x-dd-drop-icon{
+	visibility:hidden;
+}
+.x-dd-drop-icon{
+    position:absolute;
+	top:3px;
+	left:3px;
+	display:block;
+	width:16px;
+	height:16px;
+	background-color:transparent;
+	background-position: center;
+	background-repeat: no-repeat;
+	z-index:1;
+}
+.x-view-selector {
+    position:absolute;
+    left:0;
+    top:0;
+    width:0;
+    border:1px dotted;
+	opacity: .5;
+    -moz-opacity: .5;
+    filter:alpha(opacity=50);
+    zoom:1;
+}
+
+.x-dd-cursor {
+  cursor: default !important; 
+}
+
+.x-insert-bar {
+  position: absolute;
+
+  z-index: 99999;
+}
+
+.x-insert-bar td {
+  line-height: 1px;
+  font-size: 1px;
+}
+
+.x-insert-left {
+  background: url(../images/gxt/dd/insert-bg.gif) no-repeat;
+}
+
+.x-insert-mid {
+  background: url(../images/gxt/dd/insert-bg.gif) repeat-x 0 -12px;
+}
+
+.x-insert-right {
+  background: url(../images/gxt/dd/insert-bg.gif) no-repeat 0px -6px;
+}
+.tree-folder {
+	background: url(../images/gxt/icons/folder-closed.gif) no-repeat center
+		left !important;
+}
+
+.tree-folder-open {
+	background: url(../images/gxt/icons/folder.gif) no-repeat center left
+		!important;
+}
+
+.my-tree {
+	cursor: default;
+	font-size: 11px;
+	-moz-outline: none;
+	-moz-user-focus: none;
+}
+
+.my-root-item {
+	padding: 4px;
+}
+
+.my-tree-item,.my-tree-item table,.my-tree-item table td {
+	-moz-outline: none;
+	-moz-user-focus: normal;
+	font-size: 11px;
+}
+
+.my-tree-item td {
+	height: 19px;
+}
+
+.my-tree-indent {
+	line-height: 1px;
+	font-size: 1px;
+}
+
+.my-tree-joint div {
+	width: 15px;
+	height: 19px;
+	line-height: 1px;
+	font-size: 1px;
+}
+
+.my-tree-left,.my-tree-left div,.my-tree-right {
+	line-height: 1px;
+	font-size: 1px;
+	width: 3px;
+}
+
+.my-tree-left div,.my-tree-right div {
+	width: 3px;
+}
+
+.my-tree-item,.my-treeitem-wrap {
+	-moz-outline: none;
+	-moz-user-focus: normal;
+}
+
+.my-tree-check div {
+	width: 17px;
+	height: 17px;
+	line-height: 1px;
+	font-size: 1px;
+}
+
+.my-tree-icon div {
+	width: 16px;
+	height: 17px;
+	cursor: pointer;
+	background-repeat: no-repeat;
+	background-position: center;
+}
+
+.my-tree-item-text span {
+	font-family: arial, tahoma, helvetica, sans-serif;
+	font-size: 12px;
+	white-space: nowrap;
+	padding-left: 3px;
+	padding-right: 3px;
+	display: block;
+	height: 15px;
+	cursor: pointer;
+}
+
+.my-tree-over .my-tree-left {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left
+		-57px;
+}
+
+.my-tree-over .my-tree-right {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right
+		-76px;
+}
+
+.my-tree-over .my-tree-check,.my-tree-over .my-tree-icon,.my-tree-over .my-tree-item-text
+	{
+	background: url(../images/gxt/shared/select-19-bg.gif) left -95px;
+}
+
+.my-tree-sel .my-tree-left {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left
+		0px;
+}
+
+.my-tree-sel .my-tree-right {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right
+		-19px;
+}
+
+.my-tree-sel .my-tree-check,.my-tree-sel .my-tree-icon,.my-tree-sel .my-tree-item-text
+	{
+	background: url(../images/gxt/shared/select-19-bg.gif) left -38px;
+}
+
+.my-tree-drop .my-tree-left {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left
+		-115px;
+}
+
+.my-tree-drop .my-tree-right {
+	background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right
+		-133px;
+}
+
+.my-tree-drop .my-tree-check,.my-tree-drop .my-tree-icon,.my-tree-drop .my-tree-item-text
+	{
+	background: url(../images/gxt/shared/select-19-bg.gif) left -152px;
+}
+
+.my-tree-close {
+	background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px
+		1px;
+}
+
+.my-tree-open {
+	background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px
+		-32px;
+}
+
+.my-tree-joint-over  .my-tree-open {
+	background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px
+		-48px;
+}
+
+.my-tree-joint-over .my-tree-close {
+	background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px
+		-15px;
+}
+
+.my-tree-notchecked {
+	background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 50%;
+}
+
+.my-tree-checked {
+	background: url(../images/gxt/tree/checked.gif) no-repeat 0px 50%;
+}
+
+.my-tree-loading .tree-folder {
+	background: url(../images/gxt/icons/wait.gif) no-repeat 0px -1px
+		!important;
+}
+
+.my-tree-loading .my-tree-item-text span {
+	font-style: italic;
+}
+
+.x-ftree-selected .x-ftree-text {
+	background-color: #d9e8fb;
+}
+
+.x-ftree-node-over .x-ftree-text {
+	background-color: #eee;
+}
+
+.x-ftree-item {
+	line-height: 18px;
+}
+
+.x-ftree-joint,.x-ftree-icon {
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: top;
+	width: 16px;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+
+.x-ftree-text {
+	color: black;
+	font: normal 11px arial, tahoma, helvetica, sans-serif;
+	white-space: nowrap;
+	text-decoration: none;
+	color: black;
+	padding-left: 4px;
+	vertical-align: middle;
+	line-height: 18px;
+	padding: 2px 4px 4px 4px;
+}
+
+/* some default icons for leaf/folder */
+.x-ftree-expanded .x-ftree-icon {
+	background-image: url(../images/default/tree/folder-open.gif);
+}
+
+.x-ftree-leaf .x-ftree-icon {
+	background-image: url(../images/default/tree/leaf.gif);
+}
+
+.x-ftree-collapsed .x-ftree-icon {
+	background-image: url(../images/gxt/icons/folder-closed.gif);
+}
+
+/* Arrows */
+.x-ftree-arrows .x-ftree-joint {
+	background: transparent;
+}
+
+.x-ftree-arrows .x-ftree-joint-plus {
+	background: transparent url(../images/default/tree/arrows.gif) no-repeat
+		0 0;
+}
+
+.x-ftree-arrows .x-ftree-joint-minus {
+	background: transparent url(../images/default/tree/arrows.gif) no-repeat
+		-16px 0;
+}
+
+.x-ftree-arrows .x-ftree-ec-over .x-ftree-joint-plus {
+	background-position: -32px 0;
+}
+
+.x-ftree-arrows .x-ftree-ec-over .x-ftree-joint-minus {
+	background-position: -48px 0;
+}
+
+.x-ftree2-selected {
+	background-color: #d9e8fb !important;
+}
+
+.x-ftree2-node-over {
+	background-color: #eee;
+}
+
+.x-ftree2-node-drop {
+	background-color: #defadc;
+}
+
+.x-ftree2-joint,.x-ftree2-icon {
+	border: 0 none;
+	height: 18px;
+	margin: 0;
+	padding: 0;
+	vertical-align: top;
+	width: 16px;
+	background-position: center;
+	background-repeat: no-repeat;
+}
+
+.x-ftree2-joint div {
+	width: 16px;
+}
+
+.x-ftree2-el-ct {
+	display: none;
+}
+
+.x-ftree2-node {
+	padding-bottom: 1px;
+}
+
+.x-ftree2-text {
+	vertical-align: middle !important;
+	white-space: nowrap !important;
+}
+
+.x-ftree2-text span {
+	color: black;
+	font: normal 11px arial, tahoma, helvetica, sans-serif;
+	white-space: nowrap;
+	text-decoration: none;
+	color: black;
+	padding: 2px 4px 2px 1px;
+	display: block;
+}
+
+.ext-ie .x-ftree2-text span {
+	padding-left: 3px;
+}
+
+.x-ftree2-check {
+	width: 17px;
+}
+
+.x-ftree2-check div {
+	width: 17px;
+	height: 17px;
+}
+
+/* some default icons for leaf/folder */
+.x-ftree2-expanded .x-ftree2-icon {
+	background-image: url(../images/default/tree/folder-open.gif);
+}
+
+.x-ftree2-leaf .x-ftree2-icon {
+	background-image: url(../images/default/tree/leaf.gif);
+}
+
+.x-ftree2-collapsed .x-ftree2-icon {
+	background-image: url(../images/gxt/icons/folder-closed.gif);
+}
+
+/* Arrows */
+.x-ftree2-arrows .x-ftree2-joint {
+	background: transparent;
+}
+
+.x-ftree2-arrows .x-ftree2-joint-plus {
+	background: transparent url(../images/default/tree/arrows.gif) no-repeat
+		0 0;
+}
+
+.x-ftree2-arrows .x-ftree2-joint-minus {
+	background: transparent url(../images/default/tree/arrows.gif) no-repeat
+		-16px 0;
+}
+
+.x-ftree2-arrows .x-ftree2-ec-over .x-ftree2-joint-plus {
+	background-position: -32px 0;
+}
+
+.x-ftree2-arrows .x-ftree2-ec-over .x-ftree2-joint-minus {
+	background-position: -48px 0;
+}
+
+.x-treegrid {
+	-moz-outline: none;
+	-moz-user-focus: none;
+}
+
+.x-treegrid .x-treegrid-column .x-grid3-cell-inner {
+	padding: 0px !important;
+}
+
+.x-tree3 {
+	cursor: default;
+	-moz-outline: none;
+	-moz-user-focus: none;
+}
+
+.x-tree3-node {
+	cursor: default;
+}
+
+.x-tree3-el {
+	white-space: nowrap;
+	height: 21px;
+	position: relative;
+}
+
+.x-tree3-node-text {
+	white-space: nowrap;
+	line-height: 11px;
+	text-decoration: none;
+	padding: 0 0 0 3px;
+	position: relative;
+	top: -4px;
+}
+
+.x-tree3-node-ct {
+	display: none;
+}
+
+.x-tree3-node-text-widget {
+	position: static !important;
+	padding: 0px !important;
+}.x-date-picker {
+    border: 1px solid;
+    border-top:0 none;
+	position:relative;
+}
+.x-date-picker a {
+    -moz-outline:0 none;
+    outline:0 none;
+}
+.x-date-inner, .x-date-inner td, .x-date-inner th{
+    border-collapse:separate;
+}
+.x-date-middle,.x-date-left,.x-date-right {
+	background: repeat-x 0 -83px;
+	overflow:hidden;
+}
+.x-date-middle .x-btn-tc,.x-date-middle .x-btn-tl,.x-date-middle .x-btn-tr,
+.x-date-middle .x-btn-mc,.x-date-middle .x-btn-ml,.x-date-middle .x-btn-mr,
+.x-date-middle .x-btn-bc,.x-date-middle .x-btn-bl,.x-date-middle .x-btn-br{
+	background:transparent !important;
+    vertical-align:middle;
+}
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+    background:transparent no-repeat right 0;
+}
+.x-date-right, .x-date-left {
+    width:18px;
+}
+.x-date-right{
+    text-align:right;
+}
+.x-date-middle {
+    padding-top:2px;
+    padding-bottom:2px;
+    width:130px;  
+}
+.x-date-right a, .x-date-left a{
+    display:block;
+    width:16px;
+	height:16px;
+	background-position: center;
+	background-repeat: no-repeat;
+	cursor:pointer;
+    -moz-opacity: 0.6;
+    opacity:.6;
+    filter: alpha(opacity=60);
+}
+.x-date-right a:hover, .x-date-left a:hover{
+    -moz-opacity: 1;
+    opacity:1;
+    filter: alpha(opacity=100);
+}
+.x-date-right a {
+    margin-right:2px;
+    text-decoration:none !important;
+}
+.x-date-left a{
+    margin-left:2px;
+    text-decoration:none !important;
+}
+table.x-date-inner {
+    width:100%;
+    table-layout:fixed;
+}
+.x-date-inner th {
+    width:25px;
+}
+.x-date-inner th {
+    background: repeat-x left top;
+    text-align:right !important;
+	border-bottom: 1px solid;
+	cursor:default;
+    padding:0;
+    border-collapse:separate;
+}
+.x-date-inner th span {
+    display:block;
+    padding:2px;
+    padding-right:7px;
+}
+.x-date-inner td {
+    border: 1px solid;
+	text-align:right;
+    padding:0;
+}
+.x-date-inner a {
+    padding:2px 5px;
+    display:block;
+	text-decoration:none;
+    text-align:right;
+    zoom:1;
+}
+.x-date-inner .x-date-active{
+	cursor:pointer;
+	color:black;
+}
+.x-date-inner .x-date-selected a{
+	background: repeat-x left top;
+	border:1px solid;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-today a{
+	border: 1px solid;
+    padding:1px 4px;
+}
+.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a {
+    text-decoration:none !important;
+}
+.x-date-bottom {
+    padding:4px;
+    border-top: 1px solid;
+    background: repeat-x left top;
+}
+.x-date-inner a:hover, .x-date-inner .x-date-disabled a:hover{
+    text-decoration:none !important;
+}
+.x-date-inner .x-date-disabled a {
+	cursor:default;
+}
+.x-date-mmenu .x-menu-item {
+	padding:1px 24px 1px 4px;
+	white-space: nowrap;
+}
+.x-date-mmenu .x-menu-item .x-menu-item-icon {
+    width:10px;
+    height:10px;
+    margin-right:5px;
+    background-position:center -4px !important;
+}
+.x-date-mp {
+	position:absolute;
+	left:0;
+	top:0;
+	display:none;
+}
+.x-date-mp td {
+    padding:2px;
+	font:normal 11px arial, helvetica,tahoma,sans-serif;
+}
+td.x-date-mp-month,td.x-date-mp-year,td.x-date-mp-ybtn {
+    border: 0 none;
+	text-align:center;
+	vertical-align: middle;
+	width:25%;
+}
+.x-date-mp-ok {
+	margin-right:3px;
+}
+.x-date-mp-btns button {
+	text-decoration:none;
+	text-align:center;
+	text-decoration:none !important;
+	border:1px solid;
+	padding:1px 3px 1px;
+	cursor:pointer;
+}
+.x-date-mp-btns {
+	background: repeat-x left top;
+}
+.x-date-mp-btns td {
+	border-top: 1px solid;
+    text-align:center;
+}
+td.x-date-mp-month a,td.x-date-mp-year a {
+	display:block;
+	padding:2px 4px;
+	text-decoration:none;
+	text-align:center;
+}
+td.x-date-mp-month a:hover,td.x-date-mp-year a:hover {
+	text-decoration:none;
+	cursor:pointer;
+}
+td.x-date-mp-sel a {
+	padding:1px 3px;
+	background: repeat-x left top;
+	border:1px solid;
+}
+.x-date-mp-ybtn a {
+    overflow:hidden;
+    width:15px;
+    height:15px;
+    cursor:pointer;
+    background:transparent no-repeat;
+    display:block;
+    margin:0 auto;
+}
+.x-date-mp-ybtn a.x-date-mp-next {
+    background-position:0 -120px;
+}
+.x-date-mp-ybtn a.x-date-mp-next:hover {
+    background-position:-15px -120px;
+}
+.x-date-mp-ybtn a.x-date-mp-prev {
+    background-position:0 -105px;
+}
+.x-date-mp-ybtn a.x-date-mp-prev:hover {
+    background-position:-15px -105px;
+}
+.x-date-mp-ybtn {
+   text-align:center;
+}
+td.x-date-mp-sep {
+   border-right:1px solid;
+}
+
+.x-date-picker, .x-date-picker a {
+  font-size: 11px; 
+}
+
+.x-date-right-icon {
+  background-image: url(../images/default/shared/right-btn.gif);
+  margin-right: 2px;
+  text-decoration: none !important;
+}
+
+.x-date-left-icon {
+  background-image: url(../images/default/shared/left-btn.gif);
+  margin-left: 4px;
+  text-decoration: none !important;
+}
+
+.x-date-days {
+  table-layout: fixed;
+  width: 100%;
+}
+
+.x-date-days td {
+  width: 25px;
+  border: none;
+}
+
+.x-date-days td span {
+  display: block;
+  padding: 2px 7px 2px 2px;
+}
+
+.x-date-days td {
+  background: #DFECFB url(../images/default/shared/glass-bg.gif) repeat-x scroll left top;
+  border-bottom: 1px solid #A3BAD9;
+  border-collapse: separate;
+  color: #233D6D;
+  cursor: default;
+  font-family: arial, helvetica, tahoma, sans-serif;
+  font-size: 10px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  line-height: normal;
+  padding: 0pt;
+  text-align: right !important;
+}
+
+.x-date-picker .x-date-header {
+  background: url(../images/default/shared/hd-sprite.gif) repeat-x 0 -83px;
+  height: 22px;
+  left: 10px;
+  top: 10px;
+  width: 157px;
+}
+
+.x-date-header .x-btn .x-btn-text {
+  color: #fff;
+}
+
+.x-date-picker-footer {
+  width: 100%;
+}
+
+.x-date-picker-footer td {
+  text-align: center;
+}
+
+.x-date-left {
+  background: transparent url(../images/default/shared/hd-sprite.gif) repeat-x scroll 0pt -83px;
+  color: #FFFFFF;
+  font-family: "sans serif", tahoma, verdana, helvetica;
+  font-size: 11px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: bold;
+  line-height: normal;
+  overflow: hidden;
+}
+
+.x-date-inner .x-date-active-hover {
+  background: #ddecfe !important;
+}
+.x-tip{
+	position: absolute;
+	top: 0;
+    left:0;
+    visibility: hidden;
+	z-index: 20000;
+    border:0 none;
+}
+.x-tip .x-tip-close{
+	height: 15px;
+	float:right;
+	width: 15px;
+    margin:0 0 2px 2px;
+    cursor:pointer;
+    display:none;
+}
+.x-tip .x-tip-tc {
+	background: transparent no-repeat 0 -62px;
+	padding-top:3px;
+    overflow:hidden;
+    zoom:1;
+}
+.x-tip .x-tip-tl {
+	background: transparent no-repeat 0 0;
+	padding-left:6px;
+    overflow:hidden;
+    zoom:1;
+}
+.x-tip .x-tip-tr {
+	background: transparent no-repeat right 0;
+	padding-right:6px;
+    overflow:hidden;
+    zoom:1;
+}
+.x-tip .x-tip-bc {
+	background: transparent no-repeat 0 -121px;
+	height:3px;
+    overflow:hidden;
+}
+.x-tip .x-tip-bl {
+	background: transparent no-repeat 0 -59px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-br {
+	background: transparent no-repeat right -59px;
+	padding-right:6px;
+    zoom:1;
+}
+.x-tip .x-tip-mc {
+    border:0 none;
+}
+.x-tip .x-tip-ml {
+	background: no-repeat 0 -124px;
+	padding-left:6px;
+    zoom:1;
+}
+.x-tip .x-tip-mr {
+	background: transparent no-repeat right -124px;
+	padding-right:6px;
+    zoom:1;
+}
+.ext-ie .x-tip .x-tip-header,.ext-ie .x-tip .x-tip-tc {
+    font-size:0;
+    line-height:0;
+}
+.x-tip .x-tip-header-text {
+    padding:0;
+    margin:0 0 2px 0;
+}
+.x-tip .x-tip-body {
+    margin:0 !important;
+    line-height:14px;
+    padding:0;
+}
+.x-tip .x-tip-body .loading-indicator {
+    margin:0;
+}
+.x-tip-draggable .x-tip-header,.x-tip-draggable .x-tip-header-text {
+    cursor:move;
+}
+.x-form-invalid-tip .x-tip-tc {
+	background: repeat-x 0 -12px;
+    padding-top:6px;
+}
+.x-form-invalid-tip .x-tip-bc {
+	background: repeat-x 0 -18px;
+    height:6px;
+}
+.x-form-invalid-tip .x-tip-bl {
+	background: no-repeat 0 -6px;
+}
+.x-form-invalid-tip .x-tip-br {
+	background: no-repeat right -6px;
+}
+.x-form-invalid-tip .x-tip-body {
+    padding:2px;
+}
+.x-form-invalid-tip .x-tip-body {
+    padding-left:24px;
+    background:transparent no-repeat 2px 2px;
+}
+.x-tip-anchor {
+    position: absolute;
+    width: 9px;
+    height: 10px;
+    overflow:hidden;
+    background: transparent no-repeat 0 0;
+    zoom:1;
+}
+.x-tip-anchor-bottom {
+    background-position: -9px 0;
+}
+.x-tip-anchor-right {
+    background-position: -18px 0;
+    width: 10px;
+}
+.x-tip-anchor-left {
+    background-position: -28px 0;
+    width: 10px;
+}
+.x-menu {
+  border: 1px solid;
+  z-index: 15000;
+  zoom: 1;
+  background: repeat-y;
+  -moz-outline: none;
+}
+
+.x-menu a {
+  text-decoration: none !important;
+}
+
+.ext-ie .x-menu {
+  zoom: 1;
+  overflow: hidden;
+}
+
+.x-menu-list {
+  padding: 2px;
+  background: transparent;
+  border: 0 none;
+  overflow: hidden;
+  overflow-y: hidden;
+}
+
+.ext-strict .ext-ie .x-menu-list {
+  position: relative;
+}
+
+.x-menu li {
+  line-height: 100%;
+}
+
+.x-menu li.x-menu-sep-li {
+  font-size: 1px;
+  line-height: 1px;
+}
+
+.x-menu-list-item {
+  white-space: nowrap;
+  -moz-user-select: none;
+  -khtml-user-select: none;
+   -webkit-user-select: ignore
+  display: block;
+  padding: 1px;
+}
+
+.x-menu-item-arrow {
+  background: transparent no-repeat right;
+}
+
+.x-menu-sep {
+  display: block;
+  font-size: 1px;
+  line-height: 1px;
+  margin: 2px 3px;
+  border-bottom: 1px solid;
+  overflow: hidden;
+}
+
+.x-menu-focus {
+  position: absolute;
+  left: -1px;
+  top: -1px;
+  width: 1px;
+  height: 1px;
+  line-height: 1px;
+  font-size: 1px;
+  -moz-outline: 0 none;
+  outline: 0 none;
+  -moz-user-select: none;
+  -khtml-user-select: none;
+   -webkit-user-select: ignore
+  overflow: hidden;
+  display: block;
+}
+
+a.x-menu-item {
+  cursor: pointer;
+  display: block;
+  line-height: 16px;
+  outline-color: -moz-use-text-color;
+  outline-style: none;
+  outline-width: 0;
+  padding: 3px 21px 3px 27px;
+  position: relative;
+  text-decoration: none;
+  white-space: nowrap;
+}
+
+.x-menu-item-active {
+  border-style: solid;
+  border-width: 1px;
+  padding: 0;
+}
+
+.x-menu-item-icon {
+  border: 0 none;
+  height: 16px;
+  padding: 0;
+  vertical-align: top;
+  width: 16px;
+  position: absolute;
+  left: 3px;
+  top: 3px;
+  margin: 0;
+  background-position: center;
+}
+
+.ext-ie .x-menu-item-icon {
+  left: -24px;
+}
+
+.ext-strict .x-menu-item-icon {
+  left: 3px;
+}
+
+.ext-ie6 .x-menu-item-icon {
+  left: -24px;
+}
+
+.ext-ie .x-menu-item-icon {
+  vertical-align: middle;
+}
+
+.x-date-menu .x-menu-list {
+  padding: 0;
+}
+
+.x-menu-date-item {
+  padding: 0;
+}
+
+.x-menu .x-color-palette,.x-menu .x-date-picker {
+  margin-left: 26px;
+  margin-right: 4px;
+}
+
+.x-menu .x-date-picker {
+  border: 1px solid;
+  margin-top: 2px;
+  margin-bottom: 2px;
+}
+
+.x-menu-plain .x-color-palette,.x-menu-plain .x-date-picker {
+  margin: 0;
+  border: 0 none;
+}
+
+.x-date-menu {
+  padding: 0 !important;
+}
+
+.x-cycle-menu .x-menu-item-checked {
+  border: 1px dotted !important;
+  padding: 0;
+}
+
+.x-menu .x-menu-scroller {
+  width: 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+  height: 8px;
+  line-height: 8px;
+  cursor: pointer;
+  margin: 0;
+  padding: 0;
+}
+
+.x-menu .x-menu-scroller-active {
+  height: 6px;
+  line-height: 6px;
+}
+
+.x-menu-list-item-indent {
+  padding-left: 27px;
+}
+
+.x-menu-text {
+  
+  border-style: solid;
+  background: #D6E3F2;
+  border-color:#DAE6F4 #99bbe8 #99bbe8 #DAE6F4;
+  border-width: 1px;
+  margin:-2px -2px 0;
+  color:#15428b;
+  font:bold 10px tahoma,arial,verdana,sans-serif;
+  display:block;
+  padding:3px;
+}
+
+.x-menubar {
+  padding: 3px;
+  border-style: solid;
+  border-width: 0 0 1px 0;
+  cursor: default;
+  border-color: #a9bfd3;
+  background-color: #d0def0;
+  padding: 3px;
+  background-image: url(../images/default/toolbar/bg.gif);
+}
+
+.x-menubar-item {
+  padding: 1px 8px;
+  font: 12px arial, verdana, sans-serif;
+}
+
+.x-menubar-item-over {
+  background-color: #98c5f5;
+}
+
+.x-menubar-item-active {
+  background-color: #98c5f5;
+}.x-box-tl {
+	background: transparent no-repeat 0 0;
+    zoom:1;
+}
+.x-box-tc {
+	height: 8px;
+	background: transparent repeat-x 0 0;
+	overflow: hidden;
+}
+.x-box-tr {
+	background: transparent no-repeat right -8px;
+}
+.x-box-ml {
+	background: transparent repeat-y 0;
+	padding-left: 4px;
+	overflow: hidden;
+    zoom:1;
+}
+.x-box-mc {
+	background: repeat-x 0 -16px;
+	padding: 4px 10px;
+}
+.x-box-mc h3 {
+	margin: 0 0 4px 0;
+    zoom:1;
+}
+.x-box-mr {
+	background: transparent repeat-y right;
+	padding-right: 4px;
+	overflow: hidden;
+}
+.x-box-bl {
+	background: transparent no-repeat 0 -16px;
+    zoom:1;
+}
+.x-box-bc {
+	background: transparent repeat-x 0 -8px;
+	height: 8px;
+	overflow: hidden;
+}
+.x-box-br {
+	background: transparent no-repeat right -24px;
+}
+.x-box-tl, .x-box-bl {
+	padding-left: 8px;
+	overflow: hidden;
+}
+.x-box-tr, .x-box-br {
+	padding-right: 8px;
+	overflow: hidden;
+}
+.x-combo-list {
+    border:1px solid;
+    zoom:1;
+    overflow:hidden;
+}
+.x-combo-list-inner {
+    overflow:auto;
+    position:relative;  
+    zoom:1;
+    overflow-x:hidden;
+}
+.x-combo-list-hd {
+    border-bottom:1px solid;
+    padding:3px;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom:1px solid;
+}
+.x-combo-list-item {
+    padding:2px;
+    border:1px solid;
+    white-space: nowrap;
+    overflow:hidden;
+    text-overflow: ellipsis;
+}
+.x-combo-list .x-combo-selected{
+	border:1px dotted !important;
+    cursor:pointer;
+}
+.x-combo-list .x-toolbar {
+    border-top:1px solid;
+    border-bottom:0 none;
+}
+.x-panel {
+    border-style: solid;
+    border-width:0;
+}
+.x-panel-header {
+    overflow:hidden;
+    zoom:1;
+    padding:5px 3px 4px 5px;
+    border:1px solid;
+    line-height: 15px;
+    background: transparent repeat-x 0 -1px;
+}
+.x-panel-body {
+    border:1px solid;
+    border-top:0 none;
+    overflow:hidden;
+    position: relative;  
+}
+.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar {
+    border:1px solid;
+    border-top:0 none;
+    overflow:hidden;
+    padding:2px;
+}
+.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar {
+    border-top:1px solid;
+    border-bottom: 0 none;
+}
+.x-panel-body-noheader, .x-panel-mc .x-panel-body {
+    border-top:1px solid;
+}
+.x-panel-header {
+    overflow:hidden;
+    zoom:1;
+}
+.x-panel-tl .x-panel-header {
+    padding:5px 0 4px 0;
+    border:0 none;
+    background:transparent;
+    line-height: 15px;
+}
+.x-panel-tl .x-panel-icon, .x-window-tl .x-panel-icon {
+    padding-left:20px !important;
+    background-repeat:no-repeat;
+    background-position:0 4px;
+    zoom:1;
+}
+.x-panel-inline-icon {
+    width:16px;
+	height:16px;
+    background-repeat:no-repeat;
+    background-position:0 0;
+	vertical-align:middle;
+	margin-right:4px;
+	margin-top:-1px;
+	margin-bottom:-1px;
+}
+.x-panel-tc {
+	background: transparent repeat-x 0 0;
+	overflow:hidden;
+}
+.ext-strict .ext-ie7 .x-panel-tc {
+    overflow: visible;
+}
+.x-panel-tl {
+	background: transparent no-repeat 0 0;
+	padding-left:6px;
+    zoom:1;
+    border-bottom:1px solid;
+}
+.x-panel-tr {
+	background: transparent no-repeat right 0;
+	zoom:1;
+    padding-right:6px;
+}
+.x-panel-bc {
+	background: transparent repeat-x 0 bottom;
+    zoom:1;
+}
+.x-panel-bc .x-panel-footer {
+    zoom:1;
+}
+.x-panel-bl {
+	background: transparent no-repeat 0 bottom;
+	padding-left:6px;
+    zoom:1;
+}
+.x-panel-br {
+	background: transparent no-repeat right bottom;
+	padding-right:6px;
+    zoom:1;
+}
+.x-panel-mc {
+    border:0 none;
+    padding:0;
+    margin:0;
+    padding-top:6px;
+}
+.x-panel-mc .x-panel-body {
+    background:transparent;
+    border: 0 none;
+}
+.x-panel-ml {
+	background: repeat-y 0 0;
+	padding-left:6px;
+    zoom:1;
+}
+.x-panel-mr {
+	background: transparent repeat-y right 0;
+	padding-right:6px;
+    zoom:1;
+}
+.x-panel-bc .x-panel-footer {
+    padding-bottom:6px;
+}
+.x-panel-nofooter .x-panel-bc, .x-panel-nofooter .x-window-bc {
+	height:6px;
+    font-size:0;
+    line-height:0;
+}
+.x-panel-bwrap {
+    overflow:hidden;
+    zoom:1;
+    left:0;
+    top:0;
+}
+.x-panel-body {
+    overflow:hidden;
+    zoom:1;
+}
+.x-panel-collapsed .x-resizable-handle{
+    display:none;
+}
+.ext-gecko .x-panel-animated * {
+    overflow:hidden !important;
+}
+.x-plain-body {
+    overflow:hidden;
+}
+.x-plain-bbar .x-toolbar {
+    overflow:hidden;
+    padding:2px;
+}
+.x-plain-tbar .x-toolbar {
+    overflow:hidden;
+    padding:2px;
+}
+.x-plain-bwrap {
+    overflow:hidden;
+    zoom:1;
+}
+.x-plain {
+    overflow:hidden;
+}
+.x-tool {
+    overflow:hidden;
+    width:15px;
+    height:15px;
+    float:right;
+    cursor:pointer;
+    background:transparent no-repeat;
+    margin-left:2px;
+}
+.x-tool-toggle {
+    background-position:0 -60px;
+}
+.x-tool-toggle-over {
+    background-position:-15px -60px;
+}
+.x-panel-collapsed .x-tool-toggle {
+    background-position:0 -75px;
+}
+.x-panel-collapsed .x-tool-toggle-over {
+    background-position:-15px -75px;
+}
+.x-tool-close {
+    background-position:0 -0;
+}
+.x-tool-close-over {
+    background-position:-15px 0;
+}
+.x-tool-minimize {
+    background-position:0 -15px;
+}
+.x-tool-minimize-over {
+    background-position:-15px -15px;
+}
+.x-tool-maximize {
+    background-position:0 -30px;
+}
+.x-tool-maximize-over {
+    background-position:-15px -30px;
+}
+.x-tool-restore {
+    background-position:0 -45px;
+}
+.x-tool-restore-over {
+    background-position:-15px -45px;
+}
+.x-tool-gear {
+    background-position:0 -90px;
+}
+.x-tool-gear-over {
+    background-position:-15px -90px;
+}
+.x-tool-pin {
+    background-position:0 -135px;
+}
+.x-tool-pin-over {
+    background-position:-15px -135px;
+}
+.x-tool-unpin {
+    background-position:0 -150px;
+}
+.x-tool-unpin-over {
+    background-position:-15px -150px;
+}
+.x-tool-right {
+    background-position:0 -165px;
+}
+.x-tool-right-over {
+    background-position:-15px -165px;
+}
+.x-tool-left {
+    background-position:0 -180px;
+}
+.x-tool-left-over {
+    background-position:-15px -180px;
+}
+.x-tool-up {
+    background-position:0 -210px;
+}
+.x-tool-up-over {
+    background-position:-15px -210px;
+}
+.x-tool-down {
+    background-position:0 -195px;
+}
+.x-tool-down-over {
+    background-position:-15px -195px;
+}
+.x-tool-refresh {
+    background-position:0 -225px;
+}
+.x-tool-refresh-over {
+    background-position:-15px -225px;
+}
+.x-tool-minus {
+    background-position:0 -255px;
+}
+.x-tool-minus-over {
+    background-position:-15px -255px;
+}
+.x-tool-plus {
+    background-position:0 -240px;
+}
+.x-tool-plus-over {
+    background-position:-15px -240px;
+}
+.x-tool-search {
+    background-position:0 -270px;
+}
+.x-tool-search-over {
+    background-position:-15px -270px;
+}
+.x-tool-save {
+    background-position:0 -285px;
+}
+.x-tool-save-over {
+    background-position:-15px -285px;
+}
+.x-tool-help {
+    background-position:0 -300px;
+}
+.x-tool-help-over {
+    background-position:-15px -300px;
+}
+.x-tool-print {
+    background-position:0 -315px;
+}
+.x-tool-print-over {
+    background-position:-15px -315px;
+}
+.x-panel-ghost {
+    z-index:12000;
+    overflow:hidden;
+    position:absolute;
+    left:0;top:0;
+    opacity:.65;
+    -moz-opacity:.65;
+    filter:alpha(opacity=65);
+}
+.x-panel-ghost ul {
+    margin:0;
+    padding:0;
+    overflow:hidden;
+    font-size:0;
+    line-height:0;
+    border:1px solid;
+    border-top:0 none;
+    display:block;
+}
+.x-panel-ghost * {
+    cursor:move !important;
+}
+.x-panel-dd-spacer {
+    border:2px dashed;
+}
+.x-panel-btns {
+    padding:5px;
+    overflow:hidden;
+}
+.x-panel-btns-left .x-buttonbar {
+	clear:none;
+}
+.x-panel-btns-center{
+	text-align:center;  
+}
+.x-panel-btns-center .x-toolbar-ct {
+	margin:0 auto;  
+    text-align:left;
+    width:auto;
+}
+.x-panel-fbar td.x-toolbar-cell{
+	padding:0px;
+}
+.x-panel-fbar {
+    display: block;
+	padding:2px;
+    position:relative;
+    left:0;
+    top:0;
+    zoom:1;
+    overflow:hidden;
+}
+
+.x-panel-fbar .x-toolbar-cell {
+    vertical-align:middle;
+}
+
+.x-panel-fbar td {
+	vertical-align:middle;
+}
+.x-panel-btns .x-btn-focus .x-btn-left{
+	background-position:0 -147px;
+}
+.x-panel-btns .x-btn-focus .x-btn-right{
+	background-position:0 -168px;
+}
+.x-panel-btns .x-btn-focus .x-btn-center{
+	background-position:0 -189px;
+}
+.x-panel-btns .x-btn-over .x-btn-left{
+	background-position:0 -63px;
+}
+.x-panel-btns .x-btn-over .x-btn-right{
+	background-position:0 -84px;
+}
+.x-panel-btns .x-btn-over .x-btn-center{
+	background-position:0 -105px;
+}
+.x-panel-btns .x-btn-click .x-btn-center{
+	background-position:0 -126px;
+}
+.x-panel-btns .x-btn-click  .x-btn-right{
+	background-position:0 -84px;
+}
+.x-panel-btns .x-btn-click .x-btn-left{
+	background-position:0 -63px;
+}
+.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{
+	white-space: nowrap;
+}
+.x-window {
+    zoom:1;
+}
+.x-window .x-resizable-handle {
+    opacity:0;
+    -moz-opacity:0;
+    filter:alpha(opacity=0);
+}
+.x-window-proxy {
+    border:1px solid;
+    z-index:12000;
+    overflow:hidden;
+    position:absolute;
+    left:0;top:0;
+    display:none;
+    opacity:.5;
+    -moz-opacity:.5;
+    filter:alpha(opacity=50);
+}
+.x-window-header {
+    overflow:hidden;
+    zoom:1;
+}
+.x-window-bwrap {
+    z-index:1;
+    position:relative;
+    zoom:1;
+    left:0;top:0;
+}
+.x-window-tl .x-window-header {
+    padding:5px 0 4px 0;
+}
+.x-window-header-text {
+    cursor:pointer;
+}
+.x-window-tc {
+	background: transparent repeat-x 0 0;
+	overflow:hidden;
+    zoom:1;
+}
+.x-window-tl {
+	background: transparent no-repeat 0 0;
+	padding-left:6px;
+    zoom:1;
+    z-index:1;
+    position:relative;
+}
+.x-window-tr {
+	background: transparent no-repeat right 0;
+	padding-right:6px;
+}
+.x-window-bc {
+	background: transparent repeat-x 0 bottom;
+    zoom:1;
+}
+.x-window-bc .x-window-footer {
+    padding-bottom:6px;
+    zoom:1;
+    font-size:0;
+    line-height:0;
+}
+.x-window-bl {
+	background: transparent no-repeat 0 bottom;
+	padding-left:6px;
+    zoom:1;
+}
+.x-window-br {
+	background: transparent no-repeat right bottom;
+	padding-right:6px;
+    zoom:1;
+}
+.x-window-mc {
+    border:1px solid;
+    padding:0;
+    margin:0;
+}
+.x-window-ml {
+	background: transparent repeat-y 0 0;
+	padding-left:6px;
+    zoom:1;
+}
+.x-window-mr {
+	background: transparent repeat-y right 0;
+	padding-right:6px;
+    zoom:1;
+}
+.x-window-body {
+    overflow:hidden;
+}
+.x-window-bwrap {
+    overflow:hidden;
+}
+.x-window-maximized .x-window-bl, .x-window-maximized .x-window-br,
+    .x-window-maximized .x-window-ml, .x-window-maximized .x-window-mr,
+    .x-window-maximized .x-window-tl, .x-window-maximized .x-window-tr {
+    padding:0;
+}
+.x-window-maximized .x-window-footer {
+    padding-bottom:0;
+}
+.x-window-maximized .x-window-tc {
+    padding-left:3px;
+    padding-right:3px;
+}
+.x-window-maximized .x-window-mc {
+    border-left:0 none;
+    border-right:0 none;
+}
+.x-window-tbar .x-toolbar, .x-window-bbar .x-toolbar {
+    border-left:0 none;
+    border-right: 0 none;
+}
+.x-window-bbar .x-toolbar {
+    border-top:1px solid;
+    border-bottom:0 none;
+}
+.x-window-draggable, .x-window-draggable .x-window-header-text {
+    cursor:move;
+}
+.x-window-maximized .x-window-draggable, .x-window-maximized .x-window-draggable .x-window-header-text {
+    cursor:default;
+}
+.x-window-body {
+    background:transparent;
+}
+.x-panel-ghost .x-window-tl {
+    border-bottom:1px solid;
+}
+.x-panel-collapsed .x-window-tl {
+    border-bottom:1px solid;
+}
+.x-window-maximized-ct {
+    overflow:hidden;
+}
+.x-window-maximized .x-resizable-handle {
+    display:none;
+}
+.x-window-sizing-ghost ul {
+    border:0 none !important;
+}
+.x-dlg-focus{
+	-moz-outline:0 none;
+	outline:0 none;
+	width:0;
+	height:0;
+	overflow:hidden;
+	position:absolute;
+	top:0;
+	left:0;
+}
+.x-dlg-mask{
+    z-index:10000;
+    display:none;
+    position:absolute;
+    top:0;
+    left:0;
+    -moz-opacity: 0.5;
+    opacity:.50;
+    filter: alpha(opacity=50);
+}
+body.ext-ie6.x-body-masked select {
+	visibility:hidden;
+}
+body.ext-ie6.x-body-masked .x-window select {
+	visibility:visible;
+}
+.x-window-plain .x-window-mc {
+    border: 1px solid;
+}
+.x-window-plain .x-window-body {
+    border: 1px solid;
+    background:transparent !important;
+}
+.x-html-editor-wrap {
+    border:1px solid;
+}
+
+.x-html-editor-tb .x-btn-text {
+    background:transparent no-repeat;
+}
+
+.x-html-editor-tip .x-tip-bd .x-tip-bd-inner {
+    padding:5px;
+    padding-bottom:1px;
+}
+
+.x-html-editor-tb .x-toolbar {
+    position:static !important;
+}.x-panel-noborder .x-panel-body-noborder {
+    border-width:0;
+}
+.x-panel-noborder .x-panel-header-noborder {
+    border-width:0 0 1px;
+    border-style:solid;
+}
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+    border-width:0 0 1px;
+    border-style:solid;
+}
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+    border-width:1px 0 0 0;
+    border-style:solid;
+}
+.x-window-noborder .x-window-mc {
+    border-width:0;
+}
+.x-window-plain .x-window-body-noborder {
+    border-width:0;
+}
+.x-tab-panel-noborder .x-tab-panel-body-noborder {
+	border-width:0;
+}
+.x-tab-panel-noborder .x-tab-panel-header-noborder {
+    border-width: 0 0 1px 0;
+}
+.x-tab-panel-noborder .x-tab-panel-footer-noborder {
+    border-width: 1px 0 0 0;
+}
+.x-tab-panel-bbar-noborder .x-toolbar {
+    border-width: 1px 0 0 0;
+    border-style:solid;
+}
+.x-tab-panel-tbar-noborder .x-toolbar {
+    border-width:0 0 1px;
+    border-style:solid;
+}
+.x-border-panel {
+    position:absolute;
+    left:0;
+    top:0;
+}
+.x-tool-collapse-south {
+    background-position:0 -195px;
+}
+.x-tool-collapse-south-over {
+    background-position:-15px -195px;
+}
+.x-tool-collapse-north {
+    background-position:0 -210px;
+}
+.x-tool-collapse-north-over {
+    background-position:-15px -210px;
+}
+.x-tool-collapse-west {
+    background-position:0 -180px;
+}
+.x-tool-collapse-west-over {
+    background-position:-15px -180px;
+}
+.x-tool-collapse-east {
+    background-position:0 -165px;
+}
+.x-tool-collapse-east-over {
+    background-position:-15px -165px;
+}
+.x-tool-expand-south {
+    background-position:0 -210px;
+}
+.x-tool-expand-south-over {
+    background-position:-15px -210px;
+}
+.x-tool-expand-north {
+    background-position:0 -195px;
+}
+.x-tool-expand-north-over {
+    background-position:-15px -195px;
+}
+.x-tool-expand-west {
+    background-position:0 -165px;
+}
+.x-tool-expand-west-over {
+    background-position:-15px -165px;
+}
+.x-tool-expand-east {
+    background-position:0 -180px;
+}
+.x-tool-expand-east-over {
+    background-position:-15px -180px;
+}
+.x-tool-expand-north, .x-tool-expand-south {
+    float:right;
+    margin:3px;
+}
+.x-tool-expand-east, .x-tool-expand-west {
+    float:none;
+    margin:3px auto;
+}
+.x-accordion-hd .x-tool-toggle {
+    background-position:0 -255px;
+}
+.x-accordion-hd .x-tool-toggle-over {
+    background-position:-15px -255px;
+}
+.x-panel-collapsed .x-accordion-hd .x-tool-toggle {
+    background-position:0 -240px;
+}
+.x-panel-collapsed .x-accordion-hd .x-tool-toggle-over {
+    background-position:-15px -240px;
+}
+.x-accordion-hd {
+	padding-top:4px;
+	padding-bottom:3px;
+	border-top:0 none;
+    background: transparent repeat-x 0 -9px;
+}
+.x-layout-collapsed{
+    position:absolute;
+    left:-10000px;
+    top:-10000px;
+    visibility:hidden;
+    width:20px;
+    height:20px;
+    overflow:hidden;
+	border:1px solid;
+	z-index:20;
+}
+.ext-border-box .x-layout-collapsed{
+    width:22px;
+    height:22px;
+}
+.x-layout-collapsed-over{
+    cursor:pointer;
+}
+.x-layout-collapsed-west .x-layout-collapsed-tools, .x-layout-collapsed-east .x-layout-collapsed-tools{
+	position:absolute;
+    top:0;
+    left:0;
+    width:20px;
+    height:20px;
+}
+.x-layout-split{
+    position:absolute;
+    height:5px;
+    width:5px;
+    line-height:1px;
+    font-size:1px;
+    z-index:3;
+    background-color:transparent;
+}
+.ext-strict .ext-ie6 .x-layout-split{
+    background-color: #fff !important;
+    filter: alpha(opacity=1);
+}
+.x-layout-split-h{
+    background-image:url(../images/default/s.gif);
+    background-position: left;
+}
+.x-layout-split-v{
+    background-image:url(../images/default/s.gif);
+    background-position: top;
+}
+.x-column-layout-ct {
+    overflow:hidden;
+    zoom:1;
+}
+.x-column {
+    float:left;
+    padding:0;
+    margin:0;
+    overflow:hidden;
+    zoom:1;
+}
+.x-column-inner {
+    overflow:hidden;
+    zoom:1;
+}
+.x-layout-mini {
+    position:absolute;
+    top:0;
+    left:0;
+    display:block;
+    width:5px;
+    height:35px;
+    cursor:pointer;
+    opacity:.5;
+    -moz-opacity:.5;
+    filter:alpha(opacity=50);
+}
+.x-layout-mini-over, .x-layout-collapsed-over .x-layout-mini{
+    opacity:1;
+    -moz-opacity:1;
+    filter:none;
+}
+.x-layout-split-west .x-layout-mini {
+    top:48%;
+}
+.x-layout-split-east .x-layout-mini {
+    top:48%;
+}
+.x-layout-split-north .x-layout-mini {
+    left:48%;
+    height:5px;
+    width:35px;
+}
+.x-layout-split-south .x-layout-mini {
+    left:48%;
+    height:5px;
+    width:35px;
+}
+.x-layout-cmini-west .x-layout-mini {
+    top:48%;
+}
+.x-layout-cmini-east .x-layout-mini {
+    top:48%;
+}
+.x-layout-cmini-north .x-layout-mini {
+    left:48%;
+    height:5px;
+    width:35px;
+}
+.x-layout-cmini-south .x-layout-mini {
+    left:48%;
+    height:5px;
+    width:35px;
+}
+.x-layout-cmini-west, .x-layout-cmini-east {
+    border:0 none;
+    width:5px !important;
+    padding:0;
+    background:transparent;
+}
+.x-layout-cmini-north, .x-layout-cmini-south {
+    border:0 none;
+    height:5px !important;
+    padding:0;
+    background:transparent;
+}
+.x-viewport, .x-viewport body {
+    margin: 0;
+    padding: 0;
+    border: 0 none;
+    overflow: hidden;
+    height: 100%;
+}
+.x-abs-layout-item {
+    position:absolute;
+    left:0;
+    top:0;
+}
+.ext-ie input.x-abs-layout-item, .ext-ie textarea.x-abs-layout-item {
+    margin:0;
+}
+.x-box-layout-ct {
+    overflow:hidden;
+    zoom:1;
+}
+.x-box-inner {
+    overflow:hidden;
+    zoom:1;
+    position:relative;
+    left:0;
+    top:0;
+}
+.x-box-item {
+    position:absolute !important;
+    left:0;
+    top:0;
+}
+.x-progress-wrap {
+    border:1px solid;
+    overflow:hidden;
+}
+.x-progress-inner {
+    height:18px;
+    background:repeat-x;
+    position:relative;
+}
+.x-progress-bar {
+    height:18px;
+    float:left;
+    width:0;
+    background: repeat-x left center;
+    border-top:1px solid;
+    border-bottom:1px solid;
+    border-right:1px solid;
+}
+.x-progress-text {
+    padding:1px 5px;
+    overflow:hidden;
+    position:absolute;
+    left:0;
+    text-align:center;
+}
+.x-progress-text-back {
+    line-height:16px;
+}
+.ext-ie .x-progress-text-back {
+    line-height:15px;
+}
+.x-slider {
+    zoom:1;
+}
+.x-slider-inner {
+    position:relative;
+    left:0;
+    top:0;
+    overflow:visible;
+    zoom:1;
+}
+.x-slider-focus {
+	position:absolute;
+	left:0;
+	top:0;
+	width:1px;
+	height:1px;
+    line-height:1px;
+    font-size:1px;
+    -moz-outline:0 none;
+    outline:0 none;
+    -moz-user-select: none;
+    -khtml-user-select: none;
+    -webkit-user-select: ignore
+	display:block;
+	overflow:hidden;  
+}
+.x-slider-horz {
+    padding-left:7px;
+    background:transparent no-repeat 0 -22px;
+}
+.x-slider-horz .x-slider-end {
+    padding-right:7px;
+    zoom:1;
+    background:transparent no-repeat right -44px;
+}
+.x-slider-horz .x-slider-inner {
+    background:transparent repeat-x 0 0;
+    height:22px;
+}
+.x-slider-horz .x-slider-thumb {
+    width:14px;
+    height:15px;
+    position:absolute;
+    left:0;
+    top:3px;
+    background:transparent no-repeat 0 0;
+}
+.x-slider-horz .x-slider-thumb-over {
+    background-position: -14px -15px;
+}
+.x-slider-horz .x-slider-thumb-drag {
+    background-position: -28px -30px;
+}
+.x-slider-vert {
+    padding-top:7px;
+    background:transparent no-repeat -44px 0;
+    width:22px;
+}
+.x-slider-vert .x-slider-end {
+    padding-bottom:7px;
+    zoom:1;
+    background:transparent no-repeat -22px bottom;
+}
+.x-slider-vert .x-slider-inner {
+    background:transparent repeat-y 0 0;
+}
+.x-slider-vert .x-slider-thumb {
+    width:15px;
+    height:14px;
+    position:absolute;
+    left:3px;
+    bottom:0;
+    background:transparent no-repeat 0 0;
+}
+.x-slider-vert .x-slider-thumb-over {
+    background-position: -15px -14px;
+}
+.x-slider-vert .x-slider-thumb-drag {
+    background-position: -30px -28px;
+}
+.x-window-dlg .x-window-body {
+    border:0 none !important;
+    padding:5px 10px;
+    overflow:hidden !important;
+}
+.x-window-dlg .x-window-mc {
+    border:0 none !important;
+}
+.x-window-dlg .ext-mb-input {
+    margin-top:4px;
+    width:95%;
+}
+.x-window-dlg .ext-mb-textarea {
+    margin-top:4px;
+}
+.x-window-dlg .x-progress-wrap {
+    margin-top:4px;
+}
+.ext-ie .x-window-dlg .x-progress-wrap {
+    margin-top:6px;
+}
+.x-window-dlg .x-msg-box-wait {
+    background:transparent no-repeat left;
+    display:block;
+    width:300px;
+    padding-left:18px;
+    line-height:18px;
+}
+.x-window-dlg .ext-mb-icon {
+    float:left;
+    width:47px;
+    height:32px;
+}
+.ext-ie .x-window-dlg .ext-mb-icon {
+    width:44px;  
+}
+.x-window-dlg .x-dlg-icon .ext-mb-content{
+    zoom: 1; margin-left: 47px;
+}
+.x-window-dlg .ext-mb-info, .x-window-dlg .ext-mb-warning, .x-window-dlg .ext-mb-question, .x-window-dlg .ext-mb-error {
+    background:transparent no-repeat top left;
+}
+.ext-gecko2 .ext-mb-fix-cursor {
+    overflow:auto;
+}
+.arrow-top {
+  background: url(../images/gxt/icons/top2.gif) no-repeat center left !important;
+}
+.arrow-bottom {
+  background: url(../images/gxt/icons/bottom2.gif) no-repeat center left !important;
+}
+.arrow-up {
+  background: url(../images/gxt/icons/up2.gif) no-repeat center left !important;
+}
+.arrow-down {
+  background: url(../images/gxt/icons/down2.gif) no-repeat center left !important;
+}
+.arrow-left {
+  background: url(../images/gxt/icons/left2.gif) no-repeat center left !important;
+}
+.arrow-double-left {
+  background: url(../images/gxt/icons/doubleleft2.gif) no-repeat center left !important;
+}
+.arrow-right {
+  background: url(../images/gxt/icons/right2.gif) no-repeat center left !important;
+}
+.arrow-double-right {
+  background: url(../images/gxt/icons/doubleright2.gif) no-repeat center left !important;
+}
+.x-info {
+  border-style: solid;
+  border-color: #99bbe8;
+  border-width: 0;
+  z-index: 99999999;
+}
+
+.x-info-header {
+  overflow: hidden;
+  zoom: 1;
+  color: black;
+  font: bold 13px tahoma, arial, verdana, sans-serif;
+  padding: 5px 3px 4px 5px;
+  line-height: 15px;
+  background: transparent url(../images/default/panel/white-top-bottom.gif) repeat-x 0 -1px;
+}
+
+.x-info-body {
+  border-top: 0 none;
+  overflow: hidden;
+  background: white;
+  position: relative; /* added for item scroll positioning */
+}
+
+.x-info-header {
+  overflow: hidden;
+  zoom: 1;
+}
+
+.x-info-tl .x-info-header {
+  color: #555555;
+  font-family: tahoma, arial, sans-serif;
+  font-size: 13px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: bold;
+  line-height: normal;
+  padding: 5px 0 4px 0;
+  border: 0 none;
+  background: transparent;
+}
+
+.x-info-tl .x-info-icon,.x-window-tl .x-info-icon {
+  padding-left: 20px !important;
+  background-repeat: no-repeat;
+  background-position: 0 4px;
+  zoom: 1;
+}
+
+.x-info-inline-icon {
+  width: 16px;
+  height: 16px;
+  background-repeat: no-repeat;
+  background-position: 0 0;
+  vertical-align: middle;
+  margin-right: 4px;
+  margin-top: -1px;
+  margin-bottom: -1px;
+}
+
+.x-info-tc {
+  background: transparent url(../images/gxt/info/top-bottom.gif) repeat-x 0 0;
+  overflow: hidden;
+}
+
+/* fix ie7 strict mode bug */
+.ext-ie7 .x-info-tc {
+  overflow: visible;
+}
+
+.x-info-tl {
+  background: transparent url(../images/gxt/info/corners-sprite.gif) no-repeat 0 0;
+  padding-left: 6px;
+  zoom: 1;
+}
+
+.x-info-tr {
+  background: transparent url(../images/gxt/info/corners-sprite.gif) no-repeat right 0;
+  zoom: 1;
+  padding-right: 6px;
+}
+
+.x-info-bc {
+  background: transparent url(../images/default/panel/top-bottom.gif) repeat-x 0 bottom;
+  zoom: 1;
+  font-size: 0px;
+}
+
+.x-info-bc .x-info-footer {
+  zoom: 1;
+}
+
+.x-info-bl {
+  background: transparent url(../images/default/panel/corners-sprite.gif) no-repeat 0 bottom;
+  padding-left: 6px;
+  zoom: 1;
+}
+
+.x-info-br {
+  background: transparent url(../images/default/panel/corners-sprite.gif) no-repeat right bottom;
+  padding-right: 6px;
+  zoom: 1;
+}
+
+.x-info-mc {
+  border: 0 none;
+  padding: 0;
+  margin: 0;
+  font: normal 11px tahoma, arial, helvetica, sans-serif;
+  background: #dfe8f6;
+}
+
+.x-info-mc .x-info-body {
+  background: transparent;
+  border: 0 none;
+}
+
+.x-info-ml {
+  background: #fff url(../images/default/panel/left-right.gif) repeat-y 0 0;
+  padding-left: 6px;
+  zoom: 1;
+}
+
+.x-info-mr {
+  background: transparent url(../images/default/panel/left-right.gif) repeat-y right 0;
+  padding-right: 6px;
+  zoom: 1;
+}
+
+.x-info-bc .x-info-footer {
+  padding-bottom: 6px;
+}
+
+.x-info-nofooter .x-info-bc,.x-panel-nofooter .x-info-bc {
+  height: 6px;
+  font-size: 0;
+  line-height: 0;
+}
+
+.x-info-bwrap {
+  overflow: hidden;
+  zoom: 1;
+}
+
+.x-info-body {
+  overflow: hidden;
+  zoom: 1;
+  color: #555555;
+  font-family: tahoma, arial, sans-serif;
+  font-size: 12px;
+  font-size-adjust: none;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+}.x-combo-over {
+  border: 1px dotted #B5B4B4 !important;
+  background: #F1F1F1;
+  cursor: pointer;
+}
+
+.my-list {
+  border: 1px solid #99BBE8;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+  background-color: white;
+  font-family: "Myriad Pro", "Myriad Web", "Tahoma", "Helvetica", "Arial", sans-serif;
+}
+
+.my-list-notchecked {
+  background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 0px !important;
+  margin: 3px 0pt 0pt 0px;
+}
+
+.my-list-checked {
+  background: url(../images/gxt/tree/checked.gif) no-repeat 0px 0px !important;
+  margin: 3px 0pt 0pt 0px;
+}
+
+.ext-ie .my-list-notchecked {
+  margin: 2px 0pt 0pt 0px;
+}
+
+.ext-ie .my-list-checked {
+  margin: 2px 0pt 0pt 0px;
+}
+
+.my-list-flat {
+  border: 1px solid #6593cf;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+  background-color: white;
+  cursor: default;
+}
+
+.my-list-item {
+  cursor: pointer;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-list-flat .my-list-item {
+  height: 19px;
+  border: 1px solid white;
+}
+
+.my-list-flat .my-list-item-over {
+  background-color: #F1F1F1;
+  border: 1px dotted #B5B4B4;
+}
+
+.my-list-flat .my-list-item-sel {
+  background-color: #DFE8F6;
+  border: 1px dotted #9EB8ED;
+}
+
+.my-list-flat .my-list-item-over .my-list-item-l {
+  background: none;
+}
+
+.my-list-flat .my-list-item-over .my-list-item-icon,.my-list-flat .my-list-item-over .my-list-item-ml,.my-list-flat .my-list-item-over .my-list-item-c
+  {
+  background: none;
+}
+
+.my-list-flat .my-list-item-over .my-list-item-r {
+  background: none;
+}
+
+.my-list-flat .my-list-item-sel .my-list-item-l {
+  background: none;
+}
+
+.my-list-flat .my-list-item-sel .my-list-item-icon,.my-list-flat .my-list-item-sel .my-list-item-ml,.my-list-flat .my-list-item-sel .my-list-item-c
+  {
+  background: none;
+}
+
+.my-list-flat .my-list-item-sel .my-list-item-r {
+  background: none;
+}
+
+.my-list-item-text {
+  font-size: 11px;
+  padding-top: 3px;
+  padding-left: 2px;
+  white-space: nowrap;
+  overflow: hidden;
+  line-height: 19px;
+}
+
+.my-list-item-l div {
+  width: 5px;
+}
+
+.my-list-item-ml {
+  width: 18px;
+}
+
+.my-list-item-c {
+  width: 100%;
+}
+
+.my-list-item-r div {
+  width: 3px;
+}
+
+.my-list-item-over .my-list-item-l {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left -57px;
+}
+
+.my-list-item-over .my-list-item-icon,.my-list-item-over .my-list-item-check,.my-list-item-over .my-list-item-c
+  {
+  background: url(../images/gxt/shared/select-19-bg.gif) repeat-x left -95px;
+}
+
+.my-list-item-over .my-list-item-r {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -76px;
+}
+
+.my-list-item-sel .my-list-item-l {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left 0px;
+}
+
+.my-list-item-sel .my-list-item-icon,.my-list-item-sel .my-list-item-check,.my-list-item-sel .my-list-item-c
+  {
+  background: url(../images/gxt/shared/select-19-bg.gif) left -38px;
+}
+
+.my-list-item-sel .my-list-item-r {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -19px;
+}.x-view {
+  -moz-outline: none;
+  -moz-user-focus: normal;
+  padding: 1px;
+  background-color: white;
+  cursor: default;
+  border: 1px solid #98C0F4;
+  overflow: hidden;
+}
+
+.x-view-item {
+  border: 1px solid #FFFFFF;
+  font-family: tahoma, arial, helvetica, sans-serif;
+  font-size: 12px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  line-height: normal;
+  overflow: hidden;
+  padding: 2px;
+  white-space: nowrap;
+}
+
+.x-view-item-over {
+  background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top;
+  border: 1px dotted #dddddd !important;
+  cursor: pointer;
+}
+
+.x-view-item-sel {
+  background: #DFE8F6 none repeat scroll 0%;
+  border: 1px dotted #A3BAE9 !important;
+  cursor: pointer;
+}
+.x-view-item-check {
+  padding: 0px;
+}
+.x-view-item-check td {
+  font-family: tahoma, arial, helvetica, sans-serif;
+  font-size: 12px;
+  font-size-adjust: none;
+  font-stretch: normal;
+  font-style: normal;
+  font-variant: normal;
+  font-weight: normal;
+  line-height: normal;
+  white-space: nowrap;
+  vertical-align: middle;
+  padding-left: 1px;
+}.x-splitbar-shim {
+  filter: alpha(opacity =                     1);
+  opacity: 0;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  background-color: white;
+  -moz-user-select: none;
+  -khtml-user-select: none;
+  user-select: none;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.x-vsplitbar {
+  background: url(../images/default/s.gif);
+  position: absolute;
+  z-index: 3;
+  cursor: e-resize;
+  cursor: col-resize;
+}
+
+.x-hsplitbar {
+  background: url(../images/default/s.gif);
+  position: absolute;
+  font-size: 1px;
+  line-height: 1px;
+  z-index: 3;
+  cursor: s-resize;
+  cursor: row-resize;
+}
+
+.x-splitbar-proxy {
+  position: absolute;
+  background-color: #929090;
+  font-size: 1px;
+  line-height: 1px;
+  z-index: 200;
+}
+
+.my-splitbar-shim {
+  filter: alpha(opacity =       1);
+  opacity: 0;
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  z-index: 10;
+  background-color: white;
+  -moz-user-select: none;
+  -khtml-user-select: none;
+  user-select: none;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-splitbar-transparent {
+  background: none;
+  font-size: 1px;
+  line-height: 1px;
+  z-index: 2000;
+}
+
+.my-splitbar-proxy {
+  position: absolute;
+  background-color: #929090;
+  font-size: 1px;
+  line-height: 1px;
+  z-index: 200;
+}.x-status {
+  padding: 0 4px;
+  height: 21px;
+  line-height: 21px !important;
+  cursor: default;
+}
+.x-status .x-status-text{
+  padding: 2px;
+  line-height: 21px !important;
+}
+.x-status-icon {
+  padding-left: 25px !important;
+  background: transparent no-repeat left center;
+}
+.x-status-busy {   
+  background-image: url(../images/default/grid/loading.gif);
+}
+.x-status-text-panel {
+  border: 1px solid;
+  border-color: #99bbe8 #fff #fff #99bbe8;
+}
+.my-tbl {
+  border: 1px solid #99BBE8;
+  cursor: default;
+  background-color: white;
+  overflow: hidden;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 11px;
+  table-layout: fixed;
+}
+
+.my-tbl-col-overflow {
+  overflow: hidden;
+}
+
+.ext-ie .my-tbl-col-overflow {
+  
+}
+
+.my-tbl-col-text {
+  color: black;
+  padding: 5px 4px 0 4px;
+  display: block;
+  white-space: nowrap;
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 11px;
+}
+
+.my-tbl-col {
+  border-right: 1px solid #D5D5D5;
+  background: url(../images/gxt/table/vs-column-bg.gif) repeat-x;
+}
+
+.my-tbl-col-splitter {
+  position: absolute;
+  top: 0;
+  width: 6px;
+  z-index: 100;
+  height: 100%;
+  right: 0px;
+}
+
+.my-tbl-col-over {
+  background: url(../images/gxt/table/vs-column-bg.gif) repeat-x 0px -24px;
+}
+
+.my-tbl-col-sort {
+  background-position: 0px -48px;
+}
+
+.my-icon-asc {
+  background-image: url(../images/gxt/icons/hmenu-asc.gif) !important;
+}
+
+.my-icon-desc {
+  background-image: url(../images/gxt/icons/hmenu-desc.gif) !important;
+}
+
+.my-tbl-col-asc {
+  background: url(../images/gxt/table/vsort-asc.gif) no-repeat 50% top;
+}
+
+.my-tbl-col-desc {
+  background: url(../images/gxt/table/vsort-desc.gif) no-repeat 50% top;
+}
+
+.my-tbl-col-splitter {
+  background: none;
+}
+
+.my-tbl-data {
+  background-color: white;
+  overflow: hidden;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-item {
+  border-top: 1px solid white;
+  border-bottom: 1px solid white;
+  border-bottom: 1px solid #EDEDED;
+  cursor: default;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-item table {
+  -moz-outline: none;
+  -moz-user-focus: normal;
+  table-layout: fixed;
+}
+
+.my-tbl-data .my-tbl-item-cell {
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-item td {
+  -moz-user-select: none;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-vlines .my-tbl-data .my-tbl-item-cell-overflow {
+  border-right: 1px solid #EDEDED;
+}
+
+.my-tbl-data .my-tbl-item-cell-overflow {
+  white-space: nowrap;
+  overflow: hidden;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-data .my-tbl-item-cell-text {
+  padding: 3px 4px;
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 11px;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-tbl-data .my-tbl-item-cell-widget {
+  padding: 1px 4px;
+}
+
+.my-tbl-data tr {
+  overflow: hidden;
+}
+
+.my-tbl-item-over {
+  border-top: 1px solid #dddddd;
+  border-bottom: 1px solid #dddddd;
+  background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top;
+}
+
+.my-tbl-item-sel {
+  background-image: none !important;
+  background-color: #D9E1ED !important;
+  border-top: 1px dotted #9EB8ED !important;
+  border-bottom: 1px dotted #9EB8ED !important;
+}
+
+.ext-ie .my-tbl TD .x-form-text {
+  POSITION: static;
+  TOP: 0px;
+}.tree-folder {
+  background: url(../images/gxt/icons/folder-closed.gif) no-repeat -1px -1px;
+}
+
+.tree-folder-open {
+  background: url(../images/gxt/icons/folder.gif) no-repeat -1px -1px;
+}
+
+.my-treetbl-tree {
+  cursor: default;
+}
+
+.my-treetblitem,.my-treetblitem table,.my-treetblitem table td {
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-treetblitem td {
+  height: 19px;
+}
+
+.my-treetbl-indent {
+  line-height: 1px;
+  font-size: 1px;
+}
+
+.my-treetbl-joint div {
+  width: 15px;
+  height: 19px;
+  line-height: 1px;
+  font-size: 1px;
+}
+
+.my-treetbl-left,.my-treetbl-left div,.my-treetbl-right {
+  line-height: 1px;
+  font-size: 1px;
+  width: 3px;
+}
+
+.my-treetbl-left div,.my-treetbl-right div {
+  width: 3px;
+}
+
+.my-treetbl-check div {
+  width: 17px;
+  height: 19px;
+  line-height: 1px;
+  font-size: 1px;
+  display: block;
+}
+
+.my-treetbl-icon div {
+  width: 16px;
+  height: 16px;
+  margin-top: 1px;
+  cursor: pointer;
+  background-repeat: no-repeat;
+  background-position: center;
+}
+
+.my-ie .my-treetbl-icon {
+  padding-top: 2px;
+}
+
+.my-ie .my-treetbl-icon div {
+  position: static;
+}
+
+.my-treetbl-item-text span {
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 12px;
+  white-space: nowrap;
+  padding-left: 3px;
+  padding-right: 3px;
+  display: block;
+  height: 15px;
+  cursor: pointer;
+}
+
+.my-treetbl-over .my-treetbl-left {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left -57px;
+}
+
+.my-treetbl-over .my-treetbl-right {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -76px;
+}
+
+.my-treetbl-over .my-treetbl-check,.my-treetbl-over .my-treetbl-icon,.my-treetbl-over .my-treetbl-item-text
+  {
+  background: url(../images/gxt/shared/select-19-bg.gif) left -95px;
+}
+
+.my-treetbl-sel .my-treetbl-left {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat left 0px;
+}
+
+.my-treetbl-sel .my-treetbl-right {
+  background: url(../images/gxt/shared/select-19-bg.gif) no-repeat right -19px;
+}
+
+.my-treetbl-sel .my-treetbl-check,.my-treetbl-sel .my-treetbl-icon,.my-treetbl-sel .my-treetbl-item-text
+  {
+  background: url(../images/gxt/shared/select-19-bg.gif) left -38px;
+}
+
+.my-treetbl-close {
+  background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px 1px;
+}
+
+.my-treetbl-open {
+  background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -32px;
+}
+
+.my-treetbl-joint-over  .my-treetbl-open {
+  background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -48px;
+}
+
+.my-treetbl-joint-over .my-treetbl-close {
+  background: url(../images/gxt/tree/vnode_transparent.gif) no-repeat 0px -15px;
+}
+
+.my-treetbl-notchecked {
+  background: url(../images/gxt/tree/notchecked.gif) no-repeat 0px 50%;
+}
+
+.my-treetbl-checked {
+  background: url(../images/gxt/tree/checked.gif) no-repeat 0px 50%;
+}
+
+.my-treetbl-loading .tree-folder {
+  background: url(../images/gxt/icons/wait.gif) no-repeat 0px -1px;
+}
+
+.my-treetbl-loading .my-treetbl-item-text span {
+  font-style: italic;
+}
+
+.my-treetbl {
+  border: 1px solid #99BBE8;
+  cursor: default;
+  background-color: white;
+  overflow: hidden;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-treetbl-col-overflow {
+  overflow: hidden;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-treetbl-col-text {
+  color: black;
+  padding: 5px 4px 0 4px;
+  display: block;
+  white-space: nowrap;
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.my-treetbl-col {
+  border-right: 1px solid #D5D5D5;
+  background: url(../images/gxt/table/vs-column-bg.gif) repeat-x;
+}
+
+.my-treetbl-col-splitter {
+  position: absolute;
+  top: 0;
+  width: 6px;
+  z-index: 100;
+  height: 100%;
+  right: 0px;
+}
+
+.my-treetbl-col-over {
+  background: url(../images/gxt/table/vs-column-bg.gif) repeat-x 0px -24px;
+}
+
+.my-treetbl-col-sort {
+  background-position: 0px -48px;
+}
+
+.my-treetbl-col-asc {
+  background: url(../images/gxt/table/vsort-asc.gif) no-repeat 50% top;
+}
+
+.my-treetbl-col-desc {
+  background: url(../images/gxt/table/vsort-desc.gif) no-repeat 50% top;
+}
+
+.my-treetbl-col-splitter {
+  background: none;
+}
+
+.my-treetbl-data {
+  background-color: white;
+  overflow: hidden;
+}
+
+.my-treetbl-data .my-treetbl-cell {
+  height: 20px;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-treetbl-data .my-treetbl-cell-overflow {
+  white-space: nowrap;
+  overflow: hidden;
+}
+
+.my-treetbl-data .my-treetbl-cell-text {
+  padding: 0px 0px;
+  font-family: arial, tahoma, helvetica, sans-serif;
+  font-size: 12px;
+}
+
+.my-treetbl-data tr {
+  overflow: hidden;
+}
+
+.my-treetbl-item {
+  border-top: 1px solid white;
+  border-bottom: 1px solid white;
+  border-bottom: 1px solid #EDEDED;
+  cursor: default;
+  -moz-outline: none;
+  -moz-user-focus: normal;
+}
+
+.my-treetbl-item-over {
+  border-top: 1px solid #dddddd;
+  border-bottom: 1px solid #dddddd;
+  background: #efefef url(../images/default/grid/row-over.gif) repeat-x left top;
+}
+
+.my-treetbl-item-sel {
+  background-image: none;
+  background-color: #D9E1ED;
+  border-top: 1px dotted #9EB8ED;
+  border-bottom: 1px dotted #9EB8ED;
+}
+
+.my-treetbl .x-grid3-td-numberer {
+  background: transparent url(../images/gxt/tree/tree-table-special-col.gif) repeat-y
+    scroll left center;
+  height: 19px;
+  line-height: normal;
+  padding-left: 0px;
+  margin-left: 0px;
+}
+
+.x-grid3-td-numberer div {
+  font-size: 11px;
+  font-family: "segoe ui", tahoma, arial, sans-serif;
+  color: #444444;
+  padding: 3px 0px 0 5px !important;
+}
+
+.ext-ie .my-treetbl .x-grid3-td-numberer {
+  height: 20px;
+}
+
+.my-treetbl-item-sel .x-grid3-td-numberer {
+  background: transparent url(../images/gxt/tree/tree-table-special-col-sel.gif) repeat-y
+    scroll left center;
+}.ext-el-mask {
+    background-color: #ccc;
+}
+.ext-el-mask-msg {
+    border-color:#6593cf;
+    background-color:#c3daf9;
+    background-image:url(../images/default/box/tb-blue.gif);
+}
+.ext-el-mask-msg div {
+    background-color: white;
+    border-color:#a3bad9;
+    color:#222;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-mask-loading div {
+    background-color:#fbfbfb;
+    background-image:url(../images/default/grid/loading.gif);
+}
+.x-item-disabled {
+    color: gray;
+}
+.x-item-disabled * {
+    color: gray !important;
+}
+.x-splitbar-proxy {
+    background-color: #aaa;
+}
+.x-color-palette a {
+    border-color:#fff;
+}
+.x-color-palette a.x-color-palette-hover, .x-color-palette a.x-color-palette-sel {
+    border-color:#8bb8f3;
+    background-color: #deecfd;
+}
+.x-color-palette em {
+    border-color:#aca899;
+}
+.x-ie-shadow {
+    background-color:#777;
+}
+.x-shadow .xsmc {
+    background-image: url(../images/default/shadow-c.png);
+}
+.x-shadow .xsml, .x-shadow .xsmr {
+    background-image: url(../images/default/shadow-lr.png);
+}
+.x-shadow .xstl, .x-shadow .xstc,  .x-shadow .xstr, .x-shadow .xsbl, .x-shadow .xsbc, .x-shadow .xsbr{
+    background-image: url(../images/default/shadow.png);
+}
+.loading-indicator {
+    font-size: 11px;
+    background-image: url(../images/default/grid/loading.gif);
+}
+.x-spotlight {
+    background-color: #ccc;
+}
+.x-aria-focusframe-side {
+	background-color: #15428B;
+	line-height: 2px;
+	font-size: 2px;
+}
+.x-tab-panel-header, .x-tab-panel-footer {
+	background-color: #deecfd;
+	border-color:#8db2e3;
+    overflow:hidden;
+    zoom:1;
+}
+.x-tab-panel-header, .x-tab-panel-footer {
+	border-color:#8db2e3;
+}
+ul.x-tab-strip-top{
+    background-color:#cedff5;
+	background-image: url(../images/default/tabs/tab-strip-bg.gif);
+	border-bottom-color:#8db2e3;
+}
+ul.x-tab-strip-bottom{
+    background-color:#cedff5;
+	background-image: url(../images/default/tabs/tab-strip-btm-bg.gif);
+	border-top-color:#8db2e3;
+}
+.x-tab-panel-header-plain .x-tab-strip-spacer,
+.x-tab-panel-footer-plain .x-tab-strip-spacer {
+    border-color:#8db2e3;
+    background-color: #deecfd;
+}
+.x-tab-strip span.x-tab-strip-text {
+	font:normal 11px tahoma,arial,helvetica;
+	color:#416aa3;
+}
+.x-tab-strip-over span.x-tab-strip-text {
+	color:#15428b;
+}
+.x-tab-strip-active span.x-tab-strip-text {
+	color:#15428b;
+    font-weight:bold;
+}
+.x-tab-strip-disabled .x-tabs-text {
+	color:#aaaaaa;
+}
+.x-tab-strip-top .x-tab-right, .x-tab-strip-top .x-tab-left, .x-tab-strip-top .x-tab-strip-inner{
+	background-image: url(../images/default/tabs/tabs-sprite.gif);
+}
+.x-tab-strip-bottom .x-tab-right {
+	background-image: url(../images/default/tabs/tab-btm-inactive-right-bg.gif);
+}
+.x-tab-strip-bottom .x-tab-left {
+	background-image: url(../images/default/tabs/tab-btm-inactive-left-bg.gif);
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+	background-image: url(../images/default/tabs/tab-btm-right-bg.gif);
+}
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+	background-image: url(../images/default/tabs/tab-btm-left-bg.gif);
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+	background-image:url(../images/default/tabs/tab-close.gif);
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{
+	background-image:url(../images/default/tabs/tab-close.gif);
+}
+.x-tab-panel-body {
+    border-color:#8db2e3;
+    background-color:#fff;
+}
+.x-tab-panel-body-top {
+    border-top: 0 none;
+}
+.x-tab-panel-body-bottom {
+    border-bottom: 0 none;
+}
+.x-tab-scroller-left {
+    background-image:url(../images/default/tabs/scroll-left.gif);
+    border-bottom-color:#8db2e3;
+}
+.x-tab-scroller-left-over {
+    background-position: 0 0;
+}
+.x-tab-scroller-left-disabled {
+    background-position: -18px 0;
+    opacity:.5;
+    -moz-opacity:.5;
+    filter:alpha(opacity=50);
+    cursor:default;
+}
+.x-tab-scroller-right {
+    background-image:url(../images/default/tabs/scroll-right.gif);
+    border-bottom-color:#8db2e3;
+}
+.x-tab-panel-bbar .x-toolbar, .x-tab-panel-tbar .x-toolbar {
+    border-color:#99bbe8;
+}
+.x-form-field{
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+.x-form-text, textarea.x-form-field{
+    background-color:#fff;
+    background-image:url(../images/default/form/text-bg.gif);
+    border-color:#b5b8c8;
+}
+.x-form-select-one {
+    background-color:#fff;
+    border-color:#b5b8c8;
+}
+.x-form-check-group-label {
+    border-bottom: 1px solid #99bbe8;
+    color: #15428b;
+}
+.x-editor .x-form-check-wrap {
+    background-color:#fff;
+}
+.x-form-field-wrap .x-form-trigger{
+    background-image:url(../images/default/form/trigger.gif);
+    border-bottom-color:#b5b8c8;
+}
+.x-form-field-wrap .x-form-date-trigger{
+    background-image: url(../images/default/form/date-trigger.gif);
+}
+.x-form-field-wrap .x-form-clear-trigger{
+    background-image: url(../images/default/form/clear-trigger.gif);
+}
+.x-form-field-wrap .x-form-search-trigger{
+    background-image: url(../images/default/form/search-trigger.gif);
+}
+.x-trigger-wrap-focus .x-form-trigger{
+    border-bottom-color:#7eadd9;
+}
+.x-item-disabled .x-form-trigger-over{
+    border-bottom-color:#b5b8c8;
+}
+.x-item-disabled .x-form-trigger-click{
+    border-bottom-color:#b5b8c8;
+}
+.x-form-focus, textarea.x-form-focus{
+	border-color:#7eadd9;
+}
+.x-form-invalid, textarea.x-form-invalid{
+    background-color:#fff;
+	background-image:url(../images/default/grid/invalid_line.gif);
+	border-color:#c30;
+}
+.ext-safari .x-form-invalid{
+	background-color:#fee;
+	border-color:#ff7870;
+}
+.x-form-inner-invalid, textarea.x-form-inner-invalid{
+    background-color:#fff;
+	background-image:url(../images/default/grid/invalid_line.gif);
+}
+.x-form-grow-sizer {
+	font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+.x-form-item label {
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+.x-form-invalid-msg {
+    color:#c0272b;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+    background-image:url(../images/default/shared/warning.gif);
+}
+.x-form-empty-field {
+    color:gray;
+}
+.x-small-editor .x-form-field {
+    font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.ext-safari .x-small-editor .x-form-field {
+    font:normal 12px arial, tahoma, helvetica, sans-serif;
+}
+.x-form-invalid-icon {
+    background-image:url(../images/default/form/exclamation.gif);
+}
+.x-fieldset {
+    border-color:#b5b8c8;
+}
+.x-fieldset legend {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+}
+
+.x-editor .x-form-check-wrap {
+	border-color:#7eadd9;
+}
+.x-btn{
+	font:normal 11px tahoma, verdana, helvetica;
+}
+.x-btn button{
+    font:normal 11px arial,tahoma,verdana,helvetica;
+    color:#333;
+}
+.x-btn em {
+    font-style:normal;
+    font-weight:normal;
+}
+.x-btn-tl, .x-btn-tr, .x-btn-tc, .x-btn-ml, .x-btn-mr, .x-btn-mc, .x-btn-bl, .x-btn-br, .x-btn-bc{
+	background-image:url(../images/default/button/btn.gif);
+}
+.x-btn-click .x-btn-text, .x-btn-menu-active .x-btn-text, .x-btn-pressed .x-btn-text{
+    color:#000;
+}
+.x-btn-disabled *{
+	color:gray !important;
+}
+.x-btn-mc em.x-btn-arrow {
+    background-image:url(../images/default/button/arrow.gif);
+}
+.x-btn-mc em.x-btn-split {
+    background-image:url(../images/default/button/s-arrow.gif);
+}
+.x-btn-over .x-btn-mc em.x-btn-split, .x-btn-click .x-btn-mc em.x-btn-split, .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-btn-pressed .x-btn-mc em.x-btn-split {
+    background-image:url(../images/default/button/s-arrow-o.gif);
+}
+.x-btn-mc em.x-btn-arrow-bottom {
+    background-image:url(../images/default/button/s-arrow-b-noline.gif);
+}
+.x-btn-mc em.x-btn-split-bottom {
+    background-image:url(../images/default/button/s-arrow-b.gif);
+}
+.x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-btn-click .x-btn-mc em.x-btn-split-bottom, .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-btn-pressed .x-btn-mc em.x-btn-split-bottom {
+    background-image:url(../images/default/button/s-arrow-bo.gif);
+}
+.x-btn-group-header {
+    color: #3e6aaa;
+}
+.x-btn-group-tc {
+	background-image: url(../images/default/button/group-tb.gif);
+}
+.x-btn-group-tl {
+	background-image: url(../images/default/button/group-cs.gif);
+}
+.x-btn-group-tr {
+	background-image: url(../images/default/button/group-cs.gif);
+}
+.x-btn-group-bc {
+	background-image: url(../images/default/button/group-tb.gif);
+}
+.x-btn-group-bl {
+	background-image: url(../images/default/button/group-cs.gif);
+}
+.x-btn-group-br {
+	background-image: url(../images/default/button/group-cs.gif);
+}
+.x-btn-group-ml {
+	background-image: url(../images/default/button/group-lr.gif);
+}
+.x-btn-group-mr {
+	background-image: url(../images/default/button/group-lr.gif);
+}
+.x-btn-group-notitle .x-btn-group-tc {
+	background-image: url(../images/default/button/group-tb.gif);
+}
+.x-toolbar{
+	border-color:#a9bfd3;
+    background-color:#d0def0;
+    background-image:url(../images/default/toolbar/bg.gif);
+}
+.x-toolbar td,.x-toolbar span,.x-toolbar input,.x-toolbar div,.x-toolbar select,.x-toolbar label{
+    font:normal 11px arial,tahoma, helvetica, sans-serif;
+}
+.x-toolbar .x-item-disabled {
+	color:gray;
+}
+.x-toolbar .x-item-disabled * {
+	color:gray;
+}
+.x-toolbar .x-btn-mc em.x-btn-split {
+    background-image:url(../images/default/button/s-arrow-noline.gif);
+}
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split, 
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split 
+{
+    background-image:url(../images/default/button/s-arrow-o.gif);
+}
+.x-toolbar .x-btn-mc em.x-btn-split-bottom {
+    background-image:url(../images/default/button/s-arrow-b-noline.gif);
+}
+.x-toolbar .x-btn-over .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-click .x-btn-mc em.x-btn-split-bottom, 
+.x-toolbar .x-btn-menu-active .x-btn-mc em.x-btn-split-bottom, .x-toolbar .x-btn-pressed .x-btn-mc em.x-btn-split-bottom 
+{
+    background-image:url(../images/default/button/s-arrow-bo.gif);
+}
+.x-toolbar .xtb-sep {
+	background-image: url(../images/default/grid/grid-blue-split.gif);
+}
+.x-tbar-page-first{
+	background-image: url(../images/default/grid/page-first.gif) !important;
+}
+.x-tbar-refresh{
+	background-image: url(../images/default/grid/refresh.gif) !important;
+}
+.x-tbar-page-last{
+	background-image: url(../images/default/grid/page-last.gif) !important;
+}
+.x-tbar-page-next{
+	background-image: url(../images/default/grid/page-next.gif) !important;
+}
+.x-tbar-page-prev{
+	background-image: url(../images/default/grid/page-prev.gif) !important;
+}
+.x-tbar-loading{
+	background-image: url(../images/default/grid/loading.gif) !important;
+}
+.x-item-disabled .x-tbar-page-first{
+	background-image: url(../images/default/grid/page-first-disabled.gif) !important;
+}
+.x-item-disabled .x-tbar-page-last{
+	background-image: url(../images/default/grid/page-last-disabled.gif) !important;
+}
+.x-item-disabled .x-tbar-page-next{
+	background-image: url(../images/default/grid/page-next-disabled.gif) !important;
+}
+.x-item-disabled .x-tbar-page-prev{
+	background-image: url(../images/default/grid/page-prev-disabled.gif) !important;
+}
+.x-paging-info {
+    color:#444;
+}
+.x-toolbar-more-icon {
+    background-image: url(../images/default/toolbar/more.gif) !important;
+}.x-resizable-handle {
+	background-color:#fff;
+}
+.x-resizable-over .x-resizable-handle-east, .x-resizable-pinned .x-resizable-handle-east,
+.x-resizable-over .x-resizable-handle-west, .x-resizable-pinned .x-resizable-handle-west
+{
+    background-image:url(../images/default/sizer/e-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-south, .x-resizable-pinned .x-resizable-handle-south,
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north
+{
+    background-image:url(../images/default/sizer/s-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-north, .x-resizable-pinned .x-resizable-handle-north{
+    background-image:url(../images/default/sizer/s-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southeast, .x-resizable-pinned .x-resizable-handle-southeast{
+    background-image:url(../images/default/sizer/se-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northwest, .x-resizable-pinned .x-resizable-handle-northwest{
+    background-image:url(../images/default/sizer/nw-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-northeast, .x-resizable-pinned .x-resizable-handle-northeast{
+    background-image:url(../images/default/sizer/ne-handle.gif);
+}
+.x-resizable-over .x-resizable-handle-southwest, .x-resizable-pinned .x-resizable-handle-southwest{
+    background-image:url(../images/default/sizer/sw-handle.gif);
+}
+.x-resizable-proxy{
+    border-color:#3b5a82;
+}
+.x-resizable-overlay{
+    background-color:#fff;
+}
+.x-grid3 {
+    background-color:#fff;
+}
+.x-grid-panel .x-panel-mc .x-panel-body {
+    border-color:#99bbe8;
+}
+.x-grid3-hd-row .x-grid3-hd, .x-grid3-row .x-grid3-cell, .x-grid3-summary-row .x-grid3-cell{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-grid3-hd-row .x-grid3-hd {
+    border-left-color:#eee;
+    border-right-color:#d0d0d0;
+}
+.x-grid-row-loading {
+    background-color: #fff;
+    background-image:url(../images/default/shared/loading-balls.gif);
+}
+.x-grid3-row {
+    border-color:#ededed;
+    border-top-color:#fff;
+}
+.x-grid3-row-alt{
+	background-color:#fafafa;
+}
+.x-grid3-row-over {
+	border-color:#ddd;
+    background-color:#efefef;
+    background-image:url(../images/default/grid/row-over.gif);
+}
+.x-grid3-resize-proxy {
+    background-color:#777;
+}
+.x-grid3-resize-marker {
+    background-color:#777;
+}
+.x-grid3-header{
+    background-color:#f9f9f9;
+	background-image:url(../images/default/grid/grid3-hrow.gif);
+}
+.x-grid3-header-pop {
+    border-left-color:#d0d0d0;
+}
+.x-grid3-header-pop-inner {
+    border-left-color:#eee;
+    background-image:url(../images/default/grid/hd-pop.gif);
+}
+td.x-grid3-hd-over, td.sort-desc, td.sort-asc, td.x-grid3-hd-menu-open {
+    border-left-color:#aaccf6;
+    border-right-color:#aaccf6;
+}
+td.x-grid3-hd-over .x-grid3-hd-inner, td.sort-desc .x-grid3-hd-inner, td.sort-asc .x-grid3-hd-inner, td.x-grid3-hd-menu-open .x-grid3-hd-inner {
+    background-color:#ebf3fd;
+    background-image:url(../images/default/grid/grid3-hrow-over.gif);
+}
+.sort-asc .x-grid3-sort-icon {
+	background-image: url(../images/default/grid/sort_asc.gif);
+}
+.sort-desc .x-grid3-sort-icon {
+	background-image: url(../images/default/grid/sort_desc.gif);
+}
+.x-grid3-cell-text, .x-grid3-hd-text {
+	color:#000;
+}
+.x-grid3-split {
+	background-image: url(../images/default/grid/grid-split.gif);
+}
+.x-grid3-hd-text {
+	color:#15428b;
+}
+.x-dd-drag-proxy .x-grid3-hd-inner{
+    background-color:#ebf3fd;
+	background-image:url(../images/default/grid/grid3-hrow-over.gif);
+	border-color:#aaccf6;
+}
+.col-move-top{
+	background-image:url(../images/default/grid/col-move-top.gif);
+}
+.col-move-bottom{
+	background-image:url(../images/default/grid/col-move-bottom.gif);
+}
+.x-grid3-row-selected {
+    background-image: none !important;
+	background-color: #dfe8f6 !important;
+	border-color:#a3bae9;
+}
+.x-grid3-cell-selected{
+	background-color: #b8cfee !important;
+	color:#000;
+}
+.x-grid3-cell-selected span{
+	color:#000 !important;
+}
+.x-grid3-cell-selected .x-grid3-cell-text{
+	color:#000;
+}
+.x-grid3-locked td.x-grid3-row-marker, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker{
+    background-color:#ebeadb !important;
+    background-image:url(../images/default/grid/grid-hrow.gif) !important;
+    color:#000;
+    border-top-color:#fff;
+    border-right-color:#6fa0df !important;
+}
+.x-grid3-locked td.x-grid3-row-marker div, .x-grid3-locked .x-grid3-row-selected td.x-grid3-row-marker div{
+    color:#15428b !important;
+}
+.x-grid3-dirty-cell {
+    background-image:url(../images/default/grid/dirty.gif);
+}
+.x-grid3-topbar, .x-grid3-bottombar{
+	font:normal 11px arial, tahoma, helvetica, sans-serif;
+}
+.x-grid3-bottombar .x-toolbar{
+	border-top-color:#a9bfd3;
+}
+.x-props-grid .x-grid3-td-name .x-grid3-cell-inner{
+	background-image:url(../images/default/grid/grid3-special-col-bg.gif) !important;
+    color:#000 !important;
+}
+.x-props-grid .x-grid3-body .x-grid3-td-name{
+    background-color:#fff !important;
+    border-right-color:#eee;
+}
+.xg-hmenu-sort-asc .x-menu-item-icon{
+	background-image: url(../images/default/grid/hmenu-asc.gif);
+}
+.xg-hmenu-sort-desc .x-menu-item-icon{
+	background-image: url(../images/default/grid/hmenu-desc.gif);
+}
+.xg-hmenu-lock .x-menu-item-icon{
+	background-image: url(../images/default/grid/hmenu-lock.gif);
+}
+.xg-hmenu-unlock .x-menu-item-icon{
+	background-image: url(../images/default/grid/hmenu-unlock.gif);
+}
+.x-grid3-hd-btn {
+    background-color:#c3daf9;
+    background-image:url(../images/default/grid/grid3-hd-btn.gif);
+}
+.x-grid3-body .x-grid3-td-expander {
+    background-image:url(../images/default/grid/grid3-special-col-bg.gif);
+}
+.x-grid3-row-expander {
+    background-image:url(../images/default/grid/row-expand-sprite.gif);
+}
+.x-grid3-body .x-grid3-td-checker {
+    background-image: url(../images/default/grid/grid3-special-col-bg.gif);
+}
+.x-grid3-row-checker, .x-grid3-hd-checker {
+    background-image:url(../images/default/grid/row-check-sprite.gif);
+}
+.x-grid3-body .x-grid3-td-numberer {
+    background-image:url(../images/default/grid/grid3-special-col-bg.gif);
+}
+.x-grid3-body .x-grid3-td-numberer .x-grid3-cell-inner {
+	color:#444;
+}
+.x-grid3-body .x-grid3-td-row-icon {
+    background-image:url(../images/default/grid/grid3-special-col-bg.gif);
+}
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-numberer,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-checker,
+.x-grid3-body .x-grid3-row-selected .x-grid3-td-expander {
+	background-image:url(../images/default/grid/grid3-special-col-sel-bg.gif);
+}
+.x-grid3-check-col {
+	background-image:url(../images/default/menu/unchecked.gif);
+}
+.x-grid3-check-col-on {
+	background-image:url(../images/default/menu/checked.gif);
+}
+.x-grid-group, .x-grid-group-body, .x-grid-group-hd {
+    zoom:1;
+}
+.x-grid-group-hd {
+    border-bottom-color:#99bbe8;
+}
+.x-grid-group-hd div {
+    background-image:url(../images/default/grid/group-expand-sprite.gif);
+    color:#3764a0;
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-group-by-icon {
+    background-image:url(../images/default/grid/group-by.gif);
+}
+.x-cols-icon {
+    background-image:url(../images/default/grid/columns.gif);
+}
+.x-show-groups-icon {
+    background-image:url(../images/default/grid/group-by.gif);
+}
+.x-grid-empty {
+    color:gray;
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-grid-with-col-lines .x-grid3-row td.x-grid3-cell {
+    border-right-color:#ededed;
+}
+.x-grid-with-col-lines .x-grid3-row{
+    border-top-color:#ededed;
+}
+.x-grid-with-col-lines .x-grid3-row-selected {
+	border-top-color:#a3bae9;
+}
+
+.x-grid3-check-col-disabled {
+    background-color:transparent;
+	background-image:url(../images/gxt/menu/disabledcheck.gif);
+}
+
+.x-row-editor-header {
+	background: transparent url(../images/gxt/grid/row-editor-bg.gif) repeat-x 0 0;
+}
+.x-row-editor-footer {
+	background: transparent url(../images/gxt/grid/row-editor-bg.gif) repeat-x 0 -2px;
+}
+.x-row-editor-body {
+    background: #ebf2fb;
+}
+.x-row-editor .x-btns {
+    background: transparent url(../images/gxt/grid/row-editor-btns.gif) no-repeat 0 0;
+}
+.x-row-editor .x-btns .x-plain-bwrap {
+  	background: transparent url(../images/gxt/grid/row-editor-btns.gif) no-repeat right -31px;
+}
+.x-row-editor .x-btns .x-plain-body {
+	background: transparent url(../images/gxt/grid/row-editor-btns.gif) repeat-x 0 -62px;
+}
+.x-dd-drag-ghost{
+	color:#000;
+	font: normal 11px arial, helvetica, sans-serif;
+    border-color: #ddd #bbb #bbb #ddd;
+	background-color:#fff;
+}
+.x-dd-drop-nodrop .x-dd-drop-icon{
+  background-image: url(../images/default/dd/drop-no.gif);
+}
+.x-dd-drop-ok .x-dd-drop-icon{
+  background-image: url(../images/default/dd/drop-yes.gif);
+}
+.x-dd-drop-ok-add .x-dd-drop-icon{
+  background-image: url(../images/default/dd/drop-add.gif);
+}
+.x-view-selector {
+    background-color:#c3daf9;
+    border-color:#3399bb;
+}
+.x-tree-drop-ok-append .x-dd-drop-icon {
+	background-image: url(../images/default/tree/drop-add.gif);
+}
+
+.x-tree-drop-ok-above .x-dd-drop-icon {
+	background-image: url(../images/default/tree/drop-over.gif);
+}
+
+.x-tree-drop-ok-below .x-dd-drop-icon {
+	background-image: url(../images/default/tree/drop-under.gif);
+}
+
+.x-tree-drop-ok-between .x-dd-drop-icon {
+	background-image: url(../images/default/tree/drop-between.gif);
+}
+
+.x-tree3-loading {
+	background-image: url(../images/default/tree/loading.gif);
+}
+
+.x-tree3-node-text {
+	font: normal 11px arial, tahoma, helvetica, sans-serif;
+	color: black;
+}.x-date-picker {
+    border-color: #1b376c;
+    background-color:#fff;
+}
+.x-date-middle,.x-date-left,.x-date-right {
+	background-image: url(../images/default/shared/hd-sprite.gif);
+	color:#fff;
+	font:bold 11px "sans serif", tahoma, verdana, helvetica;
+}
+.x-date-middle .x-btn .x-btn-text {
+    color:#fff;
+}
+.x-date-middle .x-btn-mc em.x-btn-arrow {
+    background-image:url(../images/default/toolbar/btn-arrow-light.gif);
+}
+.x-date-right a {
+    background-image: url(../images/default/shared/right-btn.gif);
+}
+.x-date-left a{
+	background-image: url(../images/default/shared/left-btn.gif);
+}
+.x-date-inner th {
+    background-color:#dfecfb;
+    background-image:url(../images/default/shared/glass-bg.gif);
+	border-bottom-color:#a3bad9;
+    font:normal 10px arial, helvetica,tahoma,sans-serif;
+	color:#233d6d;
+}
+.x-date-inner td {
+    border-color:#fff;
+}
+.x-date-inner a {
+    font:normal 11px arial, helvetica,tahoma,sans-serif;
+    color:#000;
+}
+.x-date-inner .x-date-active{
+	color:#000;
+}
+.x-date-inner .x-date-selected a{
+    background-color:#dfecfb;
+	background-image:url(../images/default/shared/glass-bg.gif);
+	border-color:#8db2e3;
+}
+.x-date-inner .x-date-today a{
+	border-color:darkred;
+}
+.x-date-inner .x-date-selected span{
+    font-weight:bold;
+}
+.x-date-inner .x-date-prevday a,.x-date-inner .x-date-nextday a {
+	color:#aaa;
+}
+.x-date-bottom {
+    border-top-color:#a3bad9;
+    background-color:#dfecfb;
+    background-image:url(../images/default/shared/glass-bg.gif);
+}
+.x-date-inner .x-date-disabled a {
+	background-color:#eee;
+	color:#bbb;
+}
+.x-date-mmenu{
+    background-color:#eee !important;
+}
+.x-date-mmenu .x-menu-item {
+	font-size:10px;
+	color:#000;
+}
+.x-date-mp {
+	background-color:#fff;
+}
+.x-date-mp td {
+	font:normal 11px arial, helvetica,tahoma,sans-serif;
+}
+.x-date-mp-btns button {
+	background-color:#083772;
+	color:#fff;
+	border-color: #3366cc #000055 #000055 #3366cc;
+	font:normal 11px arial, helvetica,tahoma,sans-serif;
+}
+.x-date-mp-btns {
+    background-color: #dfecfb;
+	background-image: url(../images/default/shared/glass-bg.gif);
+}
+.x-date-mp-btns td {
+	border-top-color: #c5d2df;
+}
+td.x-date-mp-month a,td.x-date-mp-year a {
+	color:#15428b;
+}
+td.x-date-mp-sel a {
+    background-color: #dfecfb;
+	background-image: url(../images/default/shared/glass-bg.gif);
+	border-color:#8db2e3;
+}
+.x-date-mp-ybtn a {
+    background-image:url(../images/default/panel/tool-sprites.gif);
+}
+td.x-date-mp-sep {
+   border-right-color:#c5d2df;
+}
+.x-tip .x-tip-close{
+	background-image: url(../images/default/qtip/close.gif);
+}
+.x-tip .x-tip-tc, .x-tip .x-tip-tl, .x-tip .x-tip-tr, .x-tip .x-tip-bc, .x-tip .x-tip-bl, .x-tip .x-tip-br, .x-tip .x-tip-ml, .x-tip .x-tip-mr {
+	background-image: url(../images/default/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-mc {
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+}
+.x-tip .x-tip-ml {
+	background-color: #fff;
+}
+.x-tip .x-tip-header-text {
+    font: bold 11px tahoma,arial,helvetica,sans-serif;
+    color:#444;
+}
+.x-tip .x-tip-body {
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+    color:#444;
+}
+.x-form-invalid-tip .x-tip-tc, .x-form-invalid-tip .x-tip-tl, .x-form-invalid-tip .x-tip-tr, .x-form-invalid-tip .x-tip-bc,
+.x-form-invalid-tip .x-tip-bl, .x-form-invalid-tip .x-tip-br, .x-form-invalid-tip .x-tip-ml, .x-form-invalid-tip .x-tip-mr
+{
+	background-image: url(../images/default/form/error-tip-corners.gif);
+}
+.x-form-invalid-tip .x-tip-body {
+    background-image:url(../images/default/form/exclamation.gif);
+}
+.x-tip-anchor {
+    background-image:url(../images/default/qtip/tip-anchor-sprite.gif);
+}
+.x-menu {
+	border-color:#718bb7;
+    background-color:#f0f0f0;
+	background-image:url(../images/default/menu/menu.gif);
+}
+.x-menu-nosep {
+	background-image:none;
+}
+.x-menu-list-item{
+	font:normal 11px tahoma,arial, sans-serif;
+}
+.x-menu-item-arrow{
+	background-image:url(../images/default/menu/menu-parent.gif);
+}
+.x-menu-sep {
+    background-color:#e0e0e0;
+	border-bottom-color:#fff;
+}
+a.x-menu-item {
+	color:#222;
+}
+.x-menu-item-active {
+	background-color: #dbecf4;
+    border-color:#aaccf6;
+}
+.x-menu-item-active a.x-menu-item {
+	border-color:#aaccf6;
+}
+.x-menu-plain {
+	background-color:#fff !important;
+}
+.x-menu .x-date-picker{
+    border-color:#a3bad9;
+}
+.x-cycle-menu .x-menu-item-checked {
+    border-color:#a3bae9 !important;
+    background-color:#def8f6;
+}
+.x-menu-scroller-top {
+    background-image:url(../images/default/layout/mini-top.gif);
+}
+.x-menu-scroller-bottom {
+    background-image:url(../images/default/layout/mini-bottom.gif);
+}
+
+.x-menu-scroller{
+	border-width: 1px 0;
+}
+.x-box-tl {
+	background-image: url(../images/default/box/corners.gif);
+}
+.x-box-tc {
+	background-image: url(../images/default/box/tb.gif);
+}
+.x-box-tr {
+	background-image: url(../images/default/box/corners.gif);
+}
+.x-box-ml {
+	background-image: url(../images/default/box/l.gif);
+}
+.x-box-mc {
+	background-color: #eee;
+    background-image: url(../images/default/box/tb.gif);
+	font-family: "Myriad Pro","Myriad Web","Tahoma","Helvetica","Arial",sans-serif;
+	color: #393939;
+	font-size: 12px;
+}
+.x-box-mc h3 {
+	font-size: 14px;
+	font-weight: bold;
+}
+.x-box-mr {
+	background-image: url(../images/default/box/r.gif);
+}
+.x-box-bl {
+	background-image: url(../images/default/box/corners.gif);
+}
+.x-box-bc {
+	background-image: url(../images/default/box/tb.gif);
+}
+.x-box-br {
+	background-image: url(../images/default/box/corners.gif);
+}
+.x-box-blue .x-box-bl, .x-box-blue .x-box-br, .x-box-blue .x-box-tl, .x-box-blue .x-box-tr {
+	background-image: url(../images/default/box/corners-blue.gif);
+}
+.x-box-blue .x-box-bc, .x-box-blue .x-box-mc, .x-box-blue .x-box-tc {
+	background-image: url(../images/default/box/tb-blue.gif);
+}
+.x-box-blue .x-box-mc {
+	background-color: #c3daf9;
+}
+.x-box-blue .x-box-mc h3 {
+	color: #17385b;
+}
+.x-box-blue .x-box-ml {
+	background-image: url(../images/default/box/l-blue.gif);
+}
+.x-box-blue .x-box-mr {
+	background-image: url(../images/default/box/r-blue.gif);
+}
+.x-combo-list {
+    border-color:#98c0f4;
+    background-color:#ddecfe;
+    font:normal 12px tahoma, arial, helvetica, sans-serif;
+}
+.x-combo-list-inner {
+    background-color:#fff;
+}
+.x-combo-list-hd {
+    font:bold 11px tahoma, arial, helvetica, sans-serif;
+    color:#15428b;
+    background-image: url(../images/default/layout/panel-title-light-bg.gif);
+    border-bottom-color:#98c0f4;
+}
+.x-resizable-pinned .x-combo-list-inner {
+    border-bottom-color:#98c0f4;
+}
+.x-combo-list-item {
+    border-color:#fff;
+}
+.x-combo-list .x-combo-selected{
+	border-color:#a3bae9 !important;
+    background-color:#dfe8f6;
+}
+.x-combo-list .x-toolbar {
+    border-top-color:#98c0f4;
+}
+.x-combo-list-small {
+    font:normal 11px tahoma, arial, helvetica, sans-serif;
+}
+.x-panel {
+    border-color: #99bbe8;
+}
+.x-panel-header {
+    color:#15428b;
+	font:bold 11px tahoma,arial,verdana,sans-serif;
+    border-color:#99bbe8;
+    background-image: url(../images/default/panel/white-top-bottom.gif);
+}
+.x-panel-body {
+    border-color:#99bbe8;
+    background-color:#fff;
+}
+.x-panel-bbar .x-toolbar, .x-panel-tbar .x-toolbar {
+    border-color:#99bbe8;
+}
+.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar {
+    border-top-color:#99bbe8;
+}
+.x-panel-body-noheader, .x-panel-mc .x-panel-body {
+    border-top-color:#99bbe8;
+}
+.x-panel-tl .x-panel-header {
+    color:#15428b;
+	font:bold 11px tahoma,arial,verdana,sans-serif;
+}
+.x-panel-tc {
+	background-image: url(../images/default/panel/top-bottom.gif);
+}
+.x-panel-tl, .x-panel-tr, .x-panel-bl,  .x-panel-br{
+	background-image: url(../images/default/panel/corners-sprite.gif);
+    border-bottom-color:#99bbe8;
+}
+.x-panel-bc {
+	background-image: url(../images/default/panel/top-bottom.gif);
+}
+.x-panel-mc {
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+    background-color:#dfe8f6;
+}
+.x-panel-ml {
+	background-color: #fff;
+    background-image:url(../images/default/panel/left-right.gif);
+}
+.x-panel-mr {
+	background-image: url(../images/default/panel/left-right.gif);
+}
+.x-tool {
+    background-image:url(../images/default/panel/tool-sprites.gif);
+}
+.x-panel-ghost {
+    background-color:#cbddf3;
+}
+.x-panel-ghost ul {
+    border-color:#99bbe8;
+}
+.x-panel-dd-spacer {
+    border-color:#99bbe8;
+}
+.x-panel-fbar td,.x-panel-fbar span,.x-panel-fbar input,.x-panel-fbar div,.x-panel-fbar select,.x-panel-fbar label{
+    font:normal 11px arial,tahoma, helvetica, sans-serif;
+}
+.x-window-proxy {
+    background-color:#c7dffc;
+    border-color:#99bbe8;
+}
+.x-window-tl .x-window-header {
+    color:#15428b;
+	font:bold 11px tahoma,arial,verdana,sans-serif;
+}
+.x-window-tc {
+	background-image: url(../images/default/window/top-bottom.png);
+}
+.x-window-tl {
+	background-image: url(../images/default/window/left-corners.png);
+}
+.x-window-tr {
+	background-image: url(../images/default/window/right-corners.png);
+}
+.x-window-bc {
+	background-image: url(../images/default/window/top-bottom.png);
+}
+.x-window-bl {
+	background-image: url(../images/default/window/left-corners.png);
+}
+.x-window-br {
+	background-image: url(../images/default/window/right-corners.png);
+}
+.x-window-mc {
+    border-color:#99bbe8;
+    font: normal 11px tahoma,arial,helvetica,sans-serif;
+    background-color:#dfe8f6;
+}
+.x-window-ml {
+	background-image: url(../images/default/window/left-right.png);
+}
+.x-window-mr {
+	background-image: url(../images/default/window/left-right.png);
+}
+.x-window-maximized .x-window-tc {
+    background-color:#fff;
+}
+.x-window-bbar .x-toolbar {
+    border-top-color:#99bbe8;
+}
+.x-panel-ghost .x-window-tl {
+    border-bottom-color:#99bbe8;
+}
+.x-panel-collapsed .x-window-tl {
+    border-bottom-color:#84a0c4;
+}
+.x-dlg-mask{
+   background-color:#ccc;
+}
+.x-window-plain .x-window-mc {
+    background-color: #ccd9e8;
+    border-color: #a3bae9 #dfe8f6 #dfe8f6 #a3bae9;
+}
+.x-window-plain .x-window-body {
+    border-color: #dfe8f6 #a3bae9 #a3bae9 #dfe8f6;
+}
+body.x-body-masked .x-window-plain .x-window-mc {
+    background-color: #ccd9e8;
+}
+.x-html-editor-wrap {
+    border-color:#a9bfd3;
+    background-color:#fff;
+}
+
+.x-html-editor-tb .x-edit-bold, .x-menu-item .x-edit-bold {
+    background-position:0 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);    
+}
+
+.x-html-editor-tb .x-edit-italic, .x-menu-item .x-edit-italic {
+    background-position:-16px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-underline, .x-menu-item .x-edit-underline {
+    background-position:-32px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-forecolor, .x-menu-item .x-edit-forecolor {
+    background-position:-160px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-backcolor, .x-menu-item .x-edit-backcolor {
+    background-position:-176px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifyleft, .x-menu-item .x-edit-justifyleft {
+    background-position:-112px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifycenter, .x-menu-item .x-edit-justifycenter {
+    background-position:-128px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-justifyright, .x-menu-item .x-edit-justifyright {
+    background-position:-144px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-insertorderedlist, .x-menu-item .x-edit-insertorderedlist {
+    background-position:-80px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-insertunorderedlist, .x-menu-item .x-edit-insertunorderedlist {
+    background-position:-96px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-increasefontsize, .x-menu-item .x-edit-increasefontsize {
+    background-position:-48px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-decreasefontsize, .x-menu-item .x-edit-decreasefontsize {
+    background-position:-64px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-sourceedit, .x-menu-item .x-edit-sourceedit {
+    background-position:-192px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}
+
+.x-html-editor-tb .x-edit-createlink, .x-menu-item .x-edit-createlink {
+    background-position:-208px 0;
+    background-image:url(../images/default/editor/tb-sprite.gif);
+}.x-panel-noborder .x-panel-header-noborder {
+    border-bottom-color:#99bbe8;
+}
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+    border-bottom-color:#99bbe8;
+}
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+    border-top-color:#99bbe8;
+}
+.x-tab-panel-bbar-noborder .x-toolbar {
+    border-top-color:#99bbe8;
+}
+.x-tab-panel-tbar-noborder .x-toolbar {
+    border-bottom-color:#99bbe8;
+}
+.x-border-layout-ct {
+    background-color:#dfe8f6;
+}
+.x-accordion-hd {
+	color:#222;
+    font-weight:normal;
+    background-image: url(../images/default/panel/light-hd.gif);
+}
+.x-layout-collapsed{
+    background-color:#d2e0f2;
+	border-color:#98c0f4;
+}
+.x-layout-collapsed-over{
+    background-color:#d9e8fb;
+}
+.x-layout-split-west .x-layout-mini {
+    background-image:url(../images/default/layout/mini-left.gif);
+}
+.x-layout-split-east .x-layout-mini {
+    background-image:url(../images/default/layout/mini-right.gif);
+}
+.x-layout-split-north .x-layout-mini {
+    background-image:url(../images/default/layout/mini-top.gif);
+}
+.x-layout-split-south .x-layout-mini {
+    background-image:url(../images/default/layout/mini-bottom.gif);
+}
+.x-layout-cmini-west .x-layout-mini {
+    background-image:url(../images/default/layout/mini-right.gif);
+}
+.x-layout-cmini-east .x-layout-mini {
+    background-image:url(../images/default/layout/mini-left.gif);
+}
+.x-layout-cmini-north .x-layout-mini {
+    background-image:url(../images/default/layout/mini-bottom.gif);
+}
+.x-layout-cmini-south .x-layout-mini {
+    background-image:url(../images/default/layout/mini-top.gif);
+}
+.x-progress-wrap {
+    border-color:#6593cf;
+}
+.x-progress-inner {
+    background-color:#e0e8f3;
+    background-image:url(../images/default/qtip/bg.gif);
+}
+.x-progress-bar {
+    background-color:#9cbfee;
+    background-image:url(../images/default/progress/progress-bg.gif);
+    border-top-color:#d1e4fd;
+    border-bottom-color:#7fa9e4;
+    border-right-color:#7fa9e4;
+}
+.x-progress-text {
+    font-size:11px;
+    font-weight:bold;
+    color:#fff;
+}
+.x-progress-text-back {
+    color:#396095;
+}
+.x-slider-horz, .x-slider-horz .x-slider-end, .x-slider-horz .x-slider-inner {
+    background-image:url(../images/default/slider/slider-bg.png);
+}
+.x-slider-horz .x-slider-thumb {
+    background-image:url(../images/default/slider/slider-thumb.png);
+}
+.x-slider-vert, .x-slider-vert .x-slider-end, .x-slider-vert .x-slider-inner {
+    background-image:url(../images/default/slider/slider-v-bg.png);
+}
+.x-slider-vert .x-slider-thumb {
+    background-image:url(../images/default/slider/slider-v-thumb.png);
+}
+.x-window-dlg .ext-mb-text,
+.x-window-dlg .x-window-header-text {
+    font-size:12px;
+}
+.x-window-dlg .ext-mb-textarea {
+    font:normal 12px tahoma,arial,helvetica,sans-serif;
+}
+.x-window-dlg .x-msg-box-wait {
+    background-image:url(../images/default/grid/loading.gif);
+}
+.x-window-dlg .ext-mb-info {
+    background-image:url(../images/default/window/icon-info.gif);
+}
+.x-window-dlg .ext-mb-warning {
+    background-image:url(../images/default/window/icon-warning.gif);
+}
+.x-window-dlg .ext-mb-question {
+    background-image:url(../images/default/window/icon-question.gif);
+}
+.x-window-dlg .ext-mb-error {
+    background-image:url(../images/default/window/icon-error.gif);
+}

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-gray.css
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-gray.css	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/gwtext/css/gxt-gray.css	2010-04-14 22:14:14 UTC (rev 121)
@@ -0,0 +1,478 @@
+/*
+ * Ext GWT Library 2.0.1
+ * Copyright(c) 2006-2009, Ext JS, LLC.
+ * licensing at extjs.com
+ * 
+ * http://extjs.com/license
+ */
+.x-panel {
+    border-style: solid;
+    border-color: #d0d0d0;
+}
+.x-panel-header {
+    color:#333;
+	border:1px solid #d0d0d0;
+    background-image:url(../images/gray/panel/white-top-bottom.gif);
+}
+
+.x-panel-body {
+    border-color:#d0d0d0;
+}
+
+.x-panel-bbar .x-toolbar {
+    border-color:#d0d0d0;
+}
+
+.x-panel-tbar .x-toolbar {
+    border-color:#d0d0d0;
+}
+
+.x-panel-tbar-noheader .x-toolbar, .x-panel-mc .x-panel-tbar .x-toolbar {
+    border-color:#d0d0d0;
+}
+.x-panel-body-noheader, .x-panel-mc .x-panel-body {
+    border-color:#d0d0d0;
+}
+.x-panel-tl .x-panel-header {
+    color:#333;
+}
+.x-panel-tc {
+	background-image:url(../images/gray/panel/top-bottom.gif);
+}
+.x-panel-tl {
+	background-image:url(../images/gray/panel/corners-sprite.gif);
+    border-color:#d0d0d0;
+}
+.x-panel-tr {
+	background-image:url(../images/gray/panel/corners-sprite.gif);
+}
+.x-panel-bc {
+	background-image:url(../images/gray/panel/top-bottom.gif);
+}
+.x-panel-bl {
+	background-image:url(../images/gray/panel/corners-sprite.gif);
+}
+.x-panel-br {
+	background-image:url(../images/gray/panel/corners-sprite.gif);
+}
+.x-panel-mc {
+    background:#f1f1f1;
+}
+.x-panel-mc .x-panel-body {
+    background:transparent;
+    border: 0 none;
+}
+.x-panel-ml {
+	background-image:url(../images/gray/panel/left-right.gif);
+}
+.x-panel-mr {
+	background-image:url(../images/gray/panel/left-right.gif);
+}
+
+/* Tools */
+.x-tool {
+    background-image:url(../images/gray/panel/tool-sprites.gif);
+}
+
+/* Ghosting */
+.x-panel-ghost {
+    background:#e0e0e0;
+}
+
+.x-panel-ghost ul {
+    border-color:#b0b0b0;
+}
+
+.x-grid-panel .x-panel-mc .x-panel-body {
+    border:1px solid #d0d0d0;
+}
+
+/* Buttons */
+
+.x-btn-left{
+	background-image:url(../images/gray/button/btn-sprite.gif);
+}
+.x-btn-right{
+	background-image:url(../images/gray/button/btn-sprite.gif);
+}
+.x-btn-center{
+	background-image:url(../images/gray/button/btn-sprite.gif);
+}
+
+.x-btn-group-header {
+    color: #333333;
+}
+.x-btn-group-tc {
+	background-image: url(../images/gray/button/group-tb.gif);
+}
+.x-btn-group-tl {
+	background-image: url(../images/gray/button/group-cs.gif);
+}
+.x-btn-group-tr {
+	background-image: url(../images/gray/button/group-cs.gif);
+}
+.x-btn-group-bc {
+	background-image: url(../images/gray/button/group-tb.gif);
+}
+.x-btn-group-bl {
+	background-image: url(../images/gray/button/group-cs.gif);
+}
+.x-btn-group-br {
+	background-image: url(../images/gray/button/group-cs.gif);
+}
+.x-btn-group-ml {
+	background-image: url(../images/gray/button/group-lr.gif);
+}
+.x-btn-group-mr {
+	background-image: url(../images/gray/button/group-lr.gif);
+}
+.x-btn-group-notitle .x-btn-group-tc {
+	background-image: url(../images/gray/button/group-tb.gif);
+}
+
+/* Layout classes */
+
+.x-border-layout-ct {
+    background:#f0f0f0;
+}
+
+.x-accordion-hd {
+	background-image:url(../images/gray/panel/light-hd.gif);
+}
+
+.x-layout-collapsed{
+    background-color:#eee;
+    border-color:#e0e0e0;
+}
+.x-layout-collapsed-over{
+	 background-color:#fbfbfb;
+}
+
+
+/* qtips */
+.x-tip .x-tip-top {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-left {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-top-right {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-left {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-ft-right {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-left {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+.x-tip .x-tip-bd-right {
+	background-image:url(../images/gray/qtip/tip-sprite.gif);
+}
+
+/* Toolbars */
+
+.x-toolbar{
+	border-color:#d0d0d0;
+    background:#f0f4f5 url(../images/gray/toolbar/bg.gif) repeat-x top left;
+}
+.x-toolbar button {
+    color:#444;
+}
+.x-toolbar .x-btn-menu-arrow-wrap .x-btn-center button {
+    background-image:url(../images/gray/toolbar/btn-arrow.gif);
+}
+.x-toolbar .x-btn-text-icon .x-btn-menu-arrow-wrap .x-btn-center button {
+    background-image:url(../images/gray/toolbar/btn-arrow.gif);
+}
+.x-toolbar .x-btn-over .x-btn-left{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+.x-toolbar .x-btn-over .x-btn-right{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+.x-toolbar .x-btn-over .x-btn-center{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+.x-toolbar .x-btn-over button {
+    color:#111;
+}
+.x-toolbar .x-btn-click .x-btn-left, .x-toolbar .x-btn-pressed .x-btn-left, .x-toolbar .x-btn-menu-active .x-btn-left{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+.x-toolbar .x-btn-click .x-btn-right, .x-toolbar .x-btn-pressed .x-btn-right, .x-toolbar .x-btn-menu-active .x-btn-right{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+
+.x-toolbar .x-btn-click .x-btn-center, .x-toolbar .x-btn-pressed .x-btn-center, .x-toolbar .x-btn-menu-active .x-btn-center{
+	background-image:url(../images/gray/toolbar/tb-btn-sprite.gif);
+}
+.x-toolbar .ytb-sep {
+	background-image: url(../images/default/grid/grid-split.gif);
+}
+
+/* Tabs */
+
+.x-tab-panel-header, .x-tab-panel-footer {
+	background: #EAEAEA;
+	border-color:#d0d0d0;
+}
+
+
+.x-tab-panel-header {
+	border-color:#d0d0d0;
+}
+
+.x-tab-panel-footer {
+	border-color:#d0d0d0;
+}
+
+ul.x-tab-strip-top{
+	background:#dbdbdb url(../images/gray/tabs/tab-strip-bg.gif) repeat-x left top;
+	border-color:#d0d0d0;
+    padding-top: 2px;
+}
+
+ul.x-tab-strip-bottom{
+	background-image:url(../images/gray/tabs/tab-strip-btm-bg.gif);
+	border-color:#d0d0d0;
+}
+
+.x-tab-strip span.x-tab-strip-text {
+	color:#333;
+}
+.x-tab-strip-over span.x-tab-strip-text {
+	color:#111;
+}
+
+.x-tab-strip-active span.x-tab-strip-text {
+	color:#333;
+}
+
+.x-tab-strip-disabled .x-tabs-text {
+	color:#aaaaaa;
+}
+
+.x-tab-strip-top .x-tab-right {
+	background-image:url(../images/gray/tabs/tabs-sprite.gif);
+}
+
+.x-tab-strip-top .x-tab-left {
+	background-image:url(../images/gray/tabs/tabs-sprite.gif);
+}
+.x-tab-strip-top .x-tab-strip-inner {
+	background-image:url(../images/gray/tabs/tabs-sprite.gif);
+}
+
+.x-tab-strip-bottom .x-tab-right {
+	background-image:url(../images/gray/tabs/tab-btm-inactive-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-left {
+	background-image:url(../images/gray/tabs/tab-btm-inactive-left-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-right {
+	background-image:url(../images/gray/tabs/tab-btm-right-bg.gif);
+}
+
+.x-tab-strip-bottom .x-tab-strip-active .x-tab-left {
+	background-image:url(../images/gray/tabs/tab-btm-left-bg.gif);
+}
+
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close {
+	background-image:url(../images/gray/tabs/tab-close.gif);
+}
+.x-tab-strip .x-tab-strip-closable a.x-tab-strip-close:hover{
+	background-image:url(../images/gray/tabs/tab-close.gif);
+}
+
+.x-tab-panel-body {
+    border-color:#d0d0d0;
+    background:#fff;
+}
+.x-tab-panel-bbar .x-toolbar {
+    border-color: #d0d0d0;
+}
+
+.x-tab-panel-tbar .x-toolbar {
+    border-color: #d0d0d0;
+}
+
+.x-tab-panel-header-plain .x-tab-strip-spacer {
+    border-color:#d0d0d0;
+    background: #eaeaea;
+}
+
+.x-tab-scroller-left {
+    background-image: url(../images/gray/tabs/scroll-left.gif);
+    border-color:#aeaeae;
+}
+.x-tab-scroller-right {
+    background-image: url(../images/gray/tabs/scroll-right.gif);
+    border-color:#aeaeae;
+}
+
+/* Window */
+
+.x-window-proxy {
+    background:#e0e0e0;
+    border-color:#b0b0b0;
+}
+
+.x-window-tl .x-window-header {
+    color:#555;
+}
+.x-window-tc {
+	background-image:url(../images/gray/window/top-bottom.png);
+}
+.x-window-tl {
+	background-image:url(../images/gray/window/left-corners.png);
+}
+.x-window-tr {
+	background-image:url(../images/gray/window/right-corners.png);
+}
+.x-window-bc {
+	background-image:url(../images/gray/window/top-bottom.png);
+}
+.x-window-bl {
+	background-image:url(../images/gray/window/left-corners.png);
+}
+.x-window-br {
+	background-image:url(../images/gray/window/right-corners.png);
+}
+.x-window-mc {
+    border:1px solid #d0d0d0;
+    background:#e8e8e8;
+}
+
+.x-window-ml {
+	background-image:url(../images/gray/window/left-right.png);
+}
+.x-window-mr {
+	background-image:url(../images/gray/window/left-right.png);
+}
+.x-panel-ghost .x-window-tl {
+    border-color:#d0d0d0;
+}
+.x-panel-collapsed .x-window-tl {
+    border-color:#d0d0d0;
+}
+
+.x-window-plain .x-window-mc {
+    background: #e8e8e8;
+    border-right:1px solid #eee;
+    border-bottom:1px solid #eee;
+    border-top:1px solid #d0d0d0;
+    border-left:1px solid #d0d0d0;
+}
+
+.x-window-plain .x-window-body {
+    border-left:1px solid #eee;
+    border-top:1px solid #eee;
+    border-bottom:1px solid #d0d0d0;
+    border-right:1px solid #d0d0d0;
+    background:transparent !important;
+}
+
+body.x-body-masked .x-window-mc, body.x-body-masked .x-window-plain .x-window-mc {
+    background-color: #e4e4e4;
+}
+
+
+/* misc */
+.x-html-editor-wrap {
+    border-color:#d0d0d0;
+}
+
+/* Borders go last for specificity */
+.x-panel-noborder .x-panel-body-noborder {
+    border-width:0;
+}
+
+.x-panel-noborder .x-panel-header-noborder {
+    border-width:0;
+    border-bottom:1px solid #d0d0d0;
+}
+
+.x-panel-noborder .x-panel-tbar-noborder .x-toolbar {
+    border-width:0;
+    border-bottom:1px solid #d0d0d0;
+}
+
+.x-panel-noborder .x-panel-bbar-noborder .x-toolbar {
+    border-width:0;
+    border-top:1px solid #d0d0d0;
+}
+
+.x-window-noborder .x-window-mc {
+    border-width:0;
+}
+.x-window-plain .x-window-body-noborder {
+    border-width:0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-body-noborder {
+	border-width:0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-header-noborder {
+	border-top-width:0;
+	border-left-width:0;
+	border-right-width:0;
+}
+
+.x-tab-panel-noborder .x-tab-panel-footer-noborder {
+	border-bottom-width:0;
+	border-left-width:0;
+	border-right-width:0;
+}
+
+
+.x-tab-panel-bbar-noborder .x-toolbar {
+    border-width:0;
+    border-top:1px solid #d0d0d0;
+}
+
+.x-tab-panel-tbar-noborder .x-toolbar {
+    border-width:0;
+    border-bottom:1px solid #d0d0d0;
+}.x-accordion-hd {
+	background-color: #e5e5e5;
+}.x-border {
+  border: 1px solid #D0D0D0;
+}
+
+.x-layout-popup {
+  background-color: #F0F0F0;
+  border: 1px solid #D0D0D0;
+}
+
+.my-list {
+  border: 1px solid #D0D0D0;
+}
+
+.x-view {
+  border:1px solid #D0D0D0;
+}.my-info {
+  background: url(../images/gray/info/info-bg.gif) no-repeat;
+}.x-date-right-icon {
+  background-image: url(../images/default/shared/right-btn.gif);
+  margin-right: 2px;
+  text-decoration: none !important;
+}
+
+.x-date-left-icon {
+  background-image: url(../images/default/shared/left-btn.gif);
+  margin-right: 2px;
+  text-decoration: none !important;
+}.my-tbl {
+	border: 1px solid #C6C5C5;
+}.my-treetbl {
+	border: 1px solid #C6C5C5;
+}
\ No newline at end of file

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-bottom.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-arrow.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-arrow.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/bubble-top.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/close-button.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/close-button.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright-vertical.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright-vertical.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/copyright.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dark-red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-blue-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-blue-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/dull-red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/gray-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/gray-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/green-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/green-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-bottom-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-left.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-left.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-right.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/message-top-right.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/progress-running.gif
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/progress-running.gif
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/red-circle.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/red-circle.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/top-bubble.png
===================================================================
(Binary files differ)


Property changes on: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/public/step/images/top-bubble.png
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream



From ChrisBurrell at crosswire.org  Wed Apr 14 15:17:05 2010
From: ChrisBurrell at crosswire.org (ChrisBurrell at crosswire.org)
Date: Wed, 14 Apr 2010 22:17:05 -0000
Subject: [Tynstep-svn] r122 - in trunk: . .settings step-web-app
	step-web-app/.settings step-web-app/src step-web-app/src/main
	step-web-app/src/main/java/com/tyndalehouse/step/web
	step-web-app/src/main/resources step-web-app/src/main/resources/com
	step-web-app/src/main/resources/com/tyndalehouse
	step-web-app/src/main/resources/com/tyndalehouse/step
	step-web-app/src/main/resources/com/tyndalehouse/step/web
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps
	step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline
	step-web-app/src/main/resources/xsl
	step-web-app/src/main/resources/xsl/cswing
	step-web-app/src/main/webapp step-web-app/src/main/webapp/com
	step-web-app/src/main/webapp/com/tyndalehouse
	step-web-app/src/main/webapp/com/tyndalehouse/step
	step-web-app/src/test step-web-app/src/test/java
	step-web-app/src/test/java/com
	step-web-app/src/test/java/com/tyndalehouse
	step-web-app/src/test/java/com/tyndalehouse/step
	step-web-app/src/test/java/com/tyndalehouse/step/db
	step-web-app/src/test/java/com/tyndalehouse/step/web
	step-web-app/src/test/java/com/tyndalehouse/step/web/client
	step-web-app/src/test/java/com/tyndalehouse/step/web/client/service
	step-web-app/src/test/java/com/tyndalehouse/step/web/client/toolkit
	step-web-app/src/test/java/com/tyndalehouse/step/web/server
	step-web-app/src/test/java/com/tyndalehouse/step/web/server/db
	step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper
	step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers
	step-web-app/src/test/resources step-web-app/src/test/resources/com
	step-web-app/src/test/resources/com/tyndalehouse
	step-web-app/src/test/resources/com/tyndalehouse/step
	step-web-app/src/test/resources/com/tyndalehouse/step/web
	step-web-app/src/test/resources/com/tyndalehouse/step/web/server
	step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db
	step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries
	step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests
	step-web-app/war step-web-app/war/WEB-INF
Message-ID: <E1O2AtM-0003zk-Vu@crosswire.org>

Author: ChrisBurrell
Date: 2010-04-14 15:17:04 -0700 (Wed, 14 Apr 2010)
New Revision: 122

Added:
   trunk/.project
   trunk/.settings/
   trunk/.settings/org.maven.ide.eclipse.prefs
   trunk/pom.xml
   trunk/step-checks.xml
   trunk/step-web-app/.settings/com.google.appengine.eclipse.core.prefs
   trunk/step-web-app/.settings/com.google.gdt.eclipse.core.prefs
   trunk/step-web-app/.settings/com.google.gwt.eclipse.core.prefs
   trunk/step-web-app/.settings/org.eclipse.jdt.core.prefs
   trunk/step-web-app/.settings/org.maven.ide.eclipse.prefs
   trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/step.gwt.xml
   trunk/step-web-app/src/main/resources/
   trunk/step-web-app/src/main/resources/com/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config/environment.properties
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps/get_locations_for_passage.sql
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_events_for_date_range.sql
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_timeline_setup_data.sql
   trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/lookup_timeline_origin.sql
   trunk/step-web-app/src/main/resources/log4j.properties
   trunk/step-web-app/src/main/resources/xsl/
   trunk/step-web-app/src/main/resources/xsl/cswing/
   trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste.xsl
   trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste2.xsl
   trunk/step-web-app/src/main/resources/xsl/cswing/index.txt
   trunk/step-web-app/src/main/resources/xsl/cswing/simple.xsl
   trunk/step-web-app/src/main/resources/xsl/cswing/simple2.xsl
   trunk/step-web-app/src/main/webapp/
   trunk/step-web-app/src/main/webapp/com/
   trunk/step-web-app/src/main/webapp/com/tyndalehouse/
   trunk/step-web-app/src/main/webapp/com/tyndalehouse/step/
   trunk/step-web-app/src/main/webapp/com/tyndalehouse/step/web/
   trunk/step-web-app/src/test/
   trunk/step-web-app/src/test/java/
   trunk/step-web-app/src/test/java/com/
   trunk/step-web-app/src/test/java/com/tyndalehouse/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/db/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/db/queries/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/tests/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/service/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/service/ModuleRefDataServiceTest.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/toolkit/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/toolkit/timeline/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/StepQueryRunnerImplTest.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestProcessor.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestQueryImpl.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetCurrentBibleTextHandlerTest.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetDictionaryDefinitionHandlerTest.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetTimelineUISetupHandlerTest.java
   trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/JSwordInstallTest.java
   trunk/step-web-app/src/test/resources/
   trunk/step-web-app/src/test/resources/com/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests/
   trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests/test_query_params_different_types.sql
   trunk/step-web-app/war/
   trunk/step-web-app/war/WEB-INF/
   trunk/step-web-app/war/WEB-INF/web.xml
Log:
now that repository is smaller, i can commit without having SSL error

Added: trunk/.project
===================================================================
--- trunk/.project	                        (rev 0)
+++ trunk/.project	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>step-parent</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: trunk/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/.settings/org.maven.ide.eclipse.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,9 @@
+#Sun Apr 04 22:29:56 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/pom.xml
===================================================================
--- trunk/pom.xml	                        (rev 0)
+++ trunk/pom.xml	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,199 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>com.tyndalehouse</groupId>
+	<artifactId>step-parent</artifactId>
+	<packaging>pom</packaging>
+	<version>1.0-SNAPSHOT</version>
+	<name>step-parent</name>
+	
+	<properties>
+		<project.build.sourceEncoding>iso-8859-1
+		</project.build.sourceEncoding>
+		<project.reporting.outputEncoding>iso-8859-1
+		</project.reporting.outputEncoding>
+		<java.version>1.5</java.version>
+		<gwt.version>2.0.3</gwt.version>
+		<db.directory>${user.home}/TyndaleStep/StepDB</db.directory>
+		<derby.version>10.5.3.0_1</derby.version>
+		<db.driver>org.apache.derby.jdbc.EmbeddedDriver</db.driver>
+		<db.connection.string>jdbc:derby:${db.directory}</db.connection.string>
+	</properties>
+
+	<scm>
+		<connection>scm:svn:https://crosswire.org/svn/tynstep/trunk</connection>
+		<developerConnection>scm:svn:https://crosswire.org/svn/tynstep/trunk</developerConnection>
+		<url>https://crosswire.org/svn/tynstep/trunk/</url>
+	</scm>
+
+
+	<modules>
+		<module>step-web-app</module>
+		<module>step-dataloader</module>
+		<module>step-server</module>
+		<module>step-tools</module>
+	</modules>
+
+	<dependencyManagement>
+		<dependencies>
+			<dependency>
+				<groupId>org.crosswire</groupId>
+				<artifactId>jsword</artifactId>
+				<version>1.6.1-SNAPSHOT</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.gwt</groupId>
+				<artifactId>gwt-servlet</artifactId>
+				<version>${gwt.version}</version>
+				<scope>compile</scope>
+			</dependency>
+			<dependency>
+				<groupId>com.google.gwt</groupId>
+				<artifactId>gwt-user</artifactId>
+				<version>${gwt.version}</version>
+				<scope>provided</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>com.googlecode.gwt.inject
+				</groupId>
+				<artifactId>gin</artifactId>
+				<version>1.0</version>
+			</dependency>
+			<dependency>
+				<groupId>com.google.inject</groupId>
+				<artifactId>guice</artifactId>
+				<version>2.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.inject.extensions
+				</groupId>
+				<artifactId>guice-servlet</artifactId>
+				<version>2.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>net.customware.gwt.dispatch
+				</groupId>
+				<artifactId>gwt-dispatch</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>net.customware.gwt.presenter
+				</groupId>
+				<artifactId>gwt-presenter</artifactId>
+				<version>1.0.0</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.google.code.gwt-log</groupId>
+				<artifactId>gwt-log</artifactId>
+				<version>2.6.2</version>
+			</dependency>
+
+			<dependency>
+				<groupId>com.extjs</groupId>
+				<artifactId>gxt</artifactId>
+				<version>2.1.1</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-logging</groupId>
+				<artifactId>commons-logging</artifactId>
+				<version>1.1.1</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-dbcp</groupId>
+				<artifactId>commons-dbcp</artifactId>
+				<version>1.3</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-io</groupId>
+				<artifactId>commons-io</artifactId>
+				<version>1.4</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-dbutils</groupId>
+				<artifactId>commons-dbutils</artifactId>
+				<version>1.3</version>
+			</dependency>
+
+			<dependency>
+				<groupId>commons-lang</groupId>
+				<artifactId>commons-lang</artifactId>
+				<version>2.5</version>
+			</dependency>
+
+			<dependency>
+				<groupId>org.jmock</groupId>
+				<artifactId>jmock</artifactId>
+				<version>2.5.1</version>
+				<scope>test</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.jmock</groupId>
+				<artifactId>jmock-junit4</artifactId>
+				<version>2.5.1</version>
+				<scope>test</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.derby</groupId>
+				<artifactId>derbyclient</artifactId>
+				<version>${derby.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>org.apache.derby</groupId>
+				<artifactId>derby</artifactId>
+				<version>${derby.version}</version>
+				<scope>runtime</scope>
+			</dependency>
+
+			<dependency>
+				<groupId>net.sf.opencsv</groupId>
+				<artifactId>opencsv</artifactId>
+				<version>2.1</version>
+			</dependency>
+		</dependencies>
+	</dependencyManagement>
+
+
+
+	<build>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-compiler-plugin</artifactId>
+					<configuration>
+						<encoding>iso-8859-1</encoding>
+						<source>${java.version}</source>
+						<target>${java.version}</target>
+					</configuration>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-surefire-plugin</artifactId>
+					<configuration>
+						<junitArtifactName>junit:junit-dep
+						</junitArtifactName>
+					</configuration>
+				</plugin>
+				<plugin>
+					<groupId>org.apache.maven.plugins</groupId>
+					<artifactId>maven-eclipse-plugin</artifactId>
+					<version>2.5</version>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+</project>

Added: trunk/step-checks.xml
===================================================================
--- trunk/step-checks.xml	                        (rev 0)
+++ trunk/step-checks.xml	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<!--
+    This configuration file was written by the eclipse-cs plugin configuration editor
+-->
+<!--
+    Checkstyle-Configuration: step-checks
+    Description: none
+-->
+<module name="Checker">
+  <property name="severity" value="warning"/>
+  <module name="TreeWalker">
+    <property name="tabWidth" value="4"/>
+    <module name="FileContentsHolder"/>
+    <module name="JavadocMethod">
+      <property name="logLoadErrors" value="true"/>
+      <property name="suppressLoadErrors" value="true"/>
+    </module>
+    <module name="JavadocType"/>
+    <module name="JavadocVariable"/>
+    <module name="JavadocStyle">
+      <property name="checkFirstSentence" value="false"/>
+    </module>
+    <module name="ConstantName"/>
+    <module name="LocalFinalVariableName"/>
+    <module name="LocalVariableName"/>
+    <module name="MemberName"/>
+    <module name="MethodName"/>
+    <module name="PackageName"/>
+    <module name="ParameterName"/>
+    <module name="StaticVariableName"/>
+    <module name="TypeName"/>
+    <module name="AvoidStarImport"/>
+    <module name="IllegalImport"/>
+    <module name="RedundantImport"/>
+    <module name="UnusedImports"/>
+    <module name="FileLength"/>
+    <module name="MethodLength"/>
+    <module name="ParameterNumber"/>
+    <module name="EmptyForIteratorPad"/>
+    <module name="MethodParamPad"/>
+    <module name="NoWhitespaceAfter">
+      <property name="tokens" value="BNOT,DEC,DOT,INC,LNOT,UNARY_MINUS,UNARY_PLUS"/>
+    </module>
+    <module name="NoWhitespaceBefore"/>
+    <module name="OperatorWrap"/>
+    <module name="ParenPad">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="TypecastParenPad"/>
+    <module name="TabCharacter">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="WhitespaceAfter"/>
+    <module name="WhitespaceAround"/>
+    <module name="ModifierOrder"/>
+    <module name="RedundantModifier"/>
+    <module name="AvoidNestedBlocks"/>
+    <module name="EmptyBlock"/>
+    <module name="LeftCurly"/>
+    <module name="NeedBraces"/>
+    <module name="RightCurly"/>
+    <module name="AvoidInlineConditionals">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="DoubleCheckedLocking"/>
+    <module name="EmptyStatement"/>
+    <module name="EqualsHashCode"/>
+    <module name="HiddenField">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="IllegalInstantiation"/>
+    <module name="InnerAssignment"/>
+    <module name="MagicNumber"/>
+    <module name="MissingSwitchDefault"/>
+    <module name="RedundantThrows">
+      <property name="logLoadErrors" value="true"/>
+      <property name="suppressLoadErrors" value="true"/>
+    </module>
+    <module name="SimplifyBooleanExpression"/>
+    <module name="SimplifyBooleanReturn"/>
+    <module name="DesignForExtension">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="FinalClass"/>
+    <module name="HideUtilityClassConstructor"/>
+    <module name="InterfaceIsType"/>
+    <module name="VisibilityModifier"/>
+    <module name="ArrayTypeStyle"/>
+    <module name="FinalParameters"/>
+    <module name="GenericIllegalRegexp">
+      <property name="severity" value="ignore"/>
+      <property name="format" value="\s+$"/>
+      <property name="message" value="Line has trailing spaces."/>
+    </module>
+    <module name="TodoComment">
+      <property name="severity" value="ignore"/>
+    </module>
+    <module name="UpperEll"/>
+    <module name="CyclomaticComplexity">
+      <metadata name="net.sf.eclipsecs.core.comment" value="Cyclomatic Complexity"/>
+    </module>
+  </module>
+  <module name="JavadocPackage">
+    <property name="severity" value="ignore"/>
+  </module>
+  <module name="NewlineAtEndOfFile"/>
+  <module name="Translation"/>
+  <module name="SuppressionCommentFilter">
+    <metadata name="net.sf.eclipsecs.core.comment" value="ignore checkstyle"/>
+  </module>
+</module>

Added: trunk/step-web-app/.settings/com.google.appengine.eclipse.core.prefs
===================================================================
--- trunk/step-web-app/.settings/com.google.appengine.eclipse.core.prefs	                        (rev 0)
+++ trunk/step-web-app/.settings/com.google.appengine.eclipse.core.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,3 @@
+#Fri Apr 02 23:41:38 BST 2010
+eclipse.preferences.version=1
+filesCopiedToWebInfLib=

Added: trunk/step-web-app/.settings/com.google.gdt.eclipse.core.prefs
===================================================================
--- trunk/step-web-app/.settings/com.google.gdt.eclipse.core.prefs	                        (rev 0)
+++ trunk/step-web-app/.settings/com.google.gdt.eclipse.core.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,5 @@
+#Sat Apr 03 19:38:49 BST 2010
+eclipse.preferences.version=1
+jarsExcludedFromWebInfLib=
+warSrcDir=war
+warSrcDirIsOutput=true

Added: trunk/step-web-app/.settings/com.google.gwt.eclipse.core.prefs
===================================================================
--- trunk/step-web-app/.settings/com.google.gwt.eclipse.core.prefs	                        (rev 0)
+++ trunk/step-web-app/.settings/com.google.gwt.eclipse.core.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,4 @@
+#Sat Apr 03 19:49:33 BST 2010
+eclipse.preferences.version=1
+entryPointModules=
+filesCopiedToWebInfLib=gwt-servlet.jar

Added: trunk/step-web-app/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- trunk/step-web-app/.settings/org.eclipse.jdt.core.prefs	                        (rev 0)
+++ trunk/step-web-app/.settings/org.eclipse.jdt.core.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,73 @@
+#Mon Apr 05 12:08:26 BST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+org.eclipse.jdt.core.compiler.source=1.5
+org.eclipse.jdt.core.compiler.taskCaseSensitive=enabled
+org.eclipse.jdt.core.compiler.taskPriorities=NORMAL,HIGH,NORMAL,HIGH
+org.eclipse.jdt.core.compiler.taskTags=TODO,FIXME,XXX,BUG

Added: trunk/step-web-app/.settings/org.maven.ide.eclipse.prefs
===================================================================
--- trunk/step-web-app/.settings/org.maven.ide.eclipse.prefs	                        (rev 0)
+++ trunk/step-web-app/.settings/org.maven.ide.eclipse.prefs	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,9 @@
+#Sun Apr 04 22:29:56 BST 2010
+activeProfiles=
+eclipse.preferences.version=1
+fullBuildGoals=process-test-resources
+includeModules=false
+resolveWorkspaceProjects=true
+resourceFilterGoals=process-resources resources\:testResources
+skipCompilerPlugin=true
+version=1

Added: trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/step.gwt.xml
===================================================================
--- trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/step.gwt.xml	                        (rev 0)
+++ trunk/step-web-app/src/main/java/com/tyndalehouse/step/web/step.gwt.xml	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 1.7.0//EN" "http://google-web-toolkit.googlecode.com/svn/tags/1.7.0/distro-source/core/src/gwt-module.dtd">
+<module rename-to='step'>
+ <!-- Inherit the core Web Toolkit stuff.                        -->
+ <inherits name="com.google.gwt.user.User" />
+ <inherits name="com.google.gwt.inject.Inject" />
+ <inherits name='net.customware.gwt.dispatch.Dispatch' />
+ <inherits name='net.customware.gwt.presenter.Presenter' />
+
+
+ <!-- Inherit the default GWT style sheet.  You can change       -->
+ <!-- the theme of your GWT application by uncommenting          -->
+ <!-- any one of the following lines.                            -->
+ <inherits name='com.google.gwt.user.theme.standard.Standard' />
+ <!-- <inherits name='com.google.gwt.user.theme.chrome.Chrome'/> -->
+ <!-- <inherits name='com.google.gwt.user.theme.dark.Dark'/>     -->
+
+ <!-- Specify the app entry point class.                         -->
+ <entry-point class='com.tyndalehouse.step.web.client.StepEntryPoint' />
+
+ <!-- Add gwt-log support, default level `OFF` - check for 
+      extended property 'log_level' to see if this is overridden -->
+ <inherits name="com.allen_sauer.gwt.log.gwt-log-OFF" />
+
+<!-- including GWT-EXT for timeline module -->
+<inherits name='com.google.gwt.json.JSON'/>
+<inherits name='com.extjs.gxt.ui.GXT'/>
+
+ <!-- Also compile Logger at `INFO` level -->
+ <extend-property name="log_level" values="DEBUG,INFO" />
+ <set-property name="log_level" value="INFO" />
+ 
+ <!-- Turn off the floating logger - output will be shown in the 
+   hosted mode console -->
+ <set-property name="log_DivLogger" value="DISABLED" />
+ 
+ 
+ <source path="shared" />
+ <source path="client" />
+
+<!--   <stylesheet src="js/api/ext/resources/css/ext-all.css" /> -->
+<stylesheet src="gwtext/css/gxt-all.css" />
+
+
+<!--  DEV MODE SETTINGS -->
+
+ 
+</module>

Added: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config/environment.properties
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config/environment.properties	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/config/environment.properties	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,20 @@
+#some simple set up parameters for the database pool
+db.user=step
+db.password=step
+db.pool.initialSize=10
+db.pool.maxSize=20
+db.pool.validation.query=SELECT * FROM STEP.EVENT_TYPE
+db.pool.prepared.size=10
+
+#STEP can be be run with an embedded database, for e.g.
+#connection.string=jdbc:derby:c:\\documents and settings\\<username>\\TyndaleStep\\StepDB
+#db.driver=org.apache.derby.jdbc.EmbeddedDriver
+
+#or with a network server database, for e.g.
+#connection.string=jdbc:derby://localhost:1999/c:\\documents and settings\\<username>\\TyndaleStep\\StepDB
+#db.driver=org.apache.derby.jdbc.ClientDriver
+
+
+#some definitions for the query framework
+query.repository.path=com/tyndalehouse/step/web/server/db/queries/
+query.runner.cache=false

Added: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps/get_locations_for_passage.sql
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps/get_locations_for_passage.sql	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/maps/get_locations_for_passage.sql	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,22 @@
+--------------------------------------------------------
+-- Gets all the location for a given passage (qry_start, qry_end)
+--------------------------------------------------------
+define qry_start as integer
+define qry_end as integer
+
+select 
+	location_name,
+	lat,
+	long
+from 
+                   step.scripture_reference sr 
+        inner join step.location loc on sr.TARGET_ID = loc.location_id 
+		inner join step.lat_long ll on loc.location_id = ll.location_id
+where target_type = 2 
+  and 
+		((#qry_start# between start_verse_id and end_verse_id)    -- the query start is between the event range
+		or (#qry_end# between start_verse_id and end_verse_id)  -- the query end is between the event range
+		or (#qry_start# <= start_verse_id and #qry_end# >= start_verse_id)  -- the query start is before the event start, but the end is after the event start
+		or (#qry_end# >= end_verse_id and #qry_start# <= end_verse_id))     -- the end of the range is greater than event end, but the start is before the end
+  order by (end_verse_id - start_verse_id) asc
+ fetch first row only

Added: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_events_for_date_range.sql
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_events_for_date_range.sql	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_events_for_date_range.sql	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,31 @@
+--------------------------------------------------------
+-- Query get_events_for_date_range.sql
+-- This looks up the events that should be displayed
+-- in a certain time period 
+--------------------------------------------------------
+define min_date as bigint
+define max_date as bigint
+define timeband_id as integer
+
+select 
+	event_id, 
+	from_date, 
+	to_date, 
+	from_precision, 
+	to_precision, 
+	name, 
+	timeband_id, 
+	importance_id,
+	certainty, 
+	event_type_id 
+from 
+	step.event 
+where 
+	(
+			from_date between #min_date# and #max_date#
+		or 	to_date between #min_date# and #max_date#
+		or 	from_date < #min_date# and to_date > #max_date#
+	)
+and 
+	timeband_id = #timeband_id#
+order by from_date

Added: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_timeline_setup_data.sql
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_timeline_setup_data.sql	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/get_timeline_setup_data.sql	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,12 @@
+--------------------------------------------------------
+-- Query get_timeline_setup_data
+-- This looks up the main definitions for the timebands, 
+-- to initialise the timeline component
+--------------------------------------------------------
+
+select 
+	t.timeband_id, 
+	t.timeband_description,
+	t.timeband_unit
+from 
+	step.timeband t

Added: trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/lookup_timeline_origin.sql
===================================================================
--- trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/lookup_timeline_origin.sql	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/com/tyndalehouse/step/web/server/db/queries/timeline/lookup_timeline_origin.sql	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,26 @@
+--------------------------------------------------------
+-- Query lookupTimelineOrigin.sql
+-- This lookups up the origin given a particular passage
+-- then joins on the importance sub_timeband_id field
+-- to work out what the best scale is going to be
+--------------------------------------------------------
+define qry_start as integer
+define qry_end as integer
+
+select 
+    ev.from_date as origin, 
+    ev.TIMEBAND_ID,  
+    case when ev.IMPORTANCE_ID is NULL then st.sub_timeband_unit else imp.sub_timeband_unit end as unit
+from 
+                   step.scripture_reference sr 
+        inner join step.event ev on sr.TARGET_ID = ev.EVENT_ID
+        left join sub_timeband imp on imp.sub_timeband_id = ev.SUB_TIMEBAND_ID
+        left join sub_timeband st on st.SUB_TIMEBAND_ID = ev.SUB_TIMEBAND_ID
+where target_type = 1 
+  and 
+		((#qry_start# between start_verse_id and end_verse_id)    -- the query start is between the event range
+		or (#qry_end# between start_verse_id and end_verse_id)  -- the query end is between the event range
+		or (#qry_start# <= start_verse_id and #qry_end# >= start_verse_id)  -- the query start is before the event start, but the end is after the event start
+		or (#qry_end# >= end_verse_id and #qry_start# <= end_verse_id))     -- the end of the range is greater than event end, but the start is before the end
+  order by (end_verse_id - start_verse_id) asc
+ fetch first row only

Added: trunk/step-web-app/src/main/resources/log4j.properties
===================================================================
--- trunk/step-web-app/src/main/resources/log4j.properties	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/log4j.properties	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,17 @@
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=INFO, A1, A2
+
+# A1 is set to be a ConsoleAppender.
+# A1 uses PatternLayout.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
+
+
+# messages on second appender
+log4j.appender.A2=org.apache.log4j.RollingFileAppender
+log4j.appender.A2.File=../logs/step-server.log
+log4j.appender.A2.MaxFileSize=100KB
+log4j.appender.A2.MaxBackupIndex=1
+log4j.appender.A2.layout=org.apache.log4j.PatternLayout
+log4j.appender.A2.layout.ConversionPattern=%p %t %c - %m%n

Added: trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste.xsl
===================================================================
--- trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste.xsl	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste.xsl	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,601 @@
+<?xml version="1.0"?>
+<!--
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: cutandpaste.xsl 772 2005-08-14 16:06:17Z dmsmith $
+ -->
+ <!--
+ * Transforms OSIS to HTML for viewing within JSword browsers.
+ * Note: There are custom protocols which the browser must handle.
+ * 
+ * @see gnu.lgpl.License for license details.
+ *      The copyright to this program is held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+<!--
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: cutandpaste.xsl 772 2005-08-14 16:06:17Z dmsmith $
+ -->
+ <!--
+ * Transforms OSIS to HTML for viewing within JSword browsers.
+ * Note: There are custom protocols which the browser must handle.
+ * 
+ * @see gnu.lgpl.License for license details.
+ *      The copyright to this program is held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ -->
+<xsl:stylesheet xmlns="http://www.w3.org/TR/REC-html40" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:output method="html" omit-xml-declaration="yes" indent="no"/>
+  <xsl:strip-space elements="*"/>
+
+  <xsl:param name="strongs.hebrew.url" select="'dict:'"/>
+  <xsl:param name="strongs.greek.url" select="'dict:'"/>
+
+  <!-- Whether to show Strongs or not -->
+  <xsl:param name="strongs" select="'true'"/>
+
+  <!-- The CSS stylesheet to use. The url must be absolute. -->
+  <xsl:param name="css"/>
+  
+  <!-- The order of display. Hebrew is rtl (right to left) -->
+  <xsl:param name="direction" select="'ltr'"/>
+
+  <!--
+  The font that is passed in is of the form: font or font,style,size 
+  where style is a bit mask with 1 being bold and 2 being italic.
+  This needs to be changed into a style="xxx" specification
+  -->
+  <xsl:param name="font" select="Serif"/>
+  <xsl:variable name="aFont">
+    <xsl:choose>
+      <xsl:when test="substring-before($font, ',') = ''"><xsl:value-of select="$font"/>,0,16</xsl:when>
+      <xsl:otherwise><xsl:value-of select="$font"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="fontfamily" select='concat("font-family: &apos;", substring-before($aFont, ","), "&apos;;")' />
+  <xsl:variable name="fontsize" select="concat(' font-size: ', substring-after(substring-after($aFont, ','), ','), 'pt;')" />
+  <xsl:variable name="styling" select="substring-before(substring-after($aFont, ','), ',')" />
+  <xsl:variable name="fontweight">
+    <xsl:if test="$styling = '1' or $styling = '3'"><xsl:text> font-weight: bold;</xsl:text></xsl:if>
+  </xsl:variable>
+  <xsl:variable name="fontstyle">
+    <xsl:if test="$styling = '2' or $styling = '3'"> font-style: italic;</xsl:if>
+  </xsl:variable>
+  <xsl:variable name="fontspec" select="concat($fontfamily, $fontsize, $fontweight, $fontstyle)"/>
+
+  <!--
+  For now, we assume that all the works inside a corpus are of the
+  same type.
+  -->
+  <xsl:variable name="osis-id-type" select="substring-before((//osisText)[1]/@osisIDWork, '.')"/>
+
+  <xsl:variable name="page-div-type">
+    <xsl:choose>
+      <!--
+      KJV is a special case. It should be Bible.KJV, but some OSIS
+      transcriptions just use KJV instead.
+      -->
+      <xsl:when test="$osis-id-type = 'Bible' or $osis-id-type = 'KJV'">
+        <xsl:text>chapter</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Dictionary'">
+        <xsl:text>x-lexeme</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Lexicon'">
+        <xsl:text>x-lemma</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Morph'">
+        <xsl:text>x-tag</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text>FIXME</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!--=======================================================================-->
+  <xsl:template match="/osis">
+    <html dir="{$direction}">
+      <body>
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="osisCorpus">
+    <xsl:for-each select="osisText">
+      <!-- If this text has a header, apply templates to the header. -->
+      <xsl:if test="preceding-sibling::*[1][self::header]">
+        <div class="corpus-text-header">
+          <xsl:apply-templates select="preceding-sibling::*[1][self::header]"/>
+        </div>
+      </xsl:if>
+      <xsl:apply-templates select="."/>
+    </xsl:for-each>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="osisText">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="div">
+    <xsl:if test="@divTitle">
+      <h1><xsl:value-of select="@divTitle"/></h1>
+    </xsl:if>
+    <xsl:if test="@type = 'testament'">
+      <h2>
+        <xsl:choose>
+          <xsl:when test="preceding::div[@type = 'testament']">
+           <xsl:text>New Testament</xsl:text>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>Old Testament</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </h2>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:if test="@divTitle">
+      <p>&#0160;</p>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="verse">
+    <p>
+      <xsl:value-of select="substring-after(substring-after(@osisID, '.'), '.')"/>
+      <xsl:text> </xsl:text>
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="a">
+    <a href="{@href}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="note">
+    <!-- ignore notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="p">
+    <p><xsl:apply-templates/></p>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="p" mode="print-notes">
+    <!-- don't put para's in notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="seg">
+    <xsl:choose>
+      <xsl:when test="@type='font-style: italic;'">
+        <i><xsl:apply-templates/></i>
+      </xsl:when>
+      <xsl:when test="@type='font-weight: bold;'">
+        <b><xsl:apply-templates/></b>
+      </xsl:when>
+      <xsl:when test="@type='text-decoration: underline;'">
+        <u><xsl:apply-templates/></u>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="substring-before(substring-after(@type, 'color: '), ';')">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="substring-before(substring-after(@type, 'font-size: '), ';')">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:otherwise>
+        <p><xsl:apply-templates/></p>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="abbr">
+    <abbr class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </abbr>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="speaker">
+    <xsl:choose>
+      <xsl:when test="@who='Jesus'">
+        <font color="red">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:otherwise>
+        <font color="blue">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title">
+    <p align="right">
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@type='section']">
+  <!-- Done by a line in [verse]
+    <h3>
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="reference">
+    <a href="bible://{@osisRef}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+
+  <xsl:template match="caption">
+    <div class="caption">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="catchWord">
+    <span class="catchWord">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <!--
+      <cell> is handled shortly after <table> below and thus does not appear
+      here.
+  -->
+  
+  <xsl:template match="closer">
+    <div class="closer">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="date">
+    <span class="date">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="divineName">
+    <span class="divineName">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="figure">
+    <div class="figure">
+      <img src="@src"/>  <!-- FIXME: Not necessarily an image... -->
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="foreign">
+    <em class="foreign">
+      <xsl:apply-templates/>
+    </em>
+  </xsl:template>
+  
+  <!-- This is a subheading. -->
+  <xsl:template match="head//head">
+    <h5 class="head">
+      <xsl:apply-templates/>
+    </h5>
+  </xsl:template>
+  
+  <!-- This is a top-level heading. -->
+  <xsl:template match="head">
+    <h4 class="head">
+      <xsl:apply-templates/>
+    </h4>
+  </xsl:template>
+  
+  <xsl:template match="hi">
+    <span class="hi">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+
+  <xsl:template match="index">
+    <a name="index{@id}" class="index"/>
+  </xsl:template>
+  
+  <xsl:template match="inscription">
+    <span class="inscription">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="item">
+    <li class="item">
+      <xsl:apply-templates/>
+    </li>
+  </xsl:template>
+  
+  <!--
+      <item> and <label> are covered by <list> below and so do not appear here.
+  -->
+  
+  <xsl:template match="l">
+    <div class="l">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="lg">
+    <div class="lg">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="list">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label">
+                  <xsl:apply-templates/>
+                </dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item">
+                  <xsl:apply-templates/>
+                </dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper">
+                  <xsl:apply-templates select="."/>
+                </dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item">
+                  <xsl:apply-templates/>
+                </li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper">
+                  <xsl:apply-templates select="."/>
+                </li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="mentioned">
+    <span class="mentioned">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <!--
+      Note: I have not covered <milestone>, <milestoneStart>, or
+            <milestoneEnd> here, since I have no idea what they are supposed
+            to do, based on the spec.
+  -->
+  
+  <xsl:template match="name">
+    <span class="name">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="q">
+    <!--
+        FIXME: Should I use <span> here?  The spec says that this can be used
+               as an embedded quote or a block quote, but there seems to be no
+               way to figure out which it is based on context.  Currently I've
+               got it as a <blockquote> because it has block-level elements in
+               it.
+        
+        FIXME: Should I include the speaker in the text, e.g.:
+               
+                   {@who}: {text()}
+               
+               ?  I'm not sure.  Currently I've just got it as a "title"
+               attribute on the <span>.
+    -->
+    <blockquote class="q">
+      <xsl:if test="@who">
+        <xsl:attribute name="title"><xsl:value-of select="@who"/></xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </blockquote>
+  </xsl:template>
+  
+  <xsl:template match="rdg">
+    <div class="rdg">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+
+  <!--
+      <row> is handled near <table> below and so does not appear here.
+  -->
+  
+  <xsl:template match="salute">
+    <div class="salute">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="signed">
+    <span class="signed">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+
+  <xsl:template match="speech">
+    <div class="speech">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="table">
+    <table class="table">
+      <xsl:copy-of select="@rows|@cols"/>
+      <xsl:if test="head">
+        <thead class="head">
+          <xsl:apply-templates select="head"/>
+        </thead>
+      </xsl:if>
+      <tbody>
+        <xsl:apply-templates select="row"/>
+      </tbody>
+    </table>
+  </xsl:template>
+  
+  <xsl:template match="row">
+    <tr class="row">
+      <xsl:apply-templates/>
+    </tr>
+  </xsl:template>
+  
+  <xsl:template match="cell">
+    <xsl:variable name="element-name">
+      <xsl:choose>
+        <xsl:when test="@role = 'label'">
+          <xsl:text>th</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>td</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:element name="{$element-name}">
+      <xsl:attribute name="class">cell</xsl:attribute>
+      <xsl:if test="@rows">
+        <xsl:attribute name="rowspan">
+          <xsl:value-of select="@rows"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@cols">
+        <xsl:attribute name="colspan">
+          <xsl:value-of select="@cols"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </xsl:element>
+  </xsl:template>
+
+  <xsl:template match="transChange">
+    <span class="transChange">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+      Named templates
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  
+  <xsl:template name="trim-zeros-from-number">
+    <xsl:param name="number" select="'0'"/>
+    <xsl:value-of select="string(number($number))"/>
+  </xsl:template>
+  
+  <xsl:template name="print-prev-next-links">
+    <xsl:param name="div" select="."/>
+    
+    <xsl:variable name="previous-section" select="$div/preceding::div[@type = $page-div-type][1]"/>
+    <xsl:variable name="next-section" select="$div/following::div[@type = $page-div-type][1]"/>
+    <xsl:if test="$previous-section or $next-section">
+      <table width="100%" class="navigation">
+        <tr>
+          <xsl:if test="$previous-section">
+            <td align="left">
+              <a href="{$previous-section/@osisID}.html" class="previous-link">[&lt; Previous]</a>
+            </td>
+          </xsl:if>
+          <xsl:if test="$next-section">
+            <td align="right">
+              <a href="{$next-section/@osisID}.html" class="next-link">[Next &gt;]</a>
+            </td>
+          </xsl:if>
+        </tr>
+      </table>
+    </xsl:if>
+  </xsl:template>
+</xsl:stylesheet>

Added: trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste2.xsl
===================================================================
--- trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste2.xsl	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/xsl/cswing/cutandpaste2.xsl	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,578 @@
+<?xml version="1.0"?>
+<!--
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: cutandpaste2.xsl 772 2005-08-14 16:06:17Z dmsmith $
+ -->
+ <!--
+ * Transforms OSIS to HTML for viewing within JSword browsers.
+ * Note: There are custom protocols which the browser must handle.
+ * 
+ * @see gnu.lgpl.License for license details.
+ *      The copyright to this program is held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ -->
+<xsl:stylesheet xmlns="http://www.w3.org/TR/REC-html40" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+  <xsl:output method="html" omit-xml-declaration="yes" indent="no"/>
+  <xsl:strip-space elements="*"/>
+
+  <xsl:param name="strongs.hebrew.url" select="'dict:'"/>
+  <xsl:param name="strongs.greek.url" select="'dict:'"/>
+
+  <!-- Whether to show Strongs or not -->
+  <xsl:param name="strongs" select="'true'"/>
+
+  <!-- The CSS stylesheet to use. The url must be absolute. -->
+  <xsl:param name="css"/>
+  
+  <!-- The order of display. Hebrew is rtl (right to left) -->
+  <xsl:param name="direction" select="'ltr'"/>
+
+  <!--
+  The font that is passed in is of the form: font or font,style,size 
+  where style is a bit mask with 1 being bold and 2 being italic.
+  This needs to be changed into a style="xxx" specification
+  -->
+  <xsl:param name="font" select="Serif"/>
+  <xsl:variable name="aFont">
+    <xsl:choose>
+      <xsl:when test="substring-before($font, ',') = ''"><xsl:value-of select="$font"/>,0,16</xsl:when>
+      <xsl:otherwise><xsl:value-of select="$font"/></xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+  <xsl:variable name="fontfamily" select='concat("font-family: &apos;", substring-before($aFont, ","), "&apos;;")' />
+  <xsl:variable name="fontsize" select="concat(' font-size: ', substring-after(substring-after($aFont, ','), ','), 'pt;')" />
+  <xsl:variable name="styling" select="substring-before(substring-after($aFont, ','), ',')" />
+  <xsl:variable name="fontweight">
+    <xsl:if test="$styling = '1' or $styling = '3'"><xsl:text> font-weight: bold;</xsl:text></xsl:if>
+  </xsl:variable>
+  <xsl:variable name="fontstyle">
+    <xsl:if test="$styling = '2' or $styling = '3'"> font-style: italic;</xsl:if>
+  </xsl:variable>
+  <xsl:variable name="fontspec" select="concat($fontfamily, $fontsize, $fontweight, $fontstyle)"/>
+
+  <!--
+  For now, we assume that all the works inside a corpus are of the
+  same type.
+  -->
+  <xsl:variable name="osis-id-type" select="substring-before((//osisText)[1]/@osisIDWork, '.')"/>
+
+  <xsl:variable name="page-div-type">
+    <xsl:choose>
+      <!--
+      KJV is a special case. It should be Bible.KJV, but some OSIS
+      transcriptions just use KJV instead.
+      -->
+      <xsl:when test="$osis-id-type = 'Bible' or $osis-id-type = 'KJV'">
+        <xsl:text>chapter</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Dictionary'">
+        <xsl:text>x-lexeme</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Lexicon'">
+        <xsl:text>x-lemma</xsl:text>
+      </xsl:when>
+      <xsl:when test="$osis-id-type = 'Morph'">
+        <xsl:text>x-tag</xsl:text>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:text>FIXME</xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:variable>
+
+  <!--=======================================================================-->
+  <xsl:template match="/osis">
+    <html dir="{$direction}">
+      <body>
+        <xsl:apply-templates/>
+      </body>
+    </html>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="osisCorpus">
+    <xsl:for-each select="osisText">
+      <!-- If this text has a header, apply templates to the header. -->
+      <xsl:if test="preceding-sibling::*[1][self::header]">
+        <div class="corpus-text-header">
+          <xsl:apply-templates select="preceding-sibling::*[1][self::header]"/>
+        </div>
+      </xsl:if>
+      <xsl:apply-templates select="."/>
+    </xsl:for-each>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="osisText">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="div">
+    <xsl:if test="@divTitle">
+      <h1><xsl:value-of select="@divTitle"/></h1>
+    </xsl:if>
+    <xsl:if test="@type = 'testament'">
+      <h2>
+        <xsl:choose>
+          <xsl:when test="preceding::div[@type = 'testament']">
+           <xsl:text>New Testament</xsl:text>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:text>Old Testament</xsl:text>
+          </xsl:otherwise>
+        </xsl:choose>
+      </h2>
+    </xsl:if>
+    <xsl:apply-templates/>
+    <xsl:if test="@divTitle">
+      <p>&#0160;</p>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="verse">
+    <!-- ignore verse numbers -->
+
+    <xsl:variable name="title" select=".//title"/>
+    <xsl:if test="string-length($title) > 0">
+      <p><xsl:value-of select="$title"/></p>
+    </xsl:if>
+
+    <xsl:apply-templates/>
+    <xsl:text> </xsl:text>
+
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="a">
+    <a href="{@href}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="note">
+    <!-- ignore notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="p">
+    <p><xsl:apply-templates/></p>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="p" mode="print-notes">
+    <!-- don't put para's in notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="seg">
+    <xsl:choose>
+      <xsl:when test="@type='font-style: italic;'">
+        <i><xsl:apply-templates/></i>
+      </xsl:when>
+      <xsl:when test="@type='font-weight: bold;'">
+        <b><xsl:apply-templates/></b>
+      </xsl:when>
+      <xsl:when test="@type='text-decoration: underline;'">
+        <u><xsl:apply-templates/></u>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="substring-before(substring-after(@type, 'color: '), ';')">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="substring-before(substring-after(@type, 'font-size: '), ';')">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:otherwise>
+        <p><xsl:apply-templates/></p>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="abbr">
+    <abbr class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </abbr>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="speaker">
+    <xsl:choose>
+      <xsl:when test="@who='Jesus'">
+        <font color="red">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:when>
+      <xsl:otherwise>
+        <font color="blue">
+          <xsl:apply-templates/>
+        </font>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title">
+    <p align="right">
+      <xsl:apply-templates/>
+    </p>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@type='section']">
+  <!-- Done by a line in [verse]
+    <h3>
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="reference">
+    <a href="bible://{@osisRef}">
+      <xsl:apply-templates/>
+    </a>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+
+  <xsl:template match="caption">
+    <div class="caption">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="catchWord">
+    <span class="catchWord">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <!--
+      <cell> is handled shortly after <table> below and thus does not appear
+      here.
+  -->
+  
+  <xsl:template match="closer">
+    <div class="closer">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="date">
+    <span class="date">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="divineName">
+    <span class="divineName">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="figure">
+    <div class="figure">
+      <img src="@src"/>  <!-- FIXME: Not necessarily an image... -->
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="foreign">
+    <em class="foreign">
+      <xsl:apply-templates/>
+    </em>
+  </xsl:template>
+  
+  <!-- This is a subheading. -->
+  <xsl:template match="head//head">
+    <h5 class="head">
+      <xsl:apply-templates/>
+    </h5>
+  </xsl:template>
+  
+  <!-- This is a top-level heading. -->
+  <xsl:template match="head">
+    <h4 class="head">
+      <xsl:apply-templates/>
+    </h4>
+  </xsl:template>
+  
+  <xsl:template match="hi">
+    <span class="hi">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+
+  <xsl:template match="index">
+    <a name="index{@id}" class="index"/>
+  </xsl:template>
+  
+  <xsl:template match="inscription">
+    <span class="inscription">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="item">
+    <li class="item">
+      <xsl:apply-templates/>
+    </li>
+  </xsl:template>
+  
+  <!--
+      <item> and <label> are covered by <list> below and so do not appear here.
+  -->
+  
+  <xsl:template match="l">
+    <div class="l">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="lg">
+    <div class="lg">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="list">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label">
+                  <xsl:apply-templates/>
+                </dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item">
+                  <xsl:apply-templates/>
+                </dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper">
+                  <xsl:apply-templates select="."/>
+                </dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item">
+                  <xsl:apply-templates/>
+                </li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper">
+                  <xsl:apply-templates select="."/>
+                </li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="mentioned">
+    <span class="mentioned">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <!--
+      Note: I have not covered <milestone>, <milestoneStart>, or
+            <milestoneEnd> here, since I have no idea what they are supposed
+            to do, based on the spec.
+  -->
+  
+  <xsl:template match="name">
+    <span class="name">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  <xsl:template match="q">
+    <!--
+        FIXME: Should I use <span> here?  The spec says that this can be used
+               as an embedded quote or a block quote, but there seems to be no
+               way to figure out which it is based on context.  Currently I've
+               got it as a <blockquote> because it has block-level elements in
+               it.
+        
+        FIXME: Should I include the speaker in the text, e.g.:
+               
+                   {@who}: {text()}
+               
+               ?  I'm not sure.  Currently I've just got it as a "title"
+               attribute on the <span>.
+    -->
+    <blockquote class="q">
+      <xsl:if test="@who">
+        <xsl:attribute name="title"><xsl:value-of select="@who"/></xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </blockquote>
+  </xsl:template>
+  
+  <xsl:template match="rdg">
+    <div class="rdg">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+
+  <!--
+      <row> is handled near <table> below and so does not appear here.
+  -->
+  
+  <xsl:template match="salute">
+    <div class="salute">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="signed">
+    <span class="signed">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+
+  <xsl:template match="speech">
+    <div class="speech">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="table">
+    <table class="table">
+      <xsl:copy-of select="@rows|@cols"/>
+      <xsl:if test="head">
+        <thead class="head">
+          <xsl:apply-templates select="head"/>
+        </thead>
+      </xsl:if>
+      <tbody>
+        <xsl:apply-templates select="row"/>
+      </tbody>
+    </table>
+  </xsl:template>
+  
+  <xsl:template match="row">
+    <tr class="row">
+      <xsl:apply-templates/>
+    </tr>
+  </xsl:template>
+  
+  <xsl:template match="cell">
+    <xsl:variable name="element-name">
+      <xsl:choose>
+        <xsl:when test="@role = 'label'">
+          <xsl:text>th</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>td</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:element name="{$element-name}">
+      <xsl:attribute name="class">cell</xsl:attribute>
+      <xsl:if test="@rows">
+        <xsl:attribute name="rowspan">
+          <xsl:value-of select="@rows"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@cols">
+        <xsl:attribute name="colspan">
+          <xsl:value-of select="@cols"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </xsl:element>
+  </xsl:template>
+
+  <xsl:template match="transChange">
+    <span class="transChange">
+      <xsl:apply-templates/>
+    </span>
+  </xsl:template>
+  
+  
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+      Named templates
+   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+  
+  <xsl:template name="trim-zeros-from-number">
+    <xsl:param name="number" select="'0'"/>
+    <xsl:value-of select="string(number($number))"/>
+  </xsl:template>
+  
+  <xsl:template name="print-prev-next-links">
+    <xsl:param name="div" select="."/>
+    
+    <xsl:variable name="previous-section" select="$div/preceding::div[@type = $page-div-type][1]"/>
+    <xsl:variable name="next-section" select="$div/following::div[@type = $page-div-type][1]"/>
+    <xsl:if test="$previous-section or $next-section">
+      <table width="100%" class="navigation">
+        <tr>
+          <xsl:if test="$previous-section">
+            <td align="left">
+              <a href="{$previous-section/@osisID}.html" class="previous-link">[&lt; Previous]</a>
+            </td>
+          </xsl:if>
+          <xsl:if test="$next-section">
+            <td align="right">
+              <a href="{$next-section/@osisID}.html" class="next-link">[Next &gt;]</a>
+            </td>
+          </xsl:if>
+        </tr>
+      </table>
+    </xsl:if>
+  </xsl:template>
+</xsl:stylesheet>

Added: trunk/step-web-app/src/main/resources/xsl/cswing/index.txt
===================================================================
--- trunk/step-web-app/src/main/resources/xsl/cswing/index.txt	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/xsl/cswing/index.txt	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1 @@
+simple.xsl
\ No newline at end of file

Added: trunk/step-web-app/src/main/resources/xsl/cswing/simple.xsl
===================================================================
--- trunk/step-web-app/src/main/resources/xsl/cswing/simple.xsl	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/xsl/cswing/simple.xsl	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,1600 @@
+<?xml version="1.0"?>
+<!--
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: simple.xsl 1943 2009-03-25 11:43:28Z dmsmith $
+ -->
+ <!--
+ * Transforms OSIS to HTML for viewing within JSword browsers.
+ * Note: There are custom protocols which the browser must handle.
+ * 
+ * @see gnu.lgpl.License for license details.
+ *      The copyright to this program is held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ -->
+ <xsl:stylesheet
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  version="1.0"
+  xmlns:jsword="http://xml.apache.org/xalan/java"
+  extension-element-prefixes="jsword">
+
+  <!--  Version 3.0 is necessary to get br to work correctly. -->
+  <xsl:output method="html" version="3.0" omit-xml-declaration="yes" indent="no"/>
+
+  <!-- Be very careful about introducing whitespace into the document.
+       strip-space merely remove space between one tag and another tag.
+       This may cause significant whitespace to be removed.
+       
+       It is easy to have apply-templates on a line to itself which if
+       it encounters text before anything else will introduce whitespace.
+       With the browser we are using, span will introduce whitespace
+       but font does not. Therefore we use font as a span.
+    -->
+  <!-- gdef and hdef refer to hebrew and greek definitions keyed by strongs -->
+  <xsl:param name="greek.def.protocol" select="'gdef:'"/>
+  <xsl:param name="hebrew.def.protocol" select="'hdef:'"/>
+  <xsl:param name="lex.def.protocol" select="'lex:'"/>
+  <!-- currently these are not used, but they are for morphologic forms -->
+  <xsl:param name="greek.morph.protocol" select="'gmorph:'"/>
+  <xsl:param name="hebrew.morph.protocol" select="'hmorph:'"/>
+
+  <!-- The absolute base for relative references. -->
+  <xsl:param name="baseURL" select="''"/>
+
+  <!-- Whether to show Strongs or not -->
+  <xsl:param name="Strongs" select="'false'"/>
+
+  <!-- Whether to show morphologic forms or not -->
+  <xsl:param name="Morph" select="'false'"/>
+
+  <!-- Whether to start each verse on an new line or not -->
+  <xsl:param name="VLine" select="'false'"/>
+
+  <!-- Whether to show non-canonical "headings" or not -->
+  <xsl:param name="Headings" select="'true'"/>
+
+  <!-- Whether to show notes or not -->
+  <xsl:param name="Notes" select="'true'"/>
+
+  <!-- Whether to have linking cross references or not -->
+  <xsl:param name="XRef" select="'true'"/>
+
+  <!-- Whether to output no Verse numbers -->
+  <xsl:param name="NoVNum" select="'false'"/>
+
+  <!-- Whether to output Verse numbers or not -->
+  <xsl:param name="VNum" select="'true'"/>
+
+  <!-- Whether to output Chapter and Verse numbers or not -->
+  <xsl:param name="CVNum" select="'false'"/>
+
+  <!-- Whether to output Book, Chapter and Verse numbers or not -->
+  <xsl:param name="BCVNum" select="'false'"/>
+
+  <!-- Whether to output superscript verse numbers or normal size ones -->
+  <xsl:param name="TinyVNum" select="'true'"/>
+
+  <!-- The CSS stylesheet to use. The url must be absolute. -->
+  <xsl:param name="css"/>
+  
+  <!-- The order of display. Hebrew is rtl (right to left) -->
+  <xsl:param name="direction" select="'ltr'"/>
+
+  <!-- The font that is passed in is in one of two forms:
+    FamilyName-STYLE-size, where STYLE is either PLAIN, BOLD, ITALIC or BOLDITALIC
+    or
+    FamilyName,style,size, where STYLE is 0 for PLAIN, 1 for BOLD, 2 for ITALIC or 3 for BOLDITALIC.
+    This needs to be changed into a CSS style specification
+  -->
+  <xsl:param name="font" select="Serif"/>
+
+  <xsl:variable name="fontspec">
+      <xsl:call-template name="generateFontStyle">
+        <xsl:with-param name="fontspec" select="$font"/>
+        <xsl:with-param name="style">css</xsl:with-param>
+      </xsl:call-template>
+  </xsl:variable>
+
+  <!-- Create a global key factory from which OSIS ids will be generated -->
+  <xsl:variable name="keyf" select="jsword:org.crosswire.jsword.passage.PassageKeyFactory.instance()"/>
+  <!-- Create a global number shaper that can transform 0-9 into other number systems. -->
+  <xsl:variable name="shaper" select="jsword:org.crosswire.common.icu.NumberShaper.new()"/>
+
+  <!--=======================================================================-->
+  <xsl:template match="/">
+    <html dir="{$direction}">
+      <head>
+        <base href="{$baseURL}"/>
+        <style type="text/css">
+          BODY { background:white; <xsl:value-of select="$fontspec" /> }
+          A { text-decoration: none; }
+          A.strongs { color: black; text-decoration: none; }
+          SUB.strongs { font-size: 75%; color: red; }
+          SUB.morph { font-size: 75%; color: blue; }
+          SUB.lemma { font-size: 75%; color: red; }
+          SUP.verse { font-size: 75%; color: gray; }
+          SUP.note { font-size: 75%; color: green; }
+          FONT.lex { color: red; }
+          FONT.jesus { color: red; }
+          FONT.speech { color: blue; }
+          FONT.strike { text-decoration: line-through; }
+          FONT.small-caps { font-variant: small-caps; }
+          FONT.inscription { font-weight: bold; font-variant: small-caps; }
+          FONT.divineName { font-variant: small-caps; }
+          FONT.normal { font-variant: normal; }
+          FONT.caps { text-transform: uppercase; }
+          H1.level { text-align: center; font-size: 115%; color: #000000; }
+          H2.level { text-align: center; font-size: 110%; color: #000000; }
+          H3.level { text-align: center; font-size: 100%; }
+          H4.level { text-align: center; font-size: 90%; }
+          H5.level { text-align: center; font-size: 85%; }
+          H6.level { text-align: center; font-size: 80%; }
+          H3.heading { font-size: 110%; color: #666699; font-weight: bold; }
+          H2.heading { font-size: 115%; color: #669966; font-weight: bold; }
+          div.margin { font-size:90%; }
+          TD.notes { width:20%; background:#f4f4e8; }
+          TD.text { width:80%; }
+          <!-- the following are for dictionary entries -->
+          FONT.orth { font-weight: bold; }
+          FONT.pron { font-style: italic; }
+          FONT.def  { font-style: italic; }
+          FONT.usg  { font-style: plain; }
+        </style>
+        <!-- Always include the user's stylesheet even if "" -->
+        <link rel="stylesheet" type="text/css" href="{$css}" title="styling" />
+      </head>
+      <body>
+        <!-- If there are notes, output a table with notes in the 2nd column. -->
+        <!-- There is a rendering bug which prevents the notes from adhering to the right edge. -->
+        <xsl:choose>
+          <xsl:when test="$Notes = 'true' and //note[not(@type = 'x-strongsMarkup')]">
+            <xsl:choose>
+              <xsl:when test="$direction != 'rtl'">
+                <table cols="2" cellpadding="5" cellspacing="5">
+                  <tr>
+                    <!-- The two rows are swapped until the bug is fixed. -->
+                    <td valign="top" class="notes">
+                      <p>&#160;</p>
+                      <xsl:apply-templates select="//verse" mode="print-notes"/>
+                    </td>
+                    <td valign="top" class="text">
+                      <xsl:apply-templates/>
+                    </td>
+                  </tr>
+                </table>
+              </xsl:when>
+              <xsl:otherwise>
+                <!-- reverse the table for Right to Left languages -->
+                <table cols="2" cellpadding="5" cellspacing="5">
+                  <!-- In a right to left, the alignment should be reversed too -->
+                  <tr align="right">
+                    <td valign="top" class="notes">
+                      <p>&#160;</p>
+                      <xsl:apply-templates select="//note" mode="print-notes"/>
+                    </td>
+                    <td valign="top" class="text">
+                      <xsl:apply-templates/>
+                    </td>
+                  </tr>
+                </table>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:apply-templates/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </body>
+    </html>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == A proper OSIS document has osis as it's root.
+    == We dig deeper for it's content.
+    -->
+  <xsl:template match="osis">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == An OSIS document may contain more that one work.
+    == Each work is held in an osisCorpus element.
+    == If there is only one work, then this element will (should) be absent.
+    == Process each document in turn.
+    == It might be reasonable to dig into the header element of each work
+    == and get its title.
+    == Otherwise, we ignore the header and work elements and just process
+    == the osisText elements.
+    -->
+  <xsl:template match="osisCorpus">
+    <xsl:apply-templates select="osisText"/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == Each work has an osisText element.
+    == We ignore the header and work elements and process its div elements.
+    == While divs can be milestoned, the osisText element requires container
+    == divs.
+    -->
+  <xsl:template match="osisText">
+    <xsl:apply-templates select="div"/>
+  </xsl:template>
+  
+  <!-- Ignore headers and its elements -->
+  <xsl:template match="header"/>
+  <xsl:template match="revisionDesc"/>
+  <xsl:template match="work"/>
+   <!-- <xsl:template match="title"/> who's parent is work -->
+  <xsl:template match="contributor"/>
+  <xsl:template match="creator"/>
+  <xsl:template match="subject"/>
+  <!-- <xsl:template match="date"/> who's parent is work -->
+  <xsl:template match="description"/>
+  <xsl:template match="publisher"/>
+  <xsl:template match="type"/>
+  <xsl:template match="format"/>
+  <xsl:template match="identifier"/>
+  <xsl:template match="source"/>
+  <xsl:template match="language"/>
+  <xsl:template match="relation"/>
+  <xsl:template match="coverage"/>
+  <xsl:template match="rights"/>
+  <xsl:template match="scope"/>
+  <xsl:template match="workPrefix"/>
+  <xsl:template match="castList"/>
+  <xsl:template match="castGroup"/>
+  <xsl:template match="castItem"/>
+  <xsl:template match="actor"/>
+  <xsl:template match="role"/>
+  <xsl:template match="roleDesc"/>
+  <xsl:template match="teiHeader"/>
+  <xsl:template match="refSystem"/>
+
+
+  <!-- Ignore titlePage -->
+  <xsl:template match="titlePage"/>
+
+  <!--=======================================================================-->
+  <!-- 
+    == Div provides the major containers for a work.
+    == Divs are milestoneable.
+    -->
+  <xsl:template match="div[@type='x-center']">
+    <div align="center">
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+
+  <xsl:template match="div">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="div" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!-- Handle verses as containers and as a start verse.                     -->
+  <xsl:template match="verse[not(@eID)]">
+    <!-- output each preverse element in turn -->
+    <xsl:for-each select=".//*[@subType = 'x-preverse' or @subtype = 'x-preverse']">
+      <xsl:choose>
+        <xsl:when test="local-name() = 'title'">
+          <!-- Always show canonical titles or if headings is turned on -->
+          <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+            <h3 class="heading"><xsl:apply-templates /></h3>
+          </xsl:if>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+    <!-- Handle the KJV paragraph marker. -->
+    <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
+    <!-- If the verse doesn't start on its own line and -->
+    <!-- the verse is not the first verse of a set of siblings, -->
+    <!-- output an extra space. -->
+    <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
+      <xsl:text>&#160;</xsl:text>
+    </xsl:if>
+    <!-- Always output the verse -->
+    <xsl:choose>
+      <xsl:when test="$VLine = 'true'">
+        <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates/></div>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="versenum"/><xsl:apply-templates/>
+        <!-- Follow the verse with an extra space -->
+        <!-- when they don't start on lines to themselves -->
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="verse[not(@eID)]" mode="jesus">
+    <!-- If the verse doesn't start on its own line and -->
+    <!-- the verse is not the first verse of a set of siblings, -->
+    <!-- output an extra space. -->
+    <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
+      <xsl:text>&#160;</xsl:text>
+    </xsl:if>
+    <xsl:variable name="title" select=".//title"/>
+    <xsl:if test="string-length($title) > 0">
+      <h3 class="heading"><xsl:value-of select="$title"/></h3>
+    </xsl:if>
+    <!-- Handle the KJV paragraph marker. -->
+    <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
+    <!-- Always output the verse -->
+    <xsl:choose>
+      <xsl:when test="$VLine = 'true'">
+        <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates mode="jesus"/></div>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="versenum"/><xsl:apply-templates mode="jesus"/>
+        <!-- Follow the verse with an extra space -->
+        <!-- when they don't start on lines to themselves -->
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="verse" mode="print-notes">
+    <xsl:if test=".//note[not(@type) or not(@type = 'x-strongsMarkup')]">
+      <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
+      <a href="#{substring-before(concat(@osisID, ' '), ' ')}">
+        <xsl:value-of select="jsword:getName($passage)"/>
+      </a>
+      <xsl:apply-templates select=".//note" mode="print-notes" />
+      <div><xsl:text>&#160;</xsl:text></div>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template name="versenum">
+    <!-- Are verse numbers wanted? -->
+    <xsl:if test="$NoVNum = 'false'">
+      <!-- An osisID can be a space separated list of them -->
+      <xsl:variable name="firstOsisID" select="substring-before(concat(@osisID, ' '), ' ')"/>
+      <xsl:variable name="book" select="substring-before($firstOsisID, '.')"/>
+      <xsl:variable name="chapter" select="jsword:shape($shaper, substring-before(substring-after($firstOsisID, '.'), '.'))"/>
+      <!-- If n is present use it for the number -->
+      <xsl:variable name="verse">
+        <xsl:choose>
+          <xsl:when test="@n">
+            <xsl:value-of select="jsword:shape($shaper, string(@n))"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="jsword:shape($shaper, substring-after(substring-after($firstOsisID, '.'), '.'))"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="versenum">
+        <xsl:choose>
+          <xsl:when test="$BCVNum = 'true'">
+            <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
+            <xsl:value-of select="jsword:getName($passage)"/>
+          </xsl:when>
+          <xsl:when test="$CVNum = 'true'">
+            <xsl:value-of select="concat($chapter, ' : ', $verse)"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="$verse"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <!--
+        == Surround versenum with something that forces a proper bidi context in Java.
+        == Sup does not.
+        -->
+      <xsl:choose>
+        <xsl:when test="$TinyVNum = 'true' and $Notes = 'true'">
+          <a name="{@osisID}"><sup class="verse"><font><xsl:value-of select="$versenum"/></font></sup></a>
+        </xsl:when>
+        <xsl:when test="$TinyVNum = 'true' and $Notes = 'false'">
+          <sup class="verse"><font><xsl:value-of select="$versenum"/></font></sup>
+        </xsl:when>
+        <xsl:when test="$TinyVNum = 'false' and $Notes = 'true'">
+          <a name="{@osisID}">(<font><xsl:value-of select="$versenum"/></font>)</a>
+          <xsl:text> </xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          (<font><xsl:value-of select="$versenum"/></font>)
+          <xsl:text> </xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+    <xsl:if test="$VNum = 'false' and $Notes = 'true'">
+      <a name="{@osisID}"></a>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="a">
+    <a href="{@href}"><xsl:apply-templates/></a>
+  </xsl:template>
+
+  <xsl:template match="a" mode="jesus">
+    <a href="{@href}"><xsl:apply-templates mode="jesus"/></a>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!-- When we encounter a note, we merely output a link to the note. -->
+  <xsl:template match="note[@type = 'x-strongsMarkup']"/>
+  <xsl:template match="note[@type = 'x-strongsMarkup']" mode="jesus"/>
+  <xsl:template match="note[@type = 'x-strongsMarkup']" mode="print-notes"/>
+
+  <xsl:template match="note">
+    <xsl:if test="$Notes = 'true'">
+      <!-- If there is a following sibling that is a note, emit a separator -->
+      <xsl:variable name="siblings" select="../child::node()"/>
+      <xsl:variable name="next-position" select="position() + 1"/>
+      <xsl:choose>
+        <xsl:when test="name($siblings[$next-position]) = 'note'">
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
+        </xsl:when>
+        <xsl:otherwise>
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="note" mode="jesus">
+    <xsl:if test="$Notes = 'true'">
+     <!-- If there is a following sibling that is a note, emit a separator -->
+      <xsl:variable name="siblings" select="../child::node()"/>
+      <xsl:variable name="next-position" select="position() + 1"/>
+      <xsl:choose>
+        <xsl:when test="$siblings[$next-position] and name($siblings[$next-position]) = 'note'">
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
+        </xsl:when>
+        <xsl:otherwise>
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="note" mode="print-notes">
+    <div class="margin">
+      <strong><xsl:call-template name="generateNoteXref"/></strong>
+      <a name="note-{generate-id(.)}">
+        <xsl:text> </xsl:text>
+      </a>
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+
+  <!--
+    == If the n attribute is present then use that for the cross ref otherwise create a letter.
+    == Note: numbering restarts with each verse.
+    -->
+  <xsl:template name="generateNoteXref">
+    <xsl:choose>
+      <xsl:when test="@n">
+        <xsl:value-of select="@n"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:number level="any" from="/osis//verse" format="a"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="p">
+    <p><xsl:apply-templates/></p>
+  </xsl:template>
+  
+  <xsl:template match="p" mode="jesus">
+    <p><xsl:apply-templates mode="jesus"/></p>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="p" mode="print-notes">
+    <!-- FIXME: This ignores text in the note. -->
+    <!-- don't put para's in notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="w">
+    <!-- Output the content followed by all the lemmas and then all the morphs. -->
+    <xsl:apply-templates/>
+    <xsl:if test="$Strongs = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
+      <xsl:call-template name="lemma">
+        <xsl:with-param name="lemma" select="@lemma"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
+      <xsl:call-template name="morph">
+        <xsl:with-param name="morph" select="@morph"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="$Strongs = 'true' and starts-with(@lemma, 'lemma.Strong:')">
+      <xsl:call-template name="lemma">
+        <xsl:with-param name="lemma" select="@lemma"/>
+      </xsl:call-template>
+    </xsl:if>
+    <!--
+        except when followed by a text node or non-printing node.
+        This is true whether the href is output or not.
+    -->
+    <xsl:variable name="siblings" select="../child::node()"/>
+    <xsl:variable name="next-position" select="position() + 1"/>
+    <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
+      <xsl:text> </xsl:text>
+    </xsl:if>
+  </xsl:template>
+  
+  <xsl:template match="w" mode="jesus">
+    <!-- Output the content followed by all the lemmas and then all the morphs. -->
+    <xsl:apply-templates mode="jesus"/>
+    <xsl:if test="$Strongs = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
+      <xsl:call-template name="lemma">
+        <xsl:with-param name="lemma" select="@lemma"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
+      <xsl:call-template name="morph">
+        <xsl:with-param name="morph" select="@morph"/>
+      </xsl:call-template>
+    </xsl:if>
+    <!--
+        except when followed by a text node or non-printing node.
+        This is true whether the href is output or not.
+    -->
+    <xsl:variable name="siblings" select="../child::node()"/>
+    <xsl:variable name="next-position" select="position() + 1"/>
+    <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
+      <xsl:text> </xsl:text>
+    </xsl:if>
+  </xsl:template>
+  
+  <xsl:template name="lemma">
+    <xsl:param name="lemma"/>
+    <xsl:param name="part" select="0"/>
+    <xsl:variable name="orig-lemma" select="substring-after($lemma, ':')"/>
+    <xsl:variable name="protocol">
+      <xsl:choose>
+        <xsl:when test="substring($orig-lemma, 1, 1) = 'H'">
+          <xsl:value-of select="$hebrew.def.protocol"/>
+        </xsl:when>
+        <xsl:when test="substring($orig-lemma, 1, 1) = 'G'">
+          <xsl:value-of select="$greek.def.protocol"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$lex.def.protocol"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="separator">
+      <xsl:choose>
+        <xsl:when test="contains($orig-lemma, '|')">
+          <xsl:value-of select="'|'"/>
+        </xsl:when>
+        <xsl:when test="contains($orig-lemma, ' ')">
+          <xsl:value-of select="' '"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="sub">
+      <xsl:choose>
+        <xsl:when test="$separator != '' and $part = '0'">
+          <xsl:value-of select="$part + 1"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$part"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$protocol = $lex.def.protocol">
+        <font class="lex">[<xsl:value-of select="$orig-lemma"/>]</font>
+      </xsl:when>
+      <xsl:when test="$separator = ''">
+        <!-- <sub class="strongs"><a href="{$protocol}{$orig-lemma}">S<xsl:number level="any" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a></sub> -->
+        <sub class="strongs"><a href="{$protocol}{$orig-lemma}"><xsl:value-of select="format-number(substring($orig-lemma,2),'#')"/></a></sub>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- <sub class="strongs"><a href="{$protocol}{substring-before($orig-lemma, $separator)}">S<xsl:number level="single" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a>, </sub> -->
+        <sub class="strongs"><a href="{$protocol}{substring-before($orig-lemma, $separator)}"><xsl:value-of select="format-number(substring(substring-before($orig-lemma, $separator),2),'#')"/></a>, </sub>
+        <xsl:call-template name="lemma">
+          <xsl:with-param name="lemma" select="substring-after($lemma, $separator)"/>
+          <xsl:with-param name="part">
+            <xsl:choose>
+              <xsl:when test="$sub">
+                <xsl:value-of select="$sub + 1"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="1"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:with-param>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="morph">
+    <xsl:param name="morph"/>
+    <xsl:param name="part" select="0"/>
+    <xsl:variable name="orig-work" select="substring-before($morph, ':')"/>
+    <xsl:variable name="orig-morph" select="substring-after($morph, ':')"/>
+    <xsl:variable name="protocol">
+      <xsl:choose>
+        <xsl:when test="starts-with($orig-work, 'x-Robinson') or starts-with($orig-work, 'robinson')">
+          <xsl:value-of select="$greek.morph.protocol"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$hebrew.morph.protocol"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="separator">
+      <xsl:choose>
+        <xsl:when test="contains($orig-morph, '|')">
+          <xsl:value-of select="'|'"/>
+        </xsl:when>
+        <xsl:when test="contains($orig-morph, ' ')">
+          <xsl:value-of select="' '"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="sub">
+      <xsl:choose>
+        <xsl:when test="$separator != '' and $part = '0'">
+          <xsl:value-of select="$part + 1"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$part"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$separator = ''">
+        <!-- <sub class="morph"><a href="{$protocol}{$orig-morph}">M<xsl:number level="any" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a></sub> -->
+        <sub class="morph"><a href="{$protocol}{$orig-morph}"><xsl:value-of select="$orig-morph"/></a></sub>
+      </xsl:when>
+      <xsl:otherwise>
+        <!-- <sub class="morph"><a href="{$protocol}{substring-before($orig-morph, $separator)}">M<xsl:number level="single" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a>, </sub> -->
+        <sub class="morph"><a href="{$protocol}{substring-before($orig-morph, $separator)}"><xsl:value-of select="substring-before($orig-morph, $separator)"/></a>, </sub>
+        <xsl:call-template name="morph">
+          <xsl:with-param name="morph" select="substring-after($morph, $separator)"/>
+          <xsl:with-param name="part">
+            <xsl:choose>
+              <xsl:when test="$sub">
+                <xsl:value-of select="$sub + 1"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="1"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:with-param>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="seg">
+    <xsl:choose>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="@type = 'x-variant'">
+        <xsl:if test="@subType = 'x-class-1'">
+          <xsl:apply-templates/>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="seg" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
+      </xsl:when>
+      <xsl:when test="@type = 'x-variant'">
+        <xsl:if test="@subType = 'x-class:1'">
+          <xsl:apply-templates mode="jesus"/>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="jesus"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <!-- expansion is OSIS, expan is TEI -->
+  <xsl:template match="abbr">
+    <font class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@expan">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expan"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </font>
+  </xsl:template>
+
+  <xsl:template match="abbr" mode="jesus">
+    <font class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@expan">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expan"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates mode="jesus"/>
+    </font>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="speaker[@who = 'Jesus']">
+    <font class="jesus"><xsl:apply-templates mode="jesus"/></font>
+  </xsl:template>
+
+  <xsl:template match="speaker">
+    <font class="speech"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']">
+  <!-- Done by a line in [verse]
+    <h3 class="heading">
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']" mode="jesus">
+  <!-- Done by a line in [verse]
+    <h3 class="heading">
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@level]">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <xsl:choose>
+        <xsl:when test="@level = '1'">
+          <h1 class="level"><xsl:apply-templates/></h1>
+        </xsl:when>
+        <xsl:when test="@level = '2'">
+          <h2 class="level"><xsl:apply-templates/></h2>
+        </xsl:when>
+        <xsl:when test="@level = '3'">
+          <h3 class="level"><xsl:apply-templates/></h3>
+        </xsl:when>
+        <xsl:when test="@level = '4'">
+          <h4 class="level"><xsl:apply-templates/></h4>
+        </xsl:when>
+        <xsl:when test="@level = '5'">
+          <h5 class="level"><xsl:apply-templates/></h5>
+        </xsl:when>
+        <xsl:otherwise>
+          <h6 class="level"><xsl:apply-templates/></h6>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="title[@level]" mode="jesus">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <xsl:choose>
+        <xsl:when test="@level = '1'">
+          <h1 class="level"><xsl:apply-templates/></h1>
+        </xsl:when>
+        <xsl:when test="@level = '2'">
+          <h2 class="level"><xsl:apply-templates/></h2>
+        </xsl:when>
+        <xsl:when test="@level = '3'">
+          <h3 class="level"><xsl:apply-templates/></h3>
+        </xsl:when>
+        <xsl:when test="@level = '4'">
+          <h4 class="level"><xsl:apply-templates/></h4>
+        </xsl:when>
+        <xsl:when test="@level = '5'">
+          <h5 class="level"><xsl:apply-templates/></h5>
+        </xsl:when>
+        <xsl:otherwise>
+          <h6 class="level"><xsl:apply-templates/></h6>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <h2 class="heading"><xsl:apply-templates/></h2>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="title" mode="jesus">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <h2 class="heading"><xsl:apply-templates/></h2>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="reference">
+    <xsl:choose>
+      <xsl:when test="$XRef = 'true'">
+        <a href="bible://{@osisRef}"><xsl:apply-templates/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="reference" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="$XRef = 'true'">
+        <a href="bible://{@osisRef}"><xsl:apply-templates mode="jesus"/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="jesus"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="caption">
+    <div class="caption"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="caption" mode="jesus">
+    <div class="caption"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="catchWord">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="catchWord" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <!--
+      <cell> is handled shortly after <table> below and thus does not appear
+      here.
+  -->
+  
+  <xsl:template match="closer">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="closer" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <xsl:template match="date">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="date" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <xsl:template match="divineName">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+  
+  <xsl:template match="divineName" mode="jesus">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+  
+  <xsl:template match="figure">
+    <div class="figure">
+      <xsl:choose>
+        <xsl:when test="starts-with(@src, '/')">
+          <img src="{concat($baseURL, @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:when>
+        <xsl:otherwise>
+          <img src="{concat($baseURL, '/',  @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="figure" mode="jesus">
+    <div class="figure">
+      <xsl:choose>
+        <xsl:when test="starts-with(@src, '/')">
+          <img src="{concat($baseURL, @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:when>
+        <xsl:otherwise>
+          <img src="{concat($baseURL, '/',  @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates mode="jesus"/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="foreign">
+    <em class="foreign"><xsl:apply-templates/></em>
+  </xsl:template>
+  
+  <xsl:template match="foreign" mode="jesus">
+    <em class="foreign"><xsl:apply-templates mode="jesus"/></em>
+  </xsl:template>
+  
+  <!-- This is a subheading. -->
+  <xsl:template match="head//head">
+    <h5 class="head"><xsl:apply-templates/></h5>
+  </xsl:template>
+  
+  <!-- This is a top-level heading. -->
+  <xsl:template match="head">
+    <h4 class="head"><xsl:apply-templates/></h4>
+  </xsl:template>
+  
+  <xsl:template match="index">
+    <a name="index{@id}" class="index"/>
+  </xsl:template>
+
+  <xsl:template match="inscription">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+
+  <xsl:template match="inscription" mode="jesus">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+
+  <xsl:template match="item">
+    <li class="item"><xsl:apply-templates/></li>
+  </xsl:template>
+
+  <xsl:template match="item" mode="jesus">
+    <li class="item"><xsl:apply-templates mode="jesus"/></li>
+  </xsl:template>
+  
+  <!--
+      <item> and <label> are covered by <list> below and so do not appear here.
+  -->
+
+  <xsl:template match="lg">
+    <div class="lg"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="lg" mode="jesus">
+    <div class="lg"><xsl:apply-templates mode="jesus"/></div>
+  </xsl:template>
+  
+  <xsl:template match="lg[@sID or @eID]"/>
+  <xsl:template match="lg[@sID or @eID]" mode="jesus"/>
+
+  <xsl:template match="l[@sID]"/>
+  <xsl:template match="l[@sID]" mode="jesus"/>
+
+  <xsl:template match="l[@eID]"><br/></xsl:template>
+  <xsl:template match="l[@eID]" mode="jesus"><br/></xsl:template>
+
+  <xsl:template match="l">
+    <xsl:apply-templates/><br/>
+  </xsl:template>
+  
+  <xsl:template match="l" mode="jesus">
+    <xsl:apply-templates mode="jesus"/><br/>
+  </xsl:template>
+
+  <!-- While a BR is a break, if it is immediately followed by punctuation,
+       indenting this rule can introduce whitespace.
+    -->
+  <xsl:template match="lb"><br/></xsl:template>
+  <xsl:template match="lb" mode="jesus"><br/></xsl:template>
+
+  <xsl:template match="list">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label"><xsl:apply-templates/></dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item"><xsl:apply-templates/></dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper"><xsl:apply-templates select="."/></dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item"><xsl:apply-templates/></li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper"><xsl:apply-templates select="."/></li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+
+  <xsl:template match="list" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label"><xsl:apply-templates mode="jesus"/></dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item"><xsl:apply-templates mode="jesus"/></dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates mode="jesus"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item"><xsl:apply-templates mode="jesus"/></li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates mode="jesus"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="mentioned">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="mentioned" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <!-- Milestones represent characteristics of the original manuscript.
+    == that are being preserved. For this reason, most are ignored.
+    ==
+    == The defined types are:
+    == column   Marks the end of a column where there is a multi-column display.
+    == footer   Marks the footer region of a page.
+    == halfLine Used to mark half-line units if not otherwise encoded.
+    == header   Marks the header region of a page.
+    == line     Marks line breaks, particularly important in recording appearance of an original text, such as a manuscript.
+    == pb       Marks a page break in a text.
+    == screen   Marks a preferred place for breaks in an on-screen rendering of the text.
+    == cQuote   Marks the location of a continuation quote mark, with marker containing the publishers mark.
+    -->
+  <!--  This is used by the KJV for paragraph markers. -->
+  <xsl:template match="milestone[@type = 'x-p']"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
+  <xsl:template match="milestone[@type = 'x-p']" mode="jesus"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
+
+  <xsl:template match="milestone[@type = 'cQuote']">
+    <xsl:value-of select="@marker"/>
+  </xsl:template>
+
+  <xsl:template match="milestone[@type = 'cQuote']" mode="jesus">
+    <xsl:value-of select="@marker"/>
+  </xsl:template>
+
+  <xsl:template match="milestone[@type = 'line']"><br/></xsl:template>
+
+  <xsl:template match="milestone[@type = 'line']" mode="jesus"><br/></xsl:template>
+
+  <!--
+    == Milestone start and end are deprecated.
+    == At this point we expect them to not be in the document.
+    == These have been replace with milestoneable elements.
+    -->
+  <xsl:template match="milestoneStart"/>
+  <xsl:template match="milestoneEnd"/>
+  
+  <xsl:template match="name">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="name" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!-- If there is a milestoned q then just output a quotation mark -->
+  <xsl:template match="q[@sID or @eID]">
+    <xsl:choose>
+      <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
+      <!-- The chosen mark should be based on the work's author's locale. -->
+      <xsl:otherwise>"</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@sID or @eID]" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
+      <!-- The chosen mark should be based on the work's author's locale. -->
+      <xsl:otherwise>"</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@who = 'Jesus']">
+    <font class="jesus"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></font>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'blockquote']">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'blockquote']" mode="jesus">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'citation']">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'citation']" mode="jesus">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'embedded']">
+    <xsl:choose>
+      <xsl:when test="@marker">
+        <xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <quote class="q"><xsl:apply-templates/></quote>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@type = 'embedded']" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="@marker">
+      <xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <quote class="q"><xsl:apply-templates/></quote>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!-- An alternate reading. -->
+  <xsl:template match="rdg">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+   <xsl:template match="rdg" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!--
+      <row> is handled near <table> below and so does not appear here.
+  -->
+  
+  <xsl:template match="salute">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+ <!-- Avoid adding whitespace -->
+  <xsl:template match="salute" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <xsl:template match="signed">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="signed" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <xsl:template match="speech">
+    <div class="speech"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="speech" mode="jesus">
+    <div class="speech"><xsl:apply-templates mode="jesus"/></div>
+  </xsl:template>
+
+  <xsl:template match="table">
+    <table class="table">
+      <xsl:copy-of select="@rows|@cols"/>
+      <xsl:if test="head">
+        <thead class="head"><xsl:apply-templates select="head"/></thead>
+      </xsl:if>
+      <tbody><xsl:apply-templates select="row"/></tbody>
+    </table>
+  </xsl:template>
+
+  <xsl:template match="row">
+    <tr class="row"><xsl:apply-templates/></tr>
+  </xsl:template>
+  
+  <xsl:template match="cell">
+    <xsl:variable name="element-name">
+      <xsl:choose>
+        <xsl:when test="@role = 'label'">
+          <xsl:text>th</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>td</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="cell-direction">
+      <xsl:if test="@xml:lang">
+        <xsl:call-template name="getDirection">
+         <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
+        </xsl:call-template>
+      </xsl:if>
+    </xsl:variable>
+    <xsl:element name="{$element-name}">
+      <xsl:attribute name="class">cell</xsl:attribute>
+      <xsl:attribute name="valign">top</xsl:attribute>
+      <xsl:if test="@xml:lang">
+        <xsl:attribute name="dir">
+          <xsl:value-of select="$cell-direction"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="$cell-direction = 'rtl'">
+        <xsl:attribute name="align">
+          <xsl:value-of select="'right'"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@rows">
+        <xsl:attribute name="rowspan">
+          <xsl:value-of select="@rows"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@cols">
+        <xsl:attribute name="colspan">
+          <xsl:value-of select="@cols"/>
+        </xsl:attribute>
+      </xsl:if>
+      <!-- hack alert -->
+      <xsl:choose>
+        <xsl:when test="$cell-direction = 'rtl'">
+          <xsl:text>&#8235;</xsl:text><xsl:apply-templates/><xsl:text>&#8236;</xsl:text>
+        </xsl:when>
+        <xsl:when test="$cell-direction = 'ltr'">
+          <xsl:text>&#8234;</xsl:text><xsl:apply-templates/><xsl:text>&#8236;</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:element>
+  </xsl:template>
+
+  <xsl:template match="transChange">
+    <em><xsl:apply-templates/></em>
+  </xsl:template>
+  <xsl:template match="transChange" mode="jesus">
+    <em><xsl:apply-templates/></em>
+  </xsl:template>
+  
+  <!-- @type is OSIS, @rend is TEI -->
+  <xsl:template match="hi">
+    <xsl:variable name="style">
+      <xsl:choose>
+        <xsl:when test="@type">
+          <xsl:value-of select="@type"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="@rend"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$style = 'acrostic'">
+        <xsl:apply-templates/>
+      </xsl:when>
+      <xsl:when test="$style = 'bold'">
+        <strong><xsl:apply-templates/></strong>
+      </xsl:when>
+      <xsl:when test="$style = 'emphasis'">
+        <em><xsl:apply-templates/></em>
+      </xsl:when>
+      <xsl:when test="$style = 'illuminated'">
+        <strong><em><xsl:apply-templates/></em></strong>
+      </xsl:when>
+      <xsl:when test="$style = 'italic'">
+        <em><xsl:apply-templates/></em>
+      </xsl:when>
+      <xsl:when test="$style = 'line-through'">
+        <font class="strike"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'normal'">
+        <font class="normal"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'small-caps'">
+        <font class="small-caps"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'sub'">
+        <sub><xsl:apply-templates/></sub>
+      </xsl:when>
+      <xsl:when test="$style = 'super'">
+        <sup><xsl:apply-templates/></sup>
+      </xsl:when>
+      <xsl:when test="$style = 'underline'">
+        <u><xsl:apply-templates/></u>
+      </xsl:when>
+      <xsl:when test="$style = 'x-caps'">
+        <font class="caps"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="hi" mode="jesus">
+    <xsl:variable name="style">
+      <xsl:choose>
+        <xsl:when test="@type">
+          <xsl:value-of select="@type"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="@rend"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$style = 'acrostic'">
+        <xsl:apply-templates/>
+      </xsl:when>
+      <xsl:when test="$style = 'bold'">
+        <strong><xsl:apply-templates/></strong>
+      </xsl:when>
+      <xsl:when test="$style = 'emphasis'">
+        <em><xsl:apply-templates/></em>
+      </xsl:when>
+      <xsl:when test="$style = 'illuminated'">
+        <strong><em><xsl:apply-templates/></em></strong>
+      </xsl:when>
+      <xsl:when test="$style = 'italic'">
+        <em><xsl:apply-templates/></em>
+      </xsl:when>
+      <xsl:when test="$style = 'line-through'">
+        <font class="strike"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'normal'">
+        <font class="normal"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'small-caps'">
+        <font class="small-caps"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="$style = 'sub'">
+        <sub><xsl:apply-templates/></sub>
+      </xsl:when>
+      <xsl:when test="$style = 'super'">
+        <sup><xsl:apply-templates/></sup>
+      </xsl:when>
+      <xsl:when test="$style = 'underline'">
+        <u><xsl:apply-templates/></u>
+      </xsl:when>
+      <xsl:when test="$style = 'x-caps'">
+        <font class="caps"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--
+    The following elements are actually TEI and there is some expectation
+    that these will make it into OSIS.
+  -->
+  <xsl:template match="superentry">
+    <!-- output each preverse element in turn -->
+    <xsl:for-each select="entry|entryFree">
+      <xsl:apply-templates/><br/><br/>
+    </xsl:for-each>
+  </xsl:template>
+
+  <xsl:template match="entry">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="entryFree">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="form">
+    <xsl:apply-templates/><br/>
+  </xsl:template>
+
+  <xsl:template match="orth">
+    <font class="orth"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <xsl:template match="pron">
+    <font class="pron"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <xsl:template match="etym">
+    <font class="etym"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <xsl:template match="def">
+    <font class="def"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <xsl:template match="usg">
+    <font class="usg"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <xsl:template match="@xml:lang">
+    <xsl:variable name="dir">
+      <xsl:if test="@xml:lang">
+        <xsl:call-template name="getDirection">
+         <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
+        </xsl:call-template>
+      </xsl:if>
+    </xsl:variable>
+    <xsl:if test="$dir">
+      <xsl:attribute name="dir">
+        <xsl:value-of select="$dir"/>
+      </xsl:attribute>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="text()" mode="small-caps">
+  <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
+  </xsl:template>
+
+  <!--
+    Generate a css or an inline style representation of a font spec.
+    The fontspec that is passed in is in one of two forms:
+    FamilyName-STYLE-size, where STYLE is either PLAIN, BOLD, ITALIC or BOLDITALIC
+    or
+    FamilyName,style,size, where STYLE is 0 for PLAIN, 1 for BOLD, 2 for ITALIC or 3 for BOLDITALIC.
+
+    The style attribute is css for a css style specification or anything else for an inline style one.
+  -->
+  <xsl:template name="generateFontStyle">
+    <xsl:param name="fontspec"/>
+    <xsl:param name="style"/>
+    <xsl:variable name="fontSeparator">
+      <xsl:choose>
+        <xsl:when test="contains($fontspec, ',')">
+          <xsl:value-of select="','"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="'-'"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="aFont">
+      <xsl:choose>
+        <xsl:when test="substring-before($fontspec, $fontSeparator) = ''"><xsl:value-of select="$fontspec"/>,0,16</xsl:when>
+        <xsl:otherwise><xsl:value-of select="$fontspec"/></xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fontfamily" select="substring-before($aFont, $fontSeparator)" />
+    <xsl:variable name="fontsize" select="substring-after(substring-after($aFont, $fontSeparator), $fontSeparator)" />
+    <xsl:variable name="styling" select="substring-before(substring-after($aFont, $fontSeparator), $fontSeparator)" />
+    <xsl:variable name="fontweight">
+      <xsl:choose>
+        <xsl:when test="$styling = '1' or $styling = '3' or contains($styling, 'bold')">bold</xsl:when>
+        <xsl:otherwise>normal</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fontstyle">
+      <xsl:choose>
+        <xsl:when test="$styling = '2' or $styling = '3' or contains($styling, 'italic')">italic</xsl:when>
+        <xsl:otherwise>normal</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$style = 'css'">
+        <xsl:value-of select='concat("font-family: &apos;", $fontfamily, "&apos;, Serif; ",
+                                     "font-size:   ",       $fontsize,   "pt; ",
+                                     "font-weight: ",       $fontweight, "; ",
+                                     "font-style:  ",       $fontstyle,  ";")'/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select='concat("font-family=&apos;",  $fontfamily, "&apos;, Serif; ",
+                                     "font-size=",          $fontsize,   "pt; ",
+                                     "font-weight=",        $fontweight, "; ",
+                                     "font-style=",         $fontstyle,  "; ")'/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--
+    The direction is deduced from the xml:lang attribute and is assumed to be meaningful for those elements.
+    Note: there is a bug that prevents dir=rtl from working.
+    see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4296022 and 4866977
+  -->
+  <xsl:template name="getDirection">
+    <xsl:param name="lang"/>
+    <xsl:choose>
+      <xsl:when test="$lang = 'he' or $lang = 'ar' or $lang = 'fa' or $lang = 'ur' or $lang = 'syr'">
+        <xsl:value-of select="'rtl'"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="'ltr'"/>
+      </xsl:otherwise>
+    </xsl:choose>
+   </xsl:template>
+  
+</xsl:stylesheet>

Added: trunk/step-web-app/src/main/resources/xsl/cswing/simple2.xsl
===================================================================
--- trunk/step-web-app/src/main/resources/xsl/cswing/simple2.xsl	                        (rev 0)
+++ trunk/step-web-app/src/main/resources/xsl/cswing/simple2.xsl	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,1465 @@
+<?xml version="1.0"?>
+<!--
+ * Distribution License:
+ * JSword is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License, version 2.1 as published by
+ * the Free Software Foundation. This program is distributed in the hope
+ * that it will be useful, but WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU Lesser General Public License for more details.
+ *
+ * The License is available on the internet at:
+ *       http://www.gnu.org/copyleft/lgpl.html
+ * or by writing to:
+ *      Free Software Foundation, Inc.
+ *      59 Temple Place - Suite 330
+ *      Boston, MA 02111-1307, USA
+ *
+ * Copyright: 2005
+ *     The copyright to this program is held by it's authors.
+ *
+ * ID: $Id: simple.xsl 1603 2007-08-03 15:37:45Z dmsmith $
+ -->
+ <!--
+ * Transforms OSIS to HTML for viewing within JSword browsers.
+ * Note: There are custom protocols which the browser must handle.
+ * 
+ * @see gnu.lgpl.License for license details.
+ *      The copyright to this program is held by it's authors.
+ * @author Joe Walker [joe at eireneh dot com]
+ * @author DM Smith [dmsmith555 at yahoo dot com]
+ -->
+ <xsl:stylesheet
+  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+  version="1.0"
+  xmlns:jsword="http://xml.apache.org/xalan/java"
+  extension-element-prefixes="jsword">
+
+  <!--  Version 3.0 is necessary to get br to work correctly. -->
+  <xsl:output method="html" version="3.0" omit-xml-declaration="yes" indent="no"/>
+
+  <!-- Be very careful about introducing whitespace into the document.
+       strip-space merely remove space between one tag and another tag.
+       This may cause significant whitespace to be removed.
+       
+       It is easy to have apply-templates on a line to itself which if
+       it encounters text before anything else will introduce whitespace.
+       With the browser we are using, span will introduce whitespace
+       but font does not. Therefore we use font as a span.
+    -->
+  <!-- gdef and hdef refer to hebrew and greek definitions keyed by strongs -->
+  <xsl:param name="greek.def.protocol" select="'gdef:'"/>
+  <xsl:param name="hebrew.def.protocol" select="'hdef:'"/>
+  <!-- currently these are not used, but they are for morphologic forms -->
+  <xsl:param name="greek.morph.protocol" select="'gmorph:'"/>
+  <xsl:param name="hebrew.morph.protocol" select="'hmorph:'"/>
+
+  <!-- The absolute base for relative references. -->
+  <xsl:param name="baseURL" select="''"/>
+
+  <!-- Whether to show Strongs or not -->
+  <xsl:param name="Strongs" select="'false'"/>
+
+  <!-- Whether to show morphologic forms or not -->
+  <xsl:param name="Morph" select="'false'"/>
+
+  <!-- Whether to start each verse on an new line or not -->
+  <xsl:param name="VLine" select="'false'"/>
+
+  <!-- Whether to show non-canonical "headings" or not -->
+  <xsl:param name="Headings" select="'true'"/>
+
+  <!-- Whether to show notes or not -->
+  <xsl:param name="Notes" select="'true'"/>
+
+  <!-- Whether to have linking cross references or not -->
+  <xsl:param name="XRef" select="'true'"/>
+
+  <!-- Whether to output no Verse numbers -->
+  <xsl:param name="NoVNum" select="'false'"/>
+
+  <!-- Whether to output Verse numbers or not -->
+  <xsl:param name="VNum" select="'true'"/>
+
+  <!-- Whether to output Chapter and Verse numbers or not -->
+  <xsl:param name="CVNum" select="'false'"/>
+
+  <!-- Whether to output Book, Chapter and Verse numbers or not -->
+  <xsl:param name="BCVNum" select="'false'"/>
+
+  <!-- Whether to output superscript verse numbers or normal size ones -->
+  <xsl:param name="TinyVNum" select="'true'"/>
+
+  <!-- The CSS stylesheet to use. The url must be absolute. -->
+  <xsl:param name="css"/>
+  
+  <!-- The order of display. Hebrew is rtl (right to left) -->
+  <xsl:param name="direction" select="'ltr'"/>
+
+  <!-- The font that is passed in is in one of two forms:
+    FamilyName-STYLE-size, where STYLE is either PLAIN, BOLD, ITALIC or BOLDITALIC
+    or
+    FamilyName,style,size, where STYLE is 0 for PLAIN, 1 for BOLD, 2 for ITALIC or 3 for BOLDITALIC.
+    This needs to be changed into a CSS style specification
+  -->
+  <xsl:param name="font" select="Serif"/>
+
+  <xsl:variable name="fontspec">
+      <xsl:call-template name="generateFontStyle">
+        <xsl:with-param name="fontspec" select="$font"/>
+        <xsl:with-param name="style">css</xsl:with-param>
+      </xsl:call-template>
+  </xsl:variable>
+
+  <!-- Create a global key factory from which OSIS ids will be generated -->
+  <xsl:variable name="keyf" select="jsword:org.crosswire.jsword.passage.PassageKeyFactory.instance()"/>
+
+  <!--=======================================================================-->
+  <xsl:template match="/">
+    <html dir="{$direction}">
+      <head>
+        <base href="{$baseURL}"/>
+        <style type="text/css">
+          BODY { <xsl:value-of select="$fontspec" /> }
+          A { text-decoration: none; }
+          A.strongs { color: black; text-decoration: none; }
+          SUB.strongs { font-size: 75%; color: red; }
+          SUB.morph { font-size: 75%; color: blue; }
+          SUB.lemma { font-size: 75%; color: red; }
+          SUP.verse { font-size: 75%; color: gray; }
+          SUP.note { font-size: 75%; color: green; }
+          FONT.jesus { color: red; }
+          FONT.speech { color: blue; }
+          FONT.strike { text-decoration: line-through; }
+          FONT.small-caps { font-variant: small-caps; }
+          FONT.inscription { font-weight: bold; font-variant: small-caps; }
+          FONT.divineName { font-variant: small-caps; }
+          FONT.normal { font-variant: normal; }
+          FONT.caps { text-transform: uppercase; }
+          H1.level { text-align: center; font-size: 115%; color: #000000; }
+          H2.level { text-align: center; font-size: 110%; color: #000000; }
+          H3.level { text-align: center; font-size: 100%; }
+          H4.level { text-align: center; font-size: 90%; }
+          H5.level { text-align: center; font-size: 85%; }
+          H6.level { text-align: center; font-size: 80%; }
+          H3.heading { font-size: 110%; color: #666699; font-weight: bold; }
+          H2.heading { font-size: 115%; color: #669966; font-weight: bold; }
+          div.margin { font-size:90%; }
+          TD.notes { width:20%; background:#f4f4e8; }
+          TD.text { width:80%; }
+        </style>
+        <!-- Always include the user's stylesheet even if "" -->
+        <link rel="stylesheet" type="text/css" href="{$css}" title="styling" />
+      </head>
+      <body>
+        <!-- If there are notes, output a table with notes in the 2nd column. -->
+        <!-- There is a rendering bug which prevents the notes from adhering to the right edge. -->
+        <xsl:choose>
+          <xsl:when test="$Notes = 'true' and //note[not(@type = 'x-strongsMarkup')]">
+            <xsl:choose>
+              <xsl:when test="$direction != 'rtl'">
+	            <table cols="2" cellpadding="5" cellspacing="5">
+	              <tr>
+	                <!-- The two rows are swapped until the bug is fixed. -->
+	                <td valign="top" class="notes">
+	                  <p>&#160;</p>
+	                  <xsl:apply-templates select="//verse" mode="print-notes"/>
+	                </td>
+	                <td valign="top" class="text">
+	                  <xsl:apply-templates/>
+	                </td>
+	              </tr>
+	            </table>
+              </xsl:when>
+              <xsl:otherwise>
+                <!-- reverse the table for Right to Left languages -->
+	            <table cols="2" cellpadding="5" cellspacing="5">
+	              <!-- In a right to left, the alignment should be reversed too -->
+	              <tr align="right">
+	                <td valign="top" class="notes">
+	                  <p>&#160;</p>
+	                  <xsl:apply-templates select="//note" mode="print-notes"/>
+	                </td>
+	                <td valign="top" class="text">
+	                  <xsl:apply-templates/>
+	                </td>
+	              </tr>
+	            </table>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:apply-templates/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </body>
+    </html>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == A proper OSIS document has osis as it's root.
+    == We dig deeper for it's content.
+    -->
+  <xsl:template match="osis">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == An OSIS document may contain more that one work.
+    == Each work is held in an osisCorpus element.
+    == If there is only one work, then this element will (should) be absent.
+    == Process each document in turn.
+    == It might be reasonable to dig into the header element of each work
+    == and get its title.
+    == Otherwise, we ignore the header and work elements and just process
+    == the osisText elements.
+    -->
+  <xsl:template match="osisCorpus">
+    <xsl:apply-templates select="osisText"/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!--
+    == Each work has an osisText element.
+    == We ignore the header and work elements and process its div elements.
+    == While divs can be milestoned, the osisText element requires container
+    == divs.
+    -->
+  <xsl:template match="osisText">
+    <xsl:apply-templates select="div"/>
+  </xsl:template>
+  
+  <!-- Ignore headers and its elements -->
+  <xsl:template match="header"/>
+  <xsl:template match="revisionDesc"/>
+  <xsl:template match="work"/>
+   <!-- <xsl:template match="title"/> who's parent is work -->
+  <xsl:template match="contributor"/>
+  <xsl:template match="creator"/>
+  <xsl:template match="subject"/>
+  <!-- <xsl:template match="date"/> who's parent is work -->
+  <xsl:template match="description"/>
+  <xsl:template match="publisher"/>
+  <xsl:template match="type"/>
+  <xsl:template match="format"/>
+  <xsl:template match="identifier"/>
+  <xsl:template match="source"/>
+  <xsl:template match="language"/>
+  <xsl:template match="relation"/>
+  <xsl:template match="coverage"/>
+  <xsl:template match="rights"/>
+  <xsl:template match="scope"/>
+  <xsl:template match="workPrefix"/>
+  <xsl:template match="castList"/>
+  <xsl:template match="castGroup"/>
+  <xsl:template match="castItem"/>
+  <xsl:template match="actor"/>
+  <xsl:template match="role"/>
+  <xsl:template match="roleDesc"/>
+  <xsl:template match="teiHeader"/>
+  <xsl:template match="refSystem"/>
+
+
+  <!-- Ignore titlePage -->
+  <xsl:template match="titlePage"/>
+
+  <!--=======================================================================-->
+  <!-- 
+    == Div provides the major containers for a work.
+    == Divs are milestoneable.
+    -->
+  <xsl:template match="div">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="div" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!-- Handle verses as containers and as a start verse.                     -->
+  <xsl:template match="verse[not(@eID)]">
+    <!-- If the verse doesn't start on its own line and -->
+    <!-- the verse is not the first verse of a set of siblings, -->
+    <!-- output an extra space. -->
+    <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
+      <xsl:text>&#160;</xsl:text>
+    </xsl:if>
+    <!-- output each preverse element in turn -->
+    <xsl:for-each select=".//*[@subType = 'x-preverse' or @subtype = 'x-preverse']">
+      <xsl:choose>
+        <xsl:when test="local-name() = 'title'">
+          <!-- Always show canonical titles or if headings is turned on -->
+          <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+            <h3 class="heading"><xsl:apply-templates /></h3>
+          </xsl:if>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates />
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:for-each>
+    <!-- Handle the KJV paragraph marker. -->
+    <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
+    <!-- Always output the verse -->
+    <xsl:choose>
+ 	  <xsl:when test="$VLine = 'true'">
+        <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates/></div>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="versenum"/><xsl:apply-templates/>
+        <!-- Follow the verse with an extra space -->
+        <!-- when they don't start on lines to themselves -->
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="verse[not(@eID)]" mode="jesus">
+    <!-- If the verse doesn't start on its own line and -->
+    <!-- the verse is not the first verse of a set of siblings, -->
+    <!-- output an extra space. -->
+    <xsl:if test="$VLine = 'false' and preceding-sibling::*[local-name() = 'verse']">
+      <xsl:text>&#160;</xsl:text>
+    </xsl:if>
+    <xsl:variable name="title" select=".//title"/>
+    <xsl:if test="string-length($title) > 0">
+      <h3 class="heading"><xsl:value-of select="$title"/></h3>
+    </xsl:if>
+    <!-- Handle the KJV paragraph marker. -->
+    <xsl:if test="milestone[@type = 'x-p']"><br/><br/></xsl:if>
+    <!-- Always output the verse -->
+    <xsl:choose>
+ 	  <xsl:when test="$VLine = 'true'">
+        <div class="l"><a name="{@osisID}"><xsl:call-template name="versenum"/></a><xsl:apply-templates mode="jesus"/></div>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:call-template name="versenum"/><xsl:apply-templates mode="jesus"/>
+        <!-- Follow the verse with an extra space -->
+        <!-- when they don't start on lines to themselves -->
+        <xsl:text> </xsl:text>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="verse" mode="print-notes">
+    <xsl:if test=".//note[not(@type) or not(@type = 'x-strongsMarkup')]">
+      <xsl:variable name="passage" select="jsword:getValidKey($keyf, @osisID)"/>
+      <a href="#{substring-before(concat(@osisID, ' '), ' ')}">
+        <xsl:value-of select="jsword:getName($passage)"/>
+      </a>
+      <xsl:apply-templates select=".//note" mode="print-notes" />
+      <div><xsl:text>&#160;</xsl:text></div>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template name="versenum">
+    <!-- Are verse numbers wanted? -->
+    <xsl:if test="$NoVNum = 'false'">
+      <!-- An osisID can be a space separated list of them -->
+      <xsl:variable name="firstOsisID" select="substring-before(concat(@osisID, ' '), ' ')"/>
+      <xsl:variable name="book" select="substring-before($firstOsisID, '.')"/>
+      <xsl:variable name="chapter" select="substring-before(substring-after($firstOsisID, '.'), '.')"/>
+      <!-- If n is present use it for the number -->
+      <xsl:variable name="verse">
+        <xsl:choose>
+          <xsl:when test="@n">
+            <xsl:value-of select="@n"/>
+          </xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="substring-after(substring-after($firstOsisID, '.'), '.')"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:variable name="versenum">
+        <xsl:choose>
+          <xsl:when test="$BCVNum = 'true'">
+          	<xsl:value-of select="concat($book, '&#160;', $chapter, ':', $verse)"/>
+          </xsl:when>
+          <xsl:when test="$CVNum = 'true'">
+          	<xsl:value-of select="concat($chapter, ':', $verse)"/>
+          </xsl:when>
+          <xsl:otherwise>
+          	<xsl:value-of select="$verse"/>
+          </xsl:otherwise>
+        </xsl:choose>
+      </xsl:variable>
+      <xsl:choose>
+        <xsl:when test="$TinyVNum = 'true' and $Notes = 'true'">
+      	  <a name="{@osisID}"><sup class="verse"><xsl:value-of select="$versenum"/></sup></a>
+      	</xsl:when>
+        <xsl:when test="$TinyVNum = 'true' and $Notes = 'false'">
+      	  <sup class="verse"><xsl:value-of select="$versenum"/></sup>
+      	</xsl:when>
+        <xsl:when test="$TinyVNum = 'false' and $Notes = 'true'">
+      	  <a name="{@osisID}">(<xsl:value-of select="$versenum"/>)</a>
+      	  <xsl:text> </xsl:text>
+      	</xsl:when>
+      	<xsl:otherwise>
+      	  (<xsl:value-of select="$versenum"/>)
+      	  <xsl:text> </xsl:text>
+      	</xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+    <xsl:if test="$VNum = 'false' and $Notes = 'true'">
+      <a name="{@osisID}"></a>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="a">
+    <a href="{@href}"><xsl:apply-templates/></a>
+  </xsl:template>
+
+  <xsl:template match="a" mode="jesus">
+    <a href="{@href}"><xsl:apply-templates mode="jesus"/></a>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <!-- When we encounter a note, we merely output a link to the note. -->
+  <xsl:template match="note[@type = 'x-strongsMarkup']"/>
+  <xsl:template match="note[@type = 'x-strongsMarkup']" mode="jesus"/>
+  <xsl:template match="note[@type = 'x-strongsMarkup']" mode="print-notes"/>
+
+  <xsl:template match="note">
+    <xsl:if test="$Notes = 'true'">
+      <!-- If there is a following sibling that is a note, emit a separator -->
+      <xsl:variable name="siblings" select="../child::node()"/>
+      <xsl:variable name="next-position" select="position() + 1"/>
+      <xsl:choose>
+        <xsl:when test="name($siblings[$next-position]) = 'note'">
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
+        </xsl:when>
+        <xsl:otherwise>
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="note" mode="jesus">
+    <xsl:if test="$Notes = 'true'">
+     <!-- If there is a following sibling that is a note, emit a separator -->
+      <xsl:variable name="siblings" select="../child::node()"/>
+      <xsl:variable name="next-position" select="position() + 1"/>
+      <xsl:choose>
+        <xsl:when test="$siblings[$next-position] and name($siblings[$next-position]) = 'note'">
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a>, </sup>
+        </xsl:when>
+        <xsl:otherwise>
+          <sup class="note"><a href="#note-{generate-id(.)}"><xsl:call-template name="generateNoteXref"/></a></sup>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="note" mode="print-notes">
+    <div class="margin">
+      <strong><xsl:call-template name="generateNoteXref"/></strong>
+      <a name="note-{generate-id(.)}">
+        <xsl:text> </xsl:text>
+      </a>
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+
+  <!--
+    == If the n attribute is present then use that for the cross ref otherwise create a letter.
+    == Note: numbering restarts with each verse.
+    -->
+  <xsl:template name="generateNoteXref">
+  	<xsl:choose>
+  	  <xsl:when test="@n">
+  	    <xsl:value-of select="@n"/>
+  	  </xsl:when>
+  	  <xsl:otherwise>
+  	    <xsl:number level="any" from="/osis//verse" format="a"/>
+  	  </xsl:otherwise>
+  	</xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="p">
+    <p><xsl:apply-templates/></p>
+  </xsl:template>
+  
+  <xsl:template match="p" mode="jesus">
+    <p><xsl:apply-templates mode="jesus"/></p>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="p" mode="print-notes">
+    <!-- FIXME: This ignores text in the note. -->
+    <!-- don't put para's in notes -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="w">
+    <!-- Output the content followed by all the lemmas and then all the morphs. -->
+    <xsl:apply-templates/>
+    <xsl:if test="$Strongs = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
+      <xsl:call-template name="lemma">
+        <xsl:with-param name="lemma" select="@lemma"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
+      <xsl:call-template name="morph">
+        <xsl:with-param name="morph" select="@morph"/>
+      </xsl:call-template>
+    </xsl:if>
+    <!--
+        except when followed by a text node or non-printing node.
+        This is true whether the href is output or not.
+    -->
+    <xsl:variable name="siblings" select="../child::node()"/>
+    <xsl:variable name="next-position" select="position() + 1"/>
+    <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
+      <xsl:text> </xsl:text>
+    </xsl:if>
+  </xsl:template>
+  
+  <xsl:template match="w" mode="jesus">
+    <!-- Output the content followed by all the lemmas and then all the morphs. -->
+    <xsl:apply-templates mode="jesus"/>
+    <xsl:if test="$Strongs = 'true' and (starts-with(@lemma, 'x-Strongs:') or starts-with(@lemma, 'strong:'))">
+      <xsl:call-template name="lemma">
+        <xsl:with-param name="lemma" select="@lemma"/>
+      </xsl:call-template>
+    </xsl:if>
+    <xsl:if test="$Morph = 'true' and (starts-with(@morph, 'x-Robinson:') or starts-with(@morph, 'robinson:'))">
+      <xsl:call-template name="morph">
+        <xsl:with-param name="morph" select="@morph"/>
+      </xsl:call-template>
+    </xsl:if>
+    <!--
+        except when followed by a text node or non-printing node.
+        This is true whether the href is output or not.
+    -->
+    <xsl:variable name="siblings" select="../child::node()"/>
+    <xsl:variable name="next-position" select="position() + 1"/>
+    <xsl:if test="$siblings[$next-position] and name($siblings[$next-position]) != ''">
+      <xsl:text> </xsl:text>
+    </xsl:if>
+  </xsl:template>
+  
+  <xsl:template name="lemma">
+    <xsl:param name="lemma"/>
+    <xsl:param name="part" select="0"/>
+    <xsl:variable name="orig-lemma" select="substring-after($lemma, ':')"/>
+    <xsl:variable name="protocol">
+      <xsl:choose>
+        <xsl:when test="substring($orig-lemma, 1, 1) = 'H'">
+          <xsl:value-of select="$hebrew.def.protocol"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$greek.def.protocol"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="separator">
+      <xsl:choose>
+        <xsl:when test="contains($orig-lemma, '|')">
+          <xsl:value-of select="'|'"/>
+        </xsl:when>
+        <xsl:when test="contains($orig-lemma, ' ')">
+          <xsl:value-of select="' '"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="sub">
+      <xsl:choose>
+        <xsl:when test="$separator != '' and $part = '0'">
+          <xsl:value-of select="$part + 1"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$part"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$separator = ''">
+        <sub class="strongs"><a href="{$protocol}{$orig-lemma}">S<xsl:number level="any" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a></sub>
+      </xsl:when>
+      <xsl:otherwise>
+        <sub class="strongs"><a href="{$protocol}{substring-before($orig-lemma, $separator)}">S<xsl:number level="single" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a>, </sub>
+        <xsl:call-template name="lemma">
+          <xsl:with-param name="lemma" select="substring-after($lemma, $separator)"/>
+          <xsl:with-param name="part">
+            <xsl:choose>
+              <xsl:when test="$sub">
+                <xsl:value-of select="$sub + 1"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="1"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:with-param>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template name="morph">
+    <xsl:param name="morph"/>
+    <xsl:param name="part" select="0"/>
+    <xsl:variable name="orig-work" select="substring-before($morph, ':')"/>
+    <xsl:variable name="orig-morph" select="substring-after($morph, ':')"/>
+    <xsl:variable name="protocol">
+      <xsl:choose>
+        <xsl:when test="starts-with($orig-work, 'x-Robinson') or starts-with($orig-work, 'robinson')">
+          <xsl:value-of select="$greek.morph.protocol"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$hebrew.morph.protocol"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="separator">
+      <xsl:choose>
+        <xsl:when test="contains($orig-morph, '|')">
+          <xsl:value-of select="'|'"/>
+        </xsl:when>
+        <xsl:when test="contains($orig-morph, ' ')">
+          <xsl:value-of select="' '"/>
+        </xsl:when>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="sub">
+      <xsl:choose>
+        <xsl:when test="$separator != '' and $part = '0'">
+          <xsl:value-of select="$part + 1"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="$part"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$separator = ''">
+        <sub class="morph"><a href="{$protocol}{$orig-morph}">M<xsl:number level="any" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a></sub>
+      </xsl:when>
+      <xsl:otherwise>
+        <sub class="morph"><a href="{$protocol}{substring-before($orig-morph, $separator)}">M<xsl:number level="single" from="/osis//verse" format="1"/><xsl:number value="$sub" format="a"/></a>, </sub>
+        <xsl:call-template name="morph">
+          <xsl:with-param name="morph" select="substring-after($morph, $separator)"/>
+          <xsl:with-param name="part">
+            <xsl:choose>
+              <xsl:when test="$sub">
+                <xsl:value-of select="$sub + 1"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="1"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:with-param>
+        </xsl:call-template>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="seg">
+    <xsl:choose>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates/></font>
+      </xsl:when>
+      <xsl:when test="@type = 'x-variant'">
+        <xsl:if test="@subType = 'x-class:1'">
+          <xsl:apply-templates/>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="seg" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="starts-with(@type, 'color:')">
+        <font color="{substring-before(substring-after(@type, 'color: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
+      </xsl:when>
+      <xsl:when test="starts-with(@type, 'font-size:')">
+        <font size="{substring-before(substring-after(@type, 'font-size: '), ';')}"><xsl:apply-templates mode="jesus"/></font>
+      </xsl:when>
+      <xsl:when test="@type = 'x-variant'">
+        <xsl:if test="@subType = 'x-class:1'">
+          <xsl:apply-templates mode="jesus"/>
+        </xsl:if>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="jesus"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="abbr">
+    <abbr class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </abbr>
+  </xsl:template>
+
+  <xsl:template match="abbr" mode="jesus">
+    <abbr class="abbr">
+      <xsl:if test="@expansion">
+        <xsl:attribute name="title">
+          <xsl:value-of select="@expansion"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates mode="jesus"/>
+    </abbr>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="speaker[@who = 'Jesus']">
+    <font class="jesus"><xsl:apply-templates mode="jesus"/></font>
+  </xsl:template>
+
+  <xsl:template match="speaker">
+    <font class="speech"><xsl:apply-templates/></font>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']">
+  <!-- Done by a line in [verse]
+    <h3 class="heading">
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <xsl:template match="title[@subType ='x-preverse' or @subtype = 'x-preverse']" mode="jesus">
+  <!-- Done by a line in [verse]
+    <h3 class="heading">
+      <xsl:apply-templates/>
+    </h3>
+  -->
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title[@level]">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <xsl:choose>
+        <xsl:when test="@level = '1'">
+          <h1 class="level"><xsl:apply-templates/></h1>
+        </xsl:when>
+        <xsl:when test="@level = '2'">
+          <h2 class="level"><xsl:apply-templates/></h2>
+        </xsl:when>
+        <xsl:when test="@level = '3'">
+          <h3 class="level"><xsl:apply-templates/></h3>
+        </xsl:when>
+        <xsl:when test="@level = '4'">
+          <h4 class="level"><xsl:apply-templates/></h4>
+        </xsl:when>
+        <xsl:when test="@level = '5'">
+          <h5 class="level"><xsl:apply-templates/></h5>
+        </xsl:when>
+        <xsl:otherwise>
+          <h6 class="level"><xsl:apply-templates/></h6>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="title[@level]" mode="jesus">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <xsl:choose>
+        <xsl:when test="@level = '1'">
+          <h1 class="level"><xsl:apply-templates/></h1>
+        </xsl:when>
+        <xsl:when test="@level = '2'">
+          <h2 class="level"><xsl:apply-templates/></h2>
+        </xsl:when>
+        <xsl:when test="@level = '3'">
+          <h3 class="level"><xsl:apply-templates/></h3>
+        </xsl:when>
+        <xsl:when test="@level = '4'">
+          <h4 class="level"><xsl:apply-templates/></h4>
+        </xsl:when>
+        <xsl:when test="@level = '5'">
+          <h5 class="level"><xsl:apply-templates/></h5>
+        </xsl:when>
+        <xsl:otherwise>
+          <h6 class="level"><xsl:apply-templates/></h6>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="title">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <h2 class="heading"><xsl:apply-templates/></h2>
+    </xsl:if>
+  </xsl:template>
+
+  <xsl:template match="title" mode="jesus">
+    <!-- Always show canonical titles or if headings is turned on -->
+    <xsl:if test="@canonical = 'true' or $Headings = 'true'">
+      <h2 class="heading"><xsl:apply-templates/></h2>
+    </xsl:if>
+  </xsl:template>
+
+  <!--=======================================================================-->
+  <xsl:template match="reference">
+    <xsl:choose>
+      <xsl:when test="$XRef = 'true'">
+        <a href="bible://{@osisRef}"><xsl:apply-templates/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="reference" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="$XRef = 'true'">
+        <a href="bible://{@osisRef}"><xsl:apply-templates mode="jesus"/></a>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:apply-templates mode="jesus"/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!--=======================================================================-->
+  <xsl:template match="caption">
+    <div class="caption"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="caption" mode="jesus">
+    <div class="caption"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="catchWord">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="catchWord" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <!--
+      <cell> is handled shortly after <table> below and thus does not appear
+      here.
+  -->
+  
+  <xsl:template match="closer">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="closer" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <xsl:template match="date">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="date" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <xsl:template match="divineName">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+  
+  <xsl:template match="divineName" mode="jesus">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+  
+  <xsl:template match="figure">
+    <div class="figure">
+      <xsl:choose>
+        <xsl:when test="starts-with(@src, '/')">
+          <img src="{concat($baseURL, @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:when>
+        <xsl:otherwise>
+          <img src="{concat($baseURL, '/',  @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="figure" mode="jesus">
+    <div class="figure">
+      <xsl:choose>
+        <xsl:when test="starts-with(@src, '/')">
+          <img src="{concat($baseURL, @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:when>
+        <xsl:otherwise>
+          <img src="{concat($baseURL, '/',  @src)}"/>   <!-- FIXME: Not necessarily an image... -->
+        </xsl:otherwise>
+      </xsl:choose>
+      <xsl:apply-templates mode="jesus"/>
+    </div>
+  </xsl:template>
+  
+  <xsl:template match="foreign">
+    <em class="foreign"><xsl:apply-templates/></em>
+  </xsl:template>
+  
+  <xsl:template match="foreign" mode="jesus">
+    <em class="foreign"><xsl:apply-templates mode="jesus"/></em>
+  </xsl:template>
+  
+  <!-- This is a subheading. -->
+  <xsl:template match="head//head">
+    <h5 class="head"><xsl:apply-templates/></h5>
+  </xsl:template>
+  
+  <!-- This is a top-level heading. -->
+  <xsl:template match="head">
+    <h4 class="head"><xsl:apply-templates/></h4>
+  </xsl:template>
+  
+  <xsl:template match="index">
+    <a name="index{@id}" class="index"/>
+  </xsl:template>
+
+  <xsl:template match="inscription">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+
+  <xsl:template match="inscription" mode="jesus">
+    <xsl:apply-templates mode="small-caps"/>
+  </xsl:template>
+
+  <xsl:template match="item">
+    <li class="item"><xsl:apply-templates/></li>
+  </xsl:template>
+
+  <xsl:template match="item" mode="jesus">
+    <li class="item"><xsl:apply-templates mode="jesus"/></li>
+  </xsl:template>
+  
+  <!--
+      <item> and <label> are covered by <list> below and so do not appear here.
+  -->
+
+  <xsl:template match="lg">
+    <div class="lg"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="lg" mode="jesus">
+    <div class="lg"><xsl:apply-templates mode="jesus"/></div>
+  </xsl:template>
+  
+  <xsl:template match="lg[@sID or @eID]"/>
+  <xsl:template match="lg[@sID or @eID]" mode="jesus"/>
+
+  <xsl:template match="l[@sID]"/>
+  <xsl:template match="l[@sID]" mode="jesus"/>
+
+  <xsl:template match="l[@eID]"><br/></xsl:template>
+  <xsl:template match="l[@eID]" mode="jesus"><br/></xsl:template>
+
+  <xsl:template match="l">
+    <xsl:apply-templates/><br/>
+  </xsl:template>
+  
+  <xsl:template match="l" mode="jesus">
+    <xsl:apply-templates mode="jesus"/><br/>
+  </xsl:template>
+
+  <!-- While a BR is a break, if it is immediately followed by punctuation,
+       indenting this rule can introduce whitespace.
+    -->
+  <xsl:template match="lb"><br/></xsl:template>
+  <xsl:template match="lb" mode="jesus"><br/></xsl:template>
+
+  <xsl:template match="list">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label"><xsl:apply-templates/></dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item"><xsl:apply-templates/></dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper"><xsl:apply-templates select="."/></dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item"><xsl:apply-templates/></li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper"><xsl:apply-templates select="."/></li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+
+  <xsl:template match="list" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="label">
+        <!-- If there are <label>s in the list, it's a <dl>. -->
+        <dl class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::label">
+                <dt class="label"><xsl:apply-templates mode="jesus"/></dt>
+              </xsl:when>
+              <xsl:when test="self::item">
+                <dd class="item"><xsl:apply-templates mode="jesus"/></dd>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <dd class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></dd>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates mode="jesus"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </dl>
+      </xsl:when>
+
+      <xsl:otherwise>
+        <!-- If there are no <label>s in the list, it's a plain old <ul>. -->
+        <ul class="list">
+          <xsl:for-each select="node()">
+            <xsl:choose>
+              <xsl:when test="self::item">
+                <li class="item"><xsl:apply-templates mode="jesus"/></li>
+              </xsl:when>
+              <xsl:when test="self::list">
+                <li class="list-wrapper"><xsl:apply-templates select="." mode="jesus"/></li>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:apply-templates mode="jesus"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:for-each>
+        </ul>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="mentioned">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+  <xsl:template match="mentioned" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+  
+  <!-- Milestones represent characteristics of the original manuscript.
+    == that are being preserved. For this reason, most are ignored.
+    ==
+    == The defined types are:
+    == column   Marks the end of a column where there is a multi-column display.
+    == footer   Marks the footer region of a page.
+    == halfLine Used to mark half-line units if not otherwise encoded.
+    == header   Marks the header region of a page.
+    == line     Marks line breaks, particularly important in recording appearance of an original text, such as a manuscript.
+    == pb       Marks a page break in a text.
+    == screen   Marks a preferred place for breaks in an on-screen rendering of the text.
+    == cQuote   Marks the location of a continuation quote mark, with marker containing the publishers mark.
+    -->
+  <!--  This is used by the KJV for paragraph markers. -->
+  <xsl:template match="milestone[@type = 'x-p']"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
+  <xsl:template match="milestone[@type = 'x-p']" mode="jesus"><xsl:text> </xsl:text><xsl:value-of select="@marker"/><xsl:text> </xsl:text></xsl:template>
+
+  <xsl:template match="milestone[@type = 'cQuote']">
+    <xsl:value-of select="@marker"/>
+  </xsl:template>
+
+  <xsl:template match="milestone[@type = 'cQuote']" mode="jesus">
+    <xsl:value-of select="@marker"/>
+  </xsl:template>
+
+  <xsl:template match="milestone[@type = 'line']"><br/></xsl:template>
+
+  <xsl:template match="milestone[@type = 'line']" mode="jesus"><br/></xsl:template>
+
+  <!--
+    == Milestone start and end are deprecated.
+    == At this point we expect them to not be in the document.
+    == These have been replace with milestoneable elements.
+    -->
+  <xsl:template match="milestoneStart"/>
+  <xsl:template match="milestoneEnd"/>
+  
+  <xsl:template match="name">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="name" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!-- If there is a milestoned q then just output a quotation mark -->
+  <xsl:template match="q[@sID or @eID]">
+    <xsl:choose>
+      <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
+      <!-- The chosen mark should be based on the work's author's locale. -->
+      <xsl:otherwise>"</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@sID or @eID]" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="@marker"><xsl:value-of select="@marker"/></xsl:when>
+      <!-- The chosen mark should be based on the work's author's locale. -->
+      <xsl:otherwise>"</xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@who = 'Jesus']">
+    <font class="jesus"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></font>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'blockquote']">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'blockquote']" mode="jesus">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'citation']">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'citation']" mode="jesus">
+    <blockquote class="q"><xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/></blockquote>
+  </xsl:template>
+
+  <xsl:template match="q[@type = 'embedded']">
+    <xsl:choose>
+      <xsl:when test="@marker">
+        <xsl:value-of select="@marker"/><xsl:apply-templates/><xsl:value-of select="@marker"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <quote class="q"><xsl:apply-templates/></quote>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <xsl:template match="q[@type = 'embedded']" mode="jesus">
+    <xsl:choose>
+      <xsl:when test="@marker">
+      <xsl:value-of select="@marker"/><xsl:apply-templates mode="jesus"/><xsl:value-of select="@marker"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <quote class="q"><xsl:apply-templates/></quote>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+  
+  <!-- An alternate reading. -->
+  <xsl:template match="rdg">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+   <xsl:template match="rdg" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <!--
+      <row> is handled near <table> below and so does not appear here.
+  -->
+  
+  <xsl:template match="salute">
+    <xsl:apply-templates/>
+  </xsl:template>
+  
+ <!-- Avoid adding whitespace -->
+  <xsl:template match="salute" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <xsl:template match="signed">
+    <xsl:apply-templates/>
+  </xsl:template>
+
+  <xsl:template match="signed" mode="jesus">
+    <xsl:apply-templates mode="jesus"/>
+  </xsl:template>
+
+  <xsl:template match="speech">
+    <div class="speech"><xsl:apply-templates/></div>
+  </xsl:template>
+  
+  <xsl:template match="speech" mode="jesus">
+    <div class="speech"><xsl:apply-templates mode="jesus"/></div>
+  </xsl:template>
+
+  <xsl:template match="table">
+    <table class="table">
+      <xsl:copy-of select="@rows|@cols"/>
+      <xsl:if test="head">
+        <thead class="head"><xsl:apply-templates select="head"/></thead>
+      </xsl:if>
+      <tbody><xsl:apply-templates select="row"/></tbody>
+    </table>
+  </xsl:template>
+
+  <xsl:template match="row">
+    <tr class="row"><xsl:apply-templates/></tr>
+  </xsl:template>
+  
+  <xsl:template match="cell">
+    <xsl:variable name="element-name">
+      <xsl:choose>
+        <xsl:when test="@role = 'label'">
+          <xsl:text>th</xsl:text>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:text>td</xsl:text>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="cell-direction">
+      <xsl:if test="@xml:lang">
+        <xsl:call-template name="getDirection">
+         <xsl:with-param name="lang"><xsl:value-of select="@xml:lang"/></xsl:with-param>
+        </xsl:call-template>
+      </xsl:if>
+    </xsl:variable>
+    <xsl:element name="{$element-name}">
+      <xsl:attribute name="class">cell</xsl:attribute>
+      <xsl:attribute name="valign">top</xsl:attribute>
+      <xsl:if test="@xml:lang">
+        <xsl:attribute name="dir">
+          <xsl:value-of select="$cell-direction"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="$cell-direction = 'rtl'">
+        <xsl:attribute name="align">
+          <xsl:value-of select="'right'"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@rows">
+        <xsl:attribute name="rowspan">
+          <xsl:value-of select="@rows"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:if test="@cols">
+        <xsl:attribute name="colspan">
+          <xsl:value-of select="@cols"/>
+        </xsl:attribute>
+      </xsl:if>
+      <xsl:apply-templates/>
+    </xsl:element>
+  </xsl:template>
+
+  <xsl:template match="transChange">
+    <em><xsl:apply-templates/></em>
+  </xsl:template>
+  <xsl:template match="transChange" mode="jesus">
+    <em><xsl:apply-templates/></em>
+  </xsl:template>
+  
+  
+  <xsl:template match="hi">
+      <xsl:choose>
+        <xsl:when test="@type = 'acrostic'">
+          <xsl:apply-templates/>
+        </xsl:when>
+        <xsl:when test="@type = 'bold'">
+          <strong><xsl:apply-templates/></strong>
+        </xsl:when>
+        <xsl:when test="@type = 'emphasis'">
+          <em><xsl:apply-templates/></em>
+        </xsl:when>
+        <xsl:when test="@type = 'illuminated'">
+          <strong><em><xsl:apply-templates/></em></strong>
+        </xsl:when>
+        <xsl:when test="@type = 'italic'">
+          <em><xsl:apply-templates/></em>
+        </xsl:when>
+        <xsl:when test="@type = 'line-through'">
+          <font class="strike"><xsl:apply-templates/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'normal'">
+          <font class="normal"><xsl:apply-templates/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'small-caps'">
+          <font class="small-caps"><xsl:apply-templates/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'sub'">
+          <sub><xsl:apply-templates/></sub>
+        </xsl:when>
+        <xsl:when test="@type = 'super'">
+          <sup><xsl:apply-templates/></sup>
+        </xsl:when>
+        <xsl:when test="@type = 'underline'">
+          <u><xsl:apply-templates/></u>
+        </xsl:when>
+        <xsl:when test="@type = 'x-caps'">
+          <font class="caps"><xsl:apply-templates/></font>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates/>
+        </xsl:otherwise>
+      </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="hi" mode="jesus">
+      <xsl:choose>
+        <xsl:when test="@type = 'acrostic'">
+          <xsl:apply-templates mode="jesus"/>
+        </xsl:when>
+        <xsl:when test="@type = 'bold'">
+          <strong><xsl:apply-templates mode="jesus"/></strong>
+        </xsl:when>
+        <xsl:when test="@type = 'emphasis'">
+          <em><xsl:apply-templates mode="jesus"/></em>
+        </xsl:when>
+        <xsl:when test="@type = 'illuminated'">
+          <strong><em><xsl:apply-templates mode="jesus"/></em></strong>
+        </xsl:when>
+        <xsl:when test="@type = 'italic'">
+          <em><xsl:apply-templates mode="jesus"/></em>
+        </xsl:when>
+        <xsl:when test="@type = 'line-through'">
+          <font class="strike"><xsl:apply-templates mode="jesus"/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'normal'">
+          <font class="normal"><xsl:apply-templates mode="jesus"/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'small-caps'">
+          <font class="small-caps"><xsl:apply-templates mode="small-caps"/></font>
+        </xsl:when>
+        <xsl:when test="@type = 'sub'">
+          <sub><xsl:apply-templates mode="jesus"/></sub>
+        </xsl:when>
+        <xsl:when test="@type = 'super'">
+          <sup><xsl:apply-templates mode="jesus"/></sup>
+        </xsl:when>
+        <xsl:when test="@type = 'underline'">
+          <u><xsl:apply-templates mode="jesus"/></u>
+        </xsl:when>
+        <xsl:when test="@type = 'x-caps'">
+          <font class="caps"><xsl:apply-templates mode="jesus"/></font>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:apply-templates/>
+        </xsl:otherwise>
+      </xsl:choose>
+  </xsl:template>
+
+  <xsl:template match="text()" mode="small-caps">
+  <xsl:value-of select="translate(., 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
+  </xsl:template>
+
+  <!--
+    Generate a css or an inline style representation of a font spec.
+    The fontspec that is passed in is in one of two forms:
+    FamilyName-STYLE-size, where STYLE is either PLAIN, BOLD, ITALIC or BOLDITALIC
+    or
+    FamilyName,style,size, where STYLE is 0 for PLAIN, 1 for BOLD, 2 for ITALIC or 3 for BOLDITALIC.
+
+    The style attribute is css for a css style specification or anything else for an inline style one.
+  -->
+  <xsl:template name="generateFontStyle">
+    <xsl:param name="fontspec"/>
+    <xsl:param name="style"/>
+    <xsl:variable name="fontSeparator">
+      <xsl:choose>
+        <xsl:when test="contains($fontspec, ',')">
+          <xsl:value-of select="','"/>
+        </xsl:when>
+        <xsl:otherwise>
+          <xsl:value-of select="'-'"/>
+        </xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="aFont">
+      <xsl:choose>
+        <xsl:when test="substring-before($fontspec, $fontSeparator) = ''"><xsl:value-of select="$fontspec"/>,0,16</xsl:when>
+        <xsl:otherwise><xsl:value-of select="$fontspec"/></xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fontfamily" select="substring-before($aFont, $fontSeparator)" />
+    <xsl:variable name="fontsize" select="substring-after(substring-after($aFont, $fontSeparator), $fontSeparator)" />
+    <xsl:variable name="styling" select="substring-before(substring-after($aFont, $fontSeparator), $fontSeparator)" />
+    <xsl:variable name="fontweight">
+      <xsl:choose>
+        <xsl:when test="$styling = '1' or $styling = '3' or contains($styling, 'bold')">bold</xsl:when>
+        <xsl:otherwise>normal</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:variable name="fontstyle">
+      <xsl:choose>
+        <xsl:when test="$styling = '2' or $styling = '3' or contains($styling, 'italic')">italic</xsl:when>
+        <xsl:otherwise>normal</xsl:otherwise>
+      </xsl:choose>
+    </xsl:variable>
+    <xsl:choose>
+      <xsl:when test="$style = 'css'">
+        <xsl:value-of select='concat("font-family: &apos;", $fontfamily, "&apos;, Serif; ",
+                                     "font-size:   ",       $fontsize,   "pt; ",
+                                     "font-weight: ",       $fontweight, "; ",
+                                     "font-style:  ",       $fontstyle,  ";")'/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select='concat("font-family=&apos;",  $fontfamily, "&apos;, Serif; ",
+                                     "font-size=",          $fontsize,   "pt; ",
+                                     "font-weight=",        $fontweight, "; ",
+                                     "font-style=",         $fontstyle,  "; ")'/>
+      </xsl:otherwise>
+    </xsl:choose>
+  </xsl:template>
+
+  <!--
+    The direction is deduced from the xml:lang attribute and is assumed to be meaningful for those elements.
+    Note: there is a bug that prevents dir=rtl from working.
+    see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4296022 and 4866977
+  -->
+  <xsl:template name="getDirection">
+    <xsl:param name="lang"/>
+    <xsl:choose>
+      <xsl:when test="$lang = 'he' or $lang = 'ar' or $lang = 'fa' or $lang = 'ur' or $lang = 'syr'">
+        <xsl:value-of select="'rtl'"/>
+      </xsl:when>
+      <xsl:otherwise>
+        <xsl:value-of select="'ltr'"/>
+      </xsl:otherwise>
+    </xsl:choose>
+   </xsl:template>
+  
+</xsl:stylesheet>

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/service/ModuleRefDataServiceTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/service/ModuleRefDataServiceTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/client/service/ModuleRefDataServiceTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,22 @@
+package com.tyndalehouse.step.web.client.service;
+
+import org.junit.Test;
+
+import com.tyndalehouse.step.web.client.service.refdata.ModuleName;
+import com.tyndalehouse.step.web.client.service.refdata.ModuleRefData;
+
+/**
+ * Tests the Module Reference Data client side service
+ * 
+ * @author cjburrell
+ * 
+ */
+public class ModuleRefDataServiceTest {
+	@Test
+	public void testModuleHierarchy() {
+		new ModuleName("test module", null);
+		ModuleRefData.getInstance().getListOfModules("Module");
+
+		// Assert.assertTrue(modules.contains(module.getModuleName()));
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/StepQueryRunnerImplTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/StepQueryRunnerImplTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/StepQueryRunnerImplTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,83 @@
+package com.tyndalehouse.step.web.server.db;
+
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.commons.logging.Log;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunnerImpl;
+import com.tyndalehouse.step.web.server.db.framework.UnableToRunQueryException;
+import com.tyndalehouse.step.web.server.db.helper.TestProcessor;
+
+/**
+ * Tests the StepQueryRunner framework
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at RunWith(JMock.class)
+public class StepQueryRunnerImplTest {
+
+	/** the mock object */
+	private final Mockery context = new Mockery();
+
+	/** tests running a query */
+	@Test
+	public void testRunQuery() throws UnableToRunQueryException {
+		// set up the test
+		final TestProcessor processor = new TestProcessor();
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final StepQueryRunnerImpl impl = new StepQueryRunnerImpl(log);
+
+		// Take an example ResultSet
+
+		final List<String> events = impl.run(processor);
+		Assert.assertNotNull(events);
+		Assert.assertEquals("Bantu expansion from Cameroon to Central Africa", events.get(0));
+		Assert.assertEquals("Events in Africa", events.get(1));
+
+//		TODO: Db Date has changed. this needs investigation		
+//		Assert.assertEquals("First date on the Mayan Long Count calendar", events.get(2));
+	}
+
+	/**
+	 * tests and expects a exception to be returned
+	 * 
+	 * @throws UnableToRunQueryException the query expected to be return on
+	 *             invalid query passed in
+	 */
+	@Test(expected = UnableToRunQueryException.class)
+	public void testRunQueryWithNull() throws UnableToRunQueryException {
+		// set up the test
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				allowing(log).debug(with(any(String.class)));
+				allowing(log).trace(with(any(String.class)));
+				allowing(log).info(with(any(String.class)));
+				allowing(log).isDebugEnabled();
+				allowing(log).isTraceEnabled();
+				allowing(log).isInfoEnabled();
+				allowing(log).isErrorEnabled();
+				atLeast(1).of(log).error(with(any(String.class)));
+			}
+		});
+
+		final StepQueryRunnerImpl impl = new StepQueryRunnerImpl(log);
+		impl.run(null);
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestProcessor.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestProcessor.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestProcessor.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,52 @@
+package com.tyndalehouse.step.web.server.db.helper;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.tyndalehouse.step.web.server.common.ConfigNotLoadedException;
+import com.tyndalehouse.step.web.server.db.framework.MalformedStepQueryException;
+import com.tyndalehouse.step.web.server.db.framework.Query;
+import com.tyndalehouse.step.web.server.db.framework.ResultSetProcessor;
+
+/**
+ * Test processor, to test the retrieval of data from the database
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class TestProcessor implements ResultSetProcessor<String> {
+	/**
+	 * simple constructor
+	 */
+	public TestProcessor() {
+
+	}
+
+
+	public Map<String, Object> getParameters() {
+		final Map<String, Object> params = new HashMap<String, Object>();
+		params.put("event_name", "Events in Africa");
+		params.put("event_id", 2);
+		final long l = -160321161544388L;
+		params.put("date_of_event", l);
+		return params;
+	}
+
+	public Query getQuery() {
+		return TestQueryImpl.TEST_QUERY_PARAMS_DIFFERENT_TYPES;
+	}
+
+	public List<String> process(final ResultSet rs) throws MalformedStepQueryException,
+		ConfigNotLoadedException, SQLException {
+		final List<String> events = new ArrayList<String>();
+
+		while (rs.next()) {
+			events.add(rs.getString("name"));
+		}
+		return events;
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestQueryImpl.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestQueryImpl.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/db/helper/TestQueryImpl.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,28 @@
+package com.tyndalehouse.step.web.server.db.helper;
+
+import com.tyndalehouse.step.web.server.db.framework.Query;
+
+public enum TestQueryImpl implements Query {
+	/** a test query */
+	TEST_QUERY_PARAMS_DIFFERENT_TYPES("tests");
+
+	/**
+	 * component, directory of the test queries
+	 */
+	private final String component;
+
+	/**
+	 * creates the enum
+	 * 
+	 * @param component given a component/directory where the test sql script
+	 *            lives
+	 */
+	TestQueryImpl(final String component) {
+		this.component = component;
+	}
+
+
+	public String getComponent() {
+		return component;
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetCurrentBibleTextHandlerTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetCurrentBibleTextHandlerTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetCurrentBibleTextHandlerTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,138 @@
+package com.tyndalehouse.step.web.server.handlers;
+
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.tyndalehouse.step.web.server.handler.GetCurrentBibleTextHandler;
+import com.tyndalehouse.step.web.shared.command.GetCurrentBibleTextCommand;
+import com.tyndalehouse.step.web.shared.common.scripturelookup.BibleTextLookupType;
+import com.tyndalehouse.step.web.shared.result.GetCurrentBibleTextResult;
+
+/**
+ * Tests the handler that retrieves scripture from the server
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at RunWith(JMock.class)
+public class GetCurrentBibleTextHandlerTest {
+	/**
+	 * The standard context for mocking objects
+	 */
+	private final Mockery context = new Mockery();
+
+	/**
+	 * tests a greek reverse interlinear
+	 * 
+	 * @throws ActionException exception during test
+	 **/
+	@Test
+	public void testGreekReverseInterlinear() throws ActionException {
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final GetCurrentBibleTextCommand cmd = new GetCurrentBibleTextCommand("KJV", "acts 1:1");
+		cmd.setTypeOfLookup(BibleTextLookupType.REVERSE_INTERLINEAR);
+
+		final GetCurrentBibleTextHandler handler = new GetCurrentBibleTextHandler();
+		final GetCurrentBibleTextResult result = handler.execute(cmd, null);
+
+		Assert.assertNotNull(result.getPassage());
+		Assert.assertNotNull(result.getPassage().getVerseContent());
+		Assert.assertTrue(result.getPassage().getVerseContent().size() != 0);
+
+		// TODO: add interlinear specific stuff
+
+	}
+
+	/**
+	 * tests hebrew reverse interlinear
+	 * 
+	 * @throws ActionException an exception during execution
+	 */
+	@Test
+	public void testHebrewReverseInterlinear() throws ActionException {
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final GetCurrentBibleTextCommand cmd = new GetCurrentBibleTextCommand("KJV", "Gen 1:1");
+		cmd.setTypeOfLookup(BibleTextLookupType.REVERSE_INTERLINEAR);
+
+		final GetCurrentBibleTextHandler handler = new GetCurrentBibleTextHandler();
+		final GetCurrentBibleTextResult result = handler.execute(cmd, null);
+
+		Assert.assertNotNull(result.getPassage());
+		Assert.assertNotNull(result.getPassage().getVerseContent());
+		Assert.assertTrue(result.getPassage().getVerseContent().size() != 0);
+
+		// TODO: add interlinear specific stuff
+
+	}
+
+	/**
+	 * tests a logical lookup of the passage, as opposed to plain text
+	 * 
+	 * @throws ActionException exception during running
+	 */
+	@Test
+	public void testLogicalPassage() throws ActionException {
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final GetCurrentBibleTextCommand cmd = new GetCurrentBibleTextCommand("ESV", "Gen 1:1");
+		cmd.setTypeOfLookup(BibleTextLookupType.LOGICAL);
+
+		final GetCurrentBibleTextHandler handler = new GetCurrentBibleTextHandler();
+		final GetCurrentBibleTextResult result = handler.execute(cmd, null);
+
+		Assert.assertEquals(result.getPassage().getText(),
+			"In the beginning, God created the heavens and the earth.");
+	}
+
+	/**
+	 * An lookup for plain text
+	 * 
+	 * @throws ActionException exception during the retrieval of the text
+	 */
+	@Test
+	public void testLookupText() throws ActionException {
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final GetCurrentBibleTextCommand cmd = new GetCurrentBibleTextCommand("ESV", "Gen 1:1");
+		cmd.setTypeOfLookup(BibleTextLookupType.PLAIN_TEXT);
+
+		final GetCurrentBibleTextHandler handler = new GetCurrentBibleTextHandler();
+		final GetCurrentBibleTextResult result = handler.execute(cmd, null);
+
+		Assert.assertEquals(result.getPassageText(),
+			"In the beginning, God created the heavens and the earth.");
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetDictionaryDefinitionHandlerTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetDictionaryDefinitionHandlerTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetDictionaryDefinitionHandlerTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,69 @@
+package com.tyndalehouse.step.web.server.handlers;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.Assert;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.tyndalehouse.step.web.server.handler.GetDictionaryDefinitionHandler;
+import com.tyndalehouse.step.web.shared.command.GetDictionaryDefinitionCommand;
+import com.tyndalehouse.step.web.shared.result.GetDictionaryDefinitionResult;
+
+/**
+ * Tests the retrieval of a dictionary definition from a dictionary module
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at RunWith(JMock.class)
+public class GetDictionaryDefinitionHandlerTest {
+
+	/**
+	 * The standard context for mocking objects
+	 */
+	private final Mockery context = new Mockery();
+
+	// TODO: add test to ensure that we have a negative,
+	// what happens when we lookup a reference that doesn't exist
+	// at the moment we get a false positive
+
+	/**
+	 * looks up some text for two references, one greek, one hebrew
+	 * 
+	 * @throws ActionException an exception during execution of the test
+	 */
+	@Test
+	public void testLookupText() throws ActionException {
+		final List<String> lookupReferences = new ArrayList<String>();
+		lookupReferences.add("strong:G00051");
+		lookupReferences.add("strong:H00052");
+
+		final Log log = context.mock(Log.class);
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final GetDictionaryDefinitionCommand cmd = new GetDictionaryDefinitionCommand();
+		cmd.setLookupReference(lookupReferences);
+
+		final GetDictionaryDefinitionHandler handler = new GetDictionaryDefinitionHandler();
+		final GetDictionaryDefinitionResult result = handler.execute(cmd, null);
+
+		Assert.assertTrue(result.getXsltedDefinition().contains(">00051<"));
+		Assert.assertTrue(result.getXsltedDefinition().contains("Abshay"));
+
+		Assert.assertTrue(result.getXsltedDefinition().contains(">00052<"));
+		Assert.assertTrue(result.getXsltedDefinition().contains("a thing ignored"));
+
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetTimelineUISetupHandlerTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetTimelineUISetupHandlerTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/GetTimelineUISetupHandlerTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,60 @@
+package com.tyndalehouse.step.web.server.handlers;
+
+import java.util.ArrayList;
+
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JMock;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.tyndalehouse.step.web.server.db.framework.StepQueryRunner;
+import com.tyndalehouse.step.web.server.handler.GetTimelineUISetupHandler;
+import com.tyndalehouse.step.web.shared.common.timeline.TimelineBean;
+
+/**
+ * Testing the timeline setup handler
+ * 
+ * @author CJBurrell
+ * 
+ */
+ at RunWith(JMock.class)
+public class GetTimelineUISetupHandlerTest {
+
+	/**
+	 * The standard context for mocking objects
+	 */
+	private final Mockery context = new Mockery();
+
+	/**
+	 * looks up
+	 * 
+	 * @throws ActionException an exception during the running
+	 */
+	@Test
+	public void testTimelineUIHandler() throws ActionException {
+		final Log log = context.mock(Log.class);
+
+		context.checking(new Expectations() {
+			{
+				ignoring(log);
+			}
+		});
+
+		final StepQueryRunner runner = context.mock(StepQueryRunner.class);
+		context.checking(new Expectations() {
+			{
+				atMost(1).of(runner);
+				will(returnValue(new ArrayList<TimelineBean>()));
+			}
+		});
+
+		new GetTimelineUISetupHandler(runner).execute(null, null);
+
+		// this test is purely to check we are not calling the database more
+		// than is required.
+	}
+}

Added: trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/JSwordInstallTest.java
===================================================================
--- trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/JSwordInstallTest.java	                        (rev 0)
+++ trunk/step-web-app/src/test/java/com/tyndalehouse/step/web/server/handlers/JSwordInstallTest.java	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,36 @@
+package com.tyndalehouse.step.web.server.handlers;
+
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.junit.Test;
+
+/**
+ * Tests JSword installation handler
+ * 
+ * @author CJBurrell
+ * 
+ */
+public class JSwordInstallTest {
+	/**
+	 * tests the installation of a bible version from JSword/crosswire.org
+	 * 
+	 * @throws ActionException an exception during execution of the tests
+	 */
+	@Test
+	public void testInstallESV() throws ActionException {
+		//TODO: change to a module that's tiny. Because this test is quite slow, also relies on outside world
+//		
+//		final String initials = "ASV";
+//		final InstallJswordModuleCommand cmd = new InstallJswordModuleCommand();
+//		cmd.setInitials(initials);
+//
+//		
+//		final InstallJswordModuleHandler ijmh = new InstallJswordModuleHandler();
+//		final InstallJswordModuleResult result = ijmh.execute(cmd, null);
+//
+//		Assert.assertTrue(result.isSuccessful());
+//		Assert.assertTrue(Books.installed().getBook(initials) != null);
+//		// check book is installed
+
+	}
+}

Added: trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests/test_query_params_different_types.sql
===================================================================
--- trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests/test_query_params_different_types.sql	                        (rev 0)
+++ trunk/step-web-app/src/test/resources/com/tyndalehouse/step/web/server/db/queries/tests/test_query_params_different_types.sql	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,30 @@
+--------------------------------------------------------
+-- Query test
+-- This looks up 3 events 
+--------------------------------------------------------
+define date_of_event as bigint
+define event_name as varchar
+define event_id as integer
+
+
+	select 
+		name 
+	from 
+		step.event 
+	where 
+		name = #event_name# -- 'Events in Africa'
+union
+	select 
+		name 
+	from 
+		step.event 
+	where 
+		event_id = #event_id# -- 2
+union
+	select 
+		name 
+	from 
+		step.event 
+	where 
+		from_date = #date_of_event# -- = -160321161544388
+order by name

Added: trunk/step-web-app/war/WEB-INF/web.xml
===================================================================
--- trunk/step-web-app/war/WEB-INF/web.xml	                        (rev 0)
+++ trunk/step-web-app/war/WEB-INF/web.xml	2010-04-14 22:17:04 UTC (rev 122)
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE web-app
+    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+    "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+  
+  	<!-- Remote logging agent for gwt-log -->
+	<servlet>
+		<servlet-name>remoteLoggerServiceImpl</servlet-name>
+		<servlet-class>com.allen_sauer.gwt.log.server.RemoteLoggerServiceImpl</servlet-class>
+	</servlet>
+
+	<servlet-mapping>
+		<servlet-name>remoteLoggerServiceImpl</servlet-name>
+		<url-pattern>/step/gwt-log</url-pattern>
+	</servlet-mapping>
+
+  
+  	<filter>
+		<filter-name>guiceFilter</filter-name>
+		<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
+	</filter>
+
+	<filter-mapping>
+		<filter-name>guiceFilter</filter-name>
+		<url-pattern>/*</url-pattern>
+	</filter-mapping>
+
+	<listener>
+		<listener-class>com.tyndalehouse.step.web.server.guice.MyGuiceServletConfig</listener-class>
+	</listener>
+
+	<!-- Default page to serve -->
+	<welcome-file-list>
+		<welcome-file>Step.html</welcome-file>
+	</welcome-file-list>
+
+</web-app>



