[jspwiki] 03/04: [svn-inject] Applying Debian modifications (2.8.0-4) to trunk

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Thu Nov 13 00:14:21 UTC 2014


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to annotated tag debian/2.8.0-5
in repository jspwiki.

commit 68cdf6ae12f5674ad25551c483836cd6a7de2cf4
Author: Tony Mancill <tmancill at debian.org>
Date:   Sat Nov 27 19:32:47 2010 +0000

    [svn-inject] Applying Debian modifications (2.8.0-4) to trunk
---
 debian/NEWS.jspwiki                                |  14 +
 debian/README.Debian                               |  25 +
 debian/changelog                                   | 453 ++++++++++
 debian/compat                                      |   1 +
 debian/control                                     |  21 +
 debian/copyright                                   | 146 +++
 debian/jspwiki.conffiles                           |   1 +
 debian/jspwiki.config                              |  14 +
 debian/jspwiki.copy                                |  32 +
 debian/jspwiki.links                               |  21 +
 debian/jspwiki.postinst                            |  45 +
 debian/jspwiki.postinst.pl                         |  35 +
 debian/jspwiki.postrm                              |  24 +
 debian/jspwiki.properties                          | 824 +++++++++++++++++
 debian/jspwiki.templates                           | 124 +++
 debian/jspwiki.xml                                 |   5 +
 debian/patches/01_jabsorb_api.dpatch               |  44 +
 debian/patches/02_ignore_binary_jars.dpatch        |  19 +
 debian/po/POTFILES.in                              |   1 +
 debian/po/cs.po                                    | 349 ++++++++
 debian/po/da.po                                    | 270 ++++++
 debian/po/de.po                                    | 345 +++++++
 debian/po/es.po                                    | 369 ++++++++
 debian/po/eu.po                                    | 275 ++++++
 debian/po/fi.po                                    | 264 ++++++
 debian/po/fr.po                                    | 282 ++++++
 debian/po/gl.po                                    | 272 ++++++
 debian/po/it.po                                    | 279 ++++++
 debian/po/ja.po                                    | 269 ++++++
 debian/po/nl.po                                    | 276 ++++++
 debian/po/pt.po                                    | 345 +++++++
 debian/po/ru.po                                    | 274 ++++++
 debian/po/sv.po                                    | 265 ++++++
 debian/po/templates.pot                            | 240 +++++
 debian/po/vi.po                                    | 270 ++++++
 debian/rules                                       |  87 ++
 debian/tomcat.policy                               |  36 +
 etc/i18n/CoreResources_en.properties               | 198 ++++
 etc/i18n/plugin/PluginResources_en.properties      |  49 +
 etc/i18n/templates/default_en.properties           | 658 ++++++++++++++
 src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java     |  14 +-
 src/net/sf/akismet/Akismet.java                    | 371 ++++++++
 src/org/apache/commons/jrcs/diff/AddDelta.java     | 131 +++
 src/org/apache/commons/jrcs/diff/ChangeDelta.java  | 134 +++
 src/org/apache/commons/jrcs/diff/Chunk.java        | 357 ++++++++
 src/org/apache/commons/jrcs/diff/DeleteDelta.java  | 121 +++
 src/org/apache/commons/jrcs/diff/Delta.java        | 255 ++++++
 src/org/apache/commons/jrcs/diff/Diff.java         | 347 ++++++++
 .../apache/commons/jrcs/diff/DiffAlgorithm.java    |  84 ++
 .../apache/commons/jrcs/diff/DiffException.java    |  79 ++
 .../jrcs/diff/DifferentiationFailedException.java  |  82 ++
 .../commons/jrcs/diff/PatchFailedException.java    |  82 ++
 src/org/apache/commons/jrcs/diff/Revision.java     | 253 ++++++
 .../apache/commons/jrcs/diff/RevisionVisitor.java  |  73 ++
 src/org/apache/commons/jrcs/diff/SimpleDiff.java   | 315 +++++++
 .../apache/commons/jrcs/diff/myers/DiffNode.java   |  57 ++
 .../apache/commons/jrcs/diff/myers/MyersDiff.java  | 222 +++++
 .../apache/commons/jrcs/diff/myers/PathNode.java   | 146 +++
 src/org/apache/commons/jrcs/diff/myers/Snake.java  |  97 ++
 .../apache/commons/jrcs/diff/myers/package.html    |  80 ++
 src/org/apache/commons/jrcs/diff/package.html      | 106 +++
 .../freshcookies/security/cert/CertificateDN.java  | 174 ++++
 src/org/freshcookies/security/cert/JarHelper.java  | 249 ++++++
 src/org/freshcookies/security/cert/SSLHelper.java  | 216 +++++
 src/org/freshcookies/security/cert/Trustee.java    | 457 ++++++++++
 src/org/freshcookies/security/cert/package.html    | 109 +++
 .../security/policy/Canonicalizer.java             | 400 +++++++++
 .../security/policy/GenericPrincipal.java          |  71 ++
 .../freshcookies/security/policy/LocalPolicy.java  | 312 +++++++
 .../security/policy/PolicyException.java           |  29 +
 .../freshcookies/security/policy/PolicyReader.java | 991 +++++++++++++++++++++
 .../security/policy/PrincipalComparator.java       |  55 ++
 .../security/policy/SecurityTokenFactory.java      | 489 ++++++++++
 .../security/policy/UnresolvedPrincipal.java       |  90 ++
 src/org/freshcookies/security/policy/package.html  |  19 +
 75 files changed, 14586 insertions(+), 2 deletions(-)

diff --git a/debian/NEWS.jspwiki b/debian/NEWS.jspwiki
new file mode 100644
index 0000000..31c1886
--- /dev/null
+++ b/debian/NEWS.jspwiki
@@ -0,0 +1,14 @@
+jspwiki (2.8.0-2) unstable; urgency=low
+
+  * ATOM server support has been removed due to dependency issues.
+
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 26 Oct 2008 12:00:00 +0300
+  
+jspwiki (2.6.3-1) unstable; urgency=low
+
+  * It is highly recommended that the users add the following parameter
+    to the jspwiki.properties, due to the CVE-2008-1230. The vulnerability
+    allows a user to cause arbitary JSP code executed on the server side.
+    jspwiki.attachment.forbidden=*.jsp
+
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 20 Jul 2008 12:00:00 +0300
diff --git a/debian/README.Debian b/debian/README.Debian
new file mode 100644
index 0000000..4ddd17f
--- /dev/null
+++ b/debian/README.Debian
@@ -0,0 +1,25 @@
+JSPWiki for Debian
+------------------
+
+The package does not contain any XML-RPC functionality nor ATOM
+server due to DFSG reasons. If you need these, the easiest way
+is to get a copy of the full JSPWiki.jar and drop it over the one
+in this package. You will also need the relevan library jars.
+
+The directory structure of the Debian policy compliant installation
+is as follows:
+
+/var/lib/jspwiki contains WikiPages and attachments.
+
+/usr/share/java/webapps/JSPWiki contains the JSP pages, Java libraries,
+and page templates.
+
+/etc/jspwiki contains all configuration files.
+
+/etc/tomcat6/policy.d/05jspwiki.policy is a symbolic link to
+/etc/jspwiki/tomcat.policy
+
+For more information see README.gz and http://www.jspwiki.org
+
+
+ -- Kalle Kivimaa <killer at debian.org>, Fri, 24 Oct 2008 11:50:37 z
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..f36dc54
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,453 @@
+jspwiki (2.8.0-4) unstable; urgency=low
+
+  * Team upload.
+  * Changed Build-Depends
+    - Removed (Build-)Depends on libservlet2.3-java 
+      (Closes: #576903, #581024)
+    - added tomcat6
+  * Tailored package to tomcat6 instead of tomcat5.5 (Closes: #592677)
+  * With permission of maintainer Java Team is taking over the package
+ 
+ -- Adnan Hodzic <adnan at foolcontrol.org>  Thu, 25 Nov 2010 19:01:27 +0100
+
+jspwiki (2.8.0-3.2) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Fix pending l10n issues. Debconf translations:
+    - Spanish (Francisco Javier Cuadrado).  Closes: #547625
+    - Vietnamese (Clytie Siddall).  Closes: #547996
+    - Danish (Joe Hansen).  Closes: #580408
+
+ -- Christian Perrier <bubulle at debian.org>  Tue, 11 May 2010 05:57:04 +0200
+
+jspwiki (2.8.0-3.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+  * Lintian fixes:
+    - bump debhelper compatibility to 7
+    - as a consequence, replace "dhclean -k" by dh_prep
+    - add ${misc:Depends} to binary package dependencies so that
+      debhelper-triggered dependencies are properly added
+  * Drop build dependency on obsolete tomcat5.5-webapps
+    (apparently useless)
+  * Drop dependency on tomcat5.5 packages. Use "Recommends: tomcat6"
+    instead. Closes: #526261
+  * Set JAVA_HOME when calling "ant clean" to prevent FTBFS
+    Closes: #547485
+  * Fix pending l10n issues. Debconf translations:
+    - German (Helge Kreutzmann).  Closes: #509474
+    - Portuguese (Miguel Figueiredo).  Closes: #509737
+    - French (Christian Perrier).  Closes: #509862
+    - Swedish (Martin Bagge).  Closes: #511203
+    - Russian (Yuri Kozlov).  Closes: #529056
+    - Italian (Luca Monducci).  Closes: #544191
+    - Czech (Miroslav Kure).  Closes: #546613
+    - Basque (Iñaki Larrañaga Murgoitio).  Closes: #546779
+    - Japanese (Hideki Yamane (Debian-JP)).  Closes: #547420
+
+ -- Christian Perrier <bubulle at debian.org>  Sun, 20 Sep 2009 08:14:37 +0200
+
+jspwiki (2.8.0-3) unstable; urgency=low
+
+  * Removed ecs.jar symlink. Closes: #509300
+  
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 21 Dec 2008 10:00:00 +0300
+  
+jspwiki (2.8.0-2) unstable; urgency=low
+
+  * Added baseURL setting from the installation
+  * wikipages.tar.gz fixed. Closes: #508828
+  * Added debhelper build dependency. Closes: #507177
+  * Updated the Swedish translation. Closes: #503355
+  * Changed the runtime dependency from libjdom-java to libjdom1-java.
+    Closes: #508823
+  * Fixed the license change from GPL to Apache.
+  * Removed XML-RPC capability for now.
+  * Removed ATOM capability for now.
+  * Included the source for freshcookies-security
+  * Included the source for akismet-java
+  * Included the source for jrcs-diff
+  * Fixed a typo in debian/rules to cause commons-httpclient binary
+    to be included.
+  
+ -- Kalle Kivimaa <killer at debian.org>  Fri, 19 Dec 2008 18:00:00 +0300
+  
+jspwiki (2.8.0-1) unstable; urgency=low
+
+  * New upstream release. Closes: #489900
+  * Moved package back to contrib as it requires jars which are
+    either not in Debian or in contrib. Closes: #491176
+  * New release contains fixes for the CVE-2008-1229 and CVE-2008-1231.
+    The default properties have been changed to reject .jsp uploads,
+    which fixes CVE-2008-1230 (a NEWS.Debian entry has also been added).
+    Closes: #470477
+  * control, rules and links modified to better support existing Debian
+    libraries.
+  * Added the missing jspwiki.properties
+  * ant build dependency moved to Build-Depends to conform to policy.
+  
+ -- Kalle Kivimaa <killer at debian.org>  Tue, 21 Oct 2008 12:00:00 +0300
+  
+jspwiki (2.5.139-1.1) unstable; urgency=low
+
+  * Non-maintainer upload to fix pending l10n issues
+  * Debconf templates and debian/control reviewed by the debian-l10n-
+    english team as part of the Smith review project.
+    Closes: #450862, #452166
+  * [Debconf translation updates]
+    - Galician. Closes: #451554
+    - Portuguese. Closes: #451587
+    - Finnish. Closes: #452591
+    - German. Closes: #452165
+    - Vietnamese. Closes: #453384
+    - Dutch. Closes: #453697, #453699
+    - Russian. Closes: #453717
+    - Italian. Closes: #454040
+    - French. Closes: #456392
+    - Czech. Closes: #474618
+    - Basque. Closes: #475680
+  * [Lintian] Add copyright information to debian/copyright and make that
+    file more easily readable
+  * [Lintian] Convert debian/copyright to UTF-8
+
+ -- Christian Perrier <bubulle at debian.org>  Wed, 19 Mar 2008 20:53:33 +0100
+
+jspwiki (2.5.139-1) unstable; urgency=low
+
+  * New upstream release. Closes: #430066.
+  * Upstream fixed the XSS CVE's. Closes: #445477.
+  * Updated French translation. Closes: #435780.
+  * Updated German translation. Closes: #437111.
+  * Updated Portugese translation. Closes: #445350.
+  * Fixed debconf typos. Closes: #437113.
+  * doc/Templates.txt has been removed from the upstream.
+  * Fixed the tomcat.policy.
+  * Added the new security options to the jspwiki.properties.
+  * Added empty userdatabase and groupdatabase xml files.
+
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 21 Oct 2007 08:00:00 +0300
+  
+jspwiki (2.2.33.ds1-2) unstable; urgency=low
+
+  * Depend on tomcat5.5 instead of tomcat5.
+  * Fixed some typos in deb debconf templates. Closes: #431880.
+  * Added portuguese debconf translation. Closes: #416328.
+  * Added german debconf translation. Closes:  #431877.
+  * Used debian/compat instead of DH_COMPAT in debian/rules.
+  * Force build to use java-gcj-compat.
+
+ -- Michael Koch <konqueror at gmx.de>  Thu, 19 Jul 2007 07:16:17 +0200
+
+jspwiki (2.2.33.ds1-1) unstable; urgency=low
+
+  * Sourceful upload to correct the problem of moving the package
+    from contrib to main (see #397659).
+  * Fixed the tomcat.policy to include the correct codeBase (Closes: #386309).
+
+ -- Kalle Kivimaa <killer at debian.org>  Thu,  9 Sep 2006 12:00:00 +0200
+
+jspwiki (2.2.33-5) unstable; urgency=low
+
+  * Bumped the Standards-Version from 3.6.1.0 to 3.7.2. No changes
+    were neccessary.
+
+ -- Kalle Kivimaa <killer at debian.org>  Tue, 29 Aug 2006 12:00:00 +0300
+
+jspwiki (2.2.33-4) unstable; urgency=low
+
+  * Changed the compiler build-dep to be java-gcj-compat-dev (Closes: #384952)
+
+ -- Kalle Kivimaa <killer at debian.org>  Mon, 28 Aug 2006 12:00:00 +0300
+
+jspwiki (2.2.33-3) unstable; urgency=low
+
+  * Fixed the tomcat.policy to allow Tomcat5 to run with the security
+    manager enabled.
+  * Fixed the old logging path in jspwiki.properties to be
+    /var/log/tomcat5/jspwiki.log
+
+ -- Kalle Kivimaa <killer at debian.org>  Mon, 28 Aug 2006 08:00:00 +0300
+
+jspwiki (2.2.33-2) unstable; urgency=low
+
+  * Now depends on tomcat5 intead of tomcat4 (Closes: #334057)
+  * Moved to main as tomcat5 is in main too
+  * Updated the get-orig-source to reflect 2.2.33
+  * Updated jspwiki.xml context to tomcat5
+
+ -- Kalle Kivimaa <killer at debian.org>  Thu, 17 Aug 2006 16:00:00 +0300
+
+jspwiki (2.2.33-1) unstable; urgency=low
+
+  * New upstream release.
+  * debconf-2.0 alternative added (Closes: #331874).
+  * Swedish translation included (Closes: #331075).
+  * Removed commons-logging-api.jar from WEB-INF/lib as it causes
+    tomcat4 to freeze at startup.
+
+ -- Kalle Kivimaa <killer at debian.org>  Mon, 20 Dec 2005 23:00:00 +0200
+
+jspwiki (2.2.20-1) unstable; urgency=low
+
+  * New upstream release (Closes: #316707).
+  * Czech translation included (Closes: #319401).
+
+ -- Kalle Kivimaa <killer at debian.org>  Wed, 31 Aug 2005 15:00:00 +0300
+
+jspwiki (2.0.52-12) unstable; urgency=high
+
+  * The source package is non-native again.
+
+ -- Kalle Kivimaa <killer at debian.org>  Wed, 18 May 2005 16:30:00 +0300
+
+jspwiki (2.0.52-11) unstable; urgency=high
+
+  * Fixed the postinst script to handle the case of non-debconfed
+    configuration file (Closes: #308069) courtesy of Michael Blakeley
+
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 08 May 2005 22:00:00 +0300
+
+jspwiki (2.0.52-10) unstable; urgency=high
+
+  * Fixed the postinst script to correctly recognize debconf (Closes: #302198)
+    courtesy of Kenneth Pronovici
+
+ -- Kalle Kivimaa <killer at debian.org>  Thu, 28 Apr 2005 22:00:00 +0300
+
+jspwiki (2.0.52-9) unstable; urgency=high
+
+  * Added dpatch build dependency (Closes: #296936)
+  * Compiled the package with JDK 1.4 instead of 1.5 (Closes: #296938)
+
+ -- Kalle Kivimaa <killer at debian.org>  Mon, 28 Feb 2005 09:00:00 +0200
+
+jspwiki (2.0.52-8) unstable; urgency=high
+
+  * Added dpatch support.
+  * Fixed Search.jsp to plug the security hole
+    http://www.jspwiki.org/Wiki.jsp?page=BugXSSVulnerabilityInSearch.jsp
+
+ -- Kalle Kivimaa <killer at debian.org>  Mon, 21 Feb 2005 11:00:00 +0200
+
+jspwiki (2.0.52-7) unstable; urgency=low
+
+  * Changed the postinst script to honor non-debconf changes to
+    /etc/jspwiki/jspwiki.properties (Closes: #238574).
+  * Upgraded the fr.po file as provided by the French translation
+    team (Closes: #238747)
+  * Put context configuration XML jspwiki.xml to /var/lib/tomcat4/webapps
+    (Closes: #248286)
+
+ -- Kalle Kivimaa <killer at debian.org>  Thu, 3 Jun 2004 13:00:00 +0200
+
+jspwiki (2.0.52-6) unstable; urgency=low
+
+  * Installed the French debconf template transaltions (Closes: #235191).
+
+ -- Kalle Kivimaa <killer at debian.org>  Fri, 13 Feb 2004 10:00:00 +0200
+
+jspwiki (2.0.52-5) unstable; urgency=low
+
+  * Updated the build depends and templates to conform with the Debian
+    localisation team standards (Closes: #232434).
+  * Improved the debconf extended descriptions.
+
+ -- Kalle Kivimaa <killer at debian.org>  Fri, 13 Feb 2004 10:00:00 +0200
+
+jspwiki (2.0.52-4) unstable; urgency=low
+
+  * Changed debconf question priority from high/medium to low.
+  * Fixed incorrect version number in get-orig-source rules target.
+
+ -- Kalle Kivimaa <killer at debian.org>  Thu, 22 Jan 2004 11:00:00 +0200
+
+jspwiki (2.0.52-3) unstable; urgency=low
+
+  * Removed direct support for Tomcat 3.x.
+
+ -- Kalle Kivimaa <killer at debian.org>  Fri, 5 Dec 2003 12:00:00 +0200
+
+jspwiki (2.0.52-2) unstable; urgency=low
+
+  * Updated the standards field to the latest (3.6.1.0).
+  * Package no longer restarts Tomcat on installation.
+
+ -- Kalle Kivimaa <killer at debian.org>  Sun, 19 Oct 2003 11:00:00 +0200
+
+jspwiki (2.0.52-1) unstable; urgency=low
+
+  * New upstream version.
+  * Maintainer address changed to killer at debian.org.
+  * Package sent to the Debian archive (Closes: #180340).
+
+ -- Kalle Kivimaa <killer at debian.org>  Tue, 14 Oct 2003 15:00:00 +0200
+
+jspwiki (2.0.49-0) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Thu, 17 Jul 2003 10:00:00 +0200
+
+jspwiki (2.0.45-0) unstable; urgency=low
+
+  * New upstream version.
+  * Changed the version numbering to conform with the unofficial Debian
+    package policy.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Wed, 4 Jun 2003 18:00:00 +0200
+
+jspwiki (2.0.39-3) unstable; urgency=low
+
+  * Added rudimentary debconf support.
+  * Started using dh_link in debian/rules.
+  * Moved jspwiki.tld to /etc/jspwiki.
+  * Changed the JSPWiki homepage to http://www.jspwiki.org
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sat, 3 May 2003 18:00:00 +0200
+
+jspwiki (2.0.39-2) unstable; urgency=low
+
+  * Fixed binary* build targets to conform with policy.
+  * Added get-orig-source build target.
+  * Fixed versioning problems.
+  * Fixed the jspwiki.tld problem (wrong version in the build, took the
+    upstream fix).
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Mon, 21 Apr 2003 11:00:00 +0200
+
+jspwiki (2.0.39-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sat, 12 Apr 2003 12:01:00 +0200
+
+jspwiki (2.0.36-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sun, 23 Mar 2003 17:47:00 +0200
+
+jspwiki (2.0.32-2) unstable; urgency=low
+
+  * Packaging updates.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sat, 21 Feb 2003 09:20:00 +0200
+
+jspwiki (2.0.32-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sat, 21 Feb 2003 09:20:00 +0200
+
+jspwiki (2.0.31-1) unstable; urgency=low
+
+  * New upstream version.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Fri, 21 Feb 2003 09:20:00 +0200
+
+jspwiki (2.0.27-2) unstable; urgency=low
+
+  * Fixed packaging so that lintian and linda don't complain about
+    anything else except configuration files being misplaced.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sun, 09 Feb 2003 16:04:00 +0200
+
+jspwiki (2.0.27-1) unstable; urgency=low
+
+  * New upstream version.
+  * Packaging now (almost) conforms to Debian policy.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sun, 09 Feb 2003 13:50:00 +0200
+
+jspwiki (2.0.25-3) unstable; urgency=low
+
+  * Fixed various permissions from root to tomcat4.
+  * Fixed file layout to conform with Debian policy.
+	
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sat, 08 Feb 2003 18:46:00 +0200
+
+jspwiki (2.0.25-2) unstable; urgency=low
+
+  * Fixed the various scripts so that now the Debian specific stuff
+    really is only under debian/.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Mon, 03 Feb 2003 13:17:00 +0200
+
+jspwiki (2.0.25-1) unstable; urgency=low
+
+  * Changed the packaging system to real Debian system.
+
+ -- Kalle Kivimaa <kalle.kivimaa at iki.fi>  Sun, 02 Feb 2003 23:25:00 +0200
+jspwiki (2.5.139-1.2) unstable; urgency=low
+
+  * Non-maintainer upload to fix pending l10n issues
+  * Debconf templates and debian/control reviewed by the debian-l10n-
+    english team as part of the Smith review project.
+    Closes: #450862, #452166
+  * [Debconf translation updates]
+    - Galician. Closes: #451554
+    - Portuguese. Closes: #451587
+    - Finnish. Closes: #452591
+    - German. Closes: #452165
+    - Vietnamese. Closes: #453384
+    - Dutch. Closes: #453697, #453699
+    - Russian. Closes: #453717
+    - Italian. Closes: #454040
+    - French. Closes: #456392
+  * [Lintian] Add copyright information to debian/copyright and make that
+    file more easily readable
+  * [Lintian] Convert debian/copyright to UTF-8
+  * Czech. Closes: #474618
+
+ -- Christian Perrier <bubulle at debian.org>  Mon, 07 Apr 2008 07:24:59 +0200
+jspwiki (2.5.139-1.2) UNRELEASED; urgency=low
+
+  * Non-maintainer upload to fix pending l10n issues
+  * Debconf templates and debian/control reviewed by the debian-l10n-
+    english team as part of the Smith review project.
+    Closes: #450862, #452166
+  * [Debconf translation updates]
+    - Galician. Closes: #451554
+    - Portuguese. Closes: #451587
+    - Finnish. Closes: #452591
+    - German. Closes: #452165
+    - Vietnamese. Closes: #453384
+    - Dutch. Closes: #453697, #453699
+    - Russian. Closes: #453717
+    - Italian. Closes: #454040
+    - French. Closes: #456392
+  * [Lintian] Add copyright information to debian/copyright and make that
+    file more easily readable
+  * [Lintian] Convert debian/copyright to UTF-8
+  * Czech. Closes: #474618
+
+ -- Christian Perrier <bubulle at debian.org>  Mon, 07 Apr 2008 07:25:35 +0200
+jspwiki (2.5.139-1.2) unstable; urgency=low
+
+  * Non-maintainer upload to fix pending l10n issues
+  * Debconf templates and debian/control reviewed by the debian-l10n-
+    english team as part of the Smith review project.
+    Closes: #450862, #452166
+  * [Debconf translation updates]
+    - Galician. Closes: #451554
+    - Portuguese. Closes: #451587
+    - Finnish. Closes: #452591
+    - German. Closes: #452165
+    - Vietnamese. Closes: #453384
+    - Dutch. Closes: #453697, #453699
+    - Russian. Closes: #453717
+    - Italian. Closes: #454040
+    - French. Closes: #456392
+  * [Lintian] Add copyright information to debian/copyright and make that
+    file more easily readable
+  * [Lintian] Convert debian/copyright to UTF-8
+  * Czech. Closes: #474618
+
+ -- Christian Perrier <bubulle at debian.org>  Mon, 07 Apr 2008 07:27:51 +0200
+jspwiki (2.5.139-1.3) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * Czech. Closes: #474618
+  * Czech. Closes: #474618
+
+ -- Christian Perrier <bubulle at debian.org>  Mon, 07 Apr 2008 07:28:10 +0200
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..7f8f011
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+7
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..06fa28b
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,21 @@
+Source: jspwiki
+Section: contrib/web
+Priority: optional
+Maintainer: Debian Java Maintainers <pkg-java-maintainers at lists.alioth.debian.org>
+Uploaders: Adnan Hodzic <adnan at foolcontrol.org>
+Build-Depends-Indep: tomcat6, java-gcj-compat-dev, liblucene2-java, liboro-java, liboscache-java, libjdom1-java, libjaxen-java, libgnujaf-java, libcommons-codec-java, libcommons-fileupload-java, libcommons-httpclient-java, libcommons-io-java, libcommons-lang-java, liblog4j1.2-java, wget, unzip
+Build-Depends: ant, debhelper (>> 7)
+Homepage: http://www.jspwiki.org
+Standards-Version: 3.9.1
+
+Package: jspwiki
+Architecture: all
+Section: contrib/web
+Priority: optional
+Depends: ${misc:Depends}, libgnujaf-java, libcommons-codec-java, libcommons-fileupload-java, libcommons-httpclient-java, libcommons-io-java, libcommons-lang-java, libcommons-logging-java, libjaxen-java, libjdom1-java, liblog4j1.2-java, liblucene2-java, libnekohtml-java, liboro-java, liboscache-java
+Suggests: rcs
+Description: WikiWikiWeb clone written in Java
+ JSPWiki is a simple WikiWiki clone to be run in a Java servlet container
+ (eg. Tomcat).  It keeps all of its formatting in Java Server Pages (JSP)
+ files, and uses a custom Java class called 'com.ecyrd.jspwiki.WikiEngine'
+ to all interfacing with the Wiki system.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000..52051ed
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,146 @@
+This JSPWiki package is distributed under Apache License 2.0
+(see /usr/share/common-licenses/Apache-2.0 for details).
+
+Copyright © Janne Jalkanen <jalkanen+jspwiki at ecyrd.com> and others,
+2001-2008.
+
+jrcs-diff copyright © The Apache Software Foundation, distributed under
+Apache License 1.1 (see below).
+
+Freshcookies files copyright © Andrew Jaquith.
+
+Akismet.java copyright © 2005-2006 David A. Czarnecki, copyright terms
+below.
+
+mootools.js copyright © 2006 Valerio Proietti <http://mad4milk.net>,
+MIT license, license terms below.
+
+The Debian package is maintained by Kalle Kivimaa <killer at debian.org>.
+
+French translation by Rémi Pannequin <remi.pannequin at laposte.net> and
+the Debian French localisation team <debian-l10n-french at lists.debian.org>.
+
+The original sources were fetched from
+http://www.jspwiki.org/Wiki.jsp?page=JSPWikiDownload
+
+jrcs-diff available at https://svn.apache.org/repos/asf/commons/dormant/jrcs/tags/pre_ASF_2_license/src/java/org/apache/commons/jrcs/diff/
+
+Freshcookies package available at
+http://www.freshcookies.org/freshcookies-security/
+
+Akismet package available at http://sourceforge.net/projects/akismet-java/
+
+jrcs-diff:
+
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+
+
+Akismet.java:
+
+Copyright (c) 2005-2006, David A. Czarnecki
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+Redistributions in binary form must reproduce the above copyright notice,
+this list of conditions and the following disclaimer in the documentation
+and/or other materials provided with the distribution.
+Neither the name of the "David A. Czarnecki" nor the names of
+its contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+Products derived from this software may not be called "Akismet Java API",
+nor may "Akismet Java API" appear in their name, without prior written
+permission of David A. Czarnecki.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+mootools.js:
+
+The MIT License
+
+Copyright (c) <year> <copyright holders>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/debian/jspwiki.conffiles b/debian/jspwiki.conffiles
new file mode 100644
index 0000000..b4e19b7
--- /dev/null
+++ b/debian/jspwiki.conffiles
@@ -0,0 +1 @@
+/etc/tomcat6/policy.d/05jspwiki.policy
diff --git a/debian/jspwiki.config b/debian/jspwiki.config
new file mode 100644
index 0000000..a619144
--- /dev/null
+++ b/debian/jspwiki.config
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+set -e
+
+. /usr/share/debconf/confmodule
+db_input high jspwiki/baseurl || true
+db_input low jspwiki/applicationname || true
+db_input low jspwiki/pageprovider || true
+db_input low jspwiki/usepagecache || true
+db_input low jspwiki/encoding || true
+db_input low jspwiki/breaktitlewithspaces || true
+db_input low jspwiki/matchenglishplurals || true
+db_input low jspwiki/camelcaselinks || true
+db_go || true
diff --git a/debian/jspwiki.copy b/debian/jspwiki.copy
new file mode 100644
index 0000000..cba2406
--- /dev/null
+++ b/debian/jspwiki.copy
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+if [ "z$1" == "z" ]; then
+	echo No application directory given.
+	exit 1
+fi
+
+mkdir /var/lib/tomcat4/webapps/$1
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Diff.jsp /var/lib/tomcat4/webapps/$1/Diff.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Edit.jsp /var/lib/tomcat4/webapps/$1/Edit.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Error.jsp /var/lib/tomcat4/webapps/$1/Error.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/PageInfo.jsp /var/lib/tomcat4/webapps/$1/PageInfo.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/PageModified.jsp /var/lib/tomcat4/webapps/$1/PageModified.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Preview.jsp /var/lib/tomcat4/webapps/$1/Preview.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Search.jsp /var/lib/tomcat4/webapps/$1/Search.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Upload.jsp /var/lib/tomcat4/webapps/$1/Upload.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/UserPreferences.jsp /var/lib/tomcat4/webapps/$1/UserPreferences.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/Wiki.jsp /var/lib/tomcat4/webapps/$1/Wiki.jsp
+ln -s /var/lib/tomcat4/webapps/JSPWiki/images /var/lib/tomcat4/webapps/$1/images
+ln -s /var/lib/tomcat4/webapps/JSPWiki/META-INF /var/lib/tomcat4/webapps/$1/META-INF
+ln -s /var/lib/tomcat4/webapps/JSPWiki/images /var/lib/tomcat4/webapps/$1/images
+mkdir /var/lib/tomcat4/webapps/$1/templates
+ln -s /var/lib/tomcat4/webapps/JSPWiki/templates/default /var/lib/tomcat4/webapps/$1/templates/default
+mkdir /var/lib/tomcat4/webapps/$1/WEB-INF
+ln -s /var/lib/tomcat4/webapps/JSPWiki/WEB-INF/jspwiki.tld /var/lib/tomcat4/webapps/$1/WEB-INF/jspwiki.tld
+ln -s /var/lib/tomcat4/webapps/JSPWiki/WEB-INF/lib /var/lib/tomcat4/webapps/$1/WEB-INF/lib
+mkdir /etc/jspwiki/$1
+cp /etc/jspwiki/jspwiki.properties /etc/jspwiki/web.xml /etc/jspwiki/$1
+ln -s /etc/jspwiki/$1/jspwiki.properties /var/lib/tomcat4/webapps/$1/WEB-INF/jspwiki.properties
+ln -s /etc/jspwiki/$1/web.xml /var/lib/tomcat4/webapps/$1/WEB-INF/web.xml
+
+
diff --git a/debian/jspwiki.links b/debian/jspwiki.links
new file mode 100644
index 0000000..0dc8fdc
--- /dev/null
+++ b/debian/jspwiki.links
@@ -0,0 +1,21 @@
+etc/jspwiki/jspwiki.properties usr/share/jspwiki/WEB-INF/jspwiki.properties
+etc/jspwiki/jspwiki.tld usr/share/jspwiki/WEB-INF/jspwiki.tld
+etc/jspwiki/web.xml usr/share/jspwiki/WEB-INF/web.xml
+etc/jspwiki/jspwiki.xml etc/tomcat6/Catalina/localhost/JSPWiki.xml
+etc/jspwiki/tomcat.policy etc/tomcat6/policy.d/05jspwiki.policy
+usr/share/java/log4j-1.2.jar usr/share/jspwiki/WEB-INF/lib/log4j-1.2.jar
+usr/share/java/commons-codec.jar usr/share/jspwiki/WEB-INF/lib/commons-codec.jar
+usr/share/java/commons-fileupload.jar usr/share/jspwiki/WEB-INF/lib/commons-fileupload.jar
+usr/share/java/commons-httpclient.jar usr/share/jspwiki/WEB-INF/lib/commons-httpclient.jar
+usr/share/java/commons-io.jar usr/share/jspwiki/WEB-INF/lib/commons-io.jar
+usr/share/java/commons-lang.jar usr/share/jspwiki/WEB-INF/lib/commons-lang.jar
+usr/share/java/jdom1.jar usr/share/jspwiki/WEB-INF/lib/jdom1.jar
+usr/share/java/jaxen.jar usr/share/jspwiki/WEB-INF/lib/jaxen.jar
+usr/share/java/jaxp-1.3.jar usr/share/jspwiki/WEB-INF/lib/jaxp-1.3.jar
+usr/share/java/oro.jar usr/share/jspwiki/WEB-INF/lib/oro.jar
+usr/share/java/oscache.jar usr/share/jspwiki/WEB-INF/lib/oscache.jar
+usr/share/java/lucene-core.jar usr/share/jspwiki/WEB-INF/lib/lucene-core.jar
+usr/share/java/lucene-highlighter.jar usr/share/jspwiki/WEB-INF/lib/lucene-highlighter.jar
+usr/share/java/jabsorb.jar usr/share/jspwiki/WEB-INF/lib/jabsorb.jar
+usr/share/tomcat6-webapps/jsp-examples/WEB-INF/lib/jstl.jar usr/share/jspwiki/WEB-INF/lib/jstl.jar
+usr/share/tomcat6-webapps/jsp-examples/WEB-INF/lib/standard.jar usr/share/jspwiki/WEB-INF/lib/standard.jar
diff --git a/debian/jspwiki.postinst b/debian/jspwiki.postinst
new file mode 100644
index 0000000..d269bfd
--- /dev/null
+++ b/debian/jspwiki.postinst
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+set -e
+
+. /usr/share/debconf/confmodule
+
+# retrieve the tomcat6 user
+db_get tomcat6/username && TOMCAT6_USER="$RET" || TOMCAT6_USER="tomcat6"
+
+cd /var/lib/jspwiki
+if [[ ! -f default/Main.txt ]];
+then
+    tar --extract --gunzip --keep-old-files --file /usr/share/doc/jspwiki/examples/wikipages.tar.gz || true
+    chown -R $TOMCAT6_USER default
+fi
+
+set +e
+head -1 /etc/jspwiki/jspwiki.properties | grep -q "This file is managed by Debconf" || exit 0
+set -e
+
+db_get jspwiki/applicationname
+APPLICATION="$RET"
+db_get jspwiki/baseurl
+BASEURL="$RET"
+db_get jspwiki/pageprovider
+PROVIDER="$RET"
+db_get jspwiki/usepagecache
+CACHE="$RET"
+db_get jspwiki/encoding
+ENCODING="$RET"
+db_get jspwiki/breaktitlewithspaces
+BREAKTITLE="$RET"
+db_get jspwiki/matchenglishplurals
+MATCHPLURALS="$RET"
+db_get jspwiki/camelcaselinks
+CAMELCASE="$RET"
+
+db_stop || true
+
+TEMPFILE=`tempfile`
+sed -e "s/^jspwiki\.applicationName.*/jspwiki.applicationName = $APPLICATION/" -e "s!^jspwiki\.baseURL.*!jspwiki.baseURL = $BASEURL!" -e "s/^jspwiki.pageProvider.*/jspwiki.pageProvider = $PROVIDER/" -e "s/^jspwiki.usePageCache.*/jspwiki.usePageCache = $CACHE/" -e "s/^jspwiki.encoding.*/jspwiki.encoding = $ENCODING/" -e "s/^jspwiki.breakTitleWithSpaces.*/jspwiki.breakTitleWithSpaces = $BREAKTITLE/" -e "s/^jspwiki.translatorReader.matchEnglishPlurals.*/jspwiki.translatorReader.matchEnglish [...]
+mv $TEMPFILE /etc/jspwiki/jspwiki.properties
+chmod go+r /etc/jspwiki/jspwiki.properties
+
+#DEBHELPER#
diff --git a/debian/jspwiki.postinst.pl b/debian/jspwiki.postinst.pl
new file mode 100644
index 0000000..1205518
--- /dev/null
+++ b/debian/jspwiki.postinst.pl
@@ -0,0 +1,35 @@
+#!/usr/bin/perl
+
+use Debconf::Client::ConfModule ':all';
+
+my $application = get("jspwiki/applicationname");
+my $pageprovider = get("jspwiki/pageprovider");
+my $usepagecache = get("jspwiki/usepagecache");
+my $attachmentprovider = get("jspwiki/attachments/provider");
+my $baseurl = get("jspwiki/baseurl");
+my $encoding = get("jspwiki/encoding");
+my $breaktitles = get("jspwiki/breaktitlewithspaces");
+my $matchenglishplurals = get("jspwiki/matchenglishplurals");
+my $usecamelcase = get("jspwiki/camelcaselinks");
+my $rssgenerate = get("jspwiki/rss/generate");
+my $rssrefresh = get("jspwiki/rss/refresh");
+my $rssdescription = get("jspwiki/rss/channeldescription");
+my $rsslanguage = get("jspwiki/rss/channellanguage");
+
+open(LINE, "/tmp/jspwiki.properties");
+while(<LINE>) {
+  s/^jspwiki\.applicationName =.*/jspwiki.applicationName = $application/;
+  s/^jspwiki\.pageProvider =.*/jspwiki.pageProvider = $pageprovider/;
+  s/^jspwiki\.usePageCache =.*/jspwiki.usePageCache = $usepagecache/;
+  s/^jspwiki\.attachmentProvider =.*/jspwiki.attachmentProvider = $attachmentprovider/;
+  s/^#jspwiki\.baseURL =.*/jspwiki.baseURL = $baseurl/;
+  s/^jspwiki\.baseURL =.*/jspwiki.baseURL = $baseurl/;
+  s/^jspwiki\.encoding =.*/jspwiki.encoding = $encoding/;
+  s/^jspwiki\.breakTitleWithSpaces =.*/jspwiki.breakTitleWithSpaces = $breaktitles/;
+  s/^jspwiki\.translatorReader\.matchEnglishPlurals =.*/jspwiki.translatorReader.matchEnglishPlurals = $matchenglishplurals/;
+  s/^jspwiki\.translatorReader\.camelCaseLinks =.*/jspwiki.translatorReader.camelCaseLinks = $usecamelcase/;
+  s/^jspwiki\.rss.generate =.*/jspwiki.rss.generate = $rssgenerate/;
+  s/^jspwiki\.rss.interval =.*/jspwiki.rss.interval = $rssinterval/;
+  s/^jspwiki\.rss.channelDescription =.*/jspwiki.rss.channelDescription = $rssdescription/;
+  s/^jspwiki\.rss.channelLanguage =.*/jspwiki.rss.channelLanguage = $rsslanguage/;
+}
diff --git a/debian/jspwiki.postrm b/debian/jspwiki.postrm
new file mode 100644
index 0000000..8d34882
--- /dev/null
+++ b/debian/jspwiki.postrm
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+set -e
+
+if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
+	. /usr/share/debconf/confmodule
+	db_input critical jspwiki/purgewikifiles || true
+	db_go || true
+	db_get jspwiki/purgewikifiles || true
+	if [ "$RET" == "true" ]; then
+	    cd /var/lib
+	    rm -rf jspwiki/default
+	    rmdir --ignore-fail-on-non-empty jspwiki
+	fi
+	db_purge
+else if [[ $1 == "purge" ]];
+then
+    cd /var/lib
+    rmdir --ignore-fail-on-non-empty jspwiki/default
+    rmdir --ignore-fail-on-non-empty jspwiki
+fi
+fi
+
+#DEBHELPER#
diff --git a/debian/jspwiki.properties b/debian/jspwiki.properties
new file mode 100644
index 0000000..5f51151
--- /dev/null
+++ b/debian/jspwiki.properties
@@ -0,0 +1,824 @@
+# This file is managed by Debconf. Remove this line if you don't want that!!
+# If you leave the above line intact you risk losing your changes if you
+# manually edit this file. YOU HAVE BEEN WARNED! Also, be aware that the
+# first line must be the first line in this file for the Debconf to keep
+# configuring this file.
+#
+###########################################################################
+#
+#  This is the JSPWiki configuration file.  You'll need to edit this
+#  a bit.  The first few lines are the most important ones.
+#
+#  Wherever it is said that an option can be "true" or "false", you can
+#  also use "yes"/"no", or "on/off".  Just for some convenience.
+#
+#
+#  You can use this to override the default application name.  It affects
+#  the HTML titles and logging, for example.  It can be different from
+#  the actual web name (http://my.com/mywiki) of the application, but usually
+#  it is the same.
+#
+jspwiki.applicationName = JSPWiki
+
+#
+#  Which page provider class to use.  Possibilities are:
+#
+#    RCSFileProvider        - for simple RCS-based file storage
+#    FileSystemProvider     - for simple pure file storage with no version information
+#    VersioningFileProvider - for simple, non-RCS based versioning storage.
+#
+#  Note that if you're upgrading from JSPWiki 1.x, then you need to remove the
+#  "com.ecyrd.jspwiki." part from the beginning of the path.
+#
+jspwiki.pageProvider = FileSystemProvider
+
+#
+#  Set to true, if you want to cache page data into memory.  This is
+#  in general a good idea.
+#
+#  Default is false (no cache).
+#
+#  NB: This replaces the JSPWiki 1.x "CachingProvider" setting, since it
+#      probably was too confusing.
+#
+jspwiki.usePageCache = true
+
+#
+#  Define the time period for page cache checks in milliseconds.
+#
+#jspwiki.cachingProvider.cacheCheckInterval = 100000
+
+#
+#  Determines where wiki files are kept for FileSystemProvider
+#  and RCSFileProvider
+#
+#  If you're using Windows, then you must duplicate the backslashes.
+#  For example, use:
+#  
+#  jspwiki.fileSystemProvider.pageDir = C:\\Data\\jspwiki
+#
+jspwiki.fileSystemProvider.pageDir = /var/lib/jspwiki/default/en
+
+#
+#  The JSPWiki working directory.  If not set, a temporary path will
+#  be used.  You can see the location of the workdir in the logs.
+#  It is HIGHLY recommended that you set this.
+#
+#  The working directory is used to cache things like Lucene search
+#  results.
+#
+#jspwiki.workDir =
+
+#
+#  ATTACHMENTS:
+#
+#  Use the following property to define which attachment provider
+#  you want to use.  You have basically two choices:
+#    * BasicAttachmentProvider - a simple, flat file, versioning provider
+#    * nothing - Set this property to empty, and the attachment functionality
+#                is disabled.
+#
+jspwiki.attachmentProvider = BasicAttachmentProvider
+
+#
+#  The BasicAttachmentProvider needs to know where to store the files
+#  the user has uploaded.  It's okay to put these in the same directory
+#  as you put your text files (i.e. the pageDir setting above).
+#
+#  If you're using Windows, then you must duplicate the backslashes.
+#  For example, use:
+#  
+#  jspwiki.basicAttachmentProvider.storageDir = C:\\Data\\jspwiki
+#
+jspwiki.basicAttachmentProvider.storageDir = /var/lib/jspwiki/default/en
+
+#
+#  You can tell the BasicAttachmentProvider to add a flag
+#  so that browsers do not cache certain (or all) attachment
+#  types. This is useful in intranet environments. You should activate
+#  this if your users complain that their excel files are not uploaded
+#  correctly and they still do have an old version: Usually the
+#  file was uploaded correctly, but they get the locally cached version
+#
+#  You can use regular expressions to disable the cache, e.g the
+#  following example will disable browser cache for all excel and word files
+#
+#  If you don't define this property, cache is enabled by default for
+#  all attachments
+#
+#  jspwiki.basicAttachmentProvider.disableCache = .*\.xls|.*\.doc
+
+#
+#  You can limit the maximum size of an attachment by setting this
+#  value.  The value is in bytes, and by default all attachments
+#  are accepted.
+#
+#  The following line would limit the attachment size to 100,000 bytes
+#jspwiki.attachment.maxsize=100000
+
+#  Don't allow JSP files to be uploaded. This represents a possible
+#  security issue.
+jspwiki.attachment.forbidden=*.jsp
+
+#
+#  page Diff Representation
+#
+#  To show differences between page versions, you can define a 
+# difference provider. 
+#  The following choices are available:
+#    * TraditionalDiffProvider - Uses internal (java) diff
+#        to create a list of changes and shows it line by
+#        line colored. This is the default
+#    * ContextualDiffProvider - Uses internal (java) diff
+#        to create changes inline and shows it on a word by
+#        word basis using CSS. This is much superior to the
+#        traditional diff provider, however, it is still quite
+#        new and not much tested. YMMV.
+#    * ExternalDiffProvider - uses a system diff program (which
+#        can be configured using "jspwiki.diffCommand") to 
+#        create an unified (!) diff.
+#
+#        Example for a diff command:
+#        jspwiki.diffCommand = /usr/bin/diff -u %s1 %s2
+#
+jspwiki.diffProvider = TraditionalDiffProvider
+
+#
+#  BaseURL can be used to rewrite all of JSPWiki's internal references.
+#  Sometimes, especially if you're behind a address-rewriting firewall,
+#  relative URLs don't work since the servlet container has no idea
+#  where it's actually located.
+#
+#  Leave undefined if you want to rely on what your servlet container
+#  thinks of where your application lives.  
+#
+#  You MUST define this one if you want to enable RSS (see below).  In
+#  general, this is a good idea to define it anyway.  Do not forget the
+#  trailing slash.
+#
+#  Example:
+#  jspwiki.baseURL = http://www.ecyrd.com/JSPWiki/
+#
+jspwiki.baseURL=
+
+#  Determines if you need to have relative urls or not.  If the baseURL
+#  is not set, then this has no effect, but if you set the baseURL (which
+#  is highly recommended), you can use this to set relative urls.
+#
+#  Possible values are "absolute" and "relative".
+#
+#jspwiki.referenceStyle=relative
+
+#
+#  Determines which character encoding JSPWiki should use.  If you want
+#  to support all languages in your Wiki, you probably want to enable
+#  this.  If you're upgrading, or are planning just to use the ISO-Latin1
+#  character set (like most western people would), you can just leave
+#  it at the default.  If you enable it, remember that most people won't
+#  be able to type in special characters anyway.
+#  
+#  Note that you can't switch these in the mean time, since the way the
+#  files are encoded on disk is incompatible between ISO-Latin1 and UTF-8.
+#  Don't try.  You'll get all sorts of interesting problems, if you do.
+#
+#  Possible values are 'ISO-8859-1' (default) and 'UTF-8'.
+
+jspwiki.encoding = UTF-8
+
+#
+#  Determines whether raw HTML is allowed as Wiki input.
+#
+#  THIS IS A DANGEROUS OPTION!
+#
+#  If you decide to allow raw HTML, understand that ANY person who has
+#  access to your Wiki site can embed ANY sort of malicious JavaScript,
+#  or plugin, or ActiveX, or whatever on your site.  They can even mess it
+#  up so royally it is impossible for you to replace the situation without
+#  the need of direct access to the repository.  So think twice before
+#  allowing raw HTML on your own site.
+#
+#  Most probably you want to use this on Intranets, or personal servers,
+#  where only a handful of people can access the wiki.
+#
+#  Text between {{{ and }}} -options is not affected by this setting, so
+#  it's always safe to quote HTML code with those.
+#
+#  The default for this option is "false".
+#
+jspwiki.translatorReader.allowHTML = false
+
+############################################################################
+#
+#  Usability niceties.
+#
+#
+#  If this property is set to "true", then page titles are rendered
+#  using an extra space between every capital letter.  It may make
+#  page titles readable on some occasions, but it does have the
+#  drawback of breaking acronyms, for example. (RSSFile becomes R S S File).
+#
+jspwiki.breakTitleWithSpaces = false
+
+#
+#  If set to true, this property means that "WikiName" and "WikiNames"
+#  are considered equal when linking between them.  Setting this to
+#  true does not prevent you from having both kinds of pages - we just
+#  fall back to the other one if the primary name does not exist.
+#
+#  For any other language, you'll probably want to turn this off.
+#
+jspwiki.translatorReader.matchEnglishPlurals = true
+
+#
+#  If you set this to true, the Wiki translator will then also consider
+#  "traditional" WikiNames (that is, names of pages JustSmashedTogether
+#  without square brackets) as hyperlinks.  This technique is also
+#  known as "CamelCase", or "BumpyCase", or "InterCapping".  I personally
+#  like CamelCase as a word, which is why this property is named as it is :-).
+#
+#  By default this is false, since traditional WikiLinks may confuse newbies.
+#
+jspwiki.translatorReader.camelCaseLinks = false
+
+#
+#  This sets the default template used by the Wiki engine.  The templates
+#  live in templates/<template name>.  JSPWiki will attempt to find two
+#  basic templates from that directory: "ViewTemplate" and "EditTemplate".
+#
+#  By default this is called "default".
+#
+jspwiki.templateDir = default
+
+#
+#  The name of the front page.  This is the page that gets loaded if no
+#  other page is loaded.  Up until JSPWiki 1.9.28, it was always called
+#  "Main", but now you can easily change the default front page here.  If not
+#  defined, uses "Main".
+#
+#jspwiki.frontPage = Main
+
+#
+#  Allow creation of empty pages. Defaults to false.
+#
+#jspwiki.allowCreationOfEmptyPages = false
+
+#
+#  If set to true, all outward links have a small icon attached.  The icon
+#  can be found from images/out.png.  Default is true.
+#
+jspwiki.translatorReader.useOutlinkImage = true
+
+#
+#  Set this to the number of minutes a person can "lock" a page
+#  for while he is editing it.
+#
+jspwiki.lockExpiryTime = 60
+
+#
+#  Search provider used for searching pages and attachments.
+#  Default is LuceneSearchProvider, but you can fall back to BasicSearchProvider
+#
+jspwiki.searchProvider = LuceneSearchProvider
+
+#
+#  If your wiki's language is something else than English, you might
+#  want to visit jakarta.apache.org/lucene and download a proper Analyzer
+#  for your language.  Default is to use StandardAnalyzer.
+#
+#jspwiki.lucene.analyzer = org.apache.lucene.analysis.standard.StandardAnalyzer
+
+############################################################################
+#
+#  Special page references.
+#
+#  The URL is relative to Wiki.jsp.  However, if you use
+#  a full, absolute URL, you can also do that.
+#
+# Example to redirect all requests to a page called 'OriginalWiki'
+# to the original wikiwiki at http://c2.com/cgi/wiki
+#
+# jspwiki.specialPage.OriginalWiki = http://c2.com/cgi/wiki
+#
+#  Note that it is entirely possible to override any Wiki page, even
+#  an existing one by redefining it here.
+#
+jspwiki.specialPage.CreateGroup = NewGroup.jsp
+jspwiki.specialPage.FindPage = Search.jsp
+jspwiki.specialPage.Login = Login.jsp
+jspwiki.specialPage.NewGroup = NewGroup.jsp
+jspwiki.specialPage.UserPreferences = UserPreferences.jsp
+
+#############################################################################
+#
+#  Plugin search paths.
+#
+#  Define here the packages you want to use for searching plugins, 
+#  separated with commas.
+#  For example, use the following command to add "org.myorganisation.jspwiki.myplugins"
+#  and "com.foobar.myplugins" to the search path.
+#
+#  The default path is "com.ecyrd.jspwiki.plugins", and it will be always
+#  the last item on the path.  This allows you to override JSPWiki default
+#  plugins.  Note that you are only adding to the path, not replacing it (ie.
+#  the default path is never removed.)
+#
+#  jspwiki.plugin.searchPath = org.myorganisation.jspwiki.myplugins,com.foobar.myplugins
+#
+jspwiki.plugin.searchPath = 
+
+#############################################################################
+#
+#  Page filters
+#
+#  Normally, the filter configuration is in your WEB-INF/ directory, so you
+#  do not need to go and specify this.  However, if your filters.xml live somewhere
+#  else, you'll have to specify it here.
+#
+#jspwiki.filterConfig = /some/path/to/your/filters.xml
+
+#############################################################################
+#
+#  URL Constructor
+#
+#  JSPWiki by default generates page and attachment links that use JSP
+#  pages and request parameters. It can also use alternative URL
+#  constructors so that URL pages resemble traditional website paths, too.
+#  You have three choices for generating URLs:
+#
+#     DefaultURLConstructor - uses JSPs for all references:
+#         http://mywiki.com/jspwiki/Wiki.jsp?page=Main
+#         http://mywiki.com/jspwiki/Edit.jsp?page=Main
+#
+#     ShortURLConstructor - uses path-like reference style:
+#         http://mywiki.com/jspwiki/wiki/Main
+#         http://mywiki.com/jspwiki/wiki/Main?do=Edit
+#
+#     ShortViewURLConstructor - uses path-like references for views; JSPs for everything else:
+#         http://mywiki.com/jspwiki/wiki/Main
+#         http://mywiki.com/jspwiki/Edit.jsp?page=Main
+#
+#  Of course, you can also write your own implementation if you wish.
+#
+#  For either of the ShortURL constructors, you can also specify a
+#  prefix path to go in front of page names. By default, the
+#  prefix is 'wiki/'.
+#
+#  Be warned that the ShortURLConstructor does not work well with any other editor
+#  except the built-in plaintext one.  Use ShortViewURLConstructor if you plan
+#  to enable any other ones.
+#
+#jspwiki.urlConstructor = DefaultURLConstructor
+#jspwiki.urlConstructor = ShortViewURLConstructor
+#jspwiki.shortURLConstructor.prefix = wiki/
+
+#############################################################################
+#
+# Rendering
+#
+# At this time, entries here are strictly for development and testing.
+#
+
+# Disable internal caching of pre-constructed document DOMs.
+# This may be necessary if you require custom rendering that must not be cached.
+#jspwiki.renderingManager.useCache = false
+
+
+#############################################################################
+#
+#  Security, authentication and authorization
+#
+
+#  JSPWiki supports a plugin-based interface for talking to different
+#  kinds of authentication and authorization systems. By "authentication,"
+#  we mean a system for logging in a user to establish their identity.
+#  By "authorization," we mean a system for figuring out what actions
+#  users can perform based on their authenticated identities.
+#
+#  For users looking to get started quickly, the default settings below
+#  should work fine. In addition to the properties below, you may also
+#  want to modify the security policy file WEB-INF/jspwiki.policy. See
+#  the policy file for more details.
+#
+#  AUTHENTICATION
+#
+#  For authentication, JSPWiki uses JAAS (Java Authentication and Authorization
+#  Service) in combination with a servlet filter that picks up any credentials
+#  set by the servlet container. The Authentication system is configured below.
+#
+#  You must choose either (A) Container or (B) Custom authentication. (B) is the default.
+#
+#  A) CONTAINER AUTHENTICATION 
+#  JSPWiki will always (passively) collect credentials supplied by your servlet
+#  container, via HttpServletRequest.getUserPrincipal/getRemote user. You do not
+#  need to do anything to enable this. In addition, you can cause JSPWiki users
+#  to log in to the web container by uncommenting the the <security-constraint>
+#  elements in WEB-INF/web.xml.
+#
+#  B) CUSTOM AUTHENTICATION
+#  If you do not wish to use container-managed authentication, you can use JSPWiki's
+#  own custom authentication system. This uses a JAAS LoginModule (supplied below)
+#  to log in the user. You can use any JAAS LoginModule you want.
+#  The default class is com.ecyrd.jspwiki.auth.login.UserDatabaseLoginModule,
+#  which compares the supplied username and hashed password with the values stored
+#  in the configured UserDatabase (see USER DATABASE below).
+#
+#  Supply the JAAS LoginModule class used for custom authentication here.
+#  The implementation MUST have a zero-argument constructor (as noted in the
+#  javax.security.auth.spi.LoginModule Javadocs).
+jspwiki.loginModule.class = com.ecyrd.jspwiki.auth.login.UserDatabaseLoginModule
+
+#
+# JAAS LoginContext parameters used to initialize the LoginModule. Note that 'param1'
+#  etc. should be replaced with the actual parameter names. The parameter names and
+# values will be loaded to a Map and passed to the LoginModule as the 'options' parameter
+# when its initialize() method is called. The default UserDatabaseLoginModule class does
+# not need any options.
+#jspwiki.loginModule.options.param1 = value1
+#jspwiki.loginModule.options.param2 = value2
+
+# 
+#  Cookie authentication & assertion
+#
+#  If this value is set to "true", then JSPWiki will allow you to "assert" an
+#  identity using a cookie.  It's still considered to be unsafe, just like no
+#  login at all, but it is useful when you have no need to force everyone to login.
+#
+#  By default, this is on.
+#
+#jspwiki.cookieAssertions=true
+
+#
+#  If you would like to keep your users logged in for weeks at a time, you can
+#  turn on "cookie authentication" feature.  However, this comes with important
+#  security caveats:
+#  1) User will stay logged in into your system for weeks.  This means that if
+#     someone manages to nab the cookie during this time, they can pretend to
+#     be that user.
+#  2) The mappings between cookies and users are written in your filesystem,
+#     in $jspwiki.workDir/logincookies.  Access to this directory means that
+#     the ability to fake anyone in the wiki, so please make sure that only
+#     the proper admin has read access to this directory.
+#
+#  By default, cookie authentication is off.
+#
+#jspwiki.cookieAuthentication=false
+
+#
+#  Defines how many days the cookies are kept, and how often the people have to log in.  
+#  The default is two weeks, i.e. 14 days.  If you need a shorter period than one day,
+#  turn off cookie authentication, then tweak your web.xml to allow for longer sessions.
+#
+#jspwiki.cookieAuthentication.expiry=14
+
+#
+#
+#  AUTHORIZATION
+#
+#  For authorization, JSPWiki has a two-tier system. When we want to
+#  determine whether a user has permission to perform a certain action,
+#  we first consult (A) an external "authorizer" to determine if the user
+#  is a member of the required role. In addition to checking its external
+#  authorizer, it also checks (B) its GroupManager for wiki-managed groups.
+#
+#  A) EXTERNAL AUTHORIZATION
+#  By default, JSPWiki uses the servlet container's authorization service
+#  for to check what roles the user belongs to (that is, it calls
+#  HttpServletRequest.isUserInRole(String)). After the user authenticates,
+#  the default Authorizer (WebContainerAuthorizer) checks to see if the user
+#  belongs to the roles listed in web.xml using <security-role>/<role-name> or
+#  <auth-constraint>/<role-name> elements. However, you can use another
+#  Authorizer if you wish; specify that class here.
+
+jspwiki.authorizer = com.ecyrd.jspwiki.auth.authorize.WebContainerAuthorizer
+
+#  B) GROUPS
+#  As an additional source of authorization, users can belong to discretionary
+#  "wiki groups" that the users manage themselves. Wiki groups are stored in a
+#  GroupDatabase. The default group database uses an XML file for persistent
+#  storage. Override with your own GroupDatabase implementation with this property:
+
+jspwiki.groupdatabase = com.ecyrd.jspwiki.auth.authorize.XMLGroupDatabase
+
+#  The default group database implementation stores member lists
+#  in an XML file. The location of this file should be in a secure directory
+#  in the filesystem; for example, in /etc or your servlet container's
+#  configuration directory If you do not supply a value for this property,
+#  a blank group database will be initialized in the WEB-INF/ directory of the
+#  deployed webapp. Since these directories are often overwritten when webapps
+#  are undeployed or redeployed, you should probably set this property to
+#  something useful as soon as you can. But for test wikis, it's probably
+#  ok to leave this un-set, as long as users know that their groups could
+#  "disappear" if the wiki app is ever redeployed.
+
+#jspwiki.xmlGroupDatabaseFile = /etc/tomcat/groupdatabase.xml
+
+#  USER DATABASE
+#  User's wiki profiles are stored in a UserDatabase. The default user database
+#  uses an XML file for persistent storage.
+#  Override with your own UserDatabase implementation with this property:
+
+jspwiki.userdatabase = com.ecyrd.jspwiki.auth.user.XMLUserDatabase
+
+#  The default user database implementation stores usernames and passwords
+#  in an XML file. Passwords are SHA-1 hashed. The location of this file
+#  should be in a secure directory in the filesystem; for example, in
+#  /etc or your servlet container's configuration directory.
+#  If you do not supply a value for this property, a blank user database
+#  will be initialized in the WEB-INF/ directory of the deployed webapp.
+#  Since these directories are often overwritten when webapps are
+#  undeployed or redeployed, you should probably set this property to
+#  something useful as soon as you can. But for test wikis, it's probably
+#  ok to leave this un-set, as long as users know that their profiles could
+#  "disappear" if the wiki app is ever redeployed.
+
+#jspwiki.xmlUserDatabaseFile = /etc/tomcat/userdatabase.xml
+
+# You can also use a JDBC database for storing user profiles.
+# See the online AuthenticationAndAuthorization2.3 docs for details on
+# how to configure it.
+
+#jspwiki.userdatabase = com.ecyrd.jspwiki.auth.user.JDBCUserDatabase
+
+#  If your JSPWiki user database shares login information with your
+#  web container's authentication realm, you can configure JSPWiki to
+#  add container users. At present, this only works with JDBCUserDatabase,
+#  and only if you've configured your web container to use a database
+#  with compatible columns and tables. If you don't know what this means,
+#  then leave this property set to FALSE (the default).
+
+#jspwiki.userdatabase.isSharedWithContainer = false
+
+#  ACCESS CONTROL LISTS
+#  Last but not least, JSPWiki needs a way of reading and persisting page
+#  access control lists. The default implementation reads these from the page
+#  markup. For example: "[{ALLOW edit Charlie}]". If using a custom
+#  ACL manager, specify the AclManager implementation class here:
+
+jspwiki.aclManager = com.ecyrd.jspwiki.auth.acl.DefaultAclManager
+
+#############################################################################
+#
+# InterWiki links 
+#
+# The %s is replaced with the page reference (specify
+# multiple times to get multiple references).  Page references should
+# appear in format : [wiki:wikipage].  
+#
+# This is the JSPWiki home.  In future, JSPWiki will probably rely on this
+# for error messages, so I don't recommend that you change it.
+jspwiki.interWikiRef.JSPWiki = http://www.jspwiki.org/Wiki.jsp?page=%s
+
+# Here's how you can have directly links to the JSPWiki editor.
+# Now you can put a hyperlink for editing "MainPage" by making 
+# a link [Edit:MainPage].
+jspwiki.interWikiRef.Edit = Edit.jsp?page=%s
+
+#  This is the original WikiWikiWeb
+jspwiki.interWikiRef.WikiWikiWeb = http://c2.com/cgi/wiki?%s
+
+#  TWiki, a very nice WikiClone.
+jspwiki.interWikiRef.TWiki = http://twiki.org/cgi-bin/view/TWiki/%s
+
+#  MeatballWiki, which seems to be quite popular.
+jspwiki.interWikiRef.MeatballWiki = http://usemod.com/cgi-bin/mb.pl?%s
+
+#  Wikipedia, a Wiki encyclopedia!
+jspwiki.interWikiRef.Wikipedia = http://www.wikipedia.com/wiki/%s
+
+#  Google, the ubiquitous search engine.
+jspwiki.interWikiRef.Google = http://www.google.com/search?q=%s
+
+#  JSPWiki documentation (for this release)
+jspwiki.interWikiRef.Doc = http://doc.jspwiki.org/2.2/Wiki.jsp?page=%s
+
+############################################################################
+#
+# Define which image types are inlined.
+# These are your standard glob expressions (just like in your
+# Windows or UNIX shells).  Default pattern is to include all PNG
+# images.  If you specify something here, you will override the default.
+#
+# Don't forget to increase the number after the dot - duplicate entries 
+# cause problems!
+#
+# For example:
+#   Inline all JPG files, PNG files and all files from images.com:
+#
+#      jspwiki.translatorReader.inlinePattern.1 = *.jpg
+#      jspwiki.translatorReader.inlinePattern.2 = *.png
+#      jspwiki.translatorReader.inlinePattern.3 = http://images.com/*
+
+
+###########################################################################
+#
+#  Determine how the RSS (Rich Site Summary) file generation should work.
+#  RSS is a standard pioneered by Netscape, which allows you to join your
+#  Wiki with a huge number of different news services around the world.
+#  Try a Google search on RSS and see what you can do with it.
+#
+#  All of these settings were added in JSPWiki 1.7.6.
+#
+#  Note that jspwiki.baseURL MUST BE DEFINED if you want to enable RSS!
+#
+#  Determine if the RSS file should be generated at all.  Allowed values
+#  are "true" and "false".  Default is "true".
+#
+jspwiki.rss.generate = true
+
+#
+#  Determine the name of the RSS file. This path is relative to your
+#  Wiki root.  Default is "rss.rdf"
+#
+jspwiki.rss.fileName = rss.rdf
+
+#
+#  Determine the refresh interval (ie. how often the RSS file is regenerated.
+#  It is not recommended to make this too often, or you'll choke your server.
+#  Anything above five minutes is probably okay.  The default value is one hour.
+#  The value should be in seconds.
+#
+jspwiki.rss.interval = 3600
+
+#
+#  The text you want to be shown as your "channel description" when someone
+#  subscribes to it.  You can be quite verbose here, up to 500 characters or
+#  so.  You can continue to a new line by adding a backslash to the end of the
+#  line.  Default is to have no description.
+#
+jspwiki.rss.channelDescription = Oh poor me, my owner has not set \
+                                 a channel description at all. \
+                                 Pity me.
+
+#
+#  The language of your Wiki.  This is a standard, two-letter language
+#  code, or in case of some languages, two letters for the country,
+#  a dash, and two letters for the dialect.
+#
+jspwiki.rss.channelLanguage = en-us
+
+###########################################################################
+#
+#  JDBC Configuration. Tells JSPWiki which tables and columns to map
+#  to for the JDBCUserDatabase and JDBCGroupDatabase. For more info, see the
+#  JavaDoc for classes com.ecyrd.jspwiki.auth.user.JDBCUserDatabase and
+#  com.ecyrd.jspwiki.auth.authorize.JDBCGroupDatabase.
+#
+jspwiki.userdatabase.datasource=jdbc/UserDatabase
+jspwiki.userdatabase.table=users
+jspwiki.userdatabase.uid=uid
+jspwiki.userdatabase.email=email
+jspwiki.userdatabase.fullName=full_name
+jspwiki.userdatabase.loginName=login_name
+jspwiki.userdatabase.password=password
+jspwiki.userdatabase.wikiName=wiki_name
+jspwiki.userdatabase.created=created
+jspwiki.userdatabase.modified=modified
+jspwiki.userdatabase.lockExpiry=lock_expiry
+jspwiki.userdatabase.attributes=attributes
+jspwiki.userdatabase.roleTable=roles
+jspwiki.userdatabase.role=role
+jspwiki.groupdatabase.datasource=jdbc/GroupDatabase
+jspwiki.groupdatabase.table=groups
+jspwiki.groupdatabase.membertable=group_members
+jspwiki.groupdatabase.created=created
+jspwiki.groupdatabase.creator=creator
+jspwiki.groupdatabase.name=name
+jspwiki.groupdatabase.member=member
+jspwiki.groupdatabase.modified=modified
+jspwiki.groupdatabase.modifier=modifier
+
+###########################################################################
+#
+#  JavaMail configuration. If you wish to allow your users to recover
+#  their passwords via email, you should configure these properties.
+#  JavaMail can use either a container-managed JNDI resource factory
+#  (recommended, and the default), or a stand-alone factory whose properties
+#  are configured with mail.* properties in this file (below).
+#
+
+#  A. Configure the address from which the email appears to come.
+#     If you're going to use a mail session obtained via JNDI, this setting
+#     will only be used if it hasn't already been configured in the obtained
+#     session itself. If you comment it out, JSPWiki will use its internal
+#     default value.
+#     If you're going to use a stand-alone mail session, you will surely want
+#     to configure it, otherwise the internal default value will be used.
+#
+mail.from = @mail.from@
+
+#  B. JNDI Resource Factory Configuration. JSPWiki will try this first.
+#     You will need to configure your container to provide a JavaMail
+#     resource factory. See your container documentation, or check our
+#     fairly complete documentation (with examples for Tomcat) in
+#     the JavaDocs for com.ecyrd.jspwiki.util.MailUtil.
+#
+#  JNDI resource name. The commented-out value is the default.
+#jspwiki.mail.jndiname = mail/Session
+
+#  C. Stand-alone Resource Factory. JSPWiki will use these values if JNDI fails.
+#
+#  Your SMTP host (i.e. the one which sends email)
+mail.smtp.host = @mail.smtp.host@
+
+# If for some reason the standard smtp port (25) is blocked, you can change it here
+#mail.smtp.port = @mail.smtp.port@
+
+# If you are using a webserver that is publically accessible it usually
+# doesn't allow you to send mail anonymously
+# (because then this mailserver would become an open relay).
+# Therefore you can indicate your account information here...
+#
+#mail.smtp.account = @mail.smtp.account@
+#mail.smtp.password = @mail.smtp.password@
+
+# The properties below control connection timeouts and TLS (encryption)
+# if the mailserver supports it. The commented-out values are the defaults.
+#mail.smtp.timeout = 5000
+#mail.smtp.connectiontimeout = 5000
+#mail.smtp.starttls.enable = true
+
+###########################################################################
+#
+#  Determine how certain file commands are run.  They have been
+#  commented out, since most likely you want to use the defaults.
+#  Be warned, making mistakes with these may well ruin your entire
+#  Wiki collection!
+#
+#  The command to run diff:
+#     NOTE! If you do not specify this, an internal "diff" routine is used.
+#           In most cases, you really should not touch this.
+#
+#jspwiki.diffCommand = diff -u %s1 %s2
+
+#  The command for RCS checkin
+#jspwiki.rcsFileProvider.checkinCommand = ci -q -mx -l -t-none %s
+
+#  The command for RCS checkout of the newest version
+#jspwiki.rcsFileProvider.checkoutCommand = co -l %s
+
+#  The command for checking out a specific version (%v = version number)
+#jspwiki.rcsFileProvider.checkoutVersionCommand = co -p -r1.%v %s
+
+#  The command for RCS log headers
+#jspwiki.rcsFileProvider.logCommand = rlog -zLT -h %s
+
+#  The command for getting the entire modification history
+#jspwiki.rcsFileProvider.fullLogCommand = rlog -zLT %s
+
+
+###########################################################################
+#
+#  Configure logs.  See log4j documentation for more information
+#  on how you can configure the logs.
+#
+#  Log4j is available at http://jakarta.apache.org/log4j
+#
+#  Send mail to root on all problems containing warnings.
+#
+#log4j.appender.mail = org.apache.log4j.net.SMTPAppender
+#log4j.appender.mail.Threshold = WARN
+#log4j.appender.mail.To = root at localhost
+#log4j.appender.mail.From = JSPWiki at localhost
+#log4j.appender.mail.Subject = Problem with JSPWiki!
+#log4j.appender.mail.SMTPHost = mail
+
+#log4j.appender.mail.layout = org.apache.log4j.PatternLayout
+#log4j.appender.mail.layout.ConversionPattern =%d [%t] %p %c %x - %m%n
+
+#
+#  Log everything into a file, roll it over every 10 MB, keep
+#  only 14 latest ones.
+#
+log4j.appender.FileLog = org.apache.log4j.RollingFileAppender
+log4j.appender.FileLog.MaxFileSize    = 10MB
+log4j.appender.FileLog.MaxBackupIndex = 14
+log4j.appender.FileLog.File = /var/log/tomcat6/jspwiki.log
+log4j.appender.FileLog.layout = org.apache.log4j.PatternLayout
+log4j.appender.FileLog.layout.ConversionPattern=%d [%t] %p %c %x - %m%n
+
+# Enable if you're using mailing, above.
+#log4j.rootCategory=DEBUG,FileLog,mail
+log4j.rootCategory=DEBUG,FileLog
+
+###########################################################################
+#
+# Workflow configuration
+#
+# The following properties map specific workflow steps to their associated approvers
+# The name of the workflow or decision is the part of the key after "jspwiki.approver.".
+# This is a logical name JSPWiki uses to determine which Principal to consult for approval.
+# The Principal is identified up by AuthorizationManager at runtime; it looks for a Principal
+# match as follows: GroupPrincipals; Roles; WikiPrincipals/other principals. Thus, if a value
+# of "Admin" is supplied JSPWiki will first check the GroupManager to see if group Admin exits;
+# then the container roles, if any; then, user Principals. If the value is blank or the
+# property is commented out, it means that the workflow does not require approval.
+#
+# EXAMPLE:
+# Uncomment the next line to require the Admin group (or Admin user, if a group is not found)
+# to approve wiki pages after saving.
+#jspwiki.approver.workflow.saveWikiPage=Admin
+
+# Uncomment the next line to require the Admin group to approve new user profiles
+#jspwiki.approver.workflow.createUserProfile=Admin
+
+### End of configuration file.
diff --git a/debian/jspwiki.templates b/debian/jspwiki.templates
new file mode 100644
index 0000000..1369cf2
--- /dev/null
+++ b/debian/jspwiki.templates
@@ -0,0 +1,124 @@
+# These templates have been reviewed by the debian-l10n-english
+# team
+#
+# If modifications/additions/rewording are needed, please ask
+# debian-l10n-english at lists.debian.org for advice.
+#
+# Even minor modifications require translation updates and such
+# changes should be coordinated with translators and reviewers.
+
+Template: jspwiki/applicationname
+Type: string
+Default: JSPWiki
+_Description: Default application name:
+ Please enter the name of the wiki. This name appears in HTML titles
+ and log files, and is usually the same as the top level URL (for
+ instance 'http://www.example.org/JSPWiki').
+
+Template: jspwiki/baseurl
+Type: string
+Default: http://localhost:8180/JSPWiki/
+_Description: Default application name:
+ Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki
+ internal link references, so it needs to be correct. It also needs
+ to contain the trailing slash.
+
+Template: jspwiki/pageprovider
+Type: select
+Choices: FileSystemProvider, RCSFileProvider, VersioningFileProvider
+Default: FileSystemProvider
+_Description: Page storage mechanism to be used by JSPWiki:
+ Please choose the mechanism that should be used for storing pages:
+ .
+  FileSystemProvider:     simply storing pages as files;
+  RCSFileProvider:        using an external Revision Control System;
+  VersioningFileProvider: versioning storage implemented in Java.
+
+Template: jspwiki/usepagecache
+Type: boolean
+Default: false
+_Description: Should JSPWiki use a page cache?
+ Page caching usually improves performance but increases memory usage.
+
+Template: jspwiki/baseurl
+Type: string
+Default: 
+_Description: JSPWiki base URL:
+ Base URLs are used to rewrite all of JSPWiki's internal references.
+ .
+ A trailing slash ('/') character is mandatory.
+
+Template: jspwiki/encoding
+Type: select
+Choices: ISO-8859-1, UTF-8
+Default: UTF-8
+_Description: Page encoding:
+ Please choose which character encoding should be used by
+ JSPWiki. UTF-8 is strongly recommended.
+
+Template: jspwiki/breaktitlewithspaces
+Type: boolean
+Default: false
+_Description: Break at capitals in page names?
+ Please choose whether page titles should be rendered using an extra
+ space after each capital letter. This causes 'RSSPage' to be shown as
+ 'R S S Page'.
+
+Template: jspwiki/matchenglishplurals
+Type: boolean
+Default: false
+_Description: Match plural form to singular form in page names?
+ Choosing this option will cause JSPWiki to match 'PageLinks' to
+ 'PageLink' if 'PageLinks' is not found.
+
+Template: jspwiki/camelcaselinks
+Type: boolean
+Default: false
+_Description: Use CamelCase links?
+ Please choose whether JSPWiki should consider traditional WikiNames
+ (names of pages JustSmashedTogether without square brackets) as
+ hyperlinks.
+
+Template: jspwiki/rss/generate
+Type: boolean
+Default: false
+_Description: Generate RSS feed?
+ JSPWiki can generate a Rich Site Summary feed so that users can track
+ changes to the wiki.
+
+Template: jspwiki/rss/refresh
+Type: string
+Default: 3600
+_Description: RSS refresh time in seconds:
+ Please choose the delay between RSS feed refreshes.
+
+Template: jspwiki/rss/channeldescription
+Type: string
+_Description: RSS channel description:
+ Please give a channel description for the RSS feed, to be shown in
+ channel catalogs. There is no maximum length, so include whatever
+ details users may find helpful.
+
+Template: jspwiki/rss/channellanguage
+Type: string
+Default: en-us
+_Description: RSS channel language:
+ Please choose the RSS feed language. This should match the language of the
+ wiki.
+
+Template: jspwiki/attachments/provider
+Type: select
+#flag:translate!:1
+__Choices: BasicAttachmentProvider, nothing
+Default: BasicAttachmentProvider
+_Description: Attachment storage mechanism to use:
+ 'BasicAttachmentProvider' uses the same directory structure as the
+ selected page storage mechanism. It simply stores the attachments in
+ a dedicated directory for a page.
+
+Template: jspwiki/purgewikifiles
+Type: boolean
+Default: false
+_Description: Should all wiki pages be deleted on package purge?
+ Please choose whether you want all wiki pages to be removed when the
+ package is purged.
diff --git a/debian/jspwiki.xml b/debian/jspwiki.xml
new file mode 100644
index 0000000..b44fe80
--- /dev/null
+++ b/debian/jspwiki.xml
@@ -0,0 +1,5 @@
+<Context path="/JSPWiki" docBase="/usr/share/jspwiki" allowLinking="true">
+    <Resources className="org.apache.naming.resources.FileDirContext"
+               allowLinking="true"/>
+</Context>
+
diff --git a/debian/patches/01_jabsorb_api.dpatch b/debian/patches/01_jabsorb_api.dpatch
new file mode 100644
index 0000000..060db4e
--- /dev/null
+++ b/debian/patches/01_jabsorb_api.dpatch
@@ -0,0 +1,44 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 01_jabsorb_api.dpatch by  <killer at inara.kivimaa.fi>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+diff -urNad jspwiki-2.8.0~/etc/web.xml jspwiki-2.8.0/etc/web.xml
+--- jspwiki-2.8.0~/etc/web.xml	2008-08-03 14:07:18.000000000 +0300
++++ jspwiki-2.8.0/etc/web.xml	2008-10-24 17:52:34.000000000 +0300
+@@ -126,8 +126,8 @@
+ 
+    <!-- JSON AJAX API -->
+    <servlet>
+-       <servlet-name>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-name>
+-       <servlet-class>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-class>
++       <servlet-name>org.jabsorb.JSONRPCServlet</servlet-name>
++       <servlet-class>org.jabsorb.JSONRPCServlet</servlet-class>
+    </servlet>
+ 
+    <!-- Atom Publishing Protocol -->
+@@ -204,7 +204,7 @@
+    -->
+    
+    <servlet-mapping>
+-       <servlet-name>com.metaparadigm.jsonrpc.JSONRPCServlet</servlet-name>
++       <servlet-name>org.jabsorb.JSONRPCServlet</servlet-name>
+        <url-pattern>/JSON-RPC</url-pattern>
+    </servlet-mapping>
+ 
+diff -urNad jspwiki-2.8.0~/src/com/ecyrd/jspwiki/rpc/json/JSONRPCManager.java jspwiki-2.8.0/src/com/ecyrd/jspwiki/rpc/json/JSONRPCManager.java
+--- jspwiki-2.8.0~/src/com/ecyrd/jspwiki/rpc/json/JSONRPCManager.java	2008-05-30 21:40:40.000000000 +0300
++++ jspwiki-2.8.0/src/com/ecyrd/jspwiki/rpc/json/JSONRPCManager.java	2008-10-24 17:51:29.000000000 +0300
+@@ -38,8 +38,8 @@
+ import com.ecyrd.jspwiki.rpc.RPCCallable;
+ import com.ecyrd.jspwiki.rpc.RPCManager;
+ import com.ecyrd.jspwiki.ui.TemplateManager;
+-import com.metaparadigm.jsonrpc.InvocationCallback;
+-import com.metaparadigm.jsonrpc.JSONRPCBridge;
++import org.jabsorb.InvocationCallback;
++import org.jabsorb.JSONRPCBridge;
+ 
+ /**
+  *  Provides an easy-to-use interface for different modules to AJAX-enable
diff --git a/debian/patches/02_ignore_binary_jars.dpatch b/debian/patches/02_ignore_binary_jars.dpatch
new file mode 100644
index 0000000..53f719a
--- /dev/null
+++ b/debian/patches/02_ignore_binary_jars.dpatch
@@ -0,0 +1,19 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 02_ignore_binary_jars.dpatch by  <killer at inara.kivimaa.fi>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: No description.
+
+ at DPATCH@
+diff -urNad jspwiki-2.8.0~/build.xml jspwiki-2.8.0/build.xml
+--- jspwiki-2.8.0~/build.xml	2008-09-27 20:45:04.000000000 +0300
++++ jspwiki-2.8.0/build.xml	2008-10-24 18:19:53.000000000 +0300
+@@ -141,7 +141,7 @@
+        add all the jar files in the "lib" -directory. -->
+   <path id="path.base">
+      <pathelement path="${code.build}" />
+-     <fileset dir="lib">
++     <fileset dir="/usr/share/java">
+         <include name="*.jar" />
+      </fileset>
+   </path>
diff --git a/debian/po/POTFILES.in b/debian/po/POTFILES.in
new file mode 100644
index 0000000..5c1e2de
--- /dev/null
+++ b/debian/po/POTFILES.in
@@ -0,0 +1 @@
+[type: gettext/rfc822deb] jspwiki.templates
diff --git a/debian/po/cs.po b/debian/po/cs.po
new file mode 100644
index 0000000..5b131e6
--- /dev/null
+++ b/debian/po/cs.po
@@ -0,0 +1,349 @@
+#
+#    Translators, if you are not familiar with the PO format, gettext
+#    documentation is worth reading, especially sections dedicated to
+#    this format, e.g. by running:
+#         info -n '(gettext)PO Files'
+#         info -n '(gettext)Header Entry'
+#
+#    Some information specific to po-debconf are available at
+#            /usr/share/doc/po-debconf/README-trans
+#         or http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+#    Developers do not need to manually edit POT or PO files.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-09-14 17:35+0200\n"
+"Last-Translator: Miroslav Kure <kurem at debian.cz>\n"
+"Language-Team: Czech <debian-l10n-czech at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Výchozí jméno aplikace:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Zadejte prosím jméno této wiki. Zadané jméno se objeví v titulcích HTML "
+"stránek a v logu. Obvykle bývá shodné s nejvyšším URL (například „http://www."
+"priklad.cz/JSPWiki“)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Zadejte prosím HTTP prefix této wiki. Prefix se použije pro přepisování "
+"interních wiki odkazů na platná url. Prefix je třeba zadat včetně koncového "
+"lomítka."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Způsob ukládání stránek:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Vyberte prosím způsob ukládání stránek:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     jednoduše ukládá stránky jako soubory;\n"
+" RCSFileProvider:        použije externí systém pro správu revizí;\n"
+" VersioningFileProvider: verzované úložiště implementované v Javě."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Má JSPWiki cachovat stránky?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Ukládání stránek do mezipaměti obvykle zlepší výkon, ale zvýší paměťové "
+"nároky."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "Základní URL JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr "Základní URL se používají pro přepsání všech interních odkazů JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Koncové lomítko („/“) je povinné."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Kódování stránek:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Zvolte prosím kódování znaků, které má JSPWiki používat. Je doporučeno "
+"použít kódování UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Mezery za velkými písmeny v názvech stránek?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Vyberte si, zda se mají názvy stránek vykreslit se speciální mezerou po "
+"každém velkém písmenu. To znamená, že „RSSStránka“ se zobrazí jako „R S S "
+"Stránka“."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Převádět názvy stránek z množného čísla na jednoduché?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Výběr této možnosti způsobí, že pokud JSPWiki nenalezne např. „PageLinks“, "
+"zkusí variantu „PageLink“. Na češtinu to evidentně fungovat nebude."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Používat VelbloudíOdkazy?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Vyberte, zda má JSPWiki považovat tradiční WikiJména (jména stránek "
+"StlačenáDohromady bez hranatých závorek) za hypertextové odkazy."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Vytvářet RSS kanál?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki může vytvořit RSS (Rich Site Summary) kanál, díky kterému mohou "
+"uživatelé sledovat změny ve wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Obnovování RSS (v sekundách):"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Zadejte prosím pauzu mezi obnovováním RSS kanálu."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Popis RSS kanálu:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Zadejte prosím popis tohoto RSS kanálu. Popis se zobrazí v seznamu kanálů. "
+"Nejste omezeni délkou textu, takže napište jakékoliv podrobnosti, o kterých "
+"si myslíte, že mohou pomoci vašim uživatelům."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Jazyk RSS kanálu:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Vyberte prosím jazyk RSS kanálu. Tento jazyk by měl odpovídat jazyku "
+"použitému ve wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "žádný"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Způsob ukládání příloh:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"„BasicAttachmentProvider“ používá stejnou adresářovou strukturu jako zvolený "
+"správce stránek. Přílohy jednoduše ukládá ve vyhrazeném adresáři dané "
+"stránky."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Mají se při odstranění balíku smazat všechny wiki stránky?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Rozhodněte se, zda chcete při vyčištění balíku ze systému odstranit také "
+"všechny wiki stránky."
+
+#~ msgid "Which page provider JSPWiki should use"
+#~ msgstr "Kterého správce stránek má JSWiki použít"
+
+#~ msgid ""
+#~ "Which page provider class to use. FileSystemProvider is a simple file "
+#~ "based page storage, RCSFileProvider uses RCS as the page store, and "
+#~ "VersioningFileProvider is a pure Java implementation of a versioning page "
+#~ "store."
+#~ msgstr ""
+#~ "Kterého správce stránek použít. FileSystemProvider je úložiště stránek "
+#~ "založené na jednoduchých souborech. RCSFileProvider používá pro ukládání "
+#~ "stránek RCS a třída VersioningFileProvider je čistě javovská implementace "
+#~ "verzovaného ukládání stránek."
+
+#~ msgid "JSPWiki base URL (http://www.example.com/JSPWiki/)"
+#~ msgstr "Základní adresa JSPWiki (http://www.priklad.cz/JSPWiki/)"
+
+#~| msgid ""
+#~| "Base URL's are used to rewrite all of JSPWiki's internal references. "
+#~| "Don't forget the trailing slash. This must be used if the URL that "
+#~| "JSPWiki sees through the servlet container is different from the real "
+#~| "URL."
+#~ msgid ""
+#~ "Base URLs are used to rewrite all of JSPWiki's internal references. Don't "
+#~ "forget the trailing slash. This must be used if the URL that JSPWiki sees "
+#~ "through the servlet container is different from the real URL."
+#~ msgstr ""
+#~ "Základní adresa se používá pro přepisování interních odkazů JSPWiki. "
+#~ "Nezapomeňte koncové lomítko. Tuto volbu musíte použít v případě, že se "
+#~ "adresa, kterou vidí JSPWiki přes servletový kontejner, liší od skutečné "
+#~ "adresy."
+
+#~ msgid ""
+#~ "Determines which character encoding JSPWiki should use. UTF-8 may cause "
+#~ "problems on some Tomcat 4 installations but is otherwise a good choice."
+#~ msgstr ""
+#~ "Určí kódování znaků, které má JSPWiki používat. UTF-8 může na některých "
+#~ "instalacích Tomcatu 4 způsobovat problémy, ale jinak je dobrou volbou."
+
+#~ msgid ""
+#~ "How often the RSS feed should be refreshed. An hour (3600 seconds) is a "
+#~ "good starting choice."
+#~ msgstr ""
+#~ "Jak často se má RSS kanál obnovovat. Rozumná počáteční hodnota je jedna "
+#~ "hodina (3600 sekund)."
+
+#~ msgid ""
+#~ "This describes your RSS channel. Be as verbose as you want, there is no "
+#~ "upper limit, and it helps the users."
+#~ msgstr ""
+#~ "Tímto popíšete svůj RSS kanál. Buďte upovídaní, protože neexistuje horní "
+#~ "limit pro délku a pomůže to vašim uživatelům."
+
+#~| msgid ""
+#~| "This should match the language of your Wiki. It let's people know what "
+#~| "language they should expect in the RSS feed."
+#~ msgid ""
+#~ "This should match the language of your Wiki. It lets people know what "
+#~ "language they should expect in the RSS feed."
+#~ msgstr ""
+#~ "Toto by mělo odpovídat jazyku vaší Wiki. Dáte tím světu na vědomí, jaký "
+#~ "jazyk by měli ve vašem RSS kanálu očekávat."
+
+#~ msgid ""
+#~ "If you have no important information stored in your wiki and really want "
+#~ "to get rid of the page data, the purge process can do this for you."
+#~ msgstr ""
+#~ "Pokud ve wiki nemáte žádné důležité informace a chcete se svých stránek "
+#~ "zbavit, tento skript se o to může postarat."
diff --git a/debian/po/da.po b/debian/po/da.po
new file mode 100644
index 0000000..b3ce4da
--- /dev/null
+++ b/debian/po/da.po
@@ -0,0 +1,270 @@
+# Danish translation jspwiki.
+# Copyright (C) 2010 jspwiki & Joe Hansen.
+# This file is distributed under the same license as the jspwiki package.
+# Joe Hansen <joedalton2 at yahoo.dk>, 2010. 
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2010-05-05 17:30+01:00\n"
+"Last-Translator: Joe Hansen <joedalton2 at yahoo.dk>\n"
+"Language-Team: Danish <debian-l10n-danish at lists.debian.org> \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Standardprogramnavn:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Indtast venligst navnet p?? wikien. Dette navn fremst??r i HTML-titler og "
+"logfiler, og er normalt det samme som URL'en p?? ??verste niveau (for "
+"eksempel http://www.example.org/JSPWiki)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Indtast venligst HTTP-pr??fikset p?? wikien. Dette genskriver alle interne "
+"henvisningsreferencer til JSPWiki, s?? det skal rettes. Den skal ogs?? "
+"indeholde skr??streg."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Mekanisme for sidegemning som skal bruges af JSPWiki:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "V??lg venligst mekanismen som skal bruges til at gemme sider:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" Filsystemudbyder:        Gem sider som filer;\n"
+" RCS-filudbyder:          Brug af ekstern revisionskontrolsystem;\n"
+" Versioneringsfiludbyder: Versioneringslager implementeret i Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Skal JSPWiki bruge sidemellemlager (cache)?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Sidemellemlager (cache) forbedrer normalt ydelsen men ??ger "
+"hukommelsesforbruget."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "JSPWikis base-URL:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr "Base-URL'er bruges til at genskrive alle JSPWikis interne referencer."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "En skr??streg (??/??) er obligatorisk."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Sidekodning:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"V??lg venligst hvilken tegnkodning der skal bruges af JSPWiki. UTF-8 "
+"anbefales st??rkt."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Ekstra plads ved store bogstaver i sidenavne?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"V??lg venligst om sidetitler skal optegnes med brug af ekstra plads efter "
+"hvert stort bogstav. Dette betyder at ??RSSPage?? bliver vist som ??R S S "
+"Page??."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Match flertalsform med entalsform i sidenavne?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Valg af denne indstilling vil f?? JSPWiki til at matche ??PageLinks?? med ??"
+"PageLink?? hvis ??PageLinks?? ikke findes."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Brug sammensatte henvisninger (CamelCase)?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"V??lg venligst hvorvidt JSPWiki skal anse traditionelle Wikinavne (navne p?? "
+"sider JustSmashedTogether uden klammer) som hyperhenvisninger."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Opret RSS-nyhedskilde?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki kan oprette en nyhedskilde af typen Rich Site Summary s?? brugere "
+"kan spore ??ndringer p?? wikien."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS-opdateringstid i sekunder:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "V??lg venligst forsinkelsen p?? opdateringer mellem RSS-nyhedskilder"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS-kanalbeskrivelse:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Giv venligst en kanalbeskrivelse p?? RSS-nyhedskilden, som vises i "
+"kanalkataloger. Der er ingen maksimal l??ngde, s?? inkluder alle de detaljer "
+"som kan hj??lpe brugerne."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "RSS-kanalsprog:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"V??lg venligst RSS-nyhedskildesproget. Dette skal svare til sproget p?? "
+"wikien."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "intet"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Lagermekanisme til bilag der skal bruges:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"??BasicAttachmentProvider?? bruger den samme mappestruktur som den valgte "
+"sidelagermekanisme. Den gemmer bilagene i en dedikeret mappe for en side."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Skal alle wikisider slettes ved pakkeoprydning?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"V??lg venligst hvorvidt du ??nsker, at alle wikisider skal fjernes, n??r "
+"pakken ryddes op."
diff --git a/debian/po/de.po b/debian/po/de.po
new file mode 100644
index 0000000..2b55ee5
--- /dev/null
+++ b/debian/po/de.po
@@ -0,0 +1,345 @@
+# Translation of jspwiki debconf templates to German
+# Copyright (C) Helge Kreutzmann <debian at helgefjell.de>, 2007, 2008.
+# This file is distributed under the same license as the jspwiki package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0-3\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2008-12-22 19:13+0100\n"
+"Last-Translator: Helge Kreutzmann <debian at helgefjell.de>\n"
+"Language-Team: de <debian-l10n-german at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-15\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Voreingestellter Anwendungsname:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Bitte geben Sie den Namen des Wikis ein. Dieser Name taucht in HTML-Titeln "
+"und Log-Dateien auf. Er stimmt normalerweise mit der URL der obersten Stufe "
+"(zum Beispiel �http://www.example.org/JSPWiki�) �berein."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Bitte geben Sie den HTTP-Pr�fix des Wikis ein. Dieser schreibt alle JSPWiki-"
+"internen Link-Referenzen um, daher muss er korrekt sein. Er muss auch den "
+"abschlie�enden Schr�gstrich enthalten."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Seitenspeicher-Mechanismus, der von JSPWiki verwendet werden soll:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr ""
+"Bitte w�hlen Sie den Mechanismus aus, der zum Speichern von Seiten verwendet "
+"werden soll:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     speichert Seiten einfach als Dateien;\n"
+" RCSFileProvider:        verwendet ein externes Versionskontrollsystem;\n"
+" VersioningFileProvider: in Java implementierter versionierter Speicher."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Soll JSPWiki einen Seiten-Cache verwenden?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Cachen von Seiten verbessert typischerweise die Leistung, erh�ht aber den "
+"Speicherverbrauch."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "Basis-URL des JSPWikis:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Basis-URLs werden zum Umschreiben aller internen Referenzen von JSPWiki "
+"verwendet."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Ein abschlie�ender Schr�gstrich (�/�) ist zwingend erforderlich."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Seitenkodierung:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Bitte w�hlen Sie aus, welche Zeichenkodierung von JSPWiki verwendet werden "
+"soll. UTF-8 wird nachdr�cklich empfohlen."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Bei Gro�buchstaben in Seitennamen trennen?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Bitte w�hlen Sie aus, ob Seitentitel mit einem extra Leerzeichen nach jedem "
+"Gro�buchstaben dargestellt werden sollen. Damit wird �RSSPage� als �R S S "
+"Page� angezeigt."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Verkn�pfe in Seitennamen Pluralformen mit Singularformen?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Die Auswahl dieser Option f�hrt dazu, dass in JSPWiki �PageLinks� auf "
+"�PageLink� passt, falls �PageLinks� nicht gefunden wird."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Verwende CamelCase-Links?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Bitte w�hlen Sie aus, ob JSPWiki traditionelle WikiNamen (Namen von Seiten, "
+"die EinfachZusammengequetschtSind ohne eckige Klammern) als Querverweise "
+"(Hyperlinks) betrachten soll."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Erstelle RSS-Feed?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki kann einen �Rich Site Summary�-Feed erstellen, damit Benutzer die "
+"�nderungen am Wiki verfolgen k�nnen."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS-Aktualisierungszeit in Sekunden:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr ""
+"Bitte w�hlen Sie den Zeitabstand zwischen Aktualisierungen des RSS-Feeds."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS-Kanalbeschreibung:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Bitte geben Sie eine Kanalbeschreibung f�r den RSS-Feed an, der dann im "
+"Kanalkatalog angezeigt wird. Es gibt keine Maximall�nge, f�gen Sie daher "
+"alle Details hinzu, die den Benutzern helfen k�nnten."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Sprache des RSS-Kanals"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Bitte w�hlen Sie die Sprache des RSS-Feeds. Diese sollte zu der Sprache des "
+"Wikis passen."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "nichts"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Zu verwendender Speichermechanismus f�r Anh�nge:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"�EinfacherAnhangsanbieter� verwendet die gleiche Verzeichnisstruktur wie der "
+"ausgew�hlte Seitenspeichermechanismus. Es speichert einfach die Anh�nge in "
+"einem dedizierten Verzeichnis f�r eine Seite."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr ""
+"Sollen alle Wiki-Seiten beim vollst�ndigen Entfernen des Pakets gel�scht "
+"werden?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Bitte w�hlen Sie aus, ob alle Wiki-Seiten gel�scht werden sollen, wenn das "
+"Paket endg�ltig entfernt (�purged�) wird."
+
+#~ msgid "BasicAttachmentProvider, nothing"
+#~ msgstr "EinfacherAnhangsanbieter, nichts"
+
+#~ msgid "Which page provider JSPWiki should use"
+#~ msgstr "Welchen Seitenanbieter JSPWiki verwenden soll"
+
+#~ msgid ""
+#~ "Which page provider class to use. FileSystemProvider is a simple file "
+#~ "based page storage, RCSFileProvider uses RCS as the page store, and "
+#~ "VersioningFileProvider is a pure Java implementation of a versioning page "
+#~ "store."
+#~ msgstr ""
+#~ "Welche Seitenanbieterklassen zu verwenden sind. FileSystemProvider ist "
+#~ "eine einfache Datei-basierte Seitenspeicherung, RCSFileProvider verwendet "
+#~ "RCS als Seitenspeicher und VersioningFileProvider ist eine reine Java-"
+#~ "Implementierung eines versionierten Seitenspeichers."
+
+#~ msgid "JSPWiki base URL (http://www.example.com/JSPWiki/)"
+#~ msgstr "JSPWiki Basis-URL (http://www.example.com/JSPWiki/)"
+
+#~ msgid ""
+#~ "Base URLs are used to rewrite all of JSPWiki's internal references. Don't "
+#~ "forget the trailing slash. This must be used if the URL that JSPWiki sees "
+#~ "through the servlet container is different from the real URL."
+#~ msgstr ""
+#~ "Basis-URLs werden zum Umschreiben aller JSPWiki-internen Referenzen "
+#~ "verwendet. Vergessen Sie nicht den abschlie�enden Schr�gstrich. Dies muss "
+#~ "verwendet werden, falls die URL, die JSPWiki durch den Servlet-Container "
+#~ "sieht, sich von der echten URL unterscheidet."
+
+#~ msgid ""
+#~ "Determines which character encoding JSPWiki should use. UTF-8 may cause "
+#~ "problems on some Tomcat 4 installations but is otherwise a good choice."
+#~ msgstr ""
+#~ "Bestimmt, welche Zeichenkodierung JSPWiki verwenden soll. UTF-8 k�nnte "
+#~ "Probleme bei einigen Tomcat 4-Installationen bereiten, ist aber "
+#~ "andernfalls eine gute Wahl."
+
+#~ msgid ""
+#~ "How often the RSS feed should be refreshed. An hour (3600 seconds) is a "
+#~ "good starting choice."
+#~ msgstr ""
+#~ "Wie oft der RSS-Feed aktualisiert werden soll. Eine Stunde (3600 "
+#~ "Sekunden) ist ein guter Startwert."
+
+#~ msgid ""
+#~ "This describes your RSS channel. Be as verbose as you want, there is no "
+#~ "upper limit, and it helps the users."
+#~ msgstr ""
+#~ "Dies beschreibt Ihren RSS-Kanal. Seien Sie so ausf�hrlich wie Sie "
+#~ "m�chten, es gibt keine obere Grenze und hilft den Benutzern."
+
+#~ msgid ""
+#~ "This should match the language of your Wiki. It lets people know what "
+#~ "language they should expect in the RSS feed."
+#~ msgstr ""
+#~ "Dies sollte zu der Sprache Ihres Wikis passen. Es l�sst die Leute wissen, "
+#~ "welche Sprache sie im RSS-Feed erwarten sollten."
+
+#~ msgid ""
+#~ "If you have no important information stored in your wiki and really want "
+#~ "to get rid of the page data, the purge process can do this for you."
+#~ msgstr ""
+#~ "Falls Sie keine wichtigen Informationen im Wiki gespeichert haben und "
+#~ "wirklich die Seitendaten los werden wollen, kann dies der Prozess "
+#~ "�vollst�ndiges L�schen� (purge) f�r Sie erledigen."
diff --git a/debian/po/es.po b/debian/po/es.po
new file mode 100644
index 0000000..ee1c63c
--- /dev/null
+++ b/debian/po/es.po
@@ -0,0 +1,369 @@
+# jspwiki po-debconf translation to Spanish
+# Copyright (C) 2007, 2009 Software in the Public Interest
+# This file is distributed under the same license as the jspwiki package.
+#
+# Changes:
+#   - Initial translation
+#       Enrique Matias Sanchez (aka Quique) <cronopios at gmail.com>, 2007
+#
+#   - Updates
+#       Francisco Javier Cuadrado <fcocuadrado at gmail.com>, 2009
+#
+# Traductores, si no conocen el formato PO, merece la pena leer la
+# documentación de gettext, especialmente las secciones dedicadas a este
+# formato, por ejemplo ejecutando:
+#       info -n '(gettext)PO Files'
+#       info -n '(gettext)Header Entry'
+#
+# Equipo de traducción al español, por favor, lean antes de traducir
+# los siguientes documentos:
+#
+#   - El proyecto de traducción de Debian al español
+#     http://www.debian.org/intl/spanish/
+#     especialmente las notas de traducción en
+#     http://www.debian.org/intl/spanish/notas
+#
+#   - La guía de traducción de po's de debconf:
+#     /usr/share/doc/po-debconf/README-trans
+#     o http://www.debian.org/intl/l10n/po-debconf/README-trans
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0-3\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-09-14 08:54+0100\n"
+"Last-Translator: Francisco Javier Cuadrado <fcocuadrado at gmail.com>\n"
+"Language-Team: Debian l10n Spanish <debian-l10n-spanish at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Nombre predeterminado de la aplicación:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Introduzca el nombre del wiki. Este nombre aparecerá en los títulos HTML y "
+"en los archivos de registro, y normalmente es el mismo que la URL de primer "
+"nivel (por ejemplo: «http://www.ejemplo.org/JSPWiki»)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Introduzca el prefijo HTTP del wiki. Esto hará que se reescriban todas las "
+"referencias a enlaces internos de JSPWiki, por lo que debe ser correcto. "
+"También debe contener la barra lateral del final."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Mecanismo de almacenamiento de páginas que JSPWiki va a utilizar:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr ""
+"Escoja el mecanismo que se debería utilizar para almacenar las páginas:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     almacena las páginas como archivos.\n"
+" RCSFileProvider:        utiliza un sistema de control de versiones "
+"externo.\n"
+" VersioningFileProvider: almacenamiento con versiones implementado en Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "¿Debe JSPWiki utilizar una cache de páginas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"La cache de páginas normalmente mejora el rendimiento pero incrementa el uso "
+"de la memoria."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL base de JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Las URL base se utilizarán para reescribir todas las referencias internas de "
+"JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Es obligatoria la barra lateral al final ('/')."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Codificación de la página:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Escoja que codificación de caracteres debería utilizar JSPWiki. Se "
+"recomienda encarecidamente que sea UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "¿Desea romper los nombres de páginas en las letras mayúsculas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Escoja si los títulos de las páginas se deben crear utilizando un espacio "
+"extra después de cada letra mayúscula. Esto provocaría que «PáginaRSS» se "
+"mostrase como «Página R S S»."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr ""
+"¿Desea hacer coincidir las formas plurales con las singulares en los nombres "
+"de las páginas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Escoger esta opción provocará que JSPWiki redirija «PáginaDeEnlaces» a "
+"«PáginaDeEnlace» si «PáginaDeEnlaces» no existe."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "¿Desea usar enlaces en formato «CamelCase»?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Escoja esta opción si JSPWiki debe considerar los «NombresWiki» tradicionales "
+"(nombres de páginas de «PalabrasPuestasJuntas» sin corchetes) como enlaces."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "¿Desea generar un «feed» RSS?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki puede generar un «feed» RSS («Rich Site Summary»), de modo que los "
+"usuarios puedan seguir los cambios del wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Intervalo de actualización del RSS en segundos:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Escoja el intervalo entre actualizaciones del «feed» RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Descripción del canal RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Proporcione una descripción del canal para el «feed» RSS, que se mostrará en "
+"los catálogos de canales. No hay una longitud máxima, de modo que incluya "
+"cualquier detalle que los usuarios puedan encontrar útil."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Idioma del canal RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Escoja el idioma del «feed» RSS. Debería coincidir con el idioma del wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "nada"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Mecanismo de almacenamiento de los archivos adjuntos a utilizar:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"«BasicAttachmentProvider» utiliza la misma estructura de directorios que el "
+"almacenamiento de páginas seleccionado. Simplemente almacena los archivos "
+"adjuntos en un directorio dedicado para cada página."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "¿Se deben borrar todas las páginas del wiki al purgar el paquete?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Escoja si quiere que todas las páginas del wiki se eliminen cuando el "
+"paquete se purgue."
+
+#~ msgid "Which page provider JSPWiki should use"
+#~ msgstr "¿Qué proveedor de páginas debe usar JSPWiki?"
+
+#~ msgid ""
+#~ "Which page provider class to use. FileSystemProvider is a simple file "
+#~ "based page storage, RCSFileProvider uses RCS as the page store, and "
+#~ "VersioningFileProvider is a pure Java implementation of a versioning page "
+#~ "store."
+#~ msgstr ""
+#~ "Clase de proveedor de páginas a usar. FileSystemProvider es un sencillo "
+#~ "almacenamiento de páginas basado en ficheros, RCSFileProvider utiliza RCS "
+#~ "como almacén de páginas, y VersioningFileProvider es una implementación "
+#~ "de un almacén de páginas con gestión de versiones escrita puramente en "
+#~ "Java ."
+
+#~ msgid "JSPWiki base URL (http://www.example.com/JSPWiki/)"
+#~ msgstr "URL base de JSPWiki (http://www.ejemplo.com/JSPWiki/)"
+
+#~ msgid ""
+#~ "Base URL's are used to rewrite all of JSPWiki's internal references. "
+#~ "Don't forget the trailing slash. This must be used if the URL that "
+#~ "JSPWiki sees through the servlet container is different from the real URL."
+#~ msgstr ""
+#~ "Los URL base se utilizan para reescribir todas las referencias internas "
+#~ "de JSPWiki. No olvide la barra final. Esto se debe usar si el URL que ve "
+#~ "JSPWiki a través del contenedor de miniservidores es diferente al URL "
+#~ "real."
+
+#~ msgid ""
+#~ "Determines which character encoding JSPWiki should use. UTF-8 may cause "
+#~ "problems on some Tomcat 4 installations but is otherwise a good choice."
+#~ msgstr ""
+#~ "Determina qué codificación de caracteres utilizará JSPWiki. UTF-8 puede "
+#~ "provocar problemas en algunas instalaciones de Tomcat 4, pero en los "
+#~ "demás casos es una buena elección."
+
+#~ msgid ""
+#~ "How often the RSS feed should be refreshed. An hour (3600 seconds) is a "
+#~ "good starting choice."
+#~ msgstr ""
+#~ "Cada cuanto tiempo se debe actualizar el origen RSS. Una hora (3600 "
+#~ "segundos) es un buen valor inicial."
+
+#~ msgid ""
+#~ "This describes your RSS channel. Be as verbose as you want, there is no "
+#~ "upper limit, and it helps the users."
+#~ msgstr ""
+#~ "Esto describe su canal RSS. Sea tan prolijo como quiera, no hay ningún "
+#~ "límite máximo, y ayuda a los usuarios."
+
+#~ msgid ""
+#~ "This should match the language of your Wiki. It let's people know what "
+#~ "language they should expect in the RSS feed."
+#~ msgstr ""
+#~ "Esto debería coincidir con el idioma de su wiki. Permite que la gente "
+#~ "sepa qué idioma deben esperar encontrar en el origen RSS."
+
+#~ msgid "BasicAttachmentProvider, nothing"
+#~ msgstr "BasicAttachmentProvider, ninguno"
+
+#~ msgid ""
+#~ "If you have no important information stored in your wiki and really want "
+#~ "to get rid of the page data, the purge process can do this for you."
+#~ msgstr ""
+#~ "Si no tiene información importante almacenada en su wiki y realmente "
+#~ "desea deshacerse de los datos, el proceso de purga puede hacerlo por "
+#~ "usted."
diff --git a/debian/po/eu.po b/debian/po/eu.po
new file mode 100644
index 0000000..d143e40
--- /dev/null
+++ b/debian/po/eu.po
@@ -0,0 +1,275 @@
+# translation of eu.po to Basque
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Piarres Beobide <pi at beobide.net>, 2008.
+# Iñaki Larrañaga Murgoitio <dooteo at euskalgnu.org>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: eu\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-09-14 19:33+0200\n"
+"Last-Translator: Iñaki Larrañaga Murgoitio <dooteo at euskalgnu.org>\n"
+"Language-Team: Basque <itzulpena at euskalgnu.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Lehenetsitako aplikazioaren izena:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Idatzi wiki-aren izena. Izen hau HTML izenburu eta erregistro fitxategietan "
+"agertuko da, eta normalena maila baxueneko URLaren berdina izatea da "
+"(adibidez 'http://www.example.org/JSPWiki')."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Idatzi wikiaren HTTP aurrizkia. Honek JSPWiki-ren barneko esteken "
+"erreferentzia guztiak berridazten dituenez, zuzendu beharra dago. Gainera, "
+"barra edukitzea ere eskatzen du."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "JSPWikik erabiliko duen orri biltegi mekanismoa:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Aukeratu mekanismoa orriak gordetzean erabiltzeko:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     orriak fitxategi gisa gorde;\n"
+" RCSFileProvider:        erabili kanpoko gainbegiratze kontrol-sistema bat;\n"
+" VersioningFileProvider: Javan inplementaturiko bertsio biltegia."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "JSPWiki-k orri cachea erabili behar du?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Orri cacheak normalean errendimendua hobetzen du baina memoria erabiliera "
+"handitzen du."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "JSPWiki-ren oinarrizko URLa:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Oinarrizko URLak JSPWiki-ren barneko erreferentziak aldatzeko erabiltzen "
+"dira."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Barra ('/') beharrezkoa da."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Orrialderen kodeketa:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Aukeratu JSPWiki-k erabiliko duen karaktere kodeketa. UTF8 erabiltzea biziki "
+"gomendatzen da."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Hautsi orri izenburutako maiuskulak?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Hautatu orrialde izenburuetako hizki maiuskulen karaktereetako bakoitzaren "
+"ondoren zuriune gehigarri bat utziz errenderizatu behar diren. Honek "
+"'RSSOrria' 'R S S Orria' bezala agertzea eragingo du."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Parekatu plurala eta singularra orrialdeen izenetan?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Aukera hau hautatuz JSPWikik 'OrriEstekak' eta 'OrriEsteka' berdin "
+"erabiltzea egingo du 'OrriEstekak' aurkitzen ez bada."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Erabili CamelCase estekak?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Aukeratu JSPWiki- k wiki izen tradizionalak (orrialde izena "
+"ZuriuneGabeIdatzia) esteka gisa erabili behar dituen ala ez."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Sortu RSS jarioak?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWikik \"Rich Site Summary\" (RSS) jarioak sor ditzake erabiltzaileek wiki "
+"honetako aldaketak kudeatu ahal izateko."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS freskatze tartea segundotan:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Aukeratu RSS jario freskatzeen arteko atzerapena."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS kanalaren azalpena:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Eman kanalaren azalpena RSS jarioarentzat kanalen katalogoan ager dadin. Ez "
+"dago gehiegizko luzerarik beraz txertatu erabiltzaileei lagungarri etor "
+"dakizkieketen xehetasunak."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "RSS kanalaren hizkuntza:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Aukeratu RSS jarioaren hizkuntza. Honek wikiaren hizkuntzaren berdina izan "
+"beharko luke."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "bat ere ez"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Eranskinak biltzeko mekanismoa:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"'BasicAttachmentProvider'ek hautatutako orrialdeak biltzeko mekanismoaren "
+"direktorio egitura berdina erabiliko du. Orrialde bakoitzaren eranskinak "
+"direktorio desberdin batean gordetzen ditu."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Wiki orrialde guztiak ezabatu egin behar dira paketea garbitzean?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Aukeratu paketea garbitzean wiki orrialde guztiak ezabatu behar diren ala ez."
diff --git a/debian/po/fi.po b/debian/po/fi.po
new file mode 100644
index 0000000..fc6c056
--- /dev/null
+++ b/debian/po/fi.po
@@ -0,0 +1,264 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.5.139-2\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2007-11-23 22:40+0200\n"
+"Last-Translator: Esko Arajärvi <edu at iki.fi>\n"
+"Language-Team: Finnish <debian-l10n-finnish at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Finnish\n"
+"X-Poedit-Country: Finland\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Ohjelman oletusnimi:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Anna wikin nimi. Tämä nimi esiintyy HTML-otsikoissa ja lokitiedostoissa ja "
+"on yleensä sama kuin päätason URL (esimerkiksi ”http://www.esimerkki.fi/"
+"JSPWiki”)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "JSPWikin käyttämä sivujentallennusmenetelmä:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Valitse menetelmä, jota tulisi käyttää sivujen tallentamiseen."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     tallennetaan sivut suoraan tiedostoina\n"
+" RCSFileProvider:        käytetään ulkoista versionhallintajärjestelmää\n"
+" VersioningFileProvider: Javalla toteutettu versioiva tallennus"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Tulisiko JSPWikin käyttää sivuvarastoa?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Sivujen varastoiminen yleensä parantaa suorituskykyä, mutta lisää "
+"muistinkulutusta."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "JSPWikin kanta-URL:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr "Kanta-URLeja käytetään määritettäessä JSPWikin sisäisiä viittauksia."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Kauttaviiva (”/”) lopussa on pakollinen."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Sivujen koodaus:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Valitse merkkikoodaus, jota JSPWikin tulisi käyttää. UTF-8 on erittäin "
+"suositeltava."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Jaetaanko sivujen nimet isojen kirjainten kohdalta?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Valitse tulisiko sivujen otsikoihin lisätä näytettäessä ylimääräinen "
+"välilyönti jokaisen ison kirjaimen perään. Tällöin otsikko ”RSSSivu” näkyy "
+"muodossa ”R S S Sivu”."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Tulisiko monikoiden täsmätä yksikkömuotoihin sivujen nimissä?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Tämän vaihtoehdon valitseminen merkitsee, että JSPWikin samaistaa nimen "
+"”PageLinks” nimeen ”PageLink”, jos sivua ”PageLinks” ei löydy."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Käytetäänkö CamelCase-linkkejä?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Valitse tulisiko JSPWikin käsitellä perinteisiä WikiNimiä (sivujen nimiä, "
+"joissa SanatOnKirjoitettuKiinniToisiinsa ilman hakasulkeita) hyperlinkkeinä."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Tuotetaanko RSS-syöte?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki voi tuottaa Rich Site Summary -syötteen, jonka avulla käyttäjät "
+"voivat seurata wikin muutoksia."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS:n virkistysaika sekunneissa:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Valitse RSS-syötteen päivitysten välinen viive."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS-kanavan kuvaus:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Anna RSS-syötteelle kanavakuvaus, joka näytetään kanavalistauksissa. "
+"Enimmäispituutta ei ole, joten sisällytä kaikki yksityiskohdat, joista voi "
+"olla käyttäjille hyötyä."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "RSS-kanavan kieli:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr "Valitse RSS-syötteen kieli. Tämän tulisi täsmätä wikin kieleen."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "ei mitään"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Käytettävä liitteidentallennusmenetelmä:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"”BasicAttachmentProvider” käyttää samaa hakemistorakennetta kuin valittu "
+"sivujentallennusmenetelmä. Se yksinkertaisesti tallentaa liitteet erityiseen "
+"sivukohtaiseen hakemistoon."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr ""
+"Tulisiko kaikki wikisivut poistaa poistettaessa paketti asetustiedostoineen?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Valitse haluatko, että kaikki wikisivut poistetaan, kun paketti poistetaan "
+"asetustiedostoineen."
diff --git a/debian/po/fr.po b/debian/po/fr.po
new file mode 100644
index 0000000..9bd492a
--- /dev/null
+++ b/debian/po/fr.po
@@ -0,0 +1,282 @@
+# translation of fr-new.po to French
+# Translation of jspwiki debconf templates to French
+# Copyright (C) 2007 Christian Perrier <bubulle at debian.org>
+# This file is distributed under the same license as the jspwiki package.
+#
+# Rémi Pannequin <remi.pannequin at laposte.net>, 2004.
+# Christian Perrier <bubulle at debian.org>, 2007, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: fr-new\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2008-12-23 08:30+0100\n"
+"Last-Translator: Christian Perrier <bubulle at debian.org>\n"
+"Language-Team: French <debian-l10n-french at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Nom par défaut de l'application :"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Veuillez choisir le nom que portera le wiki. Ce nom apparaît dans les titres "
+"des pages HTML et dans les journaux. En général, ce nom est le même que "
+"l'URL de base (http://www.exemple.com/JSPWiki)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Veuillez indiquer le préfixe HTTP du wiki. Ce choix permettra la réécriture "
+"de toutes les références internes de JSPWiki. Il est donc important qu'il "
+"soit correct. Il doit impérativement comporter un caractère « / » final."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Méthode de stockage des pages pour JSPWiki :"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Veuillez choisir le mécanisme à utiliser pour conserver les pages :"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider :     pages conservées en tant que fichiers\n"
+" RCSFileProvider :        utilisation d'un système de gestion "
+"de                           configuration (RCS) pour conserver les pages\n"
+" VersioningFileProvider : stockage de pages basé sur Java, avec gestion\n"
+"                          des versions. "
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "JSPWiki doit-il utiliser un cache pour les pages ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"L'utilisation d'un cache améliore généralement les performances, mais "
+"augmente l'utilisation de la mémoire."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL de base pour JSPWiki :"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Les URLs de base sont utilisées pour la réécriture de toutes les références "
+"internes de JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Un caractère barre oblique (« / ») final est obligatoire."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Encodage des pages :"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Veuillez choisir l'encodage à utiliser par JSPWiki. Il est fortement "
+"conseillé d'utiliser UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Faut-il ajouter un espace après les capitales dans les noms de pages ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Veuillez choisir si un espace doit être ajouté aux titres de pages après "
+"chaque lettre capitale. Ainsi, « RSSPage » deviendra « R S S Page »."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr ""
+"Faut-il faire pointer les pluriels vers les singuliers dans les noms de "
+"pages ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Ce choix permet, par exemple, de faire correspondre « PageLinks » "
+"à « PageLink » si « PageLinks » n'existe pas."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Faut-il utiliser des liens CamelCase ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Veuillez choisir si JSPWiki considérera les « WikiNames » (nom des pages "
+"simplement accolés sans caractères « crochets ([]) ») comme des liens "
+"hypertextes."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Faut-il créer un flux RSS (« RSS feed ») ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki peut créer un flux RSS (« Rich Site Summary » - Canal RSS) du site ce "
+"qui permet aux utilisateurs d'être informés des changements récents."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Délai de rafraîchissement du flux RSS (en secondes) :"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr ""
+"Veuillez choisir le délai à utiliser entre les rafraîchissements du flux RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Description du canal RSS :"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Veuillez indiquer la description du flux RSS qui sera utilisé dans les "
+"clients RSS. La longueur de cette description est illimitée et il est "
+"conseillé d'être précis et complet pour donner suffisamment d'informations "
+"aux utilisateurs."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Langue du canal RSS :"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Veuillez choisir la langue à utiliser dans le flux RSS. Ce choix devrait "
+"correspondre à la langue utilisée sur le wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "aucun"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Mécanisme de stockage des attachements :"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"« BasicAttachmentProvider » utilise la même structure de dossier que le "
+"fournisseur de pages sélectionné. Les attachements sont simplement "
+"enregistrés dans des répertoires dédiés à chaque page."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Faut-il supprimer toutes les pages du wiki à la purge du paquet ?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Veuillez choisir si l'ensemble des pages du wiki doivent être supprimées "
+"quand le paquet est purgé."
diff --git a/debian/po/gl.po b/debian/po/gl.po
new file mode 100644
index 0000000..78e15d1
--- /dev/null
+++ b/debian/po/gl.po
@@ -0,0 +1,272 @@
+# Galician translation of jspwiki's debconf templates
+# This file is distributed under the same license as the jspwiki package.
+# Jacobo Tarrio <jtarrio at debian.org>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2007-11-24 11:08+0000\n"
+"Last-Translator: Jacobo Tarrio <jtarrio at debian.org>\n"
+"Language-Team: Galician <proxecto at trasno.net>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Nome por defecto da aplicación:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Introduza o nome do wiki. Este nome aparece nos títulos HTML e nos ficheiros "
+"de rexistro, e adoita ser o mesmo que o URL de nivel superior (por exemplo, "
+"\"http://www.exemplo.org/JSPWiki\")."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Mecanismo de armacenamento de páxinas a empregar por JSPWiki:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Escolla o mecanismo que se debe empregar para armacenar as páxinas:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     armacenar as páxinas coma ficheiros;\n"
+" RCSFileProvider:        empregar un sistema de control de versións "
+"externo;\n"
+" VersioningFileProvider: armacenamento con versións implementado en Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "¿Debe JSPWiki empregar unha caché de páxinas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"A caché de páxinas adoita mellorar o rendemento pero aumenta a ocupación de "
+"memoria."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL base de JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Os URL base empréganse para rescribir tódalas referencias internas de "
+"JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "É obrigatorio incluír unha barra inclinada (\"/\") ao final."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Codificación da páxina:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Indique a codificación de caracteres que debe empregar JSPWiki. Recoméndase "
+"UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "¿Separar nas maiúsculas nos nomes das páxinas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Indique se quere que os títulos das páxinas se amosen cun espazo extra "
+"despois de cada letra maiúscula. Isto fai que \"RSSPage\" se amose coma \"R "
+"S S Page\"."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "¿Facer coincidir os nomes das páxinas en singular e en plural?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Se escolle esta opción ha facer que JSPWiki busque \"PageLink\" ademáis de "
+"\"PageLinks\" se non atopa \"PageLinks\"."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "¿Empregar ligazóns en CamelCase?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Indique se quere que JSPWiki empregue WikiNames tradicionais (nomes de "
+"páxinas formados por palabras UnidasTodasXuntas sen corchetes) coma ligazóns."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "¿Xerar unha fonte RSS?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki pode xerar unha fonte de información RSS para que os usuarios poidan "
+"facer un seguemento dos cambios no wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Tempo de refresco de RSS en segundos:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Escolla o retardo entre actualizacións da fonte RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Descrición da canle RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Forneza unha descrición de canle para a fonte RSS, que se vai amosar nos "
+"catálogos de canles. Non hai unha lonxitude máxima, así que pode incluír "
+"cantos detalles sexan útiles."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Idioma da canle RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Indique o idioma da fonte RSS. Este debería ser o mesmo idioma que o do wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "ningún"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Mecanismo de armacenamento dos anexos a empregar:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"\"BasicAttachmentProvider\" emprega a mesma estructura de directorios que o "
+"mecanismo de armacenamento de páxinas seleccionado. Simplemente armacena os "
+"anexos nun directorio adicado para unha páxina."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "¿Débense borrar tódalas páxinas wiki ao purgar o paquete?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Indique se quere que tódalas páxinas wiki se eliminen ao purgar o paquete."
+
+#~| msgid "BasicAttachmentProvider, nothing"
+#~ msgid "BasicAttachmentProvider"
+#~ msgstr "BasicAttachmentProvider"
diff --git a/debian/po/it.po b/debian/po/it.po
new file mode 100644
index 0000000..fa6cf0e
--- /dev/null
+++ b/debian/po/it.po
@@ -0,0 +1,279 @@
+# Italian translation of the jspwiki debconf templates
+# This file is distributed under the same license as the jspwiki package
+# Luca Monducci <luca.mo at tiscali.it>, 2007-2009.
+# 
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0 italian debconf templates\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-08-23 20:33+0200\n"
+"Last-Translator: Luca Monducci <luca.mo at tiscali.it>\n"
+"Language-Team: Italian <debian-l10n-italian at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Nome predefinito dell'applicazione:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Inserire il nome del wiki. Questo nome sarà presente nei titoli HTML e nei "
+"file di log e solitamente è uguale al livello più alto dell'URL (per esempio "
+"(\"http://www.esempio.org/JSPWiki\")."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Inserire il prefisso HTTP del wiki. Questo riscrive tutti i riferimenti "
+"interni di JSPWiki quindi è importante che sia corretto. Deve anche "
+"contenere lo slash di chiusura."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Meccanismo di memorizzazione delle pagine:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Scegliere il meccanismo da usare per la memorizzazione delle pagine:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     memorizzando le pagine come semplici file;\n"
+" RCSFileProvider:        con un sistema di controllo di revisione;\n"
+" VersioningFileProvider: con un sistema di versionamento realizzato in Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "JSPWiki deve usare una cache per le pagine?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Solitamente l'uso di una cache per le pagine migliora le prestazioni però "
+"aumenta l'uso della memoria."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL base per JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Gli URL base sono usati per riscrivere tutti i riferimenti interni di "
+"JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "È obbligatorio inserire uno slash (\"/\") come carattere finale."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Codifica delle pagine:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Scegliere quale codifica dei caratteri deve essere usata da JSPWiki. Si "
+"raccomanda l'uso di UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Spaziatura alle maiuscole nei nomi delle pagine?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Scegliere se i titoli delle pagine devono essere visualizzati usando uno "
+"spazio aggiuntivo dopo ogni carattere in maiuscolo. Questo comporta che "
+"\"RSSPage\" sia visualizzato come \"R S S Page\"."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr ""
+"Far corrispondere la forma plurale alla forma singolare per i nomi delle "
+"pagine?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Con questa opzione JSPWiki farà corrispondere \"PageLinks\" a \"PageLink\" "
+"quando \"PageLinks\" non esiste."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Usare i collegamenti CamelCase?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Scegliere se JSPWiki deve considerare i tradizionali NomiWiki (i nomi delle "
+"pagine SemplicementeAttaccatiInsieme senza parentesi quadre) come "
+"collegamenti ipertestuali."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Generare un feed RSS?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki può generare un feed RSS (Rich Site Summary) per permettere agli "
+"utenti di tracciare le modifiche al wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Intervallo di aggiornamento del RSS in secondi:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Scegliere il ritardo fra due aggiornamenti del feed RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Descrizione del canale RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Immettere una descrizione del canale per il feed RSS che verrà mostrata nei "
+"cataloghi del canale. Non c'è una lunghezza massima, quindi si può inserire "
+"qualsiasi dettaglio che potrebbe essere utile agli utenti."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Lingua del canale RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Scegliere la lingua del feed RSS. Questo valore deve corrispondere con la "
+"lingua del wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "nessuno"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Meccanismo di memorizzazione degli allegati:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"Con \"BasicAttachmentProvider\" viene usata la stessa struttura di directory "
+"scelta per la memorizzazione delle pagine. Gli allegati vengono "
+"semplicemente memorizzati in una directory dedicata per ogni pagina."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr ""
+"Eliminare tutte le pagine del wiki alla rimozione completa del pacchetto?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Scegliere se si vuole eliminare tutte le pagine del wiki quando il pacchetto "
+"viene rimosso completamente."
+
+#~ msgid "BasicAttachmentProvider, nothing"
+#~ msgstr "BasicAttachmentProvider, nessuno"
diff --git a/debian/po/ja.po b/debian/po/ja.po
new file mode 100644
index 0000000..e4d36ba
--- /dev/null
+++ b/debian/po/ja.po
@@ -0,0 +1,269 @@
+# Japanese translation of jspwiki debconf templates.
+# Copyright (C) 2009 Hideki Yamane <henrich at debian.or.jp>
+# This file is distributed under the same license as the jspwiki package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0-3\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-09-13 22:20+0900\n"
+"Last-Translator: Hideki Yamane (Debian-JP) <henrich at debian.or.jp>\n"
+"Language-Team: Japanese <debian-japanese at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "デフォルトのアプリケーション名:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"wiki の名前を入力してください。この名前は HTML のタイトルとログファイルに表示"
+"され、通常は最上位の URL (例えば 'http://www.example.org/JSPWiki' ) と同じで"
+"す。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"wiki の HTTP プレフィックスを入力してください。これは JSPWiki の内部リンク参"
+"照を全て書き換えるので、正確である必要があります。また、行末にスラッシュを含"
+"んでいる必要があります。"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "JSPWiki が利用するページ保存方法:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "ページを保存するのに使う方法を選んでください:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     単純にページをファイルとして保存する;\n"
+" RCSFileProvider:        外部のリビジョン管理システムを使う;\n"
+" VersioningFileProvider: Java で実装されたバージョン管理ストレージ"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "JSPWiki でページキャッシュを使いますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"ページキャッシュは多くの場合パフォーマンスを改善しますがメモリ消費が増大しま"
+"す。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "JSPWiki のベース URL:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr "ベース URL は JSPWiki の内部参照全てを書き換えるのに使われます。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "行末のスラッシュ ('/') 文字は強制的に必要です。"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "ページのエンコーディング:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"JSPWiki でどの文字エンコーディングを使うかを選んでください。UTF-8 を強くお勧"
+"めします。"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "ページ名の大文字を分割しますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"ページタイトルを各大文字の後に追加で空白を入れて表示するかどうかを選んでくだ"
+"さい。これによると 'RSSPage' を 'R S S Page' のように表示します。"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "ページ名で複数形を単数形とマッチさせますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"このオプションを選ぶと JSPWiki は 'PageLinks' が見つからない場合に "
+"'PageLink' を 'PageLinks' と同一視します。"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "CamelCase リンクを使いますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"JSPWiki が伝統的な Wiki 記法 (空白で区切られていない JustSmashedTogether のよ"
+"うなページの名前) をハイパーリンクと解釈するかどうかを選んでください。"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "RSS フィードを生成しますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki は RSS フィードを生成できるので、ユーザは wiki の変更を知ることが可能"
+"です。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS のリフレッシュ時間 (秒):"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "RSS フィードの再生成間隔をどの程度遅らせるか選んでください。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS チャンネルの description:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"チャンネルのカタログに表示される RSS フィードのチャンネル description を指定"
+"してください。長さに制限は無いので、ユーザが役立つと思うであろう詳細を何でも"
+"含めてください。"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "RSS チャンネルの言語:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"RSS フィードの言語を選んでください。これは wiki の言語と一致している必要があ"
+"ります。"
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "無し"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "添付ファイルの保存方法:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"'BasicAttachmentProvider' は選択したページ保存方法と同じディレクトリ構造を使"
+"います。これは単純に添付ファイルを指定したページに保存します。"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr ""
+"パッケージを完全に削除 (purge) する際に全ての wiki ページを削除しますか?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"パッケージを完全に削除 (purge) する際に全ての wiki ページを削除したいかどうか"
+"を選んでください。"
diff --git a/debian/po/nl.po b/debian/po/nl.po
new file mode 100644
index 0000000..20270ee
--- /dev/null
+++ b/debian/po/nl.po
@@ -0,0 +1,276 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2007-11-23 19:57+0100\n"
+"Last-Translator: Bart Cornelis <cobaco at skolelinux.no>\n"
+"Language-Team: debian-l10n-dutch <debian-l10n-dutch at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Poedit-Language: Dutch\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Standaard applicatienaam:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Wat is de naam van de wiki? Deze naam komt terug in HTML-titels en "
+"logbestanden, en is gewoonlijk gelijk aan de hoogste-niveau URL "
+"(bijvoorbeeld http://www.example.org/JSPWiki). "
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Door JSPWiki te gebruiken pagina-opslagmechanisme:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr ""
+"Welk mechanisme dient gebruikt te worden voor het opslaan van pagina's?"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     pagina's opslaan als bestanden;\n"
+" RCSFileProvider:           een extern 'Revisie Controle Systeem' "
+"gebruiken;\n"
+" VersioningFileProvider: versie-opslag geïmplementeerd in Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Wilt u dat JSPWiki een pagina-cache bijhoudt?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Gewoonlijk zal bijhouden van een pagina-cache de performantie verbeteren ten "
+"koste van meer geheugengebruik."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "Basis-URL van de JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Basis-URL's worden gebruikt bij het herschrijven van de JSPWiki's interne "
+"referenties."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Eindigen met een slash-karakter ('/') is verplicht."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Pagina-encodering:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Welke karakter-encodering dient JSPWiki te gebruiken? UTF-8 is ten sterkste "
+"aangeraden."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Afbreken op hoofdletters in pagina-namen?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Wilt u dat pagina-titels weergegeven worden met een extra spatie na "
+"hoofdletters? Hierdoor wordt 'RSSPagina' weergegeven als 'R S S Pagina'."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr ""
+"Meervoudige vorm doen overeenkomen met enkelvoudige vorm in pagina-namen?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Voor deze optie kiezen zorgt ervoor dat JSPWiki 'PaginaLinks' doet "
+"overeenkomen met 'PaginaLink' wanneer 'PaginaLinks' niet gevonden wordt."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Wilt u CamelCase links gebruiken?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Wilt u dat JSPWiki traditionele wiki-namen (namen van pagina's "
+"GewoonSamenGegegooid zonder vierkante haken) als hyperlinks beschouwd? "
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Wilt u een RSS-stroom genereren?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki kan een RSS-stroom (Rijke Site Samenvatting) genereren zodat "
+"gebruikers aanpassingen in de wiki kunnen volgen."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS verversingsinterval in seconden:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Om de hoeveel tijd wilt u de RSS-stroom verversen?"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS-kanaalbeschrijving:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Wat is de kanaalbeschrijving voor de RSS-stroom? Deze wordt getoond in "
+"kanaalcatalogussen. Aangezien er geen maximumlengte is kunt u alle voor "
+"gebruikers nuttige details aangeven."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Taal van het RSS-kanaal:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Wat is de taal van de RSS-stroom? Dit dient overeen te komen met de taal van "
+"de wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "niets"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Te gebruiken opslag voor bijvoegsels. "
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"'BasicAttachmentProvider' gebruikt dezelfde mappenstructuur als het "
+"geselecteerde pagina-opslagmechanisme. Het slaat de bijvoegsels gewoon op in "
+"de toegewezen map voor een pagina."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Alle wiki-pagina's verwijderen bij wissen van pakket?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Wilt u dat alle wiki-pagina's verwijderd worden wanneer dit pakket gewist "
+"wordt?"
+
+#~ msgid "BasicAttachmentProvider, nothing"
+#~ msgstr "BasicAttachmentProvider, niets"
diff --git a/debian/po/pt.po b/debian/po/pt.po
new file mode 100644
index 0000000..884c371
--- /dev/null
+++ b/debian/po/pt.po
@@ -0,0 +1,345 @@
+# Portuguese translation for JSPWiki's debconf messages
+# Copyright (C) 2007 Miguel Figueiredo
+# This file is distributed under the same license as the JSPWiki package.
+# Miguel Figueiredo <elmig at debianpt.org>, 2007-2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: JSPWiki 2.5.139-2\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2008-12-23 18:27+0000\n"
+"Last-Translator: Miguel Figueiredo <elmig at debianpt.org>\n"
+"Language-Team: Portuguese <traduz at debianpt.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Nome pré-definido da aplicação:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Por favor introduza o nome do wiki. Este nome aparece em títulos HTML e "
+"ficheiros de log, e é normalmente o mesmo que o URL de topo (por exemplo "
+"'http://www.exemplo.org/JSPWiki')."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Por favor introduza o prefixo HTTP do wiki. Isto reescreve todas as "
+"referências aos links internos, por isso tem de estar correcto. Necessita "
+"também de conter a barra no final."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Mecanismo de armazenamento de páginas a ser utilizado pelo JSPWiki:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr ""
+"Por favor escolha o mecanismo que deve ser utilizado para armazenar as "
+"páginas:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     simplesmente guarda as páginas como ficheiros;\n"
+" RCSFileProvider:        usar um sistema externo de controlo de revisão;\n"
+" VersioningFileProvider: armazenamento por versões implementado em Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Deve o JSPWiki utilizar cache de páginas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Normalmente, a cache de páginas melhora a performance mas aumenta a "
+"utilização de memória."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL base do JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Os URLs base são utilizados para reescrever todas as referências internas do "
+"JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "É obrigatório um carácter barra oblíqua ('/') no final."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Codificação da página:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Por favor escolha qual a codificação de caracteres que deve ser utilizada "
+"pelo JSPWiki. É fortemente recomendado UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Dividir nas maiúsculas nos nomes de páginas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Por favor escolha se os títulos das páginas devem ser desenhados utilizando "
+"um espaço extra após cada letra maiúscula. Isto faz com que 'RSSPage' seja "
+"mostrada como 'R S S Page'."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Coincidir a forma plural com a forma singular nos nomes de páginas?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Escolher esta opção irá fazer o JSPWiki coincidir \"PageLinks\" com "
+"\"PageLink\", caso \"PageLinks \" não seja encontrado."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Utilizar links CamelCase?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Por favor escolha se o JSPWiki deve considerar os tradicionais NomesWiki "
+"(nomes de páginas ColocadosJuntos sem parêntesis rectos) como hiper-ligações."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Gerar feed RSS?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"O JSPWiki pode gerar um feed Rich Site Summary para que os utilizadores "
+"possam acompanhar as alterações no wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Tempo de refrescamento do RSS em segundos:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Por favor escolha a pausa entre refrescamentos do feed RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Descrição de canal RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Por favor dê uma descrição de canal para o feed RSS, para ser mostrada em "
+"catálogos de canais. Não tem tamanho máximo, por isso inclua os detalhes que "
+"os utilizadores possam achar úteis."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Idioma do canal RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Por favor escolha o idioma do feed RSS. Isto deve coincidir com o idioma do "
+"seu wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "nada"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Mecanismo de armazenamento de anexos a utilizar:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"O 'BasicAttachmentProvider' utiliza a mesma estrutura de directório que o "
+"mecanismo de armazenamento de páginas seleccionado. Simplesmente guarda os "
+"anexos num directório dedicado para a página."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Devem ser apagadas todas as páginas wiki quando o pacote for purgado?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Por favor escolha se quer que todas as páginas do wiki sejam removidas "
+"quando o pacote for purgado."
+
+#, fuzzy
+#~| msgid "BasicAttachmentProvider, nothing"
+#~ msgid "BasicAttachmentProvider"
+#~ msgstr "BasicAttachmentProvider, nenhum "
+
+#~ msgid "Which page provider JSPWiki should use"
+#~ msgstr "Qual provedor de páginas deve o JSPWiki utilizar"
+
+#~ msgid ""
+#~ "Which page provider class to use. FileSystemProvider is a simple file "
+#~ "based page storage, RCSFileProvider uses RCS as the page store, and "
+#~ "VersioningFileProvider is a pure Java implementation of a versioning page "
+#~ "store."
+#~ msgstr ""
+#~ "Qual a classe de provedor de páginas a utilizar. O FileSystemProvider é "
+#~ "um armazenamento de páginas baseado em ficheiros simples, o "
+#~ "RCSFileProvider utiliza RCS para armazenar páginas, e "
+#~ "VersioningFileProvider é uma implementação pura em Java de um "
+#~ "armazenamento de versões de páginas."
+
+#~ msgid "JSPWiki base URL (http://www.example.com/JSPWiki/)"
+#~ msgstr "URL base do JSPWiki (http://www.example.com/JSPWiki/)"
+
+#~ msgid ""
+#~ "Base URLs are used to rewrite all of JSPWiki's internal references. Don't "
+#~ "forget the trailing slash. This must be used if the URL that JSPWiki sees "
+#~ "through the servlet container is different from the real URL."
+#~ msgstr ""
+#~ "Os URLs base são utilizados para reescrever todas as referências internas "
+#~ "do JSPWiki. Não se esqueça da barra no final. Isto tem de ser utilizado "
+#~ "se o URL que o JSPWiki vê através do 'servlet container' é diferente do "
+#~ "URL verdadeiro."
+
+#~ msgid ""
+#~ "Determines which character encoding JSPWiki should use. UTF-8 may cause "
+#~ "problems on some Tomcat 4 installations but is otherwise a good choice."
+#~ msgstr ""
+#~ "Determina qual a codificação de caracteres que o JSPWiki deve utilizar. "
+#~ "UTF-8 pode causar problemas em algumas instalações de Tomcat 4, mas caso "
+#~ "contrário é uma boa escolha."
+
+#~ msgid ""
+#~ "How often the RSS feed should be refreshed. An hour (3600 seconds) is a "
+#~ "good starting choice."
+#~ msgstr ""
+#~ "Com que frequência deve o feed RSS ser refrescado. Uma hora (3600 "
+#~ "segundos) é uma boa escolha à partida."
+
+#~ msgid ""
+#~ "This describes your RSS channel. Be as verbose as you want, there is no "
+#~ "upper limit, and it helps the users."
+#~ msgstr ""
+#~ "Isto descreve o seu canal RSS. Pode ser tão detalhado como você quiser, "
+#~ "não existe limite, e ajuda os utilizadores."
+
+#~ msgid ""
+#~ "This should match the language of your Wiki. It lets people know what "
+#~ "language they should expect in the RSS feed."
+#~ msgstr ""
+#~ "Isto deve coincidir com o idioma do seu Wiki. Deixa as pessoas saberem "
+#~ "que idioma devem esperar no feed RSS."
+
+#~ msgid ""
+#~ "If you have no important information stored in your wiki and really want "
+#~ "to get rid of the page data, the purge process can do this for you."
+#~ msgstr ""
+#~ "Se não tiver informação importante guardada no seu wiki e realmente se "
+#~ "quiser livrar dos dados das páginas, então o processo 'purge' pode fazer "
+#~ "isto por si."
diff --git a/debian/po/ru.po b/debian/po/ru.po
new file mode 100644
index 0000000..e3b0654
--- /dev/null
+++ b/debian/po/ru.po
@@ -0,0 +1,274 @@
+# translation of ru.po to Russian
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Yuri Kozlov <kozlov.y at gmail.com>, 2007.
+# Yuri Kozlov <yuray at komyakino.ru>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0-3\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-05-17 17:47+0400\n"
+"Last-Translator: Yuri Kozlov <yuray at komyakino.ru>\n"
+"Language-Team: Russian <debian-l10n-russian at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+"Plural-Forms:  nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%"
+"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Имя приложения по умолчанию:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Введите название вики. Это имя появится в заголовках HTML и журнальных "
+"файлах; обычно оно совпадает с URL верхнего уровня (например, 'http://www."
+"example.org/JSPWiki')."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Введите HTTP-префикс вики. При этом заменяются все внутренние ссылки "
+"JSPWiki, поэтому он должен быть правильным. Также он должен заканчиваться "
+"символом косой черты."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Механизм хранения страниц, который будет использовать JSPWiki:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Выберите механизм, который должен использоваться для хранения страниц:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     просто хранит страницы в файлах;\n"
+" RCSFileProvider:        использует внешнюю систему контроля версий;\n"
+" VersioningFileProvider: версионное хранилище, написанное на Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Включить в JSPWiki кэширование страниц?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Кэширование страниц обычно улучшает производительность, но увеличивает "
+"потребление памяти."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "Базовый URL для JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Базовый URL используется для перезаписи всех внутренних ссылок в JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Символ слэша ('/') в конце является обязательным."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Кодировка страниц:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Выберите кодировку символов, которая должна использоваться в JSPWiki. "
+"Настоятельно рекомендуется UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Отделять заглавные символы в именах страниц?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Укажите, нужно ли в заголовках страниц после каждой заглавной буквы "
+"добавлять дополнительное пространство. То есть слово 'RSSPage' будет "
+"показано как 'R S S Page'."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Учитывать реальное количество страниц в именах?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"При положительном ответе JSPWiki будет преобразовывать 'PageLinks' в "
+"'PageLink', если 'PageLink' только одна."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Использовать ссылки в ВерблюжьемСтиле?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Выберите, должна ли JSPWiki считать традиционные ВикиИмена (имена страниц "
+"ПростоСлепленныеВместе не в квадратных скобках) гиперссылками."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Генерировать RSS-ленту?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki может генерировать обогащенный конспект сайта (Rich Site Summary) "
+"для того, чтобы пользователи могли отслеживать изменения в вики."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Обновление RSS в секундах:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Укажите частоту обновления RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Описание канала RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Введите описание канала для ленты RSS, которое будет показано в каталоге "
+"каналов. Ограничения на длину нет, пишите всё, что может оказаться полезно "
+"пользователям."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Язык канала RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr "Укажите язык ленты RSS. Он должен совпадать с языком вики."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "никакой"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Используемый механизм хранения вложений:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"В 'BasicAttachmentProvider' используется такая же структура каталогов как и "
+"в выбранном механизме хранения страниц. Он просто сохраняет вложения в "
+"выделенный каталог для страницы."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Удалять страницы вики при вычистке пакета?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
+"Выберите, нужно ли удалять все вики-страницы, когда пакет вычищается из "
+"системы."
diff --git a/debian/po/sv.po b/debian/po/sv.po
new file mode 100644
index 0000000..7748c13
--- /dev/null
+++ b/debian/po/sv.po
@@ -0,0 +1,265 @@
+# Translation of debconf teamplates for jspwiki to Swedish
+# Copyright (C) 2008-2009 Martin Bagge <brother at bsnet.se>
+# This file is distributed under the same license as the jspwiki package.
+# 
+# Martin Bagge <brother at bsnet.se>, 2008, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.2.20-1\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-01-08 14:09+0100\n"
+"Last-Translator: Martin Bagge <brother at bsnet.se>\n"
+"Language-Team: Swedish <debian-l10n-swedish at lists.debian.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=utf-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Applikationsnamn:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Ange namnet på wikin. Namnet visas i titel-taggen och loggningen. Det är "
+"vanligen samma som webnamnet (http://www.exempel.se/JSPWiki) men kan också "
+"vara något helt annat."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Ange HTTP-prefixet för wikin. Detta kommer att ändra alla interna JSPWiki-"
+"länkar och måste därför vara helt korrekt. Glöm inte bort det avslutande "
+"snedstrecket."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Lagringsmetod för sidor i JSPWiki:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Ange vilken metod som ska användas för att lagra sidor:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+" FileSystemProvider:     sparar sidorna som enskilda filer på disk;\n"
+" RCSFileProvider:        externt versionshanteringssystem;\n"
+" VersioningFileProvider: versionshanteringssystem skrivet i Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "Ska JSPWiki använda sidcachning?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Detta brukar normalt sett öka prestandan men samtidigt ökas "
+"minnesanvändningen."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "Utgångs-URL för JSPWiki:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Utgångs-URL används för att skriva om alla interna referenser i JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "URL:en måste avslutas med ett snedstreck (\"/\")"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Sidkodning"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+"Ange vilken teckenkodning som skall användas av JSPWiki. UTF-8 rekomenderas."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Bryta vid versaler i sidnamn?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Ska sidtitlar ritas upp med ett extra mellanslag efter varje versal. Detta "
+"innebär att \"RSSPage\" visas som \"R S S Page\"."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Matcha pluralform till singularform i sidnamn?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Väljs detta kommer JSPWiki att peka  \"PageLinks\" till \"PageLink\" om "
+"\"PageLinks\" inte hittas."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Använda CamelCase-länkar?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Ange om JSPWiki ska betrakta traditionella WikiNamn (namn på sidor "
+"SomTrycksIhop utan hakparenteser) som hyperlänkar."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Skapa RSS-ström?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki kan skapa en Rich Site Summary-ström. Detta gör att användare "
+"enklare kan se om något har ändrats på wikin."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "RSS, uppdateringstid i sekunder"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Ange intervall mellan uppdateringar av RSS-strömmar"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "RSS, strömbeskrivning"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Ange en beskrivning som används tillsammans med RSS-strömmen. Det finns "
+"ingen maxlängd på texten, var så utförlig som möjligt."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "RSS, strömspråk"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr "Ange språket för RSS-strömmen. Det bör vara samma som språket i wikin."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "inget"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Lagringsmetod för bifogade filer:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"\"BasicAttachmentProvider\" använder samma mappstruktur som den valda "
+"sidleverantören. Den sparar helt enkelt bifogningar i en dedikerad mapp för "
+"en sida."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Ska ALLA wiki-sidor raderas när paketet tas bort?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr "Ange om du vill att alla wikisidor ska tas bort när paketet tas bort."
diff --git a/debian/po/templates.pot b/debian/po/templates.pot
new file mode 100644
index 0000000..daedced
--- /dev/null
+++ b/debian/po/templates.pot
@@ -0,0 +1,240 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr ""
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr ""
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr ""
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr ""
diff --git a/debian/po/vi.po b/debian/po/vi.po
new file mode 100644
index 0000000..8c96c44
--- /dev/null
+++ b/debian/po/vi.po
@@ -0,0 +1,270 @@
+# Vietnamese translation for JSP Wiki.
+# Copyright © 2009 Free Software Foundation, Inc.
+# Clytie Siddall <clytie at riverland.net.au>, 2007-2009.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: jspwiki 2.8.0-3.1nReport-Msgid-Bugs-To: jspwiki at packages."
+"debian.org\n"
+"Report-Msgid-Bugs-To: jspwiki at packages.debian.org\n"
+"POT-Creation-Date: 2009-09-13 19:02+0200\n"
+"PO-Revision-Date: 2009-09-23 15:18+0930\n"
+"Last-Translator: Clytie Siddall <clytie at riverland.net.au>\n"
+"Language-Team: Vietnamese <vi-VN at googlegroups.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: LocFactoryEditor 1.8\n"
+
+#. Type: string
+#. Description
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001 ../jspwiki.templates:3001
+msgid "Default application name:"
+msgstr "Tên ứng dụng mặc định:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:2001
+msgid ""
+"Please enter the name of the wiki. This name appears in HTML titles and log "
+"files, and is usually the same as the top level URL (for instance 'http://"
+"www.example.org/JSPWiki')."
+msgstr ""
+"Hãy nhập tên của wiki. Tên này xuất hiện trong các tiêu đề HTML và các tập "
+"tin ghi lưu ; nó thường trùng với địa chỉ URL cấp đầu (v.d. « http://www."
+"thí_dụ.org/JSPWiki »)."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:3001
+msgid ""
+"Please enter the HTTP prefix of the wiki. This rewrites all JSPWiki internal "
+"link references, so it needs to be correct. It also needs to contain the "
+"trailing slash."
+msgstr ""
+"Hãy gõ tiền tố HTTP của wiki. Giá trị này ghi lại tất cả các tham chiếu liên "
+"kết nội bộ của JSPWiki thì nó cần phải đúng. Nó cũng cần chứa dấu sổ chéo "
+"theo sau."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Page storage mechanism to be used by JSPWiki:"
+msgstr "Cơ chế cất giữ trang cho JSPWIki dùng:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid "Please choose the mechanism that should be used for storing pages:"
+msgstr "Hãy chọn cơ chế nên dùng để cất giữ các trang:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:4001
+msgid ""
+" FileSystemProvider:     simply storing pages as files;\n"
+" RCSFileProvider:        using an external Revision Control System;\n"
+" VersioningFileProvider: versioning storage implemented in Java."
+msgstr ""
+"• FileSystemProvider\tđơn giản lưu các trang dạng tập tin\n"
+"• RCSFileProvider        \tdùng Hệ thống Điều khiển Bản sửa đổi (RCS) bên "
+"ngoài\n"
+"• VersioningFileProvider\tcất giữ theo phiên bản, thực hiện bằng Java."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Should JSPWiki use a page cache?"
+msgstr "JSPWiki nên dùng bộ nhớ tạm trang không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:5001
+msgid "Page caching usually improves performance but increases memory usage."
+msgstr ""
+"Lưu tạm trang thì thường cái tiến hiệu suất còn tăng cách sử dụng bộ nhớ."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "JSPWiki base URL:"
+msgstr "URL JSPWiki cơ bản:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "Base URLs are used to rewrite all of JSPWiki's internal references."
+msgstr ""
+"Địa chỉ URL cơ bản được dùng để ghi lại tất cả các tham chiếu nội bộ của "
+"JSPWiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:6001
+msgid "A trailing slash ('/') character is mandatory."
+msgstr "Địa chỉ này phải kết thúc bằng dấu xuyệc (/)."
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid "Page encoding:"
+msgstr "Bảng mã trang:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:7001
+msgid ""
+"Please choose which character encoding should be used by JSPWiki. UTF-8 is "
+"strongly recommended."
+msgstr "Hãy chọn bảng mã ký tự cho JSPWiki dùng. Rất khuyên bạn dùng UTF-8."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid "Break at capitals in page names?"
+msgstr "Ngắt ở chữ hoa trong tên trang không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:8001
+msgid ""
+"Please choose whether page titles should be rendered using an extra space "
+"after each capital letter. This causes 'RSSPage' to be shown as 'R S S Page'."
+msgstr ""
+"Hãy chọn có nên vẽ tên trang có dấu cách thêm nằm sau mỗi chữ hoa, hay "
+"không. Ví dụ, « RSSPage sẽ được hiển thị dạng « R S S Page »."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid "Match plural form to singular form in page names?"
+msgstr "Khớp dạng ở số nhiều với dạng ở số ít trong tên trang không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:9001
+msgid ""
+"Choosing this option will cause JSPWiki to match 'PageLinks' to 'PageLink' "
+"if 'PageLinks' is not found."
+msgstr ""
+"Bật tùy chọn này thì JSPWiki sẽ tìm « PageLinks » nếu không tìm thấy chuỗi « "
+"PageLink ». (Có ích cho tiếng Anh)."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid "Use CamelCase links?"
+msgstr "Dùng liên kết CamelCase không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:10001
+msgid ""
+"Please choose whether JSPWiki should consider traditional WikiNames (names "
+"of pages JustSmashedTogether without square brackets) as hyperlinks."
+msgstr ""
+"Hãy chọn JSPWiki có nên xử lý các TênWiki truyền thống (tên trang "
+"ĐơnGiảnKếtHợp, không có dấu ngoặc vuông) là siêu liên kết, hay không."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid "Generate RSS feed?"
+msgstr "Tạo ra nguồn tin RSS không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:11001
+msgid ""
+"JSPWiki can generate a Rich Site Summary feed so that users can track "
+"changes to the wiki."
+msgstr ""
+"JSPWiki có khả năng tạo ra một nguồn tin tức RSS để người dùng theo dõi các "
+"thay đổi trong wiki."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "RSS refresh time in seconds:"
+msgstr "Thời gian cập nhật RSS (theo giây):"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:12001
+msgid "Please choose the delay between RSS feed refreshes."
+msgstr "Hãy chọn thời gian giữa hai lần cập nhật nguồn tin tức RSS."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid "RSS channel description:"
+msgstr "Mô tả kênh RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:13001
+msgid ""
+"Please give a channel description for the RSS feed, to be shown in channel "
+"catalogs. There is no maximum length, so include whatever details users may "
+"find helpful."
+msgstr ""
+"Hãy cung cấp mô tả kênh cho nguồn tin tức RSS, để hiển thị trong bản liệt kê "
+"các kênh. Chiều dài không phải bị hạn chế: bạn có thể cung cấp chi tiết cho "
+"người dùng biết."
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid "RSS channel language:"
+msgstr "Ngôn ngữ kênh RSS:"
+
+#. Type: string
+#. Description
+#: ../jspwiki.templates:14001
+msgid ""
+"Please choose the RSS feed language. This should match the language of the "
+"wiki."
+msgstr ""
+"Hãy chọn ngôn ngữ cho nguồn tin tức RSS. Ngôn ngữ này nên trùng với ngôn ngữ "
+"của wiki."
+
+#. Type: select
+#. Choices
+#: ../jspwiki.templates:15001
+msgid "nothing"
+msgstr "không gì"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid "Attachment storage mechanism to use:"
+msgstr "Cơ chế cất giữ đồ đính kèm cần dùng:"
+
+#. Type: select
+#. Description
+#: ../jspwiki.templates:15002
+msgid ""
+"'BasicAttachmentProvider' uses the same directory structure as the selected "
+"page storage mechanism. It simply stores the attachments in a dedicated "
+"directory for a page."
+msgstr ""
+"« BasicAttachmentProvider » dùng cùng một cấu trúc thư mục với cơ chế cất giữ "
+"trang đã chọn. Nó đơn giản cất giữ mỗi đồ đính kèm trong thư mục riêng của "
+"trang."
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid "Should all wiki pages be deleted on package purge?"
+msgstr "Tẩy gói thì xoá mọi trang wiki không?"
+
+#. Type: boolean
+#. Description
+#: ../jspwiki.templates:16001
+msgid ""
+"Please choose whether you want all wiki pages to be removed when the package "
+"is purged."
+msgstr "Hãy chọn có nên gỡ bỏ tất cả các trang wiki khi gói bị tẩy, hay không."
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..5de6f8b
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,87 @@
+#!/usr/bin/make -f
+
+export JAVA_HOME=/usr/lib/jvm/java-gcj
+
+patch: patch-stamp
+
+patch-stamp:
+	touch patch-stamp
+#	dpatch apply-all
+
+unpatch:
+#	dpatch deapply-all
+	rm -rf patch-stamp debian/patched
+
+build: patch
+	dh_testdir
+#	mv lib lib.orig
+#	mkdir lib
+#	mv src/com/ecyrd/jspwiki/rpc/atom lib.orig/atom
+#	mv src/com/ecyrd/jspwiki/xmlrpc lib.orig/xmlrpc
+#	mv src/com/ecyrd/jspwiki/filters/PingWeblogsComFilter.java lib.orig/PingWeblogsComFilter.java
+	ant opened-war
+#	mv lib.orig/atom src/com/ecyrd/jspwiki/rpc/atom
+#	mv lib.orig/xmlrpc src/com/ecyrd/jspwiki/xmlrpc
+#	mv lib.orig/PingWeblogsComFilter.java src/com/ecyrd/jspwiki/filters/PingWeblogsComFilter.java
+#	rmdir lib
+#	mv lib.orig lib
+
+binary:	binary-arch binary-indep
+
+binary-arch:
+
+binary-indep:	build
+
+clean: clean-patched unpatch
+
+clean-patched:
+	dh_testdir
+	dh_testroot
+	dh_clean
+	JAVA_HOME=/usr/lib/jvm/default-java ant clean
+
+get-orig-source:
+	mkdir jspwiki-2.8.0
+	cd jspwiki-2.8.0
+	wget http://www.ecyrd.com/~jalkanen/JSPWiki/2.8.0/JSPWiki-2.8.0-src.zip
+	unzip JSPWiki-2.8.0-src.zip
+	rm JSPWiki-2.8.0-src.zip
+	cd ..
+	tar czf jspwiki_2.8.0.orig.tar.gz jspwiki-2.8.0
+	rm -rf jspwiki-2.8.0
+
+install:	build
+	dh_testdir
+	dh_testroot
+	dh_prep
+
+binary-indep:	build install
+	dh_testdir
+	dh_testroot
+	dh_installdirs -p jspwiki etc/jspwiki etc/tomcat6/policy.d var/lib/jspwiki var/lib/tomcat6/webapps usr/share/doc/jspwiki/examples usr/share
+	cp -r build/JSPWiki debian/jspwiki/usr/share/jspwiki
+	cp debian/jspwiki.xml debian/jspwiki/etc/jspwiki/jspwiki.xml
+	cp etc/groupdatabase.xml etc/userdatabase.xml debian/jspwiki/etc/jspwiki/
+	rm -f debian/jspwiki/usr/share/jspwiki/WEB-INF/jspwiki.properties
+
+	cp debian/jspwiki.properties debian/jspwiki/etc/jspwiki/jspwiki.properties
+	mv debian/jspwiki/usr/share/jspwiki/WEB-INF/web.xml debian/jspwiki/usr/share/jspwiki/WEB-INF/jspwiki.tld debian/jspwiki/etc/jspwiki/
+	cp debian/tomcat.policy debian/jspwiki/etc/jspwiki/tomcat.policy
+
+	dh_installdocs README doc/Compiling.txt debian/README.Debian
+	dh_installchangelogs ChangeLog
+	(cd src ; mv wikipages/en default ; tar --exclude .cvsignore --create --gzip --file ../debian/jspwiki/usr/share/doc/jspwiki/examples/wikipages.tar.gz default ; mv default wikipages/en )
+
+	dh_link 
+	dh_compress
+	dh_fixperms
+	dh_installdeb
+	dh_installdebconf
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary-arch:	build install
+
+binary:	binary-indep binary-arch
+.PHONY:	build clean binary-indep binary-arch binary install
diff --git a/debian/tomcat.policy b/debian/tomcat.policy
new file mode 100644
index 0000000..a7f4406
--- /dev/null
+++ b/debian/tomcat.policy
@@ -0,0 +1,36 @@
+grant codeBase "file:/var/lib/tomcat6/webapps/JSPWiki/-" {
+  permission java.io.FilePermission "/var/lib/tomcat6/temp/-", "read,write";
+  permission java.util.PropertyPermission "java.io.tmpdir", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+  permission java.util.PropertyPermission "jspwiki.propertyfile.cascade.1", "read";
+  permission java.util.PropertyPermission "java.runtime.version", "read";
+  permission java.io.FilePermission "/etc/jspwiki/-", "read";
+  permission java.io.FilePermission "/var/log/tomcat6/-", "read,write";
+  permission java.io.FilePermission "/var/lib/jspwiki", "read,write";
+  permission java.io.FilePermission "/var/lib/jspwiki/-", "read,write";
+  permission java.io.FilePermission "/usr/share/jspwiki/-", "read";
+  permission java.io.FilePermission "/var/lib/tomcat6/webapps/JSPWiki/-", "read";
+  permission java.security.SecurityPermission "getProperty.login.configuration.provider", "read,write";
+  permission javax.security.auth.AuthPermission "*";
+  permission javax.management.MBeanServerPermission "*";
+  permission javax.management.MBeanPermission "*", "*";
+  permission javax.management.MBeanTrustPermission "*";
+};
+grant codeBase "file:/usr/share/jspwiki/-" {
+  permission java.io.FilePermission "/var/lib/tomcat6/temp/-", "read,write";
+  permission java.util.PropertyPermission "java.io.tmpdir", "read";
+  permission java.util.PropertyPermission "user.dir", "read";
+  permission java.util.PropertyPermission "jspwiki.propertyfile.cascade.1", "read";
+  permission java.util.PropertyPermission "java.runtime.version", "read";
+  permission java.io.FilePermission "/etc/jspwiki/-", "read";
+  permission java.io.FilePermission "/var/log/tomcat6/-", "read,write";
+  permission java.io.FilePermission "/var/lib/jspwiki", "read,write";
+  permission java.io.FilePermission "/var/lib/jspwiki/-", "read,write";
+  permission java.io.FilePermission "/usr/share/jspwiki/-", "read";
+  permission java.io.FilePermission "/var/lib/tomcat6/webapps/JSPWiki/-", "read";
+  permission java.security.SecurityPermission "getProperty.login.configuration.provider", "read,write";
+  permission javax.security.auth.AuthPermission "*";
+  permission javax.management.MBeanServerPermission "*";
+  permission javax.management.MBeanPermission "*", "*";
+  permission javax.management.MBeanTrustPermission "*";
+};
diff --git a/etc/i18n/CoreResources_en.properties b/etc/i18n/CoreResources_en.properties
new file mode 100644
index 0000000..7d0a944
--- /dev/null
+++ b/etc/i18n/CoreResources_en.properties
@@ -0,0 +1,198 @@
+#
+#  This is the main i18n resource file for JSPWiki internal
+#  code, the so-called core code.
+#
+# Please, do not forget to use proper HTML entities, so
+#   " = "
+#   ' = '  Note that ' is NOT HTML, and does not necessarily work in all browsers.
+
+
+
+#
+#  Time/date formatting.  Some plugins might be using some specific formats,
+#  but you are free to use these times and dates.
+#
+
+# Timedate format used when a full time/date is used
+common.datetimeformat = HH:mm:ss dd-MMM-yyyy zzz
+
+# Time stamp format when a simple time stamp is needed (without date)
+common.timeformat = HH:mm:ss
+
+# Date stamp format when showing just the date.
+common.dateformat = EEEE, MMMM d, yyyy
+
+# "Unknown author"
+
+common.unknownauthor = UnknownAuthor
+
+# Decisions: {0}=task owner; {1}=requester; {2-9}=additional message arguments for workflow
+decision.editWikiApproval=Edit page {2}
+
+# Security
+
+security.error.noaccess.logged=You don't have access to '{0}'. Do you want to log in as another user?.
+security.error.noaccess=You don't have access to '{0}'. Please log in first.
+security.error.wrongip=Attempt to post from a different IP address than where the page was originally fetched.
+
+security.error.createprofilebeforelogin=You must log in before creating a profile.
+security.error.blankpassword=Password cannot be blank
+security.error.passwordnomatch=Passwords don't match
+
+security.error.illegalfullname=Full name "{0}" is illegal
+security.error.illegalloginname=Login name "{0}" is illegal
+
+# These should roughly match whatever is used in default.properties for UserProfile.jsp
+security.user.loginname=Login name
+security.user.fullname=Full name
+security.user.email=Email address
+
+# Renaming
+
+rename.empty=New page name empty. 
+rename.error.title=Unable to rename page
+rename.error.reason=Reason:
+rename.identical=Page names identical. 
+rename.exists=Page "{0}" already exists. Please change the new name or delete the page "{0}" first.
+rename.unknownerror=An unknown error occurred ({0})
+
+# Login.jsp  
+#login.error.capslock=Invalid login (please check your Caps Lock key) #obsolete
+login.error.password=Not a valid login.
+login.error.noaccess=It seems you don't have access to that. Sorry.
+
+# Lostpassword.jsp
+
+# 0 = login name, 1 = password, 2 = URL, 3 = Application name (as signature)
+# This is text, not HTML.
+lostpwd.newpassword.email=As requested, your new password for login "{0}" is "{1}" \
+                    \n\nYou may log in at {2}.\n\n-- {3}
+lostpwd.newpassword.subject=New password for {0}
+lostpwd.nouser=No user or email "{0}" was found.
+lostpwd.nomail=Internal error: couldn't send the email!  Contact the site administrator, please.
+lostpwd.emailed=A new password has been emailed to the requested account.
+
+lostpwd.reset.title=Password reset
+lostpwd.reset.unable=Unable to reset password.  Please try again.
+
+lostpwd.reset.blurb=Lost or forgot your password?  Enter your account name or email here:
+lostpwd.reset.submit=Reset password!
+
+# TraditionalDiffProvider
+
+diff.traditional.added=At line {0} added {1}
+diff.traditional.changed=At line {0} changed {1}
+diff.traditional.removed=At line {0} removed {1}
+diff.traditional.oneline=one line
+diff.traditional.lines={2} lines
+
+# InputValidator
+
+validate.unsafechars={0} cannot contain these characters: {1}
+validate.invalidemail={0} is not valid
+validate.cantbenull={0} cannot be blank
+
+# UserProfileTag
+
+userprofile.nogroups=(none)
+userprofile.noroles=(none)
+
+# NewGroup.jsp
+newgroup.exists=Group {0} already exists. Try another name.
+
+# JSPWikiMarkupParser 
+
+markupparser.error.invalidset = Invalid SET found: {0}
+markupparser.error.nointerwikiref = No InterWiki reference defined in properties for Wiki called "{0}"!
+markupparser.error.parserfailure = Parser failed: {0}
+markupparser.error.javascriptattempt = Attempt to output javascript!
+markupparser.link.create = Create "{0}"
+
+# Captcha.jsp
+captcha.js.humancheckcomplete.alert=Please correctly identify the cats.
+captcha.description=We believe you may be a robot or a spammer.  Could you please pick out the kittens from the below \
+                    set of images, so we know you are a normal human being?
+captcha.asirra.please.select=Please select all the cat photos:
+captcha.asirra.adopt.me=Adopt me
+captcha.asirra.a.get.challenge=Request different images.
+captcha.asirra.a.whatsthis=What is this?
+captcha.submit=Submit
+
+# Install.jsp
+install.jsp.title=JSPWiki Installer
+install.jsp.intro.title=JSPWiki Installer
+install.jsp.intro.p1=Welcome!  This little JSP page is here to help you do the first difficult stage of JSPWiki \
+                     installation.  If you're seeing this page, you have already installed JSPWiki correctly \
+                     inside your container.
+install.jsp.intro.p2=There are now some things that you should configure.  When you press Configure, the \
+                     <code>jspwiki.properties</code> file from the distribution will be modified, or if it \
+                     can't be found, a new one will be created.
+install.jsp.intro.p3=This setup system is really meant for people who just want to be up and running really quickly. \
+                     If you want to integrate JSPWiki with an existing system, I would recommend that you go and edit \
+                     the <code>jspwiki.properties</code> file directly.  You can find a sample config file from \
+                     <code>yourwiki/WEB-INF/</code>.
+install.jsp.install.info=Good news: 
+install.jsp.install.warning=Warning: 
+install.jsp.install.error=Could not save configuration: 
+install.jsp.install.msg.rnd.pwd=Because no administrator account exists yet, JSPWiki created one for you, with a \
+                                random password. You can change this password later, of course. The account''s id is \
+                                {0} and the password is {1}. Please write this information down and keep it in a \
+                                safe place. JSPWiki also created a wiki group called {2} that contains this user.
+install.jsp.install.msg.admin.notexists=Is this the first time you've run the Installer? If it is, you should know that \
+                                        after JSPWiki validates and saves your configuration for the first time, you will \
+                                        need administrative privileges to access this page again. We do this to prevent \
+                                        random people on the Internet from doing bad things to your wiki.   
+
+install.jsp.basics.title=Basics
+install.jsp.basics.appname.label=Application Name
+install.jsp.basics.appname.desc=What should your wiki be called?  Try and make this a relatively short name.
+install.jsp.basics.baseurl.label=Base URL
+install.jsp.basics.baseurl.desc=Please tell JSPWiki where your wiki is located.
+install.jsp.basics.page.storage.label=Page storage
+install.jsp.basics.page.storage.desc=By default, JSPWiki will use the VersioningFileProvider that stores files in a particular \
+                                     directory on your hard drive. If you specify a directory that does not exist, JSPWiki will \
+                                     create one for you. All attachments will also be put in the same directory.
+
+install.jsp.security.title=Security
+install.jsp.security.sec.conf.label=Security configuration
+install.jsp.security.sec.conf.opt1=JAAS plus container security (default)
+install.jsp.security.sec.conf.opt2=Container security only
+install.jsp.security.sec.conf.desc=By default, JSPWiki manages access to resources using a JAAS-based security system. \
+                                   It will also respect any container security constraints you might have, \
+                                   if you've enabled them in your <code>web.xml</code> file. If you disable JAAS security, \
+                                   JSPWiki might not work as you expect. But sometimes you might want to do this if you're \
+                                   trying to troubleshoot.
+install.jsp.security.admaccount.label=Administrator account
+install.jsp.security.admaccount.enabled=Enabled
+install.jsp.security.admaccount.notenabled=Not enabled
+install.jsp.security.admaccount.enabled.desc=This wiki has an administrator account named <strong>admin</strong> that is part of \
+                                             the wiki group <strong>Admin</strong>. By default, JSPWiki's security policy grants \
+                                             all members of the Admin group the all-powerful <code>AllPermission</code>.
+install.jsp.security.admaccount.notenabled.desc=This wiki doesn't seem to have an administrator account. When you click <em>Configure!</em>,\
+                                                JSPWiki will create one for you.
+
+install.jsp.adv.settings.title=Advanced Settings
+install.jsp.adv.settings.logfile.label=Log files
+install.jsp.adv.settings.logfile.desc=JSPWiki uses Jakarta Log4j for logging.  Please tell JSPWiki where the log files should go.
+install.jsp.adv.settings.workdir.label=Work directory
+install.jsp.adv.settings.workdir.desc=This is the place where all caches and other runtime stuff is stored.
+install.jsp.instr.desc=After you click <em>Configure!</em>, the installer will write your settings to <code>{0}</code>. \
+                       It will also create an Administrator account with a random password and a corresponding Admin group. 
+install.jsp.instr.submit=Configure!
+install.jsp.validated.new.props=Here is your new jspwiki.properties
+
+# Installer.java
+install.installer.unable.read.props=Unable to read properties: {0}
+install.installer.default.appname=MyWiki
+install.installer.default.pagedir=Please configure me!
+install.installer.props.saved=Your new properties have been saved.  Please restart your container (unless this was your first \
+                              install).  Scroll down a bit to see your new jspwiki.properties.
+install.installer.props.notsaved=Unable to write properties: {0}. Please copy the file below as your jspwiki.properties:\n{1}
+install.installer.validate.baseurl=You must define the base URL for this wiki.
+install.installer.validate.pagedir=You must define the location where the files are stored.
+install.installer.validate.appname=You must define the application name.
+install.installer.validate.workdir=You must define a work directory.
+install.installer.validate.logdir=You must define a log directory.
+
+# RSSImageLinkTag
+rss.title=RSS feed for page {0}
diff --git a/etc/i18n/plugin/PluginResources_en.properties b/etc/i18n/plugin/PluginResources_en.properties
new file mode 100644
index 0000000..e19ba7b
--- /dev/null
+++ b/etc/i18n/plugin/PluginResources_en.properties
@@ -0,0 +1,49 @@
+# This is the English language bundle for JSPWiki core plugins
+# Don't add your own plugins to this file; create your own bundle, please.
+
+# Errors rendering plugins
+
+plugin.error.insertionfailed = Plugin insertion failed: {0}
+plugin.error.cannotinstantiate = Cannot instantiate plugin {0} 
+plugin.error.notallowed = Not allowed to access plugin {0}
+plugin.error.instantationfailed = Instantiation of plugin {0} failed.
+plugin.error.failed = Plugin failed
+plugin.error.couldnotfind = Could not find plugin {0}
+plugin.error.notawikiplugin = Class {0} is not a Wiki plugin.
+plugin.error.missingparameter = Missing parameter in plugin definition: {0}
+plugin.error.parsingarguments = Zyrf.  Problems with parsing arguments: {0}
+
+# TableOfContents
+tableofcontents.title = Table of Contents
+
+# BugReportHandler
+
+bugreporthandler.new = A new page has been created: {0}
+bugreporthandler.unable = Unable to create a new page!
+bugreporthandler.titlerequired = Title is required!
+
+# CurrentTimePlugin
+
+currenttimeplugin.badformat = You specified a bad format
+
+# WeblogEntryPlugin
+
+weblogentryplugin.newentry = New entry
+
+# ReferringPagesPlugin
+
+# {0} is where you put in the number how many links are still there
+referringpagesplugin.more = ...and {0} more
+referringpagesplugin.nobody = ...nobody
+
+# Forms plugins
+formclose.noneedtoshow = (no need to show close now)
+forminput.namemissing = Input element is missing parameter 'name'.
+forminput.noneedtoshow = (no need to show input field now)
+formopen.missingparam = The FormOpen element is missing the '{0}' parameter.
+formopen.postorgetonly = Method must be either 'post' or 'get'
+formopen.noneedtoshow = (no need to show form open now)
+formoutput.missingargument = Argument '{0}' required for Form plugin
+formselect.namemissing = Select element is missing parameter 'name'.
+formtextarea.noneedtoshow = (no need to show textarea field now)
+formtextarea.namemissing = Textarea element is missing parameter 'name'.
\ No newline at end of file
diff --git a/etc/i18n/templates/default_en.properties b/etc/i18n/templates/default_en.properties
new file mode 100644
index 0000000..78ff714
--- /dev/null
+++ b/etc/i18n/templates/default_en.properties
@@ -0,0 +1,658 @@
+#
+#  This file contains the localized resource definitions for
+#  the "default" template.  Any other template i18n file should
+#  be renamed in a similar way, e.g. "mytemplate.properties" under i18n/templates
+#
+# Common things
+
+common.nopage=This page does not exist.  Why don’t you go and {0}?
+common.createit=create it
+common.more=More...
+
+
+# AttachmentTab.jsp
+
+attach.tab=Attach
+attach.list=List of attachments
+attach.add=Add new attachment
+attach.add.info=In order to upload a new attachment to this page, \
+    please use the following box to find the file, then click on “Upload”.
+attach.add.permission=Only authorized users are allowed to upload new attachments.
+attach.bytes=bytes
+attach.add.selectfile=Select file:
+attach.add.changenote=Change Note:
+attach.add.submit=Upload
+attach.preview=Image preview
+attach.deleteconfirm=Please confirm that you want to delete this attachment permanently!
+attach.delete=Delete
+attach.moreinfo.title=Attachment info and version history
+
+# CommentContent.jsp
+
+comment.title.comment={0}: Comment: {1}
+comment.tab.discussionpage=Discussion page
+comment.tab.addcomment=Add comment
+comment.edithelpmissing=Ho hum, it seems that the {0} page is missing.  \
+    Someone must’ve done something to the installation...\
+    <br /><br />\
+    You can copy the text from the \
+    <a href="http://www.jspwiki.org/Wiki.jsp?page=EditPageHelp">EditPageHelp page \
+    on jspwiki.org</a>.
+
+# ConflictContent.jsp
+
+conflict.oops.title=Oops!
+conflict.oops=<p><b>Oops!  Someone modified the page while you were editing it!</b></p>\
+    <p>Since I am stupid and can’t figure out what the difference \
+    between those pages is, you will need to do that for me.  I’ve \
+    printed here the text (in Wiki) of the new page, and the \
+    modifications you made.  You’ll now need to copy the text onto a \
+    scratch pad (Notepad or emacs will do just fine), and then edit \
+    the page again.</p> \
+    <p>Note that when you go back into the editing mode, someone might have \
+    changed the page again.  So be quick.</p>
+conflict.goedit=<p>Go edit {0}</p>
+conflict.modified=Modified by someone else
+conflict.yourtext=Here’s your text
+
+# DiffContent.jsp
+
+#diff.tab=Version changes
+diff.difference=Difference between version {0} and {1}
+diff.gotofirst.title=Go to first change in this document
+diff.gotofirst=View first change
+diff.goback=Back to {0}, or {1}
+diff.versionhistory={0} page info
+diff.nodiff=No difference detected.
+
+# EditContent.jsp
+
+edit.locked=User “{0}” has started to edit this page, but has not yet \
+    saved.  I won’t stop you from editing this page anyway, BUT be aware that \
+    the other person might be quite annoyed.  It would be courteous to wait for the lock \
+    to expire or until the person stops editing the page.  The lock expires in \
+    {1} minutes.
+edit.restoring=You are about to restore version {0}. \
+    Click on “Save” to restore.  You may also edit the page before restoring it.
+edit.chooseeditor=Editor
+edit.tab.attachments=Attachments
+edit.tab.help=Help
+edit.tab.edit=Edit
+edit.tab.findreplacehelp=Find and Replace help
+
+# EditTemplate.jsp
+# 0 : Application name
+# 1 : Page name
+edit.title.edit={0}: Edit: {1}
+edit.sections=Sections
+
+# EditGroup.jsp
+editgroup.tab=Edit Group
+editgroup.heading.edit=Edit Group {0}
+editgroup.instructions=This page allows you to add or edit members for the wiki group called \
+    <strong>{0}</strong>. Generally, only members of the group can edit the \
+    membership list. By default, the person who creates the group is a member.
+editgroup.saveerror=Could not save group: 
+editgroup.memberlist=The membership for this group. Enter each user’s name or \
+    wiki name, separated by carriage returns.
+editgroup.savehelp=When you click “Save group,” this group will be saved as a group \
+    called <strong>{0}</strong>. You can specify this \
+    name in page access control lists (ACLs).
+editgroup.submit.save=Save group
+
+# Favorites.jsp
+
+fav.myfavorites=My Favorites
+fav.nomenu=Please make a {0}
+fav.greet.anonymous=G’day (anonymous guest)
+fav.greet.asserted=G’day, {0} (not logged in)
+fav.greet.authenticated=G’day, {0} (authenticated)
+fav.aggregatewiki.title=Aggregate the RSS feed of the entire wiki
+
+# FindContent.jsp
+
+find.tab=Search Wiki
+find.tab.help=Help
+find.input=Enter your query here:
+find.heading.results=Search results for “{0}”
+find.resultsstart=Found {0} hits, here are the results from {1} to {2}.
+find.results.page=Page
+find.results.score=Score
+find.noresults=No results were found.  It could be that either this wiki does not have the \
+    document you were looking for, or that you do not have permission to view the documents you were looking for.
+find.getprevious=Get previous {0} results
+find.getnext=Get next {0} results
+find.externalsearch=Try this same search on :
+find.submit.find=Find!
+find.submit.go=Go!
+find.details=Show details
+find.scope.all=Search Everywhere
+find.scope.authors=Authors
+find.scope.pagename=Page Names
+find.scope.content=Page Content
+find.scope.attach=Attachments
+
+# GroupContent.jsp
+
+group.tab=View Group
+#replaced by grp.deletegroup.confirm
+#group.areyousure=Are you sure you want to permanently delete group "{0}"? \
+#    Users might not be able to access pages whose ACLS contain this group. \\n\\n \
+#    If you click OK, the group will be removed immediately.
+group.doesnotexist=This group does not exist.
+group.createsuggestion=Why don’t you go and {0}
+group.createit=create it?
+group.errorprefix=Error 
+group.groupintro=This is the wiki group called {0}. Only members of this group can edit it.
+
+group.name=Group Name
+group.members=Group Members
+group.membership=The group’s membership.
+group.modifier={0} saved this group on {1}
+group.creator={0} created it on {1}.
+
+# GroupTab.jsp
+grp.createdon=Created on {0} by {1}
+grp.lastmodified=<br />Last modified on {0} by {1}
+grp.groupnames.title=Click to edit this group
+grp.newgroupname=(new group name)
+grp.savegroup=Save Group
+grp.savenewgroup=Save New Group
+grp.cancel=Cancel
+grp.deletegroup=Delete Group
+grp.deletegroup.confirm=Please confirm that you want to delete this group permanently!
+grp.formhelp=The membership for this group. Only members of this group can edit it. \
+	<br />Enter each user’s wiki name or full name, separated by carriage returns.
+grp.allgroups=All Groups
+
+# Header.jsp
+header.yourtrail=Your trail: 
+header.homepage.title=Home page of this wiki
+
+# InfoContent.jsp
+info.pagename=Page name
+info.parent=Parent page
+info.lastmodified=This page (revision-{0}) was last changed on {1} by {2}
+info.createdon=This page was created on {0} by {1}
+info.current=Current page version
+info.noversions=No versions.
+info.feed=Page feed
+
+info.pagediff.title=Show changes of last page update
+
+info.rename.submit=Rename page
+info.updatereferrers=Update referrers?
+info.rename.permission=Only authorized users are allowed to rename pages.
+
+
+info.delete.submit=Delete entire page
+#info.delete.attachmentwarning=<i>First delete all attachments of this page</i>
+info.confirmdelete=Please confirm that you want to delete this content permanently!
+info.delete.permission=Only authorized users are allowed to delete pages.
+
+info.moreinfo=More Info...
+info.backtomainpage=Back to {0}
+info.backtoparentpage=Back to {0} (parent page)
+
+info.history=Page revision history
+info.noversions=This page has only one version
+info.showrevisions=Show all revisions from {0} down to {1}
+info.showfrom=Show {0} revisions from {1} to {2}
+
+info.pagination=Pagination:
+info.pagination.first=<span class="first">First</span>
+info.pagination.last=<span class="last">Last</span>
+info.pagination.previous=<span class="prev">Previous</span>
+info.pagination.next=<span class="next">Next</span>
+info.pagination.all=<span class="all">all</span>
+info.pagination.total= (Total items: {0} )
+info.pagination.show.title=Show items from {0} to {1}
+info.pagination.showall.title=Show all items
+
+info.version=Version
+info.date=Date Modified
+info.size=Size
+info.author=Author
+info.changes=Changes ...
+info.changenote=Change note
+info.actions=Actions
+info.difftoprev=to previous
+info.difftolast=to last
+
+info.tab=Info
+info.attachment.tab=Attachment Info
+info.tab.links=Links
+info.tab.outgoing=Outgoing links
+info.tab.incoming=Incoming links
+info.tab.attachments=Attachments
+
+info.uploadnew=Upload new version
+#info.uploadnew.submit=Upload new attachment
+info.uploadnew.filename=Select file:
+info.uploadnew.changenote=Change note:
+info.uploadnew.help=In order to upload a new attachment to this page, \
+    please use the following box to find the file, then click on “Upload”.
+info.uploadnew.nopermission=Only authorized users are allowed to upload new attachment versions.
+
+info.deleteattachment=Delete attachment
+info.deleteattachment.submit=Delete attachment
+
+info.attachment.history=Attachment revision history
+info.attachment.type=Kind
+info.attachment.name=Attachment Name
+
+info.kilobytes=kB
+
+# LoginContent.jsp
+
+login.tab=Login
+login.title=Login
+login.heading.login=Sign in to {0}
+
+login.help=Please sign in with your login name and password.
+login.errorprefix=Error: 
+login.login=Login
+login.password=Password
+login.remember=Remember me?
+
+login.submit.login=Login
+login.invite=Wanna login?
+login.nopassword=Don’t have an account ?
+login.registernow=Join {0} now!
+login.registernow.title=Register a new user!
+
+login.lostpw=Lost your password?
+login.lostpw.tab=Lost password
+login.lostpw.title=Lost your password?
+login.lostpw.getnew=Get a new one!
+login.lostpw.heading=Reset Password
+login.lostpw.help=Lost or forgot your password?  Enter the email address you used to register with here.
+login.lostpw.name=Account email
+login.lostpw.submit=Reset password !
+login.lostpw.reset.clickhere=Click here
+login.lostpw.reset.login={0} to log in once you retrieve your new password.
+
+login.register.tab=Register New User
+
+login.tab.help=Help
+login.loginhelpmissing=Ho hum, it seems that the {0} page is missing.  \
+    Someone must’ve done something to the installation...\
+    <br /><br />\
+    You can copy the text from the \
+    <a href="http://www.jspwiki.org/Wiki.jsp?page=LoginHelp">LoginHelp page \
+    on jspwiki.org</a>.
+
+# NewGroupContent.jsp
+newgroup.heading.create=Create New Group
+newgroup.errorprefix=Error: 
+newgroup.instructions.start=This page allows you to create a new wiki group.
+newgroup.name=Name
+newgroup.name.description=The name of the new group.
+newgroup.members.description=The membership for this group. \
+    Enter each user’s name or wiki name, separated by carriage returns.
+newgroup.instructions.end=When you click “Save group,” \
+    this group will be saved as a group. You can specify the group’s name \
+    in page access control lists (ACLs).
+newgroup.creategroup=Create group
+newgroup.defaultgroupname=MyGroup
+
+
+# PageActions.jsp
+
+actions.gototop=Go to top
+actions.gotobottom=Go to bottom
+actions.view=View
+actions.view.title=View current page [ v ]
+actions.viewparent.title=View parent page [ v ]
+actions.home=Home
+actions.home.title=Go to home page {0}
+actions.edit=<span class='accesskey'>E</span>dit
+actions.edit.title=Edit current page [ e ]
+actions.editparent=<span class='accesskey'>E</span>dit parent page
+actions.editparent.title=Edit parent page [ e ]
+actions.index=Alphabetic Index
+actions.index.title=Alphabetically sorted list of all pages
+actions.recentchanges=Recent Changes
+actions.recentchanges.title=Pages sorted by modification date
+
+actions.more=More...
+actions.separator= - - - - - -
+actions.comment=Add Comment
+actions.comment.title=Add Comment
+actions.addcommenttoparent=Add Comment to parent page
+actions.upload=Attach File
+actions.info=Info
+actions.info.title=Additonal Page Info and Version history [ i ]
+actions.prefs=My <span class='accesskey'>P</span>refs
+actions.prefs.title=Manage your preferences [ p ]
+actions.editgroup=Edit group
+actions.deletegroup=Delete group
+actions.viewgroup=View group
+actions.creategroup=Create group
+actions.creategroup.title=Create new authorisation group
+actions.login=Log in
+actions.login.title=Log in or Register as new user
+actions.logout=Log out
+actions.logout.title=Log out
+actions.publishedon=This particular version was published on {0} by {1}.
+actions.notcreated=Page not created yet.
+actions.workflow=Workflow
+actions.workflow.title=Workflow
+actions.systeminfo=JSPWiki System Info
+actions.systeminfo.title=Show JSPWiki System settings & info
+actions.rawpage=View Page Source
+actions.rawpage.title=View Page Source
+
+# PageContent.jsp
+
+view.oldversion=This is version {0}. It is not the current version, and thus it cannot be edited.
+view.backtocurrent=[Back to current version]
+view.restore=[Restore this version]
+view.heading.attachments=Attachments
+
+# PageTab.jsp
+view.tab=View
+
+# PreferencesContent.jsp
+
+# 0: applicationname
+prefs.heading=User Preferences
+prefs.clear.heading=Clear User Preferences
+prefs.tab.prefs=Preferences
+prefs.tab.profile=Profile
+
+prefs.cookies=Your choices will be saved in your browser as cookies.
+
+prefs.user.skin=Skin
+prefs.user.orientation=Favorites style
+prefs.user.orientation.left=Left
+prefs.user.orientation.right=Right
+#prefs.user.editorareaheight=Editor area height  //not user anymore
+prefs.user.sectionediting=Section Editing
+prefs.user.sectionediting.text=Enable section editing via <span class="editsection"><a href="#">[edit]</a></span> links
+prefs.user.timeformat=Time Format
+prefs.user.timezone=Time Zone
+prefs.user.timezone.server=[SERVER]
+prefs.user.language=Language
+prefs.user.language.default=[DEFAULT]
+
+prefs.instructions=Set your user preferences here. Your choices will be saved in your browser as cookies.
+prefs.assertedname=Name
+prefs.assertedname.description=Your name. \
+    If you haven’t created a user profile yet, you can tell {0} \
+    who you are by ‘asserting’ an identity. You wouldn’t lie to us would you? \
+    <br /> \
+    Note that setting your user name this way isn’t a \
+    real method of authentication, because it just sets a cookie in your browser \
+    without requiring a password. Depending on the security policy, the wiki may grant \
+    you fewer privileges as an “asserted” user. {0} if \
+    you would prefer a traditional username and password, which is more \
+    secure.
+prefs.assertedname.create=Create a new user profile
+prefs.submit.setname=Set user name
+prefs.save.prefs.submit=Save User Preferences
+prefs.clear.submit=Clear User Preferences
+prefs.clear.description=\
+    In some cases, you may need to remove your ‘asserted’ user name and \
+    your user preferences from this computer. \
+    Click the ‘Clear User Preferences’ button to do that. \
+    <br /> \
+    Note that it will remove all user preferences you’ve set up, permanently. \
+    You will need to enter them again.
+
+prefs.newprofile=Create a new user profile
+prefs.oldprofile=Update your wiki profile.
+
+prefs.errorprefix.prefs=Could not save preferences: 
+prefs.errorprefix.profile=Could not save profile: 
+prefs.errorprefix.rename=Could not rename the page: 
+
+prefs.loginname=Login name *
+prefs.loginname.description=This is your login id.
+prefs.loginname.cannotset.new=You cannot set your login name because you are not \
+  logged in yet. You should log in first, using the credentials supplied by \
+  your administrator.
+prefs.loginname.cannotset.exists=You cannot set your login name because \
+  your credentials are managed by the web container, not the wiki.
+
+prefs.password=Password *
+prefs.password.description=Sets your account password. It may not be blank.
+prefs.password2=Password verify *
+prefs.password2.description=Re-type your password for verification.
+
+prefs.fullname=Name *
+prefs.fullname.description=Use your name in Access Control Lists or wiki Groups.
+
+prefs.email=E-mail address
+prefs.email.description= (optional). If you lose your password, \
+    you can ask to have a new, random password sent to this address.
+
+prefs.cookie.info=This wiki automatically remembers you using cookies, \
+    without requiring additional authentication. To use this \
+    feature, your browser must accept cookies from this \
+    website. When you click “save profile,” the cookie \
+    will be saved by your browser.
+prefs.acl.info=Access control lists or wiki groups containing your identity \
+    should specify your name or wiki name. You are also member \
+    of the above Roles and Groups.
+
+prefs.lastmodified=You created your profile on {0}, and last saved it on {1}
+prefs.save.description=Click “save profile” to save your wiki profile.
+
+prefs.save.submit=Save profile
+prefs.create.submit=Create New User Profile
+
+prefs.roles=Roles
+prefs.groups=Groups
+prefs.creationdate=Creation date
+prefs.profile.lastmodified=Last modified
+
+# Workflow generic messages
+workflow.tab=Workflow
+workflow.heading=Your Workflow Items
+workflow.decisions.heading=Inbox
+workflow.workflows.heading=Outbox
+workflow.instructions=This page contains information \
+    on workflows that you initiated, or have been asked to act on.
+workflow.noinstructions=You do not have any workflow items.
+workflow.actor.instructions=You need to take action on the following workflows:
+workflow.owner.instructions=You started the following workflows:
+workflow.id=ID
+workflow.requester=Requester
+workflow.item=Item
+workflow.startTime=Received
+workflow.actions=Actions
+workflow.actor=Current actor
+workflow.submit=Do it
+outcome.step.abort=Abort
+outcome.step.complete=Completed
+outcome.step.continue=Continue
+outcome.decision.acknowledge=OK
+outcome.decision.approve=Approve
+outcome.decision.deny=Deny
+outcome.decision.hold=Hold
+outcome.decision.reassign=Reassign
+
+workflow.details.title=Show or hide details
+workflow.details=details...
+
+# Specific workflow/decision messages
+workflow.saveWikiPage=Save wiki page <strong>{2}</strong>
+decision.saveWikiPage=Approve page <strong>{2}</strong>
+notification.saveWikiPage.reject=Your request to save page <strong>{2}</strong> was rejected.
+fact.pageName=Page name
+fact.diffText=Difference between proposed and current version
+fact.proposedText=Proposed
+fact.currentText=Current
+fact.isAuthenticated=Is Authenticated?
+
+select.one=(select one)
+workflow.creatUserProfile=New user profile <strong>{2}</strong>
+decision.createUserProfile=New user profile <strong>{2}</strong>
+notification.createUserProfile.reject=Your request to create a user profile was rejected.
+fact.submitter=Submitter
+
+#  PreviewContent.jsp
+preview.tab=Preview
+preview.info=This is a <strong>preview</strong>!  \
+    Hit “Keep Editing” to go back to the editor, \
+    or hit “Save” if you’re happy with what you see.
+
+#  SearchBox.jsp
+sbox.search.submit=Quick Navigation
+sbox.view=view
+sbox.view.title=View the selected page
+sbox.edit=edit
+sbox.edit.title=Edit the selected page
+sbox.clone=clone
+sbox.clone.title=Clone the selected page
+sbox.find=find
+sbox.find.title=Advanced Search
+sbox.search.result=Quick search
+sbox.search.target=(type ahead)
+sbox.clearrecent=(Clear)
+sbox.recentsearches=Recent Searches
+
+# UploadTemplate.jsp
+# move all to attach.
+upload.title={0}: Add Attachment
+upload.heading.upload=Upload new attachment to {0}
+upload.attachments=Current attachments
+upload.info=In order to upload a new attachment to this page, please use \
+    the following box to find the file, then click on “Upload”.
+upload.submit=Upload
+upload.done=If you are done uploading, you may wish to return to {0}
+
+
+# ViewTemplate.jsp
+# 0 : Application Name
+# 1 : Page name
+view.title.view={0}: {1}
+
+
+# The built-in editors also have their localized strings in this file.
+
+editor.plain.name=Your <span class='accesskey'>n</span>ame
+editor.plain.remember=Remember me?
+editor.plain.email=Homepage or e<span class='accesskey'>m</span>ail
+editor.plain.save.submit=Save
+editor.plain.save.title=Save [ s ]
+editor.plain.preview.submit=Preview
+editor.plain.preview.title=Preview [ v ]
+editor.plain.cancel.submit=Cancel
+editor.plain.cancel.title=Cancel editing. Your changes will be lost. [ q ]
+
+editor.plain.changenote=Change Note
+editor.commentsignature=Comment signature
+editor.plain.toolbar=Toolbar
+editor.plain.find=Find
+editor.plain.replace=Replace
+editor.plain.matchcase=Match Case
+editor.plain.regexp=RegExp
+editor.plain.global=Replace all
+editor.plain.find.submit=Replace
+editor.plain.redo.submit=Redo
+editor.plain.undo.submit=Undo
+editor.plain.redo.title=Redo last Undo
+editor.plain.undo.title=Undo last replace [ z ]
+
+#new since v2.5.100
+editor.plain.posteditor=Enter Keyword+Tab:
+editor.plain.posteditor.title=shift+enter for next next field
+
+editor.plain.smartpairs= Smart Typing Pairs
+editor.plain.smartpairs.title= Auto pairing of () [] {} <> "" ''
+editor.plain.tabcompletion=Tab Completion (keyword+Tab)
+editor.plain.tabcompletion.title=Auto expansion of keyword to Wiki Markup
+
+#editor.plain.editassist=Edit Assist
+#editor.plain.editassist.title=Toggle Edit Assist buttons
+editor.plain.sneakpreview=Sneak Preview
+editor.plain.sneakpreview.title=Sneak Preview. \
+    Click outside the textarea to refresh the sneak preview area.
+editor.plain.tbLink.title=link - Insert wiki link
+editor.plain.tbH1.title=h1 - Insert heading1
+editor.plain.tbH2.title=h2 - Insert heading2
+editor.plain.tbH3.title=h3 - Insert heading3
+editor.plain.tbHR.title=hr - Insert horizontal ruler
+editor.plain.tbBR.title=br - Insert line break
+editor.plain.tbPRE.title=pre - Insert preformatted block
+editor.plain.tbDL.title=dl - Insert definition list
+editor.plain.tbB.title=bold
+editor.plain.tbI.title=italic
+editor.plain.tbMONO.title=mono - monospace
+editor.plain.tbSUP.title=sup - superscript
+editor.plain.tbSUB.title=sub - subscript
+editor.plain.tbSTRIKE.title=strike - strikethrough
+editor.plain.tbTOC.title=toc - Insert table of contents
+editor.plain.tbTAB.title=tab - Insert tabbed section
+editor.plain.tbTABLE.title=table - Insert table
+editor.plain.tbIMG.title=img - Insert image
+editor.plain.tbCODE.title=code - Insert code block
+editor.plain.tbQUOTE.title=quote - Insert quoted block
+editor.plain.tbSIGN.title=sign - Insert your signature
+
+editor.preview.edit.submit=Keep editing
+editor.preview.edit.title=Continue to edit the current page [ e ]
+editor.preview.save.submit=Save
+editor.preview.save.title=Save the current page [ s ]
+editor.preview.cancel.submit=Cancel
+editor.preview.cancel.title=Cancel editing. Your changes will be lost. [ q ]
+
+editor.fck.noscript=You need to enable Javascript in your browser to use the FCK editor
+editor.wikiwizard.noscript=You need to enable Javascript in your browser to use the WikiWizard editor
+editor.wikiwizard.noapplet=Applets are currently not supported by your browser. \
+    Please <a href="http://www.java.com/">download Java</a>, so you can use the WikiWizard editor.
+
+#blog texts in various JSPs
+blog.commenttitle=comments
+blog.backtomain=Back to main blog page
+blog.addcomments=Add new comments
+
+
+#
+#  The Javascript stuff
+#
+javascript.sbox.clone.suffix=-New
+
+javascript.edit.allsections=( All )
+javascript.edit.startOfPage=( Start of page )
+javascript.edit.findandreplace.nomatch=No match found!
+javascript.edit.toolbar.makeSelection=Please make first a selection.
+javascript.edit.resize=Drag to resize the text area
+javascript.edit.areyousure=Without clicking the Save button, your changes will be lost. \
+    Are you sure you want to exit this page?
+
+javascript.favs.show=Click to show Favorites
+javascript.favs.hide=Click to hide Favorites
+
+javascript.quick.edit=[Edit]
+javascript.quick.edit.title=Edit section {0}...
+
+javascript.collapse=Click to collapse
+javascript.expand=Click to expand
+
+javascript.sort.click=Click to sort
+javascript.sort.ascending=Ascending order. Click to reverse sort order
+javascript.sort.descending=Descending order. Click to reverse sort order
+javascript.filter.all=( All )
+
+javascript.group.validName=Please provide a valid name for the new Group
+
+javascript.category.title=Click to show category [{0}] ...
+
+javascript.slimbox.info=Image {0} of {1}
+javascript.slimbox.error=<h2>Error</h2>There was a problem with your request.<br />Please try again
+javascript.slimbox.directLink=Direct Link to the target
+javascript.slimbox.remoteRequest=Remote Request {0} of {1}
+javascript.slimbox.previous=«Previous
+javascript.slimbox.next=Next»
+javascript.slimbox.close=Close ×
+javascript.slimbox.close.title=Close [Esc]
+
+javascript.sectionediting.label=Section Overview
+
+javascript.tip.default.title=More...
+
+javascript.prefs.areyousure=Without clicking the Save User Preferences button, \
+	your changes will be lost. Are you sure you want to exit this page?
diff --git a/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java b/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java
index a03747c..aa2e1a4 100644
--- a/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java
+++ b/src/com/ecyrd/jspwiki/plugin/WeblogPlugin.java
@@ -273,7 +273,16 @@ public class WeblogPlugin
             for( Iterator i = blogEntries.iterator(); i.hasNext() && maxEntries-- > 0 ; )
             {
                 WikiPage p = (WikiPage) i.next();
-
+                String commentPageName = TextUtil.replaceString( p.getName(),
+                                                                 "blogentry",
+                                                                 "comments" );
+                if( guessNumberOfComments( engine, commentPageName ) > 0 ) {
+                    hasComments = true;
+                }
+                else
+                {
+                    hasComments = false;
+                }
                 if( mgr.checkPermission( context.getWikiSession(), 
                                          new PagePermission(p, PagePermission.VIEW_ACTION) ) )
                 {
@@ -329,7 +338,7 @@ public class WeblogPlugin
         String html = engine.getHTML( entryCtx, engine.getPage(entry.getName()) );
 
         // Extract the first h1/h2/h3 as title, and replace with null
-        buffer.append("<div class=\"weblogentrytitle\">\n");
+        buffer.append("<div class=\"weblogentrytitle\">\n<a href=\""+entryCtx.getURL(WikiContext.VIEW, entry.getName())+"\">");
         Matcher matcher = HEADINGPATTERN.matcher( html );
         if ( matcher.find() )
         {
@@ -341,6 +350,7 @@ public class WeblogPlugin
         {
             buffer.append( entry.getName() );
         }
+        buffer.append("</a>\n");
         buffer.append("</div>\n");
 
         buffer.append("<div class=\"weblogentrybody\">\n");
diff --git a/src/net/sf/akismet/Akismet.java b/src/net/sf/akismet/Akismet.java
new file mode 100644
index 0000000..e58d79f
--- /dev/null
+++ b/src/net/sf/akismet/Akismet.java
@@ -0,0 +1,371 @@
+/**
+ * Copyright (c) 2005-2006, David A. Czarnecki
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ *      this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of the "David A. Czarnecki" nor the names of
+ * its contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * Products derived from this software may not be called "Akismet Java API",
+ * nor may "Akismet Java API" appear in their name, without prior written permission of
+ * David A. Czarnecki.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package net.sf.akismet;
+
+import org.apache.commons.httpclient.*;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.params.HttpClientParams;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * Akistmet Java API
+ * <p></p>
+ * <a href="http://akismet.com/development/api/">Akismet API</a> documentation.
+ *
+ * @author David Czarnecki
+ * @version $Id: Akismet.java,v 1.4 2006/08/06 20:10:00 czarneckid Exp $
+ */
+public class Akismet {
+
+    private Log logger = LogFactory.getLog(Akismet.class);
+
+    // Constants
+    private static final String USER_AGENT_HEADER = "User-Agent";
+    private static final String USER_AGENT_VALUE = "Akismet Java API/1.02";
+
+    private static final String API_PARAMETER_KEY = "key";
+    private static final String API_PARAMETER_BLOG = "blog";
+    private static final String API_PARAMETER_USER_IP = "user_ip";
+    private static final String API_PARAMETER_USER_AGENT = "user_agent";
+    private static final String API_PARAMETER_REFERRER = "referrer";
+    private static final String API_PARAMETER_PERMALINK = "permalink";
+    private static final String API_PARAMETER_COMMENT_TYPE = "comment_type";
+    private static final String API_PARAMETER_COMMENT_AUTHOR = "comment_author";
+    private static final String API_PARAMETER_COMMENT_AUTHOR_EMAIL = "comment_author_email";
+    private static final String API_PARAMETER_COMMENT_AUTHOR_URL = "comment_author_url";
+    private static final String API_PARAMETER_COMMENT_CONTENT = "comment_content";
+
+    private static final String VALID_RESPONSE = "valid";
+    private static final String FALSE_RESPONSE = "false";
+
+    public static final String COMMENT_TYPE_BLANK = "";
+    public static final String COMMENT_TYPE_COMMENT = "comment";
+    public static final String COMMENT_TYPE_TRACKBACK = "trackback";
+    public static final String COMMENT_TYPE_PINGBACK = "pingback";
+
+    private HttpClient httpClient;
+    private String apiKey;
+    private String blog;
+    private boolean verifiedKey = false;
+    private int httpResult;
+
+    /**
+     * Construct an instance to work with the Akismet API.
+     * <p></p>
+     * <pre>
+     * Usage:
+     * <p/>
+     * Akismet akismet = new Akismet("Your API key", "http://your.blog.com/");
+     * System.out.println("Testing comment spam: " + akismet.commentCheck("x.y.z.w", "XXX", "", "", "", "", "", "", "VIAGRA! LOTS OF VIAGRA!", null));
+     * </pre>
+     * <p>
+     * You <strong>do not</strong> need to call {@link #verifyAPIKey()} before using the {@link #commentCheck(String, String, String, String, String, String, String, String, String, java.util.Map)}, 
+     * {@link #submitSpam(String, String, String, String, String, String, String, String, String, java.util.Map)}, or
+     * {@link #submitHam(String, String, String, String, String, String, String, String, String, java.util.Map)} methods.
+     * </p>
+     *
+     * @param apiKey Akismet API key
+     * @param blog   Blog associated with the API key
+     * @throws IllegalArgumentException If either the API key or blog is <code>null</code>
+     */
+    public Akismet(String apiKey, String blog) {
+        this.apiKey = apiKey;
+        this.blog = blog;
+
+        if (apiKey == null) {
+            throw new IllegalArgumentException("API key cannot be null");
+        }
+
+        if (blog == null) {
+            throw new IllegalArgumentException("Blog cannot be null");
+        }
+
+        httpClient = new HttpClient();
+        HttpClientParams httpClientParams = new HttpClientParams();
+        DefaultHttpMethodRetryHandler defaultHttpMethodRetryHandler = new DefaultHttpMethodRetryHandler(0, false);
+        httpClientParams.setParameter(USER_AGENT_HEADER, USER_AGENT_VALUE);
+        httpClientParams.setParameter(HttpClientParams.RETRY_HANDLER, defaultHttpMethodRetryHandler);
+        httpClient.setParams(httpClientParams);
+    }
+
+    /**
+     * Return the HTTP status code of the last operation
+     *
+     * @return HTTP status code
+     */
+    public int getHttpResult() {
+        return httpResult;
+    }
+
+    /**
+     * Check to see if the API key has been verified
+     *
+     * @return <code>true</code> if the API key has been verified, <code>false</code> otherwise
+     */
+    public boolean isVerifiedKey() {
+        return verifiedKey;
+    }
+
+    /**
+     * Sets proxy configuration information. This method must be called before
+     * any calls to the API if you require proxy configuration.
+     *
+     * @param proxyHost Proxy host
+     * @param proxyPort Proxy port
+     */
+    public void setProxyConfiguration(String proxyHost, int proxyPort) {
+        HostConfiguration hostConfiguration = new HostConfiguration();
+        hostConfiguration.setProxy(proxyHost, proxyPort);
+
+        httpClient.setHostConfiguration(hostConfiguration);
+    }
+
+    /**
+     * Check to see if the input is <code>null</code> or blank
+     *
+     * @param input Input
+     * @return <code>true</code> if input is null or blank, <code>false</code> otherwise
+     */
+    private boolean checkNullOrBlank(String input) {
+        return (input == null || "".equals(input));
+    }
+
+    /**
+     * Sets proxy authentication information. This method must be called before any
+     * calls to the API if you require proxy authentication.
+     *
+     * @param proxyUsername Username to access proxy
+     * @param proxyPassword Password to access proxy
+     */
+    public void setProxyAuthenticationConfiguration(String proxyUsername, String proxyPassword) {
+        httpClient.getState().setProxyCredentials(AuthScope.ANY, new UsernamePasswordCredentials(proxyUsername, proxyPassword));
+    }
+
+    /**
+     * Verify your API key
+     *
+     * @return <code>true</code> if the API key has been verified, <code>false</code> otherwise
+     */
+    public boolean verifyAPIKey() {
+        boolean callResult = true;
+
+        PostMethod post = new PostMethod("http://rest.akismet.com/1.1/verify-key");
+        post.addParameter(API_PARAMETER_KEY, apiKey);
+        post.addParameter(API_PARAMETER_BLOG, blog);
+
+        try {
+            httpResult = httpClient.executeMethod(post);
+            String result = post.getResponseBodyAsString();
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("Akismet response: " + result);
+            }
+
+            if (!checkNullOrBlank(result)) {
+                if (!VALID_RESPONSE.equals(result)) {
+                    callResult = false;
+                }
+            }
+        } catch (IOException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e);
+            }
+
+            callResult = false;
+        }
+
+        verifiedKey = callResult;
+
+        return callResult;
+    }
+
+    /**
+     * Generic call to Akismet
+     *
+     * @param function       Function used in constructing the URL to Akismet for the proper function to call. Either "comment-check", "submit-spam", or "submit-ham".
+     * @param ipAddress      IP address of the comment submitter
+     * @param userAgent      User agent information
+     * @param referrer       The content of the HTTP_REFERER header should be sent here
+     * @param permalink      The permanent location of the entry the comment was submitted to
+     * @param commentType    May be blank, comment, trackback, pingback, or a made up value like "registration"
+     * @param author         Submitted name with the comment
+     * @param authorEmail    Submitted email address
+     * @param authorURL      Commenter URL
+     * @param commentContent The content that was submitted
+     * @param other          In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.
+     * @return <code>true</code> if the comment is identified by Akismet as spam, <code>false</code> otherwise
+     */
+    protected boolean akismetCall(String function, String ipAddress, String userAgent, String referrer, String permalink, String commentType,
+                                  String author, String authorEmail, String authorURL, String commentContent, Map other) {
+        boolean callResult = false;
+
+        String akismetURL = "http://" + apiKey + ".rest.akismet.com/1.1/" + function;
+
+        PostMethod post = new PostMethod(akismetURL);
+        post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
+        post.addParameter(new NameValuePair(API_PARAMETER_BLOG, blog));
+        if (ipAddress != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_USER_IP, ipAddress));
+        } else {
+            post.addParameter(new NameValuePair(API_PARAMETER_USER_IP, ""));
+        }
+        if (userAgent != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_USER_AGENT, userAgent));
+        }
+        if (referrer != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_REFERRER, referrer));
+        }
+        if (permalink != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_PERMALINK, permalink));
+        }
+        if (commentType != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_COMMENT_TYPE, commentType));
+        }
+        if (author != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_COMMENT_AUTHOR, author));
+        }
+        if (authorEmail != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_COMMENT_AUTHOR_EMAIL, authorEmail));
+        }
+        if (authorURL != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_COMMENT_AUTHOR_URL, authorURL));
+        }
+        if (commentContent != null) {
+            post.addParameter(new NameValuePair(API_PARAMETER_COMMENT_CONTENT, commentContent));
+        }
+
+        if (other != null && other.size() > 0) {
+            Iterator keyIterator = other.keySet().iterator();
+            while (keyIterator.hasNext()) {
+                String key = (String) keyIterator.next();
+                if ((key != null) && (other.get(key) != null)) {
+                    post.addParameter(new NameValuePair(key, other.get(key).toString()));
+                }
+            }
+        }
+
+        try {
+            httpResult = httpClient.executeMethod(post);
+            String result = post.getResponseBodyAsString();
+
+            if (logger.isDebugEnabled()) {
+                logger.debug("Akismet response: " + result);
+            }
+
+            if (!checkNullOrBlank(result)) {
+                result = result.trim();
+
+                if (!FALSE_RESPONSE.equals(result)) {
+                    callResult = true;
+                }
+            }
+        } catch (IOException e) {
+            if (logger.isErrorEnabled()) {
+                logger.error(e);
+            }
+
+            callResult = true;
+        }
+
+        return callResult;
+    }
+
+    /**
+     * From the API docs, This is basically the core of everything. This call takes a number of arguments and characteristics about the submitted content and then returns a thumbs up or thumbs down. Almost everything is optional, but performance can drop dramatically if you exclude certain elements. I would recommend erring on the side of too much data, as everything is used as part of the Akismet signature."
+     *
+     * @param ipAddress      IP address of the comment submitter
+     * @param userAgent      User agent information
+     * @param referrer       The content of the HTTP_REFERER header should be sent here
+     * @param permalink      The permanent location of the entry the comment was submitted to
+     * @param commentType    May be blank, comment, trackback, pingback, or a made up value like "registration"
+     * @param author         Submitted name with the comment
+     * @param authorEmail    Submitted email address
+     * @param authorURL      Commenter URL
+     * @param commentContent The content that was submitted
+     * @param other          In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.
+     * @return <code>true</code> if the comment is identified by Akismet as spam, <code>false</code> otherwise
+     */
+    public boolean commentCheck(String ipAddress, String userAgent, String referrer, String permalink, String commentType,
+                                String author, String authorEmail, String authorURL, String commentContent, Map other) {
+        return akismetCall("comment-check", ipAddress, userAgent, referrer, permalink, commentType, author, authorEmail,
+                authorURL, commentContent, other);
+    }
+
+    /**
+     * From the API docs, This call is for submitting comments that weren't marked as spam but should have been. It takes identical arguments as comment check."
+     *
+     * @param ipAddress      IP address of the comment submitter
+     * @param userAgent      User agent information
+     * @param referrer       The content of the HTTP_REFERER header should be sent here
+     * @param permalink      The permanent location of the entry the comment was submitted to
+     * @param commentType    May be blank, comment, trackback, pingback, or a made up value like "registration"
+     * @param author         Submitted name with the comment
+     * @param authorEmail    Submitted email address
+     * @param authorURL      Commenter URL
+     * @param commentContent The content that was submitted
+     * @param other          In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.
+     * @return <code>true</code> if the comment is identified by Akismet as spam, <code>false</code> otherwise
+     */
+    public void submitSpam(String ipAddress, String userAgent, String referrer, String permalink, String commentType,
+                           String author, String authorEmail, String authorURL, String commentContent, Map other) {
+        akismetCall("submit-spam", ipAddress, userAgent, referrer, permalink, commentType, author, authorEmail,
+                authorURL, commentContent, other);
+    }
+
+    /**
+     * From the API docs, This call is intended for the marking of false positives, things that were incorrectly marked as spam. It takes identical arguments as comment check and submit spam."
+     *
+     * @param ipAddress      IP address of the comment submitter
+     * @param userAgent      User agent information
+     * @param referrer       The content of the HTTP_REFERER header should be sent here
+     * @param permalink      The permanent location of the entry the comment was submitted to
+     * @param commentType    May be blank, comment, trackback, pingback, or a made up value like "registration"
+     * @param author         Submitted name with the comment
+     * @param authorEmail    Submitted email address
+     * @param authorURL      Commenter URL
+     * @param commentContent The content that was submitted
+     * @param other          In PHP there is an array of enviroment variables called $_SERVER which contains information about the web server itself as well as a key/value for every HTTP header sent with the request. This data is highly useful to Akismet as how the submited content interacts with the server can be very telling, so please include as much information as possible.
+     * @return <code>true</code> if the comment is identified by Akismet as spam, <code>false</code> otherwise
+     */
+    public void submitHam(String ipAddress, String userAgent, String referrer, String permalink, String commentType,
+                          String author, String authorEmail, String authorURL, String commentContent, Map other) {
+        akismetCall("submit-ham", ipAddress, userAgent, referrer, permalink, commentType, author, authorEmail,
+                authorURL, commentContent, other);
+    }
+}
diff --git a/src/org/apache/commons/jrcs/diff/AddDelta.java b/src/org/apache/commons/jrcs/diff/AddDelta.java
new file mode 100644
index 0000000..8037a63
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/AddDelta.java
@@ -0,0 +1,131 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds an add-delta between to revisions of a text.
+ *
+ * @version $Id: AddDelta.java 146038 2003-10-13 08:00:44Z rdonkin $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class AddDelta
+    extends Delta
+{
+
+    AddDelta()
+    {
+        super();
+    }
+
+    public AddDelta(int origpos, Chunk rev)
+    {
+        init(new Chunk(origpos, 0), rev);
+    }
+
+    public void verify(List target) throws PatchFailedException
+    {
+        if (original.first() > target.size())
+        {
+            throw new PatchFailedException("original.first() > target.size()");
+        }
+    }
+
+    public void applyTo(List target)
+    {
+        revised.applyAdd(original.first(), target);
+    }
+
+    public void toString(StringBuffer s)
+    {
+        s.append(original.anchor());
+        s.append("a");
+        s.append(revised.rangeString());
+        s.append(Diff.NL);
+        revised.toString(s, "> ", Diff.NL);
+    }
+
+    public void toRCSString(StringBuffer s, String EOL)
+    {
+        s.append("a");
+        s.append(original.anchor());
+        s.append(" ");
+        s.append(revised.size());
+        s.append(EOL);
+        revised.toString(s, "", EOL);
+    }
+
+    public void Accept(RevisionVisitor visitor)
+    {
+        visitor.visit(this);
+    }
+
+    public void accept(RevisionVisitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
+
+
+
+
+
diff --git a/src/org/apache/commons/jrcs/diff/ChangeDelta.java b/src/org/apache/commons/jrcs/diff/ChangeDelta.java
new file mode 100644
index 0000000..bf9162f
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/ChangeDelta.java
@@ -0,0 +1,134 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds an change-delta between to revisions of a text.
+ *
+ * @version $Id: ChangeDelta.java 146038 2003-10-13 08:00:44Z rdonkin $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class ChangeDelta extends Delta
+{
+
+    ChangeDelta()
+    {
+        super();
+    }
+
+    public ChangeDelta(Chunk orig, Chunk rev)
+    {
+        init(orig, rev);
+    }
+
+    public void verify(List target) throws PatchFailedException
+    {
+        if (!original.verify(target))
+        {
+            throw new PatchFailedException();
+        }
+        if (original.first() > target.size())
+        {
+            throw new PatchFailedException("original.first() > target.size()");
+        }
+    }
+
+    public void applyTo(List target)
+    {
+        original.applyDelete(target);
+        revised.applyAdd(original.first(), target);
+    }
+
+    public void toString(StringBuffer s)
+    {
+        original.rangeString(s);
+        s.append("c");
+        revised.rangeString(s);
+        s.append(Diff.NL);
+        original.toString(s, "< ", "\n");
+        s.append("---");
+        s.append(Diff.NL);
+        revised.toString(s, "> ", "\n");
+    }
+
+    public void toRCSString(StringBuffer s, String EOL)
+    {
+        s.append("d");
+        s.append(original.rcsfrom());
+        s.append(" ");
+        s.append(original.size());
+        s.append(EOL);
+        s.append("a");
+        s.append(original.rcsto());
+        s.append(" ");
+        s.append(revised.size());
+        s.append(EOL);
+        revised.toString(s, "", EOL);
+    }
+
+    public void accept(RevisionVisitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
+
diff --git a/src/org/apache/commons/jrcs/diff/Chunk.java b/src/org/apache/commons/jrcs/diff/Chunk.java
new file mode 100644
index 0000000..43f454b
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/Chunk.java
@@ -0,0 +1,357 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Holds a information about a parrt of the text involved in
+ * a differencing or patching operation.
+ *
+ * @version $Id: Chunk.java 146038 2003-10-13 08:00:44Z rdonkin $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Diff
+ * @see Delta
+ */
+public class Chunk
+    extends org.apache.commons.jrcs.util.ToString
+{
+
+    protected int anchor;
+
+    protected int count;
+
+    protected List chunk;
+
+    /**
+     * Creates a chunk that doesn't copy the original text.
+     * @param pos the start position in the text.
+     * @param count the size of the chunk.
+     */
+    public Chunk(int pos, int count)
+    {
+        this.anchor = pos;
+        this.count = (count >= 0 ? count : 0);
+    }
+
+    /**
+     * Creates a chunk and saves a copy the original chunk's text.
+     * @param iseq the original text.
+     * @param pos the start position in the text.
+     * @param count the size of the chunk.
+     */
+    public Chunk(Object[] iseq, int pos, int count)
+    {
+        this(pos, count);
+        chunk = slice(iseq, pos, count);
+    }
+
+    /**
+     * Creates a chunk that will be displaced in the resulting text,
+     * and saves a copy the original chunk's text.
+     * @param iseq the original text.
+     * @param pos the start position in the text.
+     * @param count the size of the chunk.
+     * @param offset the position the chunk should have in the resulting text.
+     */
+    public Chunk(Object[] iseq, int pos, int count, int offset)
+    {
+        this(offset, count);
+        chunk = slice(iseq, pos, count);
+    }
+
+    /**
+     * Creates a chunk and saves a copy the original chunk's text.
+     * @param iseq the original text.
+     * @param pos the start position in the text.
+     * @param count the size of the chunk.
+     */
+    public Chunk(List iseq, int pos, int count)
+    {
+        this(pos, count);
+        chunk = slice(iseq, pos, count);
+    }
+
+    /**
+     * Creates a chunk that will be displaced in the resulting text,
+     * and saves a copy the original chunk's text.
+     * @param iseq the original text.
+     * @param pos the start position in the text.
+     * @param count the size of the chunk.
+     * @param offset the position the chunk should have in the resulting text.
+     */
+    public Chunk(List iseq, int pos, int count, int offset)
+    {
+        this(offset, count);
+        chunk = slice(iseq, pos, count);
+    }
+
+    /**
+     * Returns the anchor position of the chunk.
+     * @return the anchor position.
+     */
+    public int anchor()
+    {
+        return anchor;
+    }
+
+    /**
+     * Returns the size of the chunk.
+     * @return the size.
+     */
+    public int size()
+    {
+        return count;
+    }
+
+    /**
+     * Returns the index of the first line of the chunk.
+     */
+    public int first()
+    {
+        return anchor();
+    }
+
+    /**
+     * Returns the index of the last line of the chunk.
+     */
+    public int last()
+    {
+        return anchor() + size() - 1;
+    }
+
+    /**
+     * Returns the <i>from</i> index of the chunk in RCS terms.
+     */
+    public int rcsfrom()
+    {
+        return anchor + 1;
+    }
+
+    /**
+     * Returns the <i>to</i> index of the chunk in RCS terms.
+     */
+    public int rcsto()
+    {
+        return anchor + count;
+    }
+
+    /**
+     * Returns the text saved for this chunk.
+     * @return the text.
+     */
+    public List chunk()
+    {
+        return chunk;
+    }
+
+    /**
+     * Verifies that this chunk's saved text matches the corresponding
+     * text in the given sequence.
+     * @param target the sequence to verify against.
+     * @return true if the texts match.
+     */
+    public boolean verify(List target)
+    {
+        if (chunk == null)
+        {
+            return true;
+        }
+        if (last() > target.size())
+        {
+            return false;
+        }
+        for (int i = 0; i < count; i++)
+        {
+            if (!target.get(anchor + i).equals(chunk.get(i)))
+            {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Delete this chunk from he given text.
+     * @param target the text to delete from.
+     */
+    public void applyDelete(List target)
+    {
+        for (int i = last(); i >= first(); i--)
+        {
+            target.remove(i);
+        }
+    }
+
+    /**
+     * Add the text of this chunk to the target at the given position.
+     * @param start where to add the text.
+     * @param target the text to add to.
+     */
+    public void applyAdd(int start, List target)
+    {
+        Iterator i = chunk.iterator();
+        while (i.hasNext())
+        {
+            target.add(start++, i.next());
+        }
+    }
+
+    /**
+     * Provide a string image of the chunk using the an empty prefix and
+     * postfix.
+     */
+    public void toString(StringBuffer s)
+    {
+        toString(s, "", "");
+    }
+
+    /**
+     * Provide a string image of the chunk using the given prefix and
+     * postfix.
+     * @param s where the string image should be appended.
+     * @param prefix the text thatshould prefix each line.
+     * @param postfix the text that should end each line.
+     */
+    public StringBuffer toString(StringBuffer s, String prefix, String postfix)
+    {
+        if (chunk != null)
+        {
+            Iterator i = chunk.iterator();
+            while (i.hasNext())
+            {
+                s.append(prefix);
+                s.append(i.next());
+                s.append(postfix);
+            }
+        }
+        return s;
+    }
+
+    /**
+     * Retreives the specified part from a {@link List List}.
+     * @param seq the list to retreive a slice from.
+     * @param pos the start position.
+     * @param count the number of items in the slice.
+     * @return a {@link List List} containing the specified items.
+     */
+    public static List slice(List seq, int pos, int count)
+    {
+        if (count <= 0)
+        {
+            return new ArrayList(seq.subList(pos, pos));
+        }
+        else
+        {
+            return new ArrayList(seq.subList(pos, pos + count));
+        }
+    }
+
+    /**
+     * Retrieves a slice from an {@link Object Object} array.
+     * @param seq the list to retreive a slice from.
+     * @param pos the start position.
+     * @param count the number of items in the slice.
+     * @return a {@link List List} containing the specified items.
+     */
+    public static List slice(Object[] seq, int pos, int count)
+    {
+        return slice(Arrays.asList(seq), pos, count);
+    }
+
+    /**
+     * Provide a string representation of the numeric range of this chunk.
+     */
+    public String rangeString()
+    {
+        StringBuffer result = new StringBuffer();
+        rangeString(result);
+        return result.toString();
+    }
+
+    /**
+     * Provide a string representation of the numeric range of this chunk.
+     * @param s where the string representation should be appended.
+     */
+    public void rangeString(StringBuffer s)
+    {
+        rangeString(s, ",");
+    }
+
+    /**
+     * Provide a string representation of the numeric range of this chunk.
+     * @param s where the string representation should be appended.
+     * @param separ what to use as line separator.
+     */
+    public void rangeString(StringBuffer s, String separ)
+    {
+        if (size() <= 1)
+        {
+            s.append(Integer.toString(rcsfrom()));
+        }
+        else
+        {
+            s.append(Integer.toString(rcsfrom()));
+            s.append(separ);
+            s.append(Integer.toString(rcsto()));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/DeleteDelta.java b/src/org/apache/commons/jrcs/diff/DeleteDelta.java
new file mode 100644
index 0000000..c99cf9e
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/DeleteDelta.java
@@ -0,0 +1,121 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds a delete-delta between to revisions of a text.
+ *
+ * @version $Id: DeleteDelta.java 146038 2003-10-13 08:00:44Z rdonkin $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ */
+public class DeleteDelta
+    extends Delta
+{
+
+    DeleteDelta()
+    {
+        super();
+    }
+
+    public DeleteDelta(Chunk orig)
+    {
+        init(orig, null);
+    }
+
+    public void verify(List target)
+        throws PatchFailedException
+    {
+        if (!original.verify(target))
+        {
+            throw new PatchFailedException();
+        }
+    }
+
+    public void applyTo(List target)
+    {
+        original.applyDelete(target);
+    }
+
+    public void toString(StringBuffer s)
+    {
+        s.append(original.rangeString());
+        s.append("d");
+        s.append(revised.rcsto());
+        s.append(Diff.NL);
+        original.toString(s, "< ", Diff.NL);
+    }
+
+    public void toRCSString(StringBuffer s, String EOL)
+    {
+        s.append("d");
+        s.append(original.rcsfrom());
+        s.append(" ");
+        s.append(original.size());
+        s.append(EOL);
+    }
+
+    public void accept(RevisionVisitor visitor)
+    {
+        visitor.visit(this);
+    }
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/Delta.java b/src/org/apache/commons/jrcs/diff/Delta.java
new file mode 100644
index 0000000..d563490
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/Delta.java
@@ -0,0 +1,255 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.List;
+
+/**
+ * Holds a "delta" difference between to revisions of a text.
+ *
+ * @version $Revision: 1.6 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ *
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @author <a href="mailto:bwm at hplb.hpl.hp.com">Brian McBride</a>
+ * @see Diff
+ * @see Chunk
+ * @see Revision
+ *
+ * modifications
+ *
+ * 27 Apr 2003 bwm
+ *
+ * Added getOriginal() and getRevised() accessor methods
+ * Added visitor pattern accept() method
+ */
+
+public abstract class Delta
+    extends org.apache.commons.jrcs.util.ToString
+{
+
+    protected Chunk original;
+
+    protected Chunk revised;
+
+    static Class[][] DeltaClass;
+
+    static
+    {
+        DeltaClass = new Class[2][2];
+        try
+        {
+            DeltaClass[0][0] = org.apache.commons.jrcs.diff.ChangeDelta.class;
+            DeltaClass[0][1] = org.apache.commons.jrcs.diff.AddDelta.class;
+            DeltaClass[1][0] = org.apache.commons.jrcs.diff.DeleteDelta.class;
+            DeltaClass[1][1] = org.apache.commons.jrcs.diff.ChangeDelta.class;
+        }
+        catch (Throwable o)
+        {
+
+        }
+    }
+
+    /**
+     * Returns a Delta that corresponds to the given chunks in the
+     * original and revised text respectively.
+     * @param orig the chunk in the original text.
+     * @param rev  the chunk in the revised text.
+     */
+    public static Delta newDelta(Chunk orig, Chunk rev)
+    {
+        Class c = DeltaClass[orig.size() > 0 ? 1 : 0]
+            [rev.size() > 0 ? 1 : 0];
+        Delta result;
+        try
+        {
+            result = (Delta) c.newInstance();
+        }
+        catch (Throwable e)
+        {
+            return null;
+        }
+        result.init(orig, rev);
+        return result;
+    }
+
+    /**
+     * Creates an uninitialized delta.
+     */
+    protected Delta()
+    {
+    }
+
+    /**
+     * Creates a delta object with the given chunks from the original
+     * and revised texts.
+     */
+    protected Delta(Chunk orig, Chunk rev)
+    {
+        init(orig, rev);
+    }
+
+    /**
+     * Initializaes the delta with the given chunks from the original
+     * and revised texts.
+     */
+    protected void init(Chunk orig, Chunk rev)
+    {
+        original = orig;
+        revised = rev;
+    }
+
+    /**
+     * Verifies that this delta can be used to patch the given text.
+     * @param target the text to patch.
+     * @throws PatchFailedException if the patch cannot be applied.
+     */
+    public abstract void verify(List target)
+        throws PatchFailedException;
+
+    /**
+     * Applies this delta as a patch to the given text.
+     * @param target the text to patch.
+     * @throws PatchFailedException if the patch cannot be applied.
+     */
+    public final void patch(List target)
+        throws PatchFailedException
+    {
+        verify(target);
+        try
+        {
+            applyTo(target);
+        }
+        catch (Exception e)
+        {
+            throw new PatchFailedException(e.getMessage());
+        }
+    }
+
+    /**
+     * Applies this delta as a patch to the given text.
+     * @param target the text to patch.
+     * @throws PatchFailedException if the patch cannot be applied.
+     */
+    public abstract void applyTo(List target);
+
+    /**
+     * Converts this delta into its Unix diff style string representation.
+     * @param s a {@link StringBuffer StringBuffer} to which the string
+     * representation will be appended.
+     */
+    public void toString(StringBuffer s)
+    {
+        original.rangeString(s);
+        s.append("x");
+        revised.rangeString(s);
+        s.append(Diff.NL);
+        original.toString(s, "> ", "\n");
+        s.append("---");
+        s.append(Diff.NL);
+        revised.toString(s, "< ", "\n");
+    }
+
+    /**
+     * Converts this delta into its RCS style string representation.
+     * @param s a {@link StringBuffer StringBuffer} to which the string
+     * representation will be appended.
+     * @param EOL the string to use as line separator.
+     */
+    public abstract void toRCSString(StringBuffer s, String EOL);
+
+    /**
+     * Converts this delta into its RCS style string representation.
+     * @param EOL the string to use as line separator.
+     */
+    public String toRCSString(String EOL)
+    {
+        StringBuffer s = new StringBuffer();
+        toRCSString(s, EOL);
+        return s.toString();
+    }
+
+    /**
+     * Accessor method to return the chunk representing the original
+     * sequence of items
+     *
+     * @return the original sequence
+     */
+    public Chunk getOriginal()
+    {
+        return original;
+    }
+
+    /**
+     * Accessor method to return the chunk representing the updated
+     * sequence of items.
+     *
+     * @return the updated sequence
+     */
+    public Chunk getRevised()
+    {
+        return revised;
+    }
+
+    /**
+     * Accepts a visitor.
+     * <p>
+     * See the Visitor pattern in "Design Patterns" by the GOF4.
+     * @param visitor The visitor.
+     */
+    public abstract void accept(RevisionVisitor visitor);
+}
diff --git a/src/org/apache/commons/jrcs/diff/Diff.java b/src/org/apache/commons/jrcs/diff/Diff.java
new file mode 100644
index 0000000..1b37d81
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/Diff.java
@@ -0,0 +1,347 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.*;
+
+import org.apache.commons.jrcs.diff.myers.MyersDiff;
+import org.apache.commons.jrcs.util.ToString;
+
+/**
+ * Implements a differencing engine that works on arrays of {@link Object Object}.
+ *
+ * <p>Within this library, the word <i>text</i> means a unit of information
+ * subject to version control.
+ *
+ * <p>Text is represented as <code>Object[]</code> because
+ * the diff engine is capable of handling more than plain ascci. In fact,
+ * arrays of any type that implements
+ * {@link java.lang.Object#hashCode hashCode()} and
+ * {@link java.lang.Object#equals equals()}
+ * correctly can be subject to differencing using this
+ * library.</p>
+ *
+ * <p>This library provides a framework in which different differencing
+ * algorithms may be used.  If no algorithm is specififed, a default
+ * algorithm is used.</p>
+ *
+ * @version $Revision: 1.16 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see     Delta
+ * @see     DiffAlgorithm
+ *
+ * modifications:
+ *
+ * 27 Apr 2003 bwm
+ *
+ * Added some comments whilst trying to figure out the algorithm
+ *
+ * 03 May 2003 bwm
+ *
+ * Factored out the algorithm implementation into a separate difference
+ * algorithm class to allow pluggable algorithms.
+ */
+
+public class Diff
+    extends ToString
+{
+    /** The standard line separator. */
+    public static final String NL = System.getProperty("line.separator");
+
+    /** The line separator to use in RCS format output. */
+    public static final String RCS_EOL = "\n";
+
+    /** The original sequence. */
+    protected final Object[] orig;
+
+    /** The differencing algorithm to use. */
+    protected DiffAlgorithm algorithm;
+
+    /**
+     * Create a differencing object using the default algorithm
+     *
+     * @param the original text that will be compared
+     */
+    public Diff(Object[] original)
+    {
+        this(original, null);
+    }
+
+    /**
+     * Create a differencing object using the given algorithm
+     *
+     * @param o the original text which will be compared against
+     * @param algorithm the difference algorithm to use.
+     */
+    public Diff(Object[] original, DiffAlgorithm algorithm)
+    {
+        if (original == null)
+        {
+            throw new IllegalArgumentException();
+        }
+
+        this.orig = original;
+        if (algorithm != null)
+            this.algorithm = algorithm;
+        else
+            this.algorithm = defaultAlgorithm();
+    }
+
+    protected DiffAlgorithm defaultAlgorithm()
+    {
+        return new MyersDiff();
+    }
+
+    /**
+     * compute the difference between an original and a revision.
+     *
+     * @param orig the original
+     * @param rev the revision to compare with the original.
+     * @return a Revision describing the differences
+     */
+    public static Revision diff(Object[] orig, Object[] rev)
+        throws DifferentiationFailedException
+    {
+        if (orig == null || rev == null)
+        {
+            throw new IllegalArgumentException();
+        }
+
+        return diff(orig, rev, null);
+    }
+
+    /**
+     * compute the difference between an original and a revision.
+     *
+     * @param orig the original
+     * @param rev the revision to compare with the original.
+     * @param algorithm the difference algorithm to use
+     * @return a Revision describing the differences
+     */
+    public static Revision diff(Object[] orig, Object[] rev,
+                                DiffAlgorithm algorithm)
+        throws DifferentiationFailedException
+    {
+        if (orig == null || rev == null)
+        {
+            throw new IllegalArgumentException();
+        }
+
+        return new Diff(orig, algorithm).diff(rev);
+    }
+
+    /**
+     * compute the difference between the original and a revision.
+     *
+     * @param rev the revision to compare with the original.
+     * @return a Revision describing the differences
+     */
+    public Revision diff(Object[] rev)
+        throws DifferentiationFailedException
+    {
+        if (orig.length == 0 && rev.length == 0)
+            return new Revision();
+        else
+            return algorithm.diff(orig, rev);
+    }
+
+    /**
+     * Compares the two input sequences.
+     * @param orig The original sequence.
+     * @param rev The revised sequence.
+     * @return true if the sequences are identical. False otherwise.
+     */
+    public static boolean compare(Object[] orig, Object[] rev)
+    {
+        if (orig.length != rev.length)
+        {
+            return false;
+        }
+        else
+        {
+            for (int i = 0; i < orig.length; i++)
+            {
+                if (!orig[i].equals(rev[i]))
+                {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Converts an array of {@link Object Object} to a string
+     * using {@link Diff#NL Diff.NL}
+     * as the line separator.
+     * @param o the array of objects.
+     */
+    public static String arrayToString(Object[] o)
+    {
+        return arrayToString(o, Diff.NL);
+    }
+
+    /**
+     * Edits all of the items in the input sequence.
+     * @param text The input sequence.
+     * @return A sequence of the same length with all the lines
+     * differing from the corresponding ones in the input.
+     */
+    public static Object[] editAll(Object[] text)
+    {
+        Object[] result = new String[text.length];
+
+        for(int i = 0; i < text.length; i++)
+            result[i] = text[i] + " <edited>";
+
+        return result;
+    }
+
+    /**
+     * Performs random edits on the input sequence. Useful for testing.
+     * @param text The input sequence.
+     * @return The sequence with random edits performed.
+     */
+    public static Object[] randomEdit(Object[] text)
+    {
+        return randomEdit(text, text.length);
+    }
+
+    /**
+     * Performs random edits on the input sequence. Useful for testing.
+     * @param text The input sequence.
+     * @param seed A seed value for the randomizer.
+     * @return The sequence with random edits performed.
+     */
+    public static Object[] randomEdit(Object[] text, long seed)
+    {
+        List result = new ArrayList(Arrays.asList(text));
+        Random r = new Random(seed);
+        int nops = r.nextInt(10);
+        for (int i = 0; i < nops; i++)
+        {
+            boolean del = r.nextBoolean();
+            int pos = r.nextInt(result.size() + 1);
+            int len = Math.min(result.size() - pos, 1 + r.nextInt(4));
+            if (del && result.size() > 0)
+            { // delete
+                result.subList(pos, pos + len).clear();
+            }
+            else
+            {
+                for (int k = 0; k < len; k++, pos++)
+                {
+                    result.add(pos,
+                               "[" + i + "] random edit[" + i + "][" + i + "]");
+                }
+            }
+        }
+        return result.toArray();
+    }
+
+    /**
+     * Shuffles around the items in the input sequence.
+     * @param text The input sequence.
+     * @return The shuffled sequence.
+     */
+    public static Object[] shuffle(Object[] text)
+    {
+        return shuffle(text, text.length);
+    }
+
+    /**
+    * Shuffles around the items in the input sequence.
+    * @param text The input sequence.
+    * @param seed A seed value for randomizing the suffle.
+    * @return The shuffled sequence.
+    */
+   public static Object[] shuffle(Object[] text, long seed)
+    {
+        List result = new ArrayList(Arrays.asList(text));
+        Collections.shuffle(result);
+        return result.toArray();
+    }
+
+    /**
+     * Generate a random sequence of the given size.
+     * @param The size of the sequence to generate.
+     * @return The generated sequence.
+     */
+    public static Object[] randomSequence(int size)
+    {
+        return randomSequence(size, size);
+    }
+
+    /**
+     * Generate a random sequence of the given size.
+     * @param The size of the sequence to generate.
+     * @param seed A seed value for randomizing the generation.
+     * @return The generated sequence.
+     */
+    public static Object[] randomSequence(int size, long seed)
+    {
+        Integer[] result = new Integer[size];
+        Random r = new Random(seed);
+        for(int i = 0; i < result.length; i++)
+        {
+            result[i] = new Integer(r.nextInt(size));
+        }
+        return result;
+    }
+
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/DiffAlgorithm.java b/src/org/apache/commons/jrcs/diff/DiffAlgorithm.java
new file mode 100644
index 0000000..39cd6a0
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/DiffAlgorithm.java
@@ -0,0 +1,84 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * A simple interface for implementations of differencing algorithms.
+ *
+ * @version $Revision: 1.6 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ *
+ * @author <a href="mailto:bwm at hplb.hpl.hp.com">Brian McBride</a>
+ */
+public interface DiffAlgorithm
+{
+    /**
+     * Computes the difference between the original
+     * sequence and the revised sequence and returns it
+     * as a {@link org.apache.commons.jrcs.diff.Revision Revision}
+     * object.
+     * <p>
+     * The revision can be used to construct the revised sequence
+     * from the original sequence.
+     *
+     * @param rev the revised text
+     * @return the revision script.
+     * @throws DifferentiationFailedException if the diff could not be computed.
+     */
+    public abstract Revision diff(Object[] orig, Object[] rev)
+        throws DifferentiationFailedException;
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/DiffException.java b/src/org/apache/commons/jrcs/diff/DiffException.java
new file mode 100644
index 0000000..154527d
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/DiffException.java
@@ -0,0 +1,79 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Base class for all exceptions emanating from this package.
+ *
+ * @version $Revision: 1.3 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ *
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ */
+public class DiffException extends Exception
+{
+
+    public DiffException()
+    {
+    }
+
+    public DiffException(String msg)
+    {
+        super(msg);
+    }
+}
+
diff --git a/src/org/apache/commons/jrcs/diff/DifferentiationFailedException.java b/src/org/apache/commons/jrcs/diff/DifferentiationFailedException.java
new file mode 100644
index 0000000..eb32ec0
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/DifferentiationFailedException.java
@@ -0,0 +1,82 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Thrown whenever the differencing engine cannot produce the differences
+ * between two revisions of ta text.
+ *
+ * @version $Revision: 1.3 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ *
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Diff
+ * @see DiffAlgorithm
+ */
+public class DifferentiationFailedException extends DiffException
+{
+
+    public DifferentiationFailedException()
+    {
+    }
+
+    public DifferentiationFailedException(String msg)
+    {
+        super(msg);
+    }
+}
+
diff --git a/src/org/apache/commons/jrcs/diff/PatchFailedException.java b/src/org/apache/commons/jrcs/diff/PatchFailedException.java
new file mode 100644
index 0000000..cc497a2
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/PatchFailedException.java
@@ -0,0 +1,82 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Thrown whenever a delta cannot be applied as a patch to a given text.
+ *
+ * @version $Revision: 1.3 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Delta
+ * @see Diff
+ */
+public class PatchFailedException extends DiffException
+{
+
+    public PatchFailedException()
+    {
+    }
+
+    public PatchFailedException(String msg)
+    {
+        super(msg);
+    }
+}
+
+
+
diff --git a/src/org/apache/commons/jrcs/diff/Revision.java b/src/org/apache/commons/jrcs/diff/Revision.java
new file mode 100644
index 0000000..fee0270
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/Revision.java
@@ -0,0 +1,253 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.commons.jrcs.util.ToString;
+
+
+/**
+ * A Revision holds the series of deltas that describe the differences
+ * between two sequences.
+ *
+ * @version $Revision: 1.8 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ *
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @author <a href="mailto:bwm at hplb.hpl.hp.com">Brian McBride</a>
+ *
+ * @see Delta
+ * @see Diff
+ * @see Chunk
+ * @see Revision
+ *
+ * modifications
+ * 27 Apr 2003 bwm
+ *
+ * Added visitor pattern Visitor interface and accept() method.
+ */
+
+public class Revision
+        extends ToString
+{
+
+    List deltas_ = new LinkedList();
+
+
+    /**
+     * Creates an empty Revision.
+     */
+    public Revision()
+    {
+    }
+
+
+    /**
+     * Adds a delta to this revision.
+     * @param delta the {@link Delta Delta} to add.
+     */
+    public synchronized void addDelta(Delta delta)
+    {
+        if (delta == null)
+        {
+            throw new IllegalArgumentException("new delta is null");
+        }
+        deltas_.add(delta);
+    }
+
+
+    /**
+     * Adds a delta to the start of this revision.
+     * @param delta the {@link Delta Delta} to add.
+     */
+    public synchronized void insertDelta(Delta delta)
+    {
+        if (delta == null)
+        {
+            throw new IllegalArgumentException("new delta is null");
+        }
+        deltas_.add(0, delta);
+    }
+
+
+    /**
+     * Retrieves a delta from this revision by position.
+     * @param i the position of the delta to retrieve.
+     * @return the specified delta
+     */
+    public Delta getDelta(int i)
+    {
+        return (Delta) deltas_.get(i);
+    }
+
+    /**
+     * Returns the number of deltas in this revision.
+     * @return the number of deltas.
+     */
+    public int size()
+    {
+        return deltas_.size();
+    }
+
+    /**
+     * Applies the series of deltas in this revision as patches to
+     * the given text.
+     * @param src the text to patch, which the method doesn't change.
+     * @return the resulting text after the patches have been applied.
+     * @throws PatchFailedException if any of the patches cannot be applied.
+     */
+    public Object[] patch(Object[] src) throws PatchFailedException
+    {
+        List target = new ArrayList(Arrays.asList(src));
+        applyTo(target);
+        return target.toArray();
+    }
+
+    /**
+     * Applies the series of deltas in this revision as patches to
+     * the given text.
+     * @param target the text to patch.
+     * @throws PatchFailedException if any of the patches cannot be applied.
+     */
+    public synchronized void applyTo(List target) throws PatchFailedException
+    {
+        ListIterator i = deltas_.listIterator(deltas_.size());
+        while (i.hasPrevious())
+        {
+            Delta delta = (Delta) i.previous();
+            delta.patch(target);
+        }
+    }
+
+    /**
+     * Converts this revision into its Unix diff style string representation.
+     * @param s a {@link StringBuffer StringBuffer} to which the string
+     * representation will be appended.
+     */
+    public synchronized void toString(StringBuffer s)
+    {
+        Iterator i = deltas_.iterator();
+        while (i.hasNext())
+        {
+            ((Delta) i.next()).toString(s);
+        }
+    }
+
+    /**
+     * Converts this revision into its RCS style string representation.
+     * @param s a {@link StringBuffer StringBuffer} to which the string
+     * representation will be appended.
+     * @param EOL the string to use as line separator.
+     */
+    public synchronized void toRCSString(StringBuffer s, String EOL)
+    {
+        Iterator i = deltas_.iterator();
+        while (i.hasNext())
+        {
+            ((Delta) i.next()).toRCSString(s, EOL);
+        }
+    }
+
+    /**
+     * Converts this revision into its RCS style string representation.
+     * @param s a {@link StringBuffer StringBuffer} to which the string
+     * representation will be appended.
+     */
+    public void toRCSString(StringBuffer s)
+    {
+        toRCSString(s, Diff.NL);
+    }
+
+    /**
+     * Converts this delta into its RCS style string representation.
+     * @param EOL the string to use as line separator.
+     */
+    public String toRCSString(String EOL)
+    {
+        StringBuffer s = new StringBuffer();
+        toRCSString(s, EOL);
+        return s.toString();
+    }
+
+    /**
+     * Converts this delta into its RCS style string representation
+     * using the default line separator.
+     */
+    public String toRCSString()
+    {
+        return toRCSString(Diff.NL);
+    }
+
+    /**
+     * Accepts a visitor.
+     * @param visitor the {@link Visitor} visiting this instance
+     */
+    public void accept(RevisionVisitor visitor) {
+        visitor.visit(this);
+        Iterator iter = deltas_.iterator();
+        while (iter.hasNext()) {
+            ((Delta) iter.next()).accept(visitor);
+        }
+    }
+
+}
diff --git a/src/org/apache/commons/jrcs/diff/RevisionVisitor.java b/src/org/apache/commons/jrcs/diff/RevisionVisitor.java
new file mode 100644
index 0000000..ba82526
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/RevisionVisitor.java
@@ -0,0 +1,73 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+/**
+ * Definition of a Visitor interface for {@link Revision Revisions}
+ * See "Design Patterns" by the Gang of Four
+ */
+public interface RevisionVisitor
+{
+    public void visit(Revision revision);
+
+    public void visit(DeleteDelta delta);
+
+    public void visit(ChangeDelta delta);
+
+    public void visit(AddDelta delta);
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/SimpleDiff.java b/src/org/apache/commons/jrcs/diff/SimpleDiff.java
new file mode 100644
index 0000000..fee2df4
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/SimpleDiff.java
@@ -0,0 +1,315 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff;
+
+import java.util.*;
+
+/**
+ * Implements a simple differencing algortithm.<p>
+ *
+ * @date $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @version $Revision: 1.7 $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ *
+ * <p><b>Overview of Algorithm</b></p>
+ *
+ * <p><i>by <a
+ * href='http://www.topmeadow.net/bwm'> bwm</a>
+ * </p>
+ *
+ * <p>The algorithm is optimised for situations where the input sequences
+ * have few repeated objects.  If it is given input with many repeated
+ * objects it will report sub-optimal changes.  However, given appropriate
+ * input, it is fast, and linear in memory usage.</p>
+ *
+ * <p>The algorithm consists of the following steps:</p>
+ * <ul>
+ *   <li>compute an equivalence set for the input data</li>
+ *   <li>translate each element of the orginal
+ *       and revised input sequences to a member of the equivalence set
+ *   </li>
+ *   <li>match the the input sequences to determine the deltas, i.e.
+ *       the differences between the original and revised sequences.</li>
+ * </ul>
+ *
+ * <p>The first step is to compute a an equivalence set for the input data.
+ *  The equivalence set is computed from objects that are in the original
+ *  input sequence</p>
+ * <pre>
+ *   eq(x) = the index of the first occurence of x in the original sequence.
+ * </pre>
+ *
+ * <p>With this equivalence function, the algorithm can compare integers rather
+ * than strings, which is considerably more efficient.</p>
+ *
+ * <p>The second step is to compute the datastructure on which the
+ * algorithm will operate.  Having computed the equivalence function
+ * in the previous step, we can compute two arrays where
+ * indx[i] = eqs(orig[i]) and jndx[i] = eqs(rev[i]).  The algorithm can
+ * now operate on indx and jndx instead of orig and rev. Thus, comparisons
+ * are then on O(int == int) instead of O(Object.equals(Object)).
+ * </p>
+ *
+ * <p>The algorithm now matches indx and jndx.  Whilst indx[i] == jndx[i]
+ * it skips matching objects in the sequence.  In seeking to match objects
+ * in the input sequence it assumes that each object is likely to be unique.
+ * It uses the known characteristics of the unique equivalence function.  It can
+ * tell from the eq value if this object appeared in the other sequence
+ * at all.  If it did not, there is no point in searching for a match.</p>
+ *
+ * <p>Recall that the eq function value is the index earliest occurrence in
+ * the orig sequence.  This information is used to search efficiently for
+ * the next match.  The algorithm is perfect when all input objects are
+ * unique, but degrades when input objects are not unique.  When input
+ * objects are not unique an optimal match may not be found, but a
+ * correct match will be.</p>
+ *
+ * <p>Having identified common matching objects in the orig and revised
+ * sequences, the differences between them are easily computed.
+ * </p>
+ *
+ * @see Delta
+ * @see Revision
+ * Modifications:
+ *
+ * 27/Apr/2003 bwm
+ * Added some comments whilst trying to figure out the algorithm
+ *
+ * 03 May 2003 bwm
+ * Created this implementation class by refactoring it out of the Diff
+ * class to enable plug in difference algorithms
+ *
+ */
+public class SimpleDiff
+    implements DiffAlgorithm
+{
+
+    static final int NOT_FOUND_i = -2;
+    static final int NOT_FOUND_j = -1;
+    static final int EOS = Integer.MAX_VALUE;
+
+    public SimpleDiff()
+    {
+    }
+
+    protected int scan(int[] ndx, int i, int target)
+    {
+        while (ndx[i] < target)
+        {
+            i++;
+        }
+        return i;
+    }
+
+    /**
+     * Compute the difference between original and revised sequences.
+     *
+     * @param orig The original sequence.
+     * @param rev The revised sequence to be compared with the original.
+     * @return A Revision object describing the differences.
+     * @throws DifferenciationFailedException if the diff could not be computed.
+     */
+    public Revision diff(Object[] orig, Object[] rev)
+        throws DifferentiationFailedException
+    {
+        // create map eqs, such that for each item in both orig and rev
+        // eqs(item) = firstOccurrence(item, orig);
+        Map eqs = buildEqSet(orig, rev);
+
+        // create an array such that
+        //   indx[i] = NOT_FOUND_i if orig[i] is not in rev
+        //   indx[i] = firstOccurrence(orig[i], orig)
+        int[] indx = buildIndex(eqs, orig, NOT_FOUND_i);
+
+        // create an array such that
+        //   jndx[j] = NOT_FOUND_j if orig[j] is not in rev
+        //   jndx[j] = firstOccurrence(rev[j], orig)
+        int[] jndx = buildIndex(eqs, rev, NOT_FOUND_j);
+
+        // what in effect has been done is to build a unique hash
+        // for each item that is in both orig and rev
+        // and to label each item in orig and new with that hash value
+        // or a marker that the item is not common to both.
+
+        eqs = null; // let gc know we're done with this
+
+        Revision deltas = new Revision(); //!!! new Revision()
+        int i = 0;
+        int j = 0;
+
+        // skip matching
+        // skip leading items that are equal
+        // could be written
+        // for (i=0; indx[i] != EOS && indx[i] == jndx[i]; i++);
+        // j = i;
+        for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++)
+        {
+            /* void */
+        }
+
+        while (indx[i] != jndx[j])
+        { // only equal if both == EOS
+            // they are different
+            int ia = i;
+            int ja = j;
+
+            // size of this delta
+            do
+            {
+                // look down rev for a match
+                // stop at a match
+                // or if the FO(rev[j]) > FO(orig[i])
+                // or at the end
+                while (jndx[j] < 0 || jndx[j] < indx[i])
+                {
+                    j++;
+                }
+                // look down orig for a match
+                // stop at a match
+                // or if the FO(orig[i]) > FO(rev[j])
+                // or at the end
+                while (indx[i] < 0 || indx[i] < jndx[j])
+                {
+                    i++;
+                }
+
+                // this doesn't do a compare each line with each other line
+                // so it won't find all matching lines
+            }
+            while (indx[i] != jndx[j]);
+
+            // on exit we have a match
+
+            // they are equal, reverse any exedent matches
+            // it is possible to overshoot, so count back matching items
+            while (i > ia && j > ja && indx[i - 1] == jndx[j - 1])
+            {
+                --i;
+                --j;
+            }
+
+            deltas.addDelta(Delta.newDelta(new Chunk(orig, ia, i - ia),
+                                           new Chunk(rev, ja, j - ja)));
+            // skip matching
+            for (; indx[i] != EOS && indx[i] == jndx[j]; i++, j++)
+            {
+                /* void */
+            }
+        }
+        return deltas;
+    }
+
+    /**
+     * create a <code>Map</code> from each common item in orig and rev
+     * to the index of its first occurrence in orig
+     *
+     * @param orig the original sequence of items
+     * @param rev  the revised sequence of items
+     */
+    protected Map buildEqSet(Object[] orig, Object[] rev)
+    {
+        // construct a set of the objects that orig and rev have in common
+
+        // first construct a set containing all the elements in orig
+        Set items = new HashSet(Arrays.asList(orig));
+
+        // then remove all those not in rev
+        items.retainAll(Arrays.asList(rev));
+
+        Map eqs = new HashMap();
+        for (int i = 0; i < orig.length; i++)
+        {
+            // if its a common item and hasn't been found before
+            if (items.contains(orig[i]))
+            {
+                // add it to the map
+                eqs.put(orig[i], new Integer(i));
+                // and make sure its not considered again
+                items.remove(orig[i]);
+            }
+        }
+        return eqs;
+    }
+
+    /**
+     * build a an array such each a[i] = eqs([i]) or NF if eqs([i]) undefined
+     *
+     * @param eqs a mapping from Object to Integer
+     * @param seq a sequence of objects
+     * @param NF  the not found marker
+     */
+    protected int[] buildIndex(Map eqs, Object[] seq, int NF)
+    {
+        int[] result = new int[seq.length + 1];
+        for (int i = 0; i < seq.length; i++)
+        {
+            Integer value = (Integer) eqs.get(seq[i]);
+            if (value == null || value.intValue() < 0)
+            {
+                result[i] = NF;
+            }
+            else
+            {
+                result[i] = value.intValue();
+            }
+        }
+        result[seq.length] = EOS;
+        return result;
+    }
+
+}
diff --git a/src/org/apache/commons/jrcs/diff/myers/DiffNode.java b/src/org/apache/commons/jrcs/diff/myers/DiffNode.java
new file mode 100644
index 0000000..a04f1eb
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/myers/DiffNode.java
@@ -0,0 +1,57 @@
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ * <p>Title: </p>
+ * <p>Description: </p>
+ * <p>Copyright: Copyright (c) 2002</p>
+ * <p>Company: </p>
+ * @author not attributable
+ * @version 1.0
+ */
+
+/**
+ * A diffnode in a diffpath.
+ * <p>
+ * A DiffNode and its previous node mark a delta between
+ * two input sequences, that is, two differing subsequences
+ * between (possibly zero length) matching sequences.
+ *
+ * {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression
+ * of diffpaths, as each snake is represented by a single {@link Snake Snake}
+ * node and each contiguous series of insertions and deletions is represented
+ * by a single {@link DiffNode DiffNodes}.
+ *
+ * @version $Revision: 1.1 $ $Date: 2003-05-10 21:56:10 +0300 (Sat, 10 May 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ *
+ */
+public final class DiffNode
+    extends PathNode
+{
+    /**
+     * Constructs a DiffNode.
+     * <p>
+     * DiffNodes are compressed. That means that
+     * the path pointed to by the <code>prev</code> parameter
+     * will be followed using {@link PathNode#previousSnake}
+     * until a non-diff node is found.
+     *
+     * @param the position in the original sequence
+     * @param the position in the revised sequence
+     * @param prev the previous node in the path.
+     */
+    public DiffNode(int i, int j, PathNode prev)
+    {
+        super(i, j, (prev == null ? null : prev.previousSnake()) );
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return false, always
+     */
+    public boolean isSnake()
+    {
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/myers/MyersDiff.java b/src/org/apache/commons/jrcs/diff/myers/MyersDiff.java
new file mode 100644
index 0000000..0f4d8fd
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/myers/MyersDiff.java
@@ -0,0 +1,222 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+import org.apache.commons.jrcs.diff.*;
+
+/**
+ * A clean-room implementation of
+ * <a href="http://www.cs.arizona.edu/people/gene/">
+ * Eugene Myers</a> differencing algorithm.
+ * <p>
+ * See the paper at
+ * <a href="http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps">
+ * http://www.cs.arizona.edu/people/gene/PAPERS/diff.ps</a>
+ *
+ * @version $Revision: 1.7 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ * @see Delta
+ * @see Revision
+ * @see Diff
+ */
+public class MyersDiff
+    implements DiffAlgorithm
+{
+    /**
+     * Constructs an instance of the Myers differencing algorithm.
+     */
+    public MyersDiff()
+    {
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public Revision diff(Object[] orig, Object[] rev)
+        throws DifferentiationFailedException
+    {
+        PathNode path = buildPath(orig, rev);
+        return buildRevision(path, orig, rev);
+    }
+
+    /**
+     * Computes the minimum diffpath that expresses de differences
+     * between the original and revised sequences, according
+     * to Gene Myers differencing algorithm.
+     *
+     * @param orig The original sequence.
+     * @param rev The revised sequence.
+     * @return A minimum {@link PathNode Path} accross the differences graph.
+     * @throws DifferentiationFailedException if a diff path could not be found.
+     */
+    public static PathNode buildPath(Object[] orig, Object[] rev)
+        throws DifferentiationFailedException
+    {
+        if (orig == null)
+            throw new IllegalArgumentException("original sequence is null");
+        if (rev == null)
+            throw new IllegalArgumentException("revised sequence is null");
+
+        // these are local constants
+        final int N = orig.length;
+        final int M = rev.length;
+
+        final int MAX = N + M + 1;
+        final int size = 1 + 2 * MAX;
+        final int middle = (size + 1) / 2;
+        final PathNode diagonal[] = new PathNode[size];
+
+        PathNode path = null;
+
+        diagonal[middle + 1] = new Snake(0, -1, null);
+        for (int d = 0; d < MAX; d++)
+        {
+            for (int k = -d; k <= d; k += 2)
+            {
+                final int kmiddle = middle + k;
+                final int kplus = kmiddle + 1;
+                final int kminus = kmiddle - 1;
+                PathNode prev = null;
+
+                int i;
+                if ( (k == -d) ||
+                    (k != d && diagonal[kminus].i < diagonal[kplus].i))
+                {
+                    i = diagonal[kplus].i;
+                    prev = diagonal[kplus];
+                }
+                else
+                {
+                    i = diagonal[kminus].i + 1;
+                    prev = diagonal[kminus];
+                }
+
+                diagonal[kminus] = null; // no longer used
+
+                int j = i - k;
+
+                PathNode node = new DiffNode(i, j, prev);
+
+                // orig and rev are zero-based
+                // but the algorithm is one-based
+                // that's why there's no +1 when indexing the sequences
+                while (i < N && j < M && orig[i].equals(rev[j]))
+                {
+                    i++;
+                    j++;
+                }
+                if (i > node.i)
+                    node = new Snake(i, j, node);
+
+                diagonal[kmiddle] = node;
+
+                if (i >= N && j >= M)
+                {
+                    return diagonal[kmiddle];
+                }
+            }
+            diagonal[middle+d-1] = null;
+
+        }
+        // According to Myers, this cannot happen
+        throw new DifferentiationFailedException("could not find a diff path");
+    }
+
+    /**
+     * Constructs a {@link Revision} from a difference path.
+     *
+     * @param path The path.
+     * @param orig The original sequence.
+     * @param rev The revised sequence.
+     * @return A {@link Revision} script corresponding to the path.
+     * @throws DifferentiationFailedException if a {@link Revision} could
+     *         not be built from the given path.
+     */
+    public static Revision buildRevision(PathNode path, Object[] orig, Object[] rev)
+    {
+        if (path == null)
+            throw new IllegalArgumentException("path is null");
+        if (orig == null)
+            throw new IllegalArgumentException("original sequence is null");
+        if (rev == null)
+            throw new IllegalArgumentException("revised sequence is null");
+
+        Revision revision = new Revision();
+        if (path.isSnake())
+            path = path.prev;
+        while (path != null && path.prev != null && path.prev.j >= 0)
+        {
+            if(path.isSnake()) 
+               throw new IllegalStateException("bad diffpath: found snake when looking for diff");
+            int i = path.i;
+            int j = path.j;
+
+            path = path.prev;
+            int ianchor = path.i;
+            int janchor = path.j;
+
+            Delta delta = Delta.newDelta(new Chunk(orig, ianchor, i - ianchor),
+                                         new Chunk(rev, janchor, j - janchor));
+            revision.insertDelta(delta);
+            if (path.isSnake())
+                path = path.prev;
+        }
+        return revision;
+    }
+
+}
diff --git a/src/org/apache/commons/jrcs/diff/myers/PathNode.java b/src/org/apache/commons/jrcs/diff/myers/PathNode.java
new file mode 100644
index 0000000..4a99e86
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/myers/PathNode.java
@@ -0,0 +1,146 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ * A node in a diffpath.
+ *
+ * @version $Revision: 1.7 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ *
+ * @see DiffNode
+ * @see Snake
+ *
+ */
+public abstract class PathNode
+{
+    /** Position in the original sequence. */
+    public final int i;
+    /** Position in the revised sequence. */
+    public final int j;
+    /** The previous node in the path. */
+    public final PathNode prev;
+
+    /**
+     * Concatenates a new path node with an existing diffpath.
+     * @param i The position in the original sequence for the new node.
+     * @param j The position in the revised sequence for the new node.
+     * @param prev The previous node in the path.
+     */
+    public PathNode(int i, int j, PathNode prev)
+    {
+        this.i = i;
+        this.j = j;
+        this.prev = prev;
+    }
+
+    /**
+     * Is this node a {@link Snake Snake node}?
+     * @return true if this is a {@link Snake Snake node}
+     */
+    public abstract boolean isSnake();
+
+    /**
+     * Is this a bootstrap node?
+     * <p>
+     * In bottstrap nodes one of the two corrdinates is
+     * less than zero.
+     * @return tru if this is a bootstrap node.
+     */
+    public boolean isBootstrap()
+    {
+        return i < 0 || j < 0;
+    }
+
+    /**
+     * Skips sequences of {@link DiffNode DiffNodes} until a
+     * {@link Snake} or bootstrap node is found, or the end
+     * of the path is reached.
+     * @return The next first {@link Snake} or bootstrap node in the path, or
+     * <code>null</code>
+     * if none found.
+     */
+    public final PathNode previousSnake()
+    {
+        if (isBootstrap())
+            return null;
+        if (!isSnake() && prev != null)
+            return prev.previousSnake();
+        return this;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer("[");
+        PathNode node = this;
+        while (node != null)
+        {
+            buf.append("(");
+            buf.append(Integer.toString(node.i));
+            buf.append(",");
+            buf.append(Integer.toString(node.j));
+            buf.append(")");
+            node = node.prev;
+        }
+        buf.append("]");
+        return buf.toString();
+    }
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/myers/Snake.java b/src/org/apache/commons/jrcs/diff/myers/Snake.java
new file mode 100644
index 0000000..1fe3e5d
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/myers/Snake.java
@@ -0,0 +1,97 @@
+/*
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2003 The Apache Software Foundation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowledgement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgement may appear in the software itself,
+ *    if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.commons.jrcs.diff.myers;
+
+/**
+ *  Represents a snake in a diffpath.
+ * <p>
+ *
+ * {@link DiffNode DiffNodes} and {@link Snake Snakes} allow for compression
+ * of diffpaths, as each snake is represented by a single {@link Snake Snake}
+ * node and each contiguous series of insertions and deletions is represented
+ * by a single {@link DiffNode DiffNodes}.
+ *
+ * @version $Revision: 1.2 $ $Date: 2003-10-13 11:00:44 +0300 (Mon, 13 Oct 2003) $
+ * @author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ *
+ */
+public final class Snake
+    extends PathNode
+{
+    /**
+     * Constructs a snake node.
+     *
+     * @param the position in the original sequence
+     * @param the position in the revised sequence
+     * @param prev the previous node in the path.
+     */
+    public Snake(int i, int j, PathNode prev)
+    {
+        super(i, j, prev);
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return true always
+     */
+    public boolean isSnake()
+    {
+        return true;
+    }
+
+}
\ No newline at end of file
diff --git a/src/org/apache/commons/jrcs/diff/myers/package.html b/src/org/apache/commons/jrcs/diff/myers/package.html
new file mode 100644
index 0000000..2b1b5ac
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/myers/package.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<!--
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache Maven" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache Maven", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+ -->
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
+    <title></title>
+  </head>
+  <body>
+    <p>
+      The {@link org.apache.maven.jrcs.diff.myers diff.myers} package
+      implements  <a href=
+      "http://www.cs.arizona.edu/people/gene/">Gene Myers</a>'
+      differencing algorithm.
+    </p>
+    <p>
+      Myer's algorithm produces optimum results (minimum diffs), but
+      consumes considerably more memory than SimpleDiff, so its not
+      suitable for very large files.
+      </p>
+ at author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ at version $Id: package.html 146029 2003-05-10 18:56:10Z juanco $
+ at see Diff 
+ at see org.apache.maven.jrcs.rcs.Archive
+  </body>
+</html>
diff --git a/src/org/apache/commons/jrcs/diff/package.html b/src/org/apache/commons/jrcs/diff/package.html
new file mode 100644
index 0000000..5534a90
--- /dev/null
+++ b/src/org/apache/commons/jrcs/diff/package.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<!--
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2002 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" and
+ *    "Apache Maven" must not be used to endorse or promote products
+ *    derived from this software without prior written permission. For
+ *    written permission, please contact apache at apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    "Apache Maven", nor may "Apache" appear in their name, without
+ *    prior written permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ */
+ -->
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Cygwin (vers 1st February 2003), see www.w3.org">
+    <title></title>
+  </head>
+  <body>
+    <p>
+      The {@link org.apache.maven.jrcs.diff diff} package implements
+      the differencing engine that JRCS uses. The engine has the power
+      of Unix diff, is simple to understand, and can be used
+      independently of the archive handling functionality. The entry
+      point to the differencing engine is class {@link
+      org.apache.maven.jrcs.diff.Diff Diff}.
+    </p>
+    <p>
+      Text is represented as <code>Object[]</code> because the diff
+      engine is capable of handling more than plain ascci. In fact,
+      arrays of any type that implements {@link
+      java.lang.Object#hashCode hashCode()} and {@link
+      java.lang.Object#equals equals()} correctly can be subject to
+      differencing using this library.
+    </p>
+    <p>
+      Two implementations of the differencing algorithm are provided.
+    </p>
+    <ul>
+      <li>
+        {@link SimpleDiff Simple Diff} is a verys imple algorithm that
+        is fast and works well with very large input sequences, but
+        that frequently produces result that are subotimal (at times
+        four or more times larger than GNU diff).
+      </li>
+      <li>
+        {@link org.apache.commons.jrcs.diff.myers.MyersDiff MyersDiff}
+        is an implementation of <a href=
+        "http://www.cs.arizona.edu/people/gene/">Gene Myers</a>
+        differencing algorithm. Myer's algorithm produces optimum
+        results (minimum diffs), but consumes considerably more memory
+        than SimpleDiff, so its not suitable for very large files.
+      </li>
+    </ul>
+<pre>
+ at author <a href="mailto:juanco at suigeneris.org">Juanco Anez</a>
+ at version $Id: package.html 146029 2003-05-10 18:56:10Z juanco $
+ at see Diff 
+ at see org.apache.maven.jrcs.rcs.Archive
+</pre>
+  </body>
+</html>
diff --git a/src/org/freshcookies/security/cert/CertificateDN.java b/src/org/freshcookies/security/cert/CertificateDN.java
new file mode 100644
index 0000000..0c176db
--- /dev/null
+++ b/src/org/freshcookies/security/cert/CertificateDN.java
@@ -0,0 +1,174 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.cert;
+
+import java.security.Principal;
+import java.security.cert.X509Certificate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Lightweight wrapper object for an X.509 certificate distinguished name.
+ * 
+ * @author Andrew R. Jaquith
+ * @version $Revision: 1.1 $ $Date: 2006/04/19 23:34:44 $
+ */
+public final class CertificateDN implements Principal {
+
+  private String commonName = null;
+
+  private String country = null;
+
+  private String domainComponent = null;
+
+  private String email = null;
+
+  private String locality = null;
+
+  private String name;
+
+  private String organization = null;
+
+  private String organizationalUnit = null;
+
+  private String state = null;
+
+  /**
+   * Constructs a new CertificateDN by parsing a supplied Principal from a
+   * certificate, such as {@link X509Certificate#getSubjectDN()} or
+   * {@link X509Certificate#getIssuerDN()}.
+   * 
+   * @param dn a Principal representing a certificate distinguished name
+   * 
+   */
+  public CertificateDN(Principal dn) {
+    if (dn == null) {
+      throw new IllegalArgumentException("Disinguished name cannot be null.");
+    }
+    this.name = dn.getName();
+
+    Pattern p = Pattern.compile("(CN|E|OU|O|L|ST|C|DC)=(\"{0,1})(.+?)(\\2),");
+    Matcher m = p.matcher(dn.getName() + ",");
+    while (m.find()) {
+      String key = m.group(1);
+      String value = m.group(3);
+      if ("CN".equals(key)) {
+        commonName = value;
+      }
+      else if ("E".equals(key)) {
+        email = value;
+      }
+      else if ("OU".equals(key)) {
+        organizationalUnit = value;
+      }
+      else if ("O".equals(key)) {
+        organization = value;
+      }
+      else if ("L".equals(key)) {
+        locality = value;
+      }
+      else if ("ST".equals(key)) {
+        state = value;
+      }
+      else if ("C".equals(key)) {
+        country = value;
+      }
+      else if ("DC".equals(key)) {
+        domainComponent = value;
+      }
+    }
+  }
+
+  /**
+   * Returns the common name
+   * 
+   * @return the common name
+   */
+  public final String getCommonName() {
+    return commonName;
+  }
+
+  /**
+   * Returns the country.
+   * 
+   * @return the country
+   */
+  public final String getCountry() {
+    return country;
+  }
+
+  /**
+   * Returns the domain component.
+   * 
+   * @return the domain component
+   */
+  public final String getDomainComponent() {
+    return domainComponent;
+  }
+
+  /**
+   * Returns the email.
+   * 
+   * @return the email
+   */
+  public final String getEmail() {
+    return email;
+  }
+
+  /**
+   * Returns the locality.
+   * 
+   * @return the locality
+   */
+  public final String getLocality() {
+    return locality;
+  }
+
+  /**
+   * Returns the distinguished name.
+   * 
+   * @return the distinguished name.
+   */
+  public final String getName() {
+    return name;
+  }
+
+  /**
+   * Returns the organization.
+   * 
+   * @return the organization
+   */
+  public final String getOrganization() {
+    return organization;
+  }
+
+  /**
+   * Returns the organizational unit.
+   * 
+   * @return the organizational unit
+   */
+  public final String getOrganizationalUnit() {
+    return organizationalUnit;
+  }
+
+  /**
+   * Returns the state.
+   * 
+   * @return the state
+   */
+  public final String getState() {
+    return state;
+  }
+
+}
diff --git a/src/org/freshcookies/security/cert/JarHelper.java b/src/org/freshcookies/security/cert/JarHelper.java
new file mode 100644
index 0000000..99acf45
--- /dev/null
+++ b/src/org/freshcookies/security/cert/JarHelper.java
@@ -0,0 +1,249 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.cert;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * <p>Extracts certificates used to sign a specified 
+ * JAR file and optionally save them to disk. If the SecurityManager is running, the 
+ * ProtectionDomain of this class must grant read access to any jar files
+ * passed to {@link #extractCACertificates(JarFile)} or
+ * {@link #extractSigningCertificates(JarFile)}. For example, to process
+ * the jar file <code>/etc/myclasses.jar</code>, the security
+ * policy file should grant the following permission to the
+ * <code>freshcookies-securty-<em>version</em>.jar</code> CodeSource and
+ * all preceding callers:</p>
+ * <blockquote><code>permission java.io.FilePermision "/etc/myclasses.jar", "read"</code></blockquote>
+ * <p>In addition, if the stand-alone {@link #main(String[])} method is used to automatically
+ * extract discovered certificates or add them to the system-wide trust store, this 
+ * CodeSource and all preceding callsers require these additional privileges:</p>
+ * <ul>
+ *   <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "read,write"</code></li>
+ *   <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+ *   <li><code>java.util.PropertyPermission "javax.net.ssl.trustStore", "read"</code></li>
+ *   <li><code>java.util.PropertyPermission "java.home" "read"</code></li>
+ * </ul>
+ * <p>None of the methods in this class perform their actions inside 
+ * <code>doPrivileged</code> blocks, so all {@link SecurityException} errors
+ * are propagated to callers.</code></p>
+ * @author Andrew R. Jaquith
+ * @version $Revision: 1.4 $ $Date: 2007/02/24 17:27:28 $
+ */
+public class JarHelper {
+
+  private Map caCache = new HashMap();
+
+  private Map certCache = new HashMap();
+
+  private Set jars = new HashSet();
+  
+  /**
+   * Constructs a new instance of JarHelper.
+   */
+  public JarHelper() {
+	  super();
+  }
+
+  /**
+   * Convenience main method that extracts the signing certificates from a jar file
+   * and optionally saves them to disk and the system trust store.
+   * @param args the absolute path to the jar file, or <code>--help</code> to print
+   * a short help message.
+   * @throws SecurityException when the SecurityManager is running, and the current 
+   * policy does not grant this ProtectionDomain and preceding callers all of the following
+   * permissions:
+   * <ul>
+   *   <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "read,write"</code></li>
+   *   <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+   *   <li><code>java.util.PropertyPermission "javax.net.ssl.trustStore", "read"</code></li>
+   *   <li><code>java.util.PropertyPermission "java.home" "read"</code></li>
+   * </ul>
+   */
+  public static void main(String[] args) {
+    if (args.length == 0) {
+      System.err.println("FATAL: you must supply a jar file (e.g., foo.jar)");
+      System.exit(1);
+    }
+
+    // Display help if the user asked for it
+    if (args[0].equals("--help") | args[0].equals("-h")) {
+      System.out.println("Usage: JarHelper jarfile");
+      System.exit(0);
+    }
+
+    // Set the jar file
+    String file = args[0];
+
+    Trustee trustee = new Trustee();
+    JarHelper helper = new JarHelper();
+
+    // Open the jar and get its signing certificates
+    System.out.print("Extracting signing certificates from " + file + "... ");
+    Set cas = new HashSet();
+    Set signers = new HashSet();
+    try {
+      JarFile jar = new JarFile(new File(file), true);
+      cas = helper.extractCACertificates(jar);
+      signers = helper.extractSigningCertificates(jar);
+    }
+    catch (IOException e) {
+      System.err.println("Couldn't get jar certificates: "
+          + e.getLocalizedMessage());
+    }
+
+    // Offer to add untrusted CA certificates to trust store
+    System.out.println("Found " + cas.size() + " CA certificates.");
+    boolean certsAdded = false;
+    int i = 0;
+    for (Iterator it = cas.iterator(); it.hasNext();) {
+      X509Certificate cert = (X509Certificate)it.next();
+      System.out.println("CA certificate [" + i + "]:");
+      System.out.println(Trustee.getCertificateInfo(cert));
+      try {
+        certsAdded = certsAdded | trustee.trustCACertificate(cert);
+      }
+      catch (Exception e) {
+        System.err.println("Could not add certificate to trust store: "
+            + e.getLocalizedMessage());
+      }
+      i++;
+    }
+
+    // Tell the user about the signing certificates we found
+    System.out.println("Found " + signers.size() + " signing certificates.");
+    i = 0;
+    for (Iterator it = signers.iterator(); it.hasNext();) {
+      X509Certificate cert = (X509Certificate)it.next();
+      System.out.println(Trustee.getCertificateInfo(cert));
+    }
+
+    // Now, save the CA certs and signing certs to disk
+    try {
+      for (Iterator it = cas.iterator(); it.hasNext();) {
+        X509Certificate cert = (X509Certificate)it.next();
+        trustee.saveCertificate(cert);
+      }
+      for (Iterator it = signers.iterator(); it.hasNext();) {
+        X509Certificate cert = (X509Certificate)it.next();
+        trustee.saveCertificate(cert);
+      }
+    }
+    catch (Exception e) {
+      System.err.println("Could not save certificate: "
+          + e.getLocalizedMessage());
+    }
+
+    // Commit the trust store changes
+    System.out.print("Committing changes to trust store... ");
+    if (trustee.commit()) {
+      System.err.println("done.");
+    }
+    else {
+      System.err.println("trust store not saved.");
+    }
+
+  }
+
+  /**
+   * Extracts the CA certificates from a Jar file.
+   * 
+   * @param jar the jar file
+   * @return an array of CA {@link java.security.cert.X509Certificate} objects
+   * @throws IOException if the jar cannot be read
+   * @throws SecurityException when the SecurityManager is running,
+   * and it denies read access to the jar file
+   */
+  public Set extractCACertificates(JarFile jar)
+      throws IOException {
+    if (!jars.contains(jar)) {
+      extractJarCerts(jar);
+      jars.add(jar);
+    }
+    return (Set)caCache.get(jar);
+  }
+
+  /**
+   * Extracts the signing certificates from a Jar file.
+   * 
+   * @param jar the jar file
+   * @return an array of {@link java.security.cert.X509Certificate} objects used to sign various files
+   * @throws IOException if the jar cannot be read
+   * @throws SecurityException when the SecurityManager is running,
+   * and it denies read access to the jar file
+   */
+  public Set extractSigningCertificates(JarFile jar)
+      throws IOException {
+    if (!jars.contains(jar)) {
+      extractJarCerts(jar);
+      jars.add(jar);
+    }
+    return (Set)certCache.get(jar);
+  }
+
+  /**
+   * Extracts signing certificates from a jar file.
+   * @param jar
+   * @throws IOException if the jar cannot be read
+   * @throws SecurityException when the SecurityManager (if running) denies access to the file
+   */
+  private void extractJarCerts(JarFile jar) throws IOException {
+    Set cas = new HashSet();
+    Set certs = new HashSet();
+    Enumeration entries = jar.entries();
+    while (entries.hasMoreElements()) {
+      JarEntry entry = (JarEntry) entries.nextElement();
+      InputStream is = jar.getInputStream(entry);
+      byte[] buf = new byte[1024];
+      while (is.read(buf) > 0) {
+      }
+      is.close();
+      Certificate[] signingCerts = entry.getCertificates();
+      if (signingCerts != null) {
+        for (int i = 0; i < signingCerts.length; i++) {
+          Certificate cert = signingCerts[i];
+          if (cert instanceof X509Certificate) {
+            X509Certificate x509cert = (X509Certificate) cert;
+            if (i == 0 && !certs.contains(x509cert)) {
+              certs.add(x509cert);
+            }
+            else if (i > 0 && !cas.contains(x509cert)) {
+              cas.add(x509cert);
+            }
+          }
+        }
+        
+        // If the chain had only one cert, it's self-signed
+        if (signingCerts.length == 1) {
+          if (signingCerts[0] instanceof X509Certificate) {
+            cas.add(signingCerts[0]);
+          }
+        }
+      }
+    }
+    caCache.put(jar, cas);
+    certCache.put(jar, certs);
+  }}
diff --git a/src/org/freshcookies/security/cert/SSLHelper.java b/src/org/freshcookies/security/cert/SSLHelper.java
new file mode 100644
index 0000000..eebd82c
--- /dev/null
+++ b/src/org/freshcookies/security/cert/SSLHelper.java
@@ -0,0 +1,216 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.cert;
+
+import java.io.IOException;
+import java.security.KeyStoreException;
+import java.security.SecureRandom;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Extracts SSL certificates from a specified webserver and optionally adds them
+ * to the JSSE truststore.
+ * 
+ * @author Andrew R. Jaquith
+ * @version $Revision: 1.3 $ $Date: 2007/02/24 17:27:28 $
+ */
+public class SSLHelper {
+
+  /**
+   * Default SSL port.
+   */
+  protected static final int SSL_PORT = 443;
+
+  /**
+   * Helper method that connects to a specified host using SSL and extracts the
+   * server's peer certificates. To do this, a new <code>SSLContext</code> is
+   * created using a "null" trust manager that accepts all peer SSL certificates
+   * as trusted. The null trust manager is provided by the method
+   * <code>nullTrustManager</code>. Note that in the array of Certificates
+   * returned by this method, the first certficate is the server's own
+   * certificate; the ones that follow are the certificate authorities in the
+   * chain.
+   * 
+   * @param hostname
+   * @return the remote host's chain of SSL certificates
+   */
+  public static Certificate[] extractSSLCertificates(String hostname, int port) {
+    Certificate certs[] = new Certificate[] {};
+    TrustManager trustManager = nullTrustManager();
+    SSLSocket socket = createSSLSocket(new TrustManager[] {
+      trustManager
+    }, hostname, port);
+    if (socket != null) {
+      try {
+        certs = socket.getSession().getPeerCertificates();
+        socket.close();
+      }
+      catch (SSLPeerUnverifiedException e) {
+        System.out.println("Could not verify peer: " + e.getMessage());
+      }
+      catch (IOException e) {
+        System.out.println("Could not close socket: " + e.getMessage());
+      }
+    }
+    else {
+      System.err.println("could not create SSL socket.");
+    }
+    return certs;
+  }
+
+  public static void main(String[] args) {
+    if (args.length == 0) {
+      System.err
+          .println("FATAL: you must supply a host name (e.g., internal.atstake.com)");
+      System.exit(1);
+    }
+
+    // Display help if the user asked for it
+    if (args[0].equals("--help") | args[0].equals("-h")) {
+      System.out.println("Usage: SSLHelper hostname [port]");
+      System.exit(0);
+    }
+
+    // Set the host name and port (defaults to SSL_PORT)
+    String host = args[0];
+    int port = SSL_PORT;
+    if (args.length > 1) {
+      port = Integer.parseInt(args[1]);
+    }
+
+    // Connect to the host and get its SSL certificates
+    System.out.print("Extracting SSL certificates from " + host + ":" + port
+        + "... ");
+    Certificate[] certs = extractSSLCertificates(host, port);
+    if (certs.length == 0) {
+      System.err
+          .println("ERROR: No certificates found. Is there an SSL server running on this host?\n");
+      System.exit(1);
+    }
+    System.out.println(certs.length + " certificate"
+        + (certs.length == 1 ? "" : "s") + " found.");
+
+    // Loop through each certificate in the chain
+    boolean certsAdded = false;
+
+    Trustee trustee = new Trustee();
+    for (int i = 0; i < certs.length; i++) {
+      if (certs[i] instanceof X509Certificate) {
+
+        // Write each cert to disk as a DER-encoded file
+        X509Certificate cert = (X509Certificate) certs[i];
+        System.out.println("Certificate[" + i + "]:");
+        System.out.println(Trustee.getCertificateInfo(cert));
+        try {
+          trustee.saveCertificate(cert);
+        }
+        catch (Exception e) {
+          System.err.println("ERROR: could not save certificate. "
+              + e.getMessage());
+        }
+
+        // Test each CA certificate to see if it is trusted; offer to
+        // add it if not
+        if (i == 0) {
+          System.out.println("This is the server certificate.");
+        }
+        else {
+          try {
+            certsAdded = certsAdded | trustee.trustCACertificate(cert);
+          }
+          catch (KeyStoreException e) {
+            System.out.println(e.getLocalizedMessage());
+          }
+        }
+        System.out.println("");
+      }
+    }
+
+    if (certs.length == 1) {
+      System.err
+          .println("WARNING: certificate chain did not include issuing CA certificate. How rude!\n");
+    }
+
+    // If changes were made to the trust store, write it to disk
+    if (certsAdded) {
+      trustee.commit();
+    }
+  }
+
+  /**
+   * Constructs a new SSLHelper.
+   */
+  public SSLHelper() {
+    super();
+  }
+
+  /**
+   * Creates a new SSL socket to a specificed host using the supplied
+   * <code>TrustManager</code>. If a connection cannot be made, the method
+   * returns null.
+   * 
+   * @param trustManager
+   * @param hostname
+   * @return
+   */
+  private static SSLSocket createSSLSocket(TrustManager[] trustManager,
+      String hostname, int port) {
+    SSLSocket socket = null;
+    try {
+      SSLContext sslContext = SSLContext.getInstance("SSL");
+      sslContext.init(null, trustManager, new SecureRandom());
+      HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
+          .getSocketFactory());
+      SocketFactory factory = sslContext.getSocketFactory();
+      socket = (SSLSocket) factory.createSocket(hostname, port);
+      socket.startHandshake();
+    }
+    catch (Exception e) {
+
+    }
+    return socket;
+  }
+
+  /**
+   * Creates and returns an implementation of a <code>TrustManager</code> that
+   * trusts all SSL certificates. This method is used in the initial handshake
+   * to the target SSL server, so that its certificates can be extracted.
+   * 
+   * @return
+   */
+  private static X509TrustManager nullTrustManager() {
+    return new X509TrustManager() {
+
+      public void checkClientTrusted(X509Certificate[] certs, String authType) {
+      }
+
+      public void checkServerTrusted(X509Certificate[] certs, String authType) {
+      }
+
+      public X509Certificate[] getAcceptedIssuers() {
+        return null;
+      }
+    };
+  }
+
+}
diff --git a/src/org/freshcookies/security/cert/Trustee.java b/src/org/freshcookies/security/cert/Trustee.java
new file mode 100644
index 0000000..80bd504
--- /dev/null
+++ b/src/org/freshcookies/security/cert/Trustee.java
@@ -0,0 +1,457 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.cert;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.text.DateFormat;
+
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * <p>Utility class that performs common certificate trust operations, such as
+ * writing to disk, updating the trust database and printing verbose certficate
+ * info.</p>
+ * <p>This class requires privileges to run with a SecurityManager.
+ * At a mimumum, this ProtectionDomain and preceding callers must be granted the following
+ * permissions:</p>
+ * <ul>
+ *   <li><code>java.util.PropertyPermission "javax.net.ssl.trustStore", "read"</code></li>
+ *   <li><code>java.util.PropertyPermission "java.home", "read"</code></li>
+ *    <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "read"</code></li>
+ * </ul>
+ * <p>In addition, if the method {@link #saveCertificate(X509Certificate)}
+ * is called, this ProtectionDomain and all preceding callers must also be 
+ * granted these additional permissions:</p>
+ * <ul>
+ *   <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+ *   <li><code>java.io.FilePermission "${user.dir}/*.cer", "write"</code></li>
+ * </ul>
+ * <p>The {@link #commit()} method requires that this ProtectionDomain and
+ * all preceding callers be granted these additional permisions:</p>
+ * <ul>
+ *   <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+ *   <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "write"</code></li>
+ * </ul>
+ * <p>None of the methods in this class perform their actions inside 
+ * <code>doPrivileged</code> blocks, so all {@link SecurityException} errors
+ * are propagated to callers.</code></p>
+ * @author Andrew R. Jaquith
+ * @version $Revision: 1.3 $ $Date: 2007/02/24 17:27:28 $
+ */
+public class Trustee {
+
+  private boolean certsAdded;
+
+  private final X509TrustManager sslTrustManager;
+
+  private String trustedCAPath;
+
+  private final KeyStore trustedCAStore;
+
+  /**
+   * Constructs a new Trustee instance, and initializes the system certificate
+   * authority (CA) keystore and SSL trust manager.
+   * @throws SecurityException when the SecurityManager is running, and the current 
+   * policy does not grant this ProtectionDomain and preceding callers all of the following
+   * permissions:
+   * <ul><li><code>java.util.PropertyPermission "javax.net.ssl.trustStore", "read"</code></li>
+   * <li><code>java.util.PropertyPermission "java.home" "read"</code></li>
+   * <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "read"</code></li></ul>
+   */
+  public Trustee() {
+    super();
+    trustedCAStore = initSystemCAStore();
+    sslTrustManager = initSSLTrustManager();
+    certsAdded = false;
+  }
+
+  /**
+   * Calculates an alias for a certificate by trying the common name,
+   * organizational unit, DC and serial number in succession.
+   * 
+   * @param cert the certificate
+   * @return the alias
+   */
+  public static String getAlias(X509Certificate cert) {
+    CertificateDN dn = new CertificateDN(cert.getSubjectDN());
+    if (dn.getCommonName() != null) {
+      return dn.getCommonName();
+    }
+    if (dn.getOrganizationalUnit() != null) {
+      return dn.getOrganizationalUnit() + "-"
+          + cert.getSerialNumber().toString();
+    }
+    if (dn.getDomainComponent() != null) {
+      return dn.getDomainComponent() + "-" + cert.getSerialNumber().toString();
+    }
+    return cert.getSerialNumber().toString();
+  }
+
+  /**
+   * Returns a string containing verbose certificate information. The format is
+   * identical to that produced by the J2SE <code>keytool</code> program.
+   * 
+   * @param cert the certificate to examine
+   */
+  public static String getCertificateInfo(X509Certificate cert) {
+    String date = DateFormat.getDateInstance(DateFormat.MEDIUM).format(
+        cert.getNotBefore());
+    String info = "Creation date: " + date + "\n";
+    info += "Owner:\n";
+    CertificateDN s = new CertificateDN(cert.getSubjectDN());
+    info += (s.getCommonName() != null) ? "         CN=" + s.getCommonName()
+        + "\n" : "";
+    info += (s.getOrganization() != null) ? "         O=" + s.getOrganization()
+        + "\n" : "";
+    info += (s.getOrganizationalUnit() != null) ? "         OU="
+        + s.getOrganizationalUnit() + "\n" : "";
+    info += (s.getDomainComponent() != null) ? "         DC="
+        + s.getDomainComponent() + "\n" : "";
+    info += (s.getLocality() != null) ? "         L=" + s.getLocality() + "\n"
+        : "";
+    info += (s.getState() != null) ? "         S=" + s.getState() + "\n" : "";
+    info += (s.getCountry() != null) ? "         C=" + s.getCountry() + "\n"
+        : "";
+    info += (s.getEmail() != null) ? "         E=" + s.getEmail() + "\n" : "";
+    info += "Issuer:\n";
+    s = new CertificateDN(cert.getIssuerDN());
+    info += (s.getCommonName() != null) ? "         CN=" + s.getCommonName()
+        + "\n" : "";
+    info += (s.getOrganization() != null) ? "         O=" + s.getOrganization()
+        + "\n" : "";
+    info += (s.getOrganizationalUnit() != null) ? "         OU="
+        + s.getOrganizationalUnit() + "\n" : "";
+    info += (s.getDomainComponent() != null) ? "         DC="
+        + s.getDomainComponent() + "\n" : "";
+    info += (s.getLocality() != null) ? "         L=" + s.getLocality() + "\n"
+        : "";
+    info += (s.getState() != null) ? "         S=" + s.getState() + "\n" : "";
+    info += (s.getCountry() != null) ? "         C=" + s.getCountry() + "\n"
+        : "";
+    info += (s.getEmail() != null) ? "         E=" + s.getEmail() + "\n" : "";
+    info += "Serial number: " + cert.getSerialNumber() + "\n";
+    info += "Valid from: " + cert.getNotBefore() + " until: "
+        + cert.getNotAfter() + "\n";
+    info += "Certificate fingerprints:\n";
+    info += "         MD5:  " + getCertFingerPrint("MD5", cert) + "\n";
+    info += "         SHA1: " + getCertFingerPrint("SHA1", cert) + "\n";
+    return info;
+  }
+
+  /**
+   * Appends an ASCII representation of a byte to a supplied StringBuffer.
+   * 
+   * @param byte0 the byte to encode
+   * @param stringbuffer the buffer to append to
+   */
+  private static void byte2hex(byte byte0, StringBuffer stringbuffer) {
+    char ac[] = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
+        'E', 'F'
+    };
+    int i = (byte0 & 0xf0) >> 4;
+    int j = byte0 & 0xf;
+    stringbuffer.append(ac[i]);
+    stringbuffer.append(ac[j]);
+  }
+
+  /**
+   * Calculates the fingerprint for a certificate and returns it as a string.
+   * 
+   * @param s the digest algorithm to use
+   * @param certificate the certificate
+   * @return the fingerprint
+   */
+  private static String getCertFingerPrint(String s, Certificate certificate) {
+    try {
+      byte abyte0[] = certificate.getEncoded();
+      MessageDigest messagedigest = MessageDigest.getInstance(s);
+      byte abyte1[] = messagedigest.digest(abyte0);
+      return toHexString(abyte1);
+    }
+    catch (Exception e) {
+      return "(error)";
+    }
+  }
+
+  /**
+   * Encodes an array of bytes and its ASCII string representation.
+   * 
+   * @param abyte0 the array of bytes to encode
+   * @return the string
+   */
+  private static String toHexString(byte abyte0[]) {
+    StringBuffer stringbuffer = new StringBuffer();
+    int i = abyte0.length;
+    for (int j = 0; j < i; j++) {
+      byte2hex(abyte0[j], stringbuffer);
+      if (j < i - 1)
+        stringbuffer.append(":");
+    }
+
+    return stringbuffer.toString();
+  }
+
+  /**
+   * <p>
+   * Adds a supplied CA certificate to the system certificate trust store as a
+   * "trusted CA certificate". This is equivalent to the following command-line
+   * action:
+   * </p>
+   * <code>keytool -import -trustcacerts -keystore <var>$JAVA_HOME</var>/lib/security/cacerts -file <var>certificate</var></code>
+   * <p>
+   * Note: a useful argument for debugging is <code>-Djavax.net.debug=all</code>.
+   * </p>
+   * 
+   * @param cert the certificate to add to the trust store
+   * @return <code>true</code> if successfully added; <code>false</code> if
+   *         not
+   * @throws KeyStoreException if the CA alias ould not be added to the trust store
+   */
+  public boolean trustCACertificate(X509Certificate cert)
+      throws KeyStoreException {
+    if (!isTrustedCA(cert)) {
+      System.out.println("This is a CA certificate. It is NOT trusted.");
+      try {
+        if (yesResponse("Do you want to trust this certificate?")) {
+          String alias = Trustee.getAlias(cert);
+          System.out.println("Adding CA to trust store with alias " + alias);
+          trustedCAStore.setCertificateEntry(alias, cert);
+          System.out.println("..success");
+          certsAdded = true;
+          return true;
+        }
+      }
+      catch (IOException e) {
+        System.out.println("Could not add certificate: "
+            + e.getLocalizedMessage());
+        return false;
+      }
+    }
+    System.out.println("This is a CA certificate. It is already trusted.");
+    return false;
+  }
+
+  /**
+   * Writes the trust store to disk. The caller must have write access to the 
+   * systemwide trust store.
+   * @return <code>true</code> if the commit succeeds; <code>false</code> if
+   *         not
+   * @throws SecurityException when the SecurityManager is running, and the current policy does
+   * not grant this ProtectionDomain and preceding callers all of the following
+   * permissions: <ul>
+   * <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+   * <li><code>java.io.FilePermission "${java.home}/lib/security/cacerts", "write"</code></li></ul>
+   */
+  public boolean commit() {
+    if (!certsAdded) {
+      System.err.println("No need to commit (no certificates added).");
+      return false;
+    }
+    try {
+      File file = new File(trustedCAPath);
+      if (file.canWrite()) {
+        OutputStream out = new FileOutputStream(trustedCAPath);
+        trustedCAStore.store(out, "changeit".toCharArray());
+        out.close();
+        return true;
+      }
+      System.out.println("FATAL: You do not have write privileges "
+          + "to the Java JSSE trust store " + trustedCAPath
+          + "\n\nTry running the application using sudo, or as root.\n");
+    }
+    catch (CertificateException e) {
+      System.out.println("Certificate exception: " + e.getMessage());
+    }
+    catch (NoSuchAlgorithmException e) {
+      System.out.println("No such algorithm: " + e.getMessage());
+    }
+    catch (KeyStoreException e) {
+      System.out.println("Keystore exception: " + e.getMessage());
+    }
+    catch (IOException e) {
+      System.out.println("IO exception: " + e.getMessage());
+    }
+    return false;
+  }
+
+  /**
+   * Saves an X.509 certificate as a binary file in the current directory. The
+   * name of the file is calculated by taking the certificate's common name and
+   * appending the suffix <code>.cer</code>. This suffix is sufficiently
+   * cross-platform that Mac OS X and Windows users alike can simply
+   * double-click on the file to install it using the respective certificate
+   * management tool.
+   * 
+   * @param cert the certificate to save
+   * @throws IOException if the file could not be written
+   * @throws CertificateEncodingException if the certificate could not be properly encoded
+   * @throws SecurityException when the SecurityManager is running, and the current policy does
+   * not grant this ProtectionDomain and preceding callers all of the following
+   * permissions: <ul>
+   * <li><code>java.lang.RuntimePermission "writeFileDescriptor"</code></li>
+   * <li><code>java.io.FilePermission "${user.dir}/*.cer", "write"</code></li></ul>
+   */
+  public void saveCertificate(X509Certificate cert) throws IOException,
+      CertificateEncodingException {
+    String alias = Trustee.getAlias(cert);
+    alias = alias.replaceAll("[,\\.\\\\/]", "");
+    String file = System.getProperty("user.dir") + "/" + alias + ".cer";
+    FileOutputStream out = new FileOutputStream(file);
+    out.write(cert.getEncoded());
+    out.close();
+    System.out.println("Saved certificate as " + file);
+  }
+
+  /**
+   * Initializes and returns the system JSSE trust manager. The algorithm used
+   * is the default returned by the system property
+   * <code>ssl.TrustManagerFactory.algorithm</code>, which in normal
+   * cicrcumstances should be <code>SunX509</code>. The keystore used for
+   * trusted CA certificates is the one previously initialized by
+   * {@link #initSystemCAStore()}.
+   * @return the SSL trust manager, initialized
+   */
+  private X509TrustManager initSSLTrustManager() {
+    TrustManager[] managers = new TrustManager[] {};
+    try {
+      TrustManagerFactory factory = TrustManagerFactory
+          .getInstance(TrustManagerFactory.getDefaultAlgorithm());
+      factory.init(trustedCAStore);
+      managers = factory.getTrustManagers();
+    }
+    catch (KeyStoreException e) {
+      System.out
+          .println("Could not initialize trust manager with system keystore: "
+              + e.getMessage());
+    }
+    catch (NoSuchAlgorithmException e) {
+      System.out.println("No such algorithm: " + e.getMessage());
+    }
+    for (int i = 0; i < managers.length; i++) {
+      if (managers[i] instanceof X509TrustManager) {
+        return (X509TrustManager) managers[i];
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Initializes and returns the KeyStore where JSSE trusted CA certificates are
+   * stored. The method first checks to see if the
+   * <code>javax.net.ssl.trustStore</code> property is set; if it is, the
+   * keystore at that location is loaded. If not, the keystore in the default
+   * location <code><var>JAVA_HOME</var>/lib/security/cacerts</code> is
+   * loaded.
+   * 
+   * @return the JSSE trust store, initialized
+   * @throws SecurityException when the SecurityManager is running, and the current policy does
+   * not grant this ProtectionDomain and preceding callers all of the following
+   * permissions: <code>java.util.PropertyPermission "javax.net.ssl.trustStore"</code>,
+   * <code>java.util.PropertyPermission "java.home"</code>,
+   * <code>java.io.FilePermission "${java.home}/lib/security/cacerts", "read"</code>
+   */
+  private KeyStore initSystemCAStore() {
+
+    // Ask where the JRE thinks the trust store is
+    this.trustedCAPath = System.getProperty("javax.net.ssl.trustStore");
+    if (trustedCAPath == null) {
+      trustedCAPath = System.getProperty("java.home") + "/lib/security/cacerts";
+    }
+
+    // Now, open it
+    KeyStore store = null;
+    try {
+      store = KeyStore.getInstance(KeyStore.getDefaultType());
+
+      InputStream fis = new FileInputStream(trustedCAPath);
+      System.out.println("Locating certificate trust store: " + trustedCAPath);
+      store.load(fis, "changeit".toCharArray());
+      fis.close();
+    }
+    catch (FileNotFoundException e) {
+      System.out.println("Could not open keystore file: " + e.getMessage());
+    }
+    catch (IOException e) {
+      System.out.println("IO exception: " + e.getMessage());
+    }
+    catch (CertificateException e) {
+      System.out.println("Certificate exception: " + e.getMessage());
+    }
+    catch (KeyStoreException e) {
+      System.out.println("Could not get keystore: " + e.getMessage());
+    }
+    catch (NoSuchAlgorithmException e) {
+      System.out.println("No such algorithm: " + e.getMessage());
+    }
+    return store;
+  }
+
+  /**
+   * Determines whether a supplied CA certificate is considered "trusted" by a
+   * TrustManager. To determine whether the certificate is already trusted, the
+   * supplied TrustManager's <code>getAcceptedIssuers</code> method is
+   * consulted.
+   * 
+   * @param cert the X.509 certificate to test
+   * @return <code>true</code> if the certificate is trusted,
+   *         <code>false</code> if not
+   */
+  private boolean isTrustedCA(X509Certificate cert) {
+    Certificate[] trustedCAs = sslTrustManager.getAcceptedIssuers();
+    boolean isCertTrusted = false;
+    for (int j = 0; j < trustedCAs.length; j++) {
+      if (cert.equals(trustedCAs[j])) {
+        isCertTrusted = true;
+        break;
+      }
+    }
+    return isCertTrusted;
+  }
+
+  /**
+   * Obtains a "yes" or "no" response from standard input.
+   * 
+   * @param prompt the prompt
+   * @return <code>true</code> if the response is "yes", <code>false</code>
+   *         otherwise
+   */
+  private synchronized boolean yesResponse(String prompt) throws IOException {
+    String response = " ";
+    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
+    while (!"YES".equals(response) && !"NO".equals(response)) {
+      System.out.print(prompt + " (yes/no): ");
+      response = reader.readLine().toUpperCase().trim();
+    }
+    return ("YES".equals(response));
+  }
+}
diff --git a/src/org/freshcookies/security/cert/package.html b/src/org/freshcookies/security/cert/package.html
new file mode 100644
index 0000000..a7179b0
--- /dev/null
+++ b/src/org/freshcookies/security/cert/package.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Mac OS X (vers 1st August 2004), see www.w3.org">
+    <title>
+    </title>
+  </head>
+  <body>
+    <p>
+      This package contains serveral useful utilities for managing
+      common security operations, such as SSL certificate extraction,
+      JAR certificate extraction, and policy file manipulation.
+    </p>
+
+    <h3>
+      JarHelper
+    </h3>
+
+    <p>
+      SSLHelper is a command-line based utility that examines the SSL
+      certificates and certificate chains for a given host and port. If
+      the SSL certificate chain is untrusted, the utility offers the
+      user the option of placing the certificates in the JSSE
+      certificate store. It also outputs all of the certificates it
+      finds (including the server's) as DER-encoded files in the
+      current directory. These files can then be double-clicked and
+      imported straight into the Windows certificate store, or appended
+      (using Keychain) to the Mac OS X trust anchors! Incredibly handy
+      for troubleshooting certificate trust issues with (for instance)
+      self-signed JNLP applications.
+    </p>
+
+    <h4>
+      Usage
+    </h4>
+
+    <p>
+      On the command line type the following:
+    </p>
+
+    <blockquote>
+      <p>
+        <code>java -cp freshcookies-security-0.3.jar
+        org.freshcookies.security.cert.SSLHelper www.example.com</code>
+      </p>
+    </blockquote>
+
+    <p>
+      SSLHelper will connect to the target website (here,
+      www.example.com) and download its SSL certificates and CA chains
+      (if provided in the handshake). An optional second parameter
+      specifies a port to use (the default is 443).
+    </p>
+
+    <p>
+      In addition to the command-line version, the
+      <code>SSLHelper</code> class itself has a method called
+      <code>extractSSLCertificates(String hostname, int port)</code>
+      that performs the same operation.that returns an array of
+      <code>java.security.cert.Certificate</code>. (It does not offer
+      to add the certificates to the JSSE certificate store if they are
+      untrusted.)
+    </p>
+
+    <h3>
+      JarHelper
+    </h3>
+
+    <p>
+      JarHelper is a command-line utility that extracts certificates
+      used to sign a specified JAR file and, if any are found, saves
+      them to disk. If the certificate chain is untrusted, the utility
+      offers the user the option of placing the certificates in the
+      java certificate trust store.
+    </p>
+
+    <h4>
+      Usage
+    </h4>
+
+    <p>
+      On the command line type the following:
+    </p>
+
+    <blockquote>
+      <p>
+        <code>java -cp freshcookies-security-0.3.jar
+        org.freshcookies.security.cert.JarHelper
+        mysignedcode.jar</code>
+      </p>
+    </blockquote>
+
+    <p>
+      In addition to the command-line version, the
+      <code>JarHelper</code> class itself has two methods called
+      <code>extractCACertificates(JarFile jar)</code> and
+      <code>extractSigningCertificates</code> that returns arrays of
+      <code>java.security.cert.Certificate</code>. (They do not offer
+      to add the certificates to the JSSE certificate store if they are
+      untrusted.)
+    </p>
+
+    <p>
+      @author Andrew R. Jaquith 
+      @version $Revision: 1.1 $ $Date: 2006/05/02 04:36:39 $
+    </p>
+  </body>
+</html>
diff --git a/src/org/freshcookies/security/policy/Canonicalizer.java b/src/org/freshcookies/security/policy/Canonicalizer.java
new file mode 100644
index 0000000..6f819fb
--- /dev/null
+++ b/src/org/freshcookies/security/policy/Canonicalizer.java
@@ -0,0 +1,400 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.cert.Certificate;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Properties;
+
+/**
+ * Utility class that canonicalizes Permissions and file paths, It will initializes a list of property substitutions that can be used when
+ * constructing file paths. This class can optionally dump a list of system properties (and their
+ * file path equivalents) to disk.
+ * @author Andrew Jaquith
+ *
+ */
+public class Canonicalizer {
+
+  /** Static String that means "no codesource." */
+  public static final String NO_CODESOURCE = "n/c";
+  
+  private static final String CODEBASE_FILE_PREFIX = "file:";
+
+  private static final String CODEBASE_URL_PREFIX = "url:";
+
+  /** 
+   * Constructs a new Canonicalizer instance.
+   */
+  public Canonicalizer()
+  {
+    super();
+  }
+  
+  /**
+   * Formats a ProtectionDomain, substituting properties into
+   * the CodeSource or path, as needed.
+   * 
+   * @param pd the protection domain
+   * @param properties a Properties map containg key-value pairs of property names and
+   * associated file paths
+   * @return a revised CodeSource, with system properties substitutions as
+   *         needed, or the same CodeSource if no properties match
+   */
+  public final CodeSource propertize(CodeSource codeSource, Properties properties) {
+    // Bail if codesource location is null
+    if (codeSource == null || codeSource.getLocation() == null) {
+      return codeSource;
+    }
+    
+    for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
+      String path = (String)it.next();
+      String property = (String)properties.get(path);
+      String cs = codeSource.getLocation().toExternalForm();
+      try {
+        // Does the codebase start with file: ?
+        String value = CODEBASE_FILE_PREFIX + path;
+        if (cs.startsWith(value)) {
+          URL url = new URL(CODEBASE_FILE_PREFIX + "${" + property + "}"
+              + cs.substring(value.length()));
+          Certificate[] certs = codeSource.getCertificates();
+          return new CodeSource(url, certs);
+        }
+
+        // Does the codebase start with url: ?
+        value = CODEBASE_URL_PREFIX + path;
+        if (cs.startsWith(value)) {
+          URL url = new URL(CODEBASE_URL_PREFIX + "${" + property + "}"
+              + cs.substring(value.length()));
+          return new CodeSource(url, codeSource.getCertificates());
+        }
+      }
+      catch (MalformedURLException e) {
+        break;
+      }
+    }
+    return codeSource;
+  }
+  
+  /**
+   * Substitutes properties into a given <code>FilePermission</code>'s
+   * URL or path, as needed.
+   * 
+   * @param perm the permission
+   * @param properties a Properties map containg key-value pairs of property names and
+   * associated file paths
+   * @return a String representing the <code>FilePermission</code>'s URL or
+   *         file path, with system properties substitutions as needed
+   */
+  public final Permission propertize(Permission perm, Properties properties) {
+    String target = perm.getName();
+    
+    if (perm instanceof FilePermission) {
+      // See if we can substitute any properties
+      for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
+    	String path = (String)it.next();
+        String property = (String)properties.get(path);
+        String value = path;
+        if (target.startsWith(value)) {
+          String newPath = "${" + property + "}" + target.substring(value.length());
+          perm = new FilePermission(newPath, perm.getActions());
+          break;
+        }
+      }
+    }
+    return perm;
+  }
+
+/**
+   * Formats a CodeSource for use with a policy file. The format is identical to
+   * that used in policy files. If the URL of the codesource ends with a file
+   * separator (/ or \), a "-" will be appended. The formatter will insert
+   * system properties (such as <code>${user.home}</code>) as needed.
+   * 
+   * @param cs the code source
+   * @return the code source, formatted nicely as a string
+   */
+  public static final String format(CodeSource codeSource) {
+    if (codeSource == null || codeSource.getLocation() == null) {
+      return NO_CODESOURCE;
+    }
+    String cs = codeSource.getLocation().toExternalForm();
+    if (cs.endsWith(File.separator)) {
+      cs += "-";
+    }
+    return cs;
+  }
+
+  /**
+   * Formats an array of Principals; the array may be <code>null</code>.
+   * 
+   * @param principals the array of Principals to formatted
+   * @return a single String, with each Principal separated by a single space
+   */
+  public static final String format(Principal[] principals) {
+    return format(principals, false);
+  }
+  
+  /**
+   * Formats an array of CachedPrincipals, optionally with line delimeters suitable
+   * for a policy file. The array may be <code>null</code>.
+   * 
+   * @param principals the array of CachedPrincipals to formatted
+   * @param forPolicy <code>true</code> if the string should be formatted for
+   *          a policy file, with indents and a linebreak after each principal
+   * @return a single String, with each Principal separated by a single space
+   */
+  public static final String format(Principal[] principals, boolean forPolicy) {
+    String out = "-";
+    if (principals != null) {
+      out = "";
+      for (int i = 0; i < principals.length; i++) {
+        if (forPolicy) {
+          out += "  principal " + format(principals[i]);
+          if (i < (principals.length - 1)) {
+            out += ',';
+          }
+          out += "\n";
+        }
+        else {
+          out += format(principals[i]);
+          if (i < (principals.length - 1)) {
+            out += ' ';
+          }
+        }
+      }
+    }
+    return out;
+  }
+  
+  /**
+   * Returns a Map of key/value pairs that correspond the subset of
+   * System properties that correspond to valid file paths.
+   * @return the map
+   */
+  public static final Properties getPathSubstitutions() {
+    final Properties substitutions = new Properties();
+    AccessController.doPrivileged(new PrivilegedAction() {
+      public Object run() {
+        Enumeration keys = System.getProperties().propertyNames();
+        while (keys.hasMoreElements()) {
+          String substitutionProperty = (String) keys.nextElement();
+          if (!substitutionProperty.equals("file.separator")) {
+            String path = System.getProperty(substitutionProperty);
+            if (path.length() > 0) {
+              // Try making a file out of it; if it exists, then dereference it
+              File file = new File(path);
+              if (file.exists()) {
+                try {
+                  path = file.getCanonicalPath();
+                }
+                catch (IOException e) {
+                  System.err.println("Error de-referencing: " + e.getMessage());
+                }
+                substitutions.put(path, substitutionProperty);
+              }
+            }
+          }
+        }
+        return null;
+      }
+    });
+    return substitutions;
+  }
+  
+  /**
+   * Formats a CachedPrincipal for use with a policy file. The string returned
+   * is the principal class, plus a space, followed by the principal's getName()
+   * value in quotes.
+   * 
+   * @param principal the Principal to format
+   * @return a nicely-formatted string representing the Principal
+   */
+  public static final String format(Principal principal) {
+    return principal.getClass().getName() + ' ' + '\"' + principal.getName() + '\"';
+  }
+  
+  /**
+   * Formats a CachedPermission for use in a policy file or log file. The format is
+   * identical to that used in policy files.
+   * @param perm the Permission to format
+   * @return a nicely-formatted string representing the Permission
+   */
+  public static final String format(Permission permission) {
+    String out = permission.getClass().getName() + " ";
+    String target = permission.getName();
+    String actions = permission.getActions();
+
+    boolean hasName = (target != null && target.length() != 0);
+    boolean hasActions = (actions != null && actions.length() != 0);
+    String formattedTarget;
+    if (hasName) {
+      formattedTarget = target.replaceAll("\"", "\\u0022");
+      out += ("\"" + formattedTarget + "\"");
+      if (hasActions) {
+        out += (", ");
+      }
+    }
+    if (hasActions) {
+      out += ("\"" + actions + "\"");
+    }
+    return out;
+  }
+  
+  /**
+   * Canonicalizes a CodeSource.
+   * @param cs the CodeSource
+   * @param properties the properties to use for expansion
+   * @return the CodeSource with its file path 
+   * @throws IOException
+   */
+  public final CodeSource canonicalize(CodeSource codeSource, Properties properties) throws IOException {
+    
+    URL url = codeSource.getLocation();
+    Certificate[] certs = codeSource.getCertificates();
+    
+    // Canonicalize the URL
+    if (url != null) {
+      String cs = url.getPath();
+      // Trim path to remove file: prefix
+      if (cs.startsWith(CODEBASE_FILE_PREFIX)) {
+        cs = cs.substring(5);
+      }
+      else if (cs.startsWith(CODEBASE_URL_PREFIX)) {
+        return codeSource;
+      }
+      
+      // See if we need to substitute any properties
+      for (Iterator it = properties.keySet().iterator(); it.hasNext();) {
+        String path = (String)it.next();
+        String property = (String)properties.get(path);
+        // Does the codebase start with the property?
+        String value = "${" + property + "}";
+        if (cs.startsWith(value)) {
+          if (!path.endsWith(File.separator) && (cs.length() <= value.length())) {
+            path += File.separator;
+          }
+          cs = path + cs.substring(value.length());
+          break;
+        }
+      }
+     
+      // Create new file with canonical path
+      File file = new File(cs).getCanonicalFile();
+      cs = file.getAbsolutePath();
+      url = new URL("file:" + cs);
+    }
+    
+    return new CodeSource(url, certs);
+  }
+  
+  /**
+   * <p>
+   * Normalizes permissions by changing permission targets to canonical forms.
+   * For example:
+   * </p>
+   * <ul>
+   * <li>{@link java.io.FilePermission} paths are converted to canonical form
+   * (symbolic links dereferenced), if possible</li>
+   * <li>{@link java.net.SocketPermission} local host names 127.0.0.1 and ""
+   * are converted to <code>localhost</code></li>
+   * </ul>
+   * <p>
+   * All other permission types are returned unchanged.
+   * </p>
+   * @param permission the permission to canonicalize
+   * @return the canonicalized permission
+   * @throws UnknownHostException 
+   */
+  public final Permission canonicalize(Permission permission)
+  {
+    // For file permissions, canonicalize the file path
+    if (permission instanceof FilePermission) {
+      File file = new File(permission.getName());
+      try {
+        String canonicalName = file.getCanonicalPath();
+        if (!permission.getName().equals(canonicalName)) {
+          String actions = permission.getActions();
+          permission = new FilePermission(canonicalName, actions);
+        }
+      }
+      catch (IOException e) {
+        System.err.println(e.getMessage());
+      }
+    }
+
+    // For socket permissions, normalize "localhost" refs
+    else if (permission instanceof SocketPermission) {
+      String host = permission.getName();
+      if (host.startsWith("localhost")) {
+        return permission;
+      }
+      
+      // Normalize
+      String port = null;
+      String target = permission.getName();
+      int lastColon = target.lastIndexOf(":");
+      if (lastColon > -1)
+      {
+        host = target.substring(0,lastColon);
+        port = target.substring(lastColon + 1, target.length());
+      }
+      
+      final String testHost = host;
+      String resolvedHost = (String)AccessController.doPrivileged(new PrivilegedAction() {
+        public Object run() {
+          try {
+            InetAddress addr = InetAddress.getByName(testHost);
+            if (addr.isLoopbackAddress())
+            {
+              return "localhost";
+            }
+          }
+          catch (AccessControlException e)
+          {
+            // If we don't have permission to resolve the host, it's ok
+            return testHost;
+          }
+          catch (UnknownHostException e) {
+            // It's ok if we can't resolve the host...
+            return testHost;
+          }
+          return testHost;
+        }
+      },null);
+
+      target = (port == null) ? resolvedHost : resolvedHost + ":" + port;
+      String actions = permission.getActions();
+      permission = new SocketPermission(target, actions);
+    }
+    
+    // All other permissions are unchanged
+    return permission;
+  }
+  
+}
diff --git a/src/org/freshcookies/security/policy/GenericPrincipal.java b/src/org/freshcookies/security/policy/GenericPrincipal.java
new file mode 100644
index 0000000..f5b0ee3
--- /dev/null
+++ b/src/org/freshcookies/security/policy/GenericPrincipal.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.security.Principal;
+
+/**
+ * Simple principal class.
+ * 
+ * @author Andrew Jaquith
+ * @version $Revision: 1.3 $ $Date: 2007/02/24 17:27:43 $
+ */
+public final class GenericPrincipal implements Principal {
+
+  private final String name;
+
+  private final int hashCode;
+
+  /**
+   * Constructs a new GenericPrincipal with a supplied name.
+   * 
+   * @param name the name of the Principal
+   */
+  public GenericPrincipal(String name) {
+    this.name = name;
+    this.hashCode = name.hashCode();
+  }
+
+  /**
+   * @see java.lang.Object#equals(java.lang.Object)
+   */
+  public final boolean equals(Object obj) {
+    if (obj instanceof GenericPrincipal) {
+      return ((GenericPrincipal) obj).getName().equals(name);
+    }
+    return false;
+  }
+
+  /**
+   * @see java.security.Principal#getName()
+   */
+  public final String getName() {
+    return name;
+  }
+
+  /**
+   * @see java.lang.Object#hashCode()
+   */
+  public final int hashCode() {
+    return hashCode;
+  }
+
+  /**
+   * @see java.lang.Object#toString()
+   */
+  public final String toString() {
+    return "(GenericPrincipal=" + name + ")";
+  }
+
+}
diff --git a/src/org/freshcookies/security/policy/LocalPolicy.java b/src/org/freshcookies/security/policy/LocalPolicy.java
new file mode 100644
index 0000000..47ba5ef
--- /dev/null
+++ b/src/org/freshcookies/security/policy/LocalPolicy.java
@@ -0,0 +1,312 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * Security policy class that implements a subset of
+ * {@link java.security.Policy} methods, using a standard Java security policy
+ * file as input. This class is ideally suited for "local authorization" cases
+ * where consultation of a global JVM policy is not necessary or desired, but
+ * where polices are expressed in the standard policy file grammar. This class
+ * differs from standard Policy implementations in that it does not extend the
+ * Policy superclass, and it implements only two of its methods:
+ * {@link #implies(ProtectionDomain, Permission)} and {@link #refresh()}.
+ * Because LocalPolicy does not extend Policy, it cannot be installed as a
+ * system-wide security policy (which is probably a good thing, because it is
+ * not optimized as expertly as Sun's standard PolicyFile implementation).
+ * </p>
+ * <p>
+ * The constructor of this class accepts a {@link java.io.File} from which the
+ * policy is parsed and read using the {@link PolicyReader} class. The policy is
+ * static and is derived <em>only</em> from the content of the file. If the
+ * policy file changes in the file system, callers may reload it by calling
+ * {@link #refresh()}.
+ * </p>
+ * <p>
+ * This class is not thread-safe. It requires the same permissions to run 
+ * as the underlying PolicyReader used to parse the policy file. 
+ * (See {@link PolicyReader} for more details.
+ * </p>
+ * 
+ * @author Andrew Jaquith
+ * @version $Revision: 1.2 $ $Date: 2007/04/09 02:34:52 $
+ * @see PolicyReader
+ */
+public class LocalPolicy {
+
+	private boolean loaded;
+
+	private final File policyFile;
+
+	private final Set pds;
+  
+  private final String charset;
+	
+	/**
+	 * Constructs a new instance of a LocalPolicy object, whose policy rules are
+	 * parsed from a supplied File using the standard Java platform encoding. 
+   * The policy file's contents and structure are
+	 * expected to be identical to those used in the J2SE default policy file 
+   * implementation.
+	 * 
+	 * @param file
+	 *            the file supplying the security policy
+	 */
+	public LocalPolicy(File file) {
+    this(file, (String)AccessController.doPrivileged( new PrivilegedAction() { 
+      public Object run() { return System.getProperty("file.encoding"); } }));
+	}
+
+  /**
+   * Constructs a new instance of a LocalPolicy object, whose policy rules are
+   * parsed from a supplied File using the standard Java platform encoding. 
+   * The policy file's contents and structure are
+   * expected to be identical to those used in the J2SE default policy file 
+   * implementation.
+   * 
+   * @param file
+   *            the file supplying the security policy
+   * @param encoding
+   *            the charset name, such as <code>UTF-8</code> or <code>ISO-8859-1</code>
+   */
+  public LocalPolicy(File file, String encoding) {
+    super();
+    loaded = false;
+    policyFile = file;
+    pds = new HashSet();
+    charset = encoding;
+  }
+  
+	/**
+	 * Returns <code>true</code> if the security policy grants a particular
+	 * Permission to a ProtectionDomain whose code source, certificates and
+   * classloader match the one supplied as a parameter. This method contains
+   * the exact same method signature as {@link java.security.Policy#implies(ProtectionDomain, Permission)}
+   * but differs in a key respect: Permissions for the supplied ProtectionDomain are
+   * looked up based on its CodeSource, ClassLoader and Principals, rather
+   * than looking for one that is logically equal to it.
+	 * 
+	 * @param domain
+	 *            the protection domain
+	 * @param permission
+	 *            the permission to check for
+	 * @return <code>true</code> if the permission was granted,
+	 *         <code>false</code> if not
+	 * @throws IllegalStateException if the policy needed refreshing but could
+	 * not be refreshed
+	 */
+	public boolean implies(ProtectionDomain domain, Permission permission) {
+
+		// If policy file not loaded, do it now
+		if (!loaded) {
+			try {
+				refresh();
+			}
+			catch (PolicyException e) {
+				throw new IllegalStateException(e.getMessage());
+			}
+		}
+
+		// Iterate through the policy domains and find
+		// one whose codesource, principals and classloader match
+		for (Iterator it = pds.iterator(); it.hasNext();) {
+			LocalProtectionDomain pd = (LocalProtectionDomain)it.next();
+			boolean samePrincipals = samePrincipals(pd.getPrincipals(), domain.getPrincipals());
+			boolean sameCodeSource = pd.getCodeSource().implies(domain.getCodeSource());
+			boolean sameClassLoader = pd.getClassLoader().equals(domain.getClassLoader());
+			if (samePrincipals && sameCodeSource && sameClassLoader) {
+				
+				// Ok! All we have to do now is see if our local policy domain grants the permission
+				// (if not, keep going...)
+        PermissionCollection permissions = pd.getPermissions();
+				if (permissions.implies(permission)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Determines whether two Principal arrays contain the same items, which may appear in any order
+	 * @param p1 the first array
+	 * @param p2 the second array
+	 * @return <code>true</code> if every item in the first array is <code>equal</code> to one other
+	 * item in the second array; <code>false</code> otherwise
+	 */
+	protected boolean samePrincipals(Principal[] p1, Principal[] p2) {
+		if (p1.length != p2.length) {
+			return false;
+		}
+		
+		// Set up a list of 'leftover' items that we pop from every time we find a match
+		List leftovers = new ArrayList();
+		for (int i = 0; i < p2.length; i++) {
+			leftovers.add(p2[i]);
+		}
+		
+		// Go through first array and remove the corresponding principal from leftover collection
+		for (int i = 0; i < p1.length; i++) {
+			Principal p = p1[i];
+			for (Iterator it = leftovers.iterator(); it.hasNext();) {
+				Principal leftover = (Principal)it.next();
+				if (p.equals(leftover)) {
+					it.remove();
+					break;
+				}
+			}
+		}
+		// If nothing left in leftovers, everything must've matched
+		return (leftovers.size() == 0);
+	}
+	
+	/**
+	 * <p>Reloads the policy from the filesystem. This method contains
+   * the exact same method signature as {@link java.security.Policy#refresh()}
+   * and is functionally equivalent. If the policy does not parse
+	 * correctly, it will print any errors to standard out and throw an
+	 * IllegalStateException. This method does not itself require security
+	 * permissions to run, although the underlying PolicyReader used to parse
+	 * the policy file does. (See {@link PolicyReader#read()} for
+	 * more details.</p>
+	 * @throws PolicyException if the policy could not be refreshed or parsed
+	 */
+	public void refresh() throws PolicyException {
+		pds.clear();
+		PolicyReader reader;
+		try {
+			reader = new PolicyReader(policyFile,charset);
+			reader.read();
+		} catch (IOException e) {
+			String msg = "Problems refreshing policy from file " + policyFile
+					+ ": " + e.getMessage();
+			System.err.println(msg);
+			throw new PolicyException(msg);
+		}
+
+		// If errors, print them out
+		if (!reader.isValid()) {
+			List messages = reader.getMessages();
+			for (Iterator it = messages.iterator(); it.hasNext();) {
+				String message = (String) it.next();
+				System.err.println(message);
+			}
+			StringBuffer s = new StringBuffer();
+			for (Iterator it = messages.iterator(); it.hasNext();) {
+				s.append((String) it.next());
+			}
+			throw new PolicyException("Errors parsing policy from file "
+					+ policyFile + ": " + s.toString());
+		}
+
+		// It parsed and validated ok, so now stash local copies of the protection domains
+		ProtectionDomain[] parsedPds = reader.getProtectionDomains();
+		for (int i = 0; i < parsedPds.length; i++) {
+      ProtectionDomain pd = parsedPds[i];
+      LocalProtectionDomain localPd = new LocalProtectionDomain(pd.getCodeSource(), pd.getPermissions(), pd.getClassLoader(), pd.getPrincipals());
+			pds.add(localPd);
+		}
+
+		loaded = true;
+	}
+  
+  /**
+   * Lightweight re-implementation of {@link java.security.ProtectionDomain} that
+   * does not allow subsequent modifications to Permissions. The default ProtectionDomain
+   * is, unfortunately, unsuitable for use with LocalPolicy because default JVM permissions
+   * are added "dynamically" subsequent to creation. This class exhibits the same
+   * basic behaviors as ProtectionDomain: <code>null</code> values are allowed for the
+   * LocalProtectionDomain's Principals, CodeSource and PermissionCollection. Also, if the
+   * Principal array supplied is <code>null</code>, it will be converted to a zero-length
+   * array.
+   * @author Andrew Jaquith
+   */
+  public static class LocalProtectionDomain { 
+    
+    private final CodeSource codesource;
+    private final ClassLoader classloader;
+    private final PermissionCollection permissions;
+    private final Principal[] principals;
+    
+    /**
+     * Constructs a new LocalProtectionDomain.
+     * @param codesource the code source; may be <code>null</code>
+     * @param permissions the permission collection; may be <code>null</code>
+     * @param principals the principals to whom the permissions are granted; may be <code>null</code>
+     */
+    public LocalProtectionDomain(CodeSource codesource, 
+      PermissionCollection permissions, ClassLoader classloader, Principal[] principals) {
+      this.codesource = codesource;
+      this.permissions = permissions;
+      if (permissions != null && !permissions.isReadOnly()) {
+        permissions.setReadOnly();
+      }
+      this.classloader = classloader;
+      this.principals = (principals == null) ? new Principal[0] : principals;
+    }
+    
+    /**
+     * Returns the ClassLoader used to construct the LocalProtectionDomain,
+     * which may be <code>null</code>.
+     * @return the class loader
+     */
+    public ClassLoader getClassLoader() {
+      return classloader;
+    }
+    
+    /**
+     * Returns the Principal array used to construct the LocalProtectionDomain,
+     * if supplied, or a zero-length array if not supplied.
+     * @return the principals
+     */
+    public Principal[] getPrincipals() {
+      return principals;
+    }
+    
+    /**
+     * Returns the PermissionCollection used to construct the LocalProtectionDomain,
+     * which may be <code>null</code>.
+     * @return the permissions
+     */
+    public PermissionCollection getPermissions() {
+      return permissions;
+    }
+    
+    /**
+     * Returns the CodeSource used to construct the LocalProtectionDomain,
+     * which may be <code>null</code>.
+     * @return the principals
+     */
+    public CodeSource getCodeSource() {
+      return codesource;
+    }
+  }
+
+}
diff --git a/src/org/freshcookies/security/policy/PolicyException.java b/src/org/freshcookies/security/policy/PolicyException.java
new file mode 100644
index 0000000..b5abfeb
--- /dev/null
+++ b/src/org/freshcookies/security/policy/PolicyException.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+/**
+ * Lightweight checked Exception subclass for propagating security policy parsing errors.
+ * @author Andrew Jaquith
+ * @version $Revision: 1.2 $ $Date: 2007/02/24 17:27:43 $
+ * 
+ */public class PolicyException extends Exception {
+
+  private static final long serialVersionUID = 1L;
+
+  public PolicyException(String message) {
+    super(message);
+  }
+  
+}
diff --git a/src/org/freshcookies/security/policy/PolicyReader.java b/src/org/freshcookies/security/policy/PolicyReader.java
new file mode 100644
index 0000000..44dd0c8
--- /dev/null
+++ b/src/org/freshcookies/security/policy/PolicyReader.java
@@ -0,0 +1,991 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Permissions;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Parses a Java security policy file into memory.
+ * <p>If a SecurityManager is running, the security policy must grant 
+ * PolicyReader's CodeSource the following permissions:</p>
+ * <ul>
+ *   <li><code>java.io.FilePermission "${java.home}/lib/security/java.policy", "read"</code></li>
+ *   <li><code>java.io.FilePermission "${user.home}/.java.policy", "read"</code></li>
+ *   <li><code>java.io.FilePermission "<em>path-to-policy-file</em>", "read"</code></li>
+ *   <li><code>java.io.FilePermission "<em>path-to-keystore</em>", "read";</code></li>
+ *   <li><code>java.util.PropertyPermission "file.encoding", "read"</code></li>
+ *   <li><code>java.util.PropertyPermission "java.security.policy", "read"</code></li>
+ *   <li><code>java.util.PropertyPermission "java.home", "read"</code></li>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+ *   <li><code>java.lang.RuntimePermission "getProtectionDomain"</code></li>
+ *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+ * </ul>
+ * <p>...where <em>path-to-policy-file</em> is the policy file to parse, 
+ * <em>path-to-keystore</em> is the path of the keystore named in the policy file (if any), 
+ * and <em>custom-permission-packages</em> and <em>custom-principal-packages</em> 
+ * denote the names of custom {@link java.security.Permission} and 
+ * {@link java.security.Principal} classes to be loaded by the current classloader when the
+ * file is parsed. The methods that require these permissions enclose their operations inside
+ * of <code>doPrivileged</code> blocks, so calling classes' ProtectionDomains do <em>not</em>
+ * need to be granted these privileges.</p>
+ * 
+ * @author Andrew Jaquith
+ * @version $Revision: 1.5 $ $Date: 2007/04/09 02:34:52 $
+ */
+public class PolicyReader {
+
+	private static final Pattern COMMENTS_PATTERN = Pattern.compile(
+			"^\\s*\\/\\/.*$", Pattern.MULTILINE);
+
+	private static final Pattern KEYSTORE_PATTERN = Pattern.compile(
+			"^keystore \"(.*?)\";.*$", Pattern.CASE_INSENSITIVE);
+
+	private static final Pattern GRANT_PATTERN = Pattern
+			.compile("grant(.*?) \\{ *(.*?) *\\};");
+
+	private static final Pattern LINEBREAKS_PATTERN = Pattern.compile(
+			"[\\n|\\r\\n|\\u0085|\\u2028|\\u2029]", Pattern.MULTILINE);
+
+	private static final String PROP_JAVA_HOME = "java.home";
+
+	private static final String PROP_USER_HOME = "user.home";
+
+	private static final String PROP_JAVA_SECURITY_POLICY = "java.security.policy";
+
+	private static final String REGEX_COMMA_DELIMITER = " *, *";
+
+	private static final String REGEX_SEMICOLON_DELIMITER = " *; *";
+
+	private static final String TOKEN_CODEBASE = "codeBase";
+
+	private static final String TOKEN_PRINCIPAL = "principal";
+
+	private static final String TOKEN_PERMISSION = "permission";
+
+	private static final String TOKEN_SIGNEDBY = "signedBy";
+
+	private static final String DOUBLE_QUOTE = "\"";
+
+	private static final String ONE_SPACE = " ";
+
+	private static final String WHITESPACE = "\\s+";
+
+	private static final int NOT_FOUND = -1;
+
+	private final File policy;
+
+	private final List domains;
+	
+	private KeyStore keystore = null;
+
+	private File keystoreFile = null;
+
+	private String policyString = null;
+
+	private final List exceptions = new ArrayList();
+
+	private SecurityTokenFactory tokenFactory = null;
+
+	private boolean validPolicy = false;
+  
+  private final String charset;
+
+	/**
+	 * <p>
+	 * Constructs a new PolicyReader for parsing a supplied policy File using the
+   * Java platform standard charset.
+	 * @param file
+	 *            the policy file to be parsed
+	 * @throws FileNotFoundException
+	 *            if the policy file does not exist in the filesystem
+	 * @throws SecurityException if the running SecurityManager denied any of the required
+	 * Permissions
+	 */
+	public PolicyReader(File file) throws FileNotFoundException {
+    this(file, (String)AccessController.doPrivileged( new PrivilegedAction() { 
+      public Object run() { return System.getProperty("file.encoding"); } }));
+	}
+
+  /**
+   * <p>
+   * Constructs a new PolicyReader for parsing a supplied policy File. If the
+   * file does not exist, this constructor returns an
+   * {@linkplain IllegalArgumentException}.
+   * </p>
+     * <p>If a SecurityManager is running, the security policy must grant 
+     * PolicyReader's CodeSource the following permissions:</p>
+     * <ul>
+   *   <li><code>java.io.FilePermission "<em>path-to-policy-file</em>", "read"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+     *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+     * </ul>
+     * <p>...where <em>custom-permission-packages</em> and <em>custom-principal-packages</em> 
+     * are the names of custom {@link java.security.Permission} and 
+     * {@link java.security.Principal} classes loaded from the current classloader.</p>
+   * 
+   * @param file
+   *            the policy file to be parsed
+   * @throws FileNotFoundException
+   *            if the policy file does not exist in the filesystem
+   * @throws SecurityException if the running SecurityManager denied any of the required
+   * Permissions
+   */
+  public PolicyReader(File file, String charset) throws FileNotFoundException {
+    super();
+    this.policy = file;
+    this.domains = new ArrayList();
+    this.charset = charset;
+    boolean exists = secureExists(policy);
+    if (!exists) {
+      throw new IllegalArgumentException("File " + policy
+          + " does not exist, or the SecurityManager prohibited access to it.");
+    }
+    
+    // Set up the token factory; if the SecurityManager prohibits it, then propagate the exception
+    this.tokenFactory = 
+      (SecurityTokenFactory)AccessController.doPrivileged(new PrivilegedAction() {
+        public Object run() throws SecurityException {
+          return new SecurityTokenFactory(new URL[0]);
+        }
+      
+      });
+  }
+  
+	/**
+	 * Examines a Keystore and returns the alias that matches a given signing
+	 * Certificate. If no match is found, this method returns <code>null</code>.
+	 * 
+	 * @param ks
+	 *            the keystore to search
+	 * @param cert
+	 *            the certificate to match
+	 * @return the alias corresponding to the certificate
+	 */
+	public static String findAlias(KeyStore ks, Certificate cert) {
+		try {
+			Enumeration aliases = ks.aliases();
+			while (aliases.hasMoreElements()) {
+				String alias = (String) aliases.nextElement();
+				if (ks.isKeyEntry(alias)) {
+					Certificate keystoreCert = ks.getCertificate(alias);
+					if (cert.equals(keystoreCert)) {
+						return alias;
+					}
+				}
+			}
+		} catch (KeyStoreException e) {
+			System.err.println(e.getMessage());
+		}
+		return null;
+	}
+
+	/**
+	 * Returns the ProtectionDomains parsed by the {@link #read()} method.
+	 * If the {@link #read()} method has not been called yet, this method 
+	 * will return a zero-length array. 
+	 * @return the ProtectionDomains parsed from the policy file
+	 */
+	public ProtectionDomain[] getProtectionDomains() {
+		return (ProtectionDomain[])domains.toArray(new ProtectionDomain[domains.size()]);
+	}
+
+	/**
+	 * <p>
+	 * Static method that identifies the active security policies for the JVM
+	 * and returns an array of PolicyReader objects (one for each active
+	 * policy).
+	 * </p>
+	 * <p>
+	 * This method accesses the file system to determine whether certain default
+	 * security policies exist, and it reads the <code>java.home</code> and
+	 * <code>user.home</code> properties to determine the location of the
+	 * system and user security policies. Therefore, to run this method under a
+	 * SecurityManager, the security policy must grant PolicyReader's 
+	 * CodeSource the following permissions:</p>
+	 * </p>
+	 * <ul>
+	 *   <li><code>java.util.PropertyPermission "java.home", "read"</code></li>
+	 *   <li><code>java.util.PropertyPermission "java.security.policy", "read"</code></li>
+	 *   <li><code>java.util.PropertyPermission "user.home", "read"</code></li>
+	 *   <li><code>java.io.FilePermission "${java.home}/lib/security/java.policy", "read"</code></li>
+	 *   <li><code>java.io.FilePermission "${user.home}/.java.policy", "read"</code></li>
+	 * </ul>
+	 * 
+	 * @return PolicyReader objects for each active policy file
+	 * @throws SecurityException if the running SecurityManager denied any of the required
+	 * Permissions
+	 */
+	public static PolicyReader[] findPolicies() {
+		final Set files = new HashSet();
+		final String fs = File.separator;
+
+		AccessController.doPrivileged(new PrivilegedAction() {
+
+			public Object run() {
+				// Add the system policy if it exists (it should!)
+				File systemPolicy = new File(System.getProperty(PROP_JAVA_HOME)
+						+ fs + "lib" + fs + "security" + fs + "java.policy");
+				if (systemPolicy.exists()) {
+					files.add(systemPolicy);
+				}
+
+				// Add the user policy if it exists
+				File userPolicy = new File(System.getProperty(PROP_USER_HOME)
+						+ fs + ".java.policy");
+				if (userPolicy.exists()) {
+					files.add(userPolicy);
+				}
+
+				// Add the file pointed at by the policy system property if it
+				// exists
+				String policyProp = System
+						.getProperty(PROP_JAVA_SECURITY_POLICY);
+				if (policyProp != null) {
+					if (policyProp.startsWith("file:")) {
+						policyProp = policyProp.substring(5);
+					}
+					if (policyProp.length() > 0) {
+						File propertyPolicy = new File(policyProp);
+						if (secureExists(propertyPolicy)) {
+							files.add(propertyPolicy);
+						}
+					}
+				}
+				return null;
+			}
+		});
+
+		// Now, create policy readers for each file we found
+		List readers = new ArrayList();
+		for (Iterator it = files.iterator(); it.hasNext();) {
+			try {
+				readers.add(new PolicyReader((File) it.next()));
+			}
+			catch (FileNotFoundException e) {
+				// Didn't find the policy file/denied access? Ok, just skip it
+			}
+		}
+		return (PolicyReader[])readers.toArray(new PolicyReader[readers.size()]);
+	}
+
+	/**
+	 * Static method that returns the certificate used to sign a particular
+	 * class. We determine the signing certificate by obtaining the class'
+	 * {@link java.security.ProtectionDomain} first, then looking up the
+	 * CodeSource and extracting certificates. If the code source was not
+	 * signed, this method returns <code>null</code>. This method obtains the
+	 * ProtectionDomain of the class. Therefore, to run this method under a
+	 * SecurityManager, the security policy must grant PolicyReader's 
+	 * CodeSource the following permission:</p>
+	 * </p>
+	 * <ul>
+	 *   <li><code>java.lang.RuntimePermission "getProtectionDomain"</code></li>
+	 * </ul>
+	 * 
+	 * @param clazz the class whose signer should be returned
+	 * @return the signing certificate, or <code>null</code> if no signer
+	 * @throws SecurityException
+	 *             if the running SecurityManager denied this ProtectionDomain 
+	 *             the permission <code>java.lang.RuntimePermission "getProtectionDomain"</code>
+	 */
+	public static Certificate getSigner(final Class clazz) {
+		ProtectionDomain pd = null;
+
+		pd = (ProtectionDomain) AccessController
+				.doPrivileged(new PrivilegedAction() {
+					public Object run() {
+						return clazz.getProtectionDomain();
+					}
+				});
+
+		if (pd != null) {
+			CodeSource cs = pd.getCodeSource();
+			if (cs != null) {
+				Certificate[] certs = cs.getCertificates();
+				if (certs != null && certs.length > 0) {
+					return certs[0];
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Returns <code>true</code> if a class is digitally signed. This looks up
+	 * the signer by delegating to {@link #getSigner(Class)}, and therefore
+	 * requires the same privileges if run under a SecurityManager.
+	 * 
+	 * @param clazz
+	 *            the class to check
+	 * @return the result.
+	 * @throws SecurityException
+	 *             if the running SecurityManager denied this ProtectionDomain 
+	 *             the permission <code>java.lang.RuntimePermission "getProtectionDomain"</code>
+	 * @see #getSigner(Class)
+	 */
+	public static boolean isSigned(Class clazz) {
+		Certificate cert = getSigner(clazz);
+		return (cert != null);
+	}
+
+	/**
+	 * Returns the File object used to instantiate this PolicyReader.
+	 * 
+	 * @see #PolicyReader(File)
+	 * @return the file
+	 */
+	public File getFile() {
+		return policy;
+	}
+
+	/**
+	 * <p>
+	 * Returns the keystore associated with the policy file, if one is specified
+	 * in the policy. The strategy used to file the keystore follows the J2SE
+	 * convention: if the file named in the <code>keystore</code> line of the
+	 * policy file is not an absolute path name, the location for the file is
+	 * assumed to be the same directory as the keystore. If the keystore cannot
+	 * be located, this method throws an {@link java.io.IOException}.
+	 * </p>
+	 * 
+	 * <p>
+	 * If the policy file does not specify a keystore, this method returns
+	 * <code>null</code>, and
+	 * <em>calling methods should check for this result!</em>
+	 * </p>
+	 * <p>
+	 * This method attempts to read the keystore into memo from the file
+	 * specified in the secuity policy. Therefore, to run this method under a
+	 * SecurityManager, the security policy must grant PolicyReader's 
+	 * CodeSource the following permission:</p>
+	 * </p>
+	 * <ul>
+	 *   <li><code>java.io.FilePermission "<em>/path-to-keystore</em>", "read"</code></li>
+	 * </ul>
+	 * 
+	 * @return the keystore associated with the policy file, or
+	 *         <code>null</code> if not found
+	 * @throws IOException
+	 *             if the keystore file cannot be read from the filesystem
+	 *             because it does not exist
+	 * @throws SecurityException if the running SecurityManager denied the Permission
+	 * <code>java.io.FilePermission "<em>path-to-keystore</em>", "read"</code>
+	 */
+	public KeyStore getKeyStore() throws IOException {
+
+		if (keystore == null) {
+
+			if (policyString == null) {
+				loadPolicy(policy);
+			}
+
+			// Get keystore, it if exists
+			Matcher matcher = KEYSTORE_PATTERN.matcher(policyString);
+			if (matcher.matches()) {
+				String match = matcher.group(1);
+				keystoreFile = new File(match);
+				if (!keystoreFile.isAbsolute()) {
+					keystoreFile = new File(policy.getParentFile(), match);
+					if (!secureExists(keystoreFile)) {
+						throw new IOException("Couldn't find keystore "
+								+ keystoreFile + ", or the SecurityManager prohibited access to it.");
+					}
+				}
+			}
+
+			// If the keystore file is not null, load the keystore itself
+			if (keystoreFile != null) {
+				try {
+					AccessController.doPrivileged(new PrivilegedExceptionAction() {
+						public Object run() throws IOException {
+							try {
+								FileInputStream is = new FileInputStream(keystoreFile);
+								keystore = KeyStore.getInstance(KeyStore.getDefaultType());
+								keystore.load(is, null);
+								return null;
+							} catch (CertificateException e) {
+								throw new IOException(e.getMessage());
+							} catch (KeyStoreException e) {
+								throw new IOException(e.getMessage());
+							} catch (NoSuchAlgorithmException e) {
+								throw new IOException(e.getMessage());
+							} catch (SecurityException e) {
+								return new IOException("Security manager prohibited read access to "
+									+ keystoreFile.getAbsolutePath());
+							}
+						}
+					});
+				} catch (PrivilegedActionException e) {
+					throw (IOException) e.getException();
+				}
+			}
+		}
+		return keystore;
+	}
+
+	/**
+	 * <p>
+	 * Parses the security policy file, and loads its contents into memory. Any
+	 * errors encountered while reading the policy will be added to an
+	 * internally cached set of error messages, which may be obtained by
+	 * {@link #getMessages()}.
+	 * </p>
+	 * <p>
+	 * Because this method attempts to read the policy file contents, it
+	 * requires <code>read</code> permissions to the file containing the
+	 * policy if a SecurityManager is running. It will also require
+	 * <code>read</code> access to the keystore named in the policy, and will
+	 * need to read named classes' ProtectionDomains to verify signatures if
+	 * required by the policy. Therefore, to run this method under a
+	 * SecurityManager, the security policy must grant PolicyReader's 
+	 * CodeSource the following permission:</p>
+     * <ul>
+     *   <li><code>permission java.io.FilePermission "<em>path-to-policy-file</em>", "read"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+	 *   <li><code>java.lang.RuntimePermission "getProtectionDomain"</code></li>
+	 *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+     * </ul>
+	 * 
+	 * @throws IOException if the policy file cannot be read
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the ProtectionDomain of this class any of the required permissions
+	 */
+	public void read() throws IOException {
+
+		if (policyString == null) {
+			loadPolicy(policy);
+			getKeyStore();
+		}
+
+		// Parse the grants
+		domains.clear();
+		Matcher m = GRANT_PATTERN.matcher(policyString);
+		while (m.find()) {
+			String granteeString = m.group(1).trim();
+			String permissionString = m.group(2).trim();
+			ProtectionDomain domain = parseProtectionDomain(granteeString, permissionString);
+			domains.add(domain);
+		}
+
+		if (exceptions.size() > 0) {
+			System.err.println("The parser returned these errors:");
+			for (Iterator it = exceptions.iterator(); it.hasNext();) {
+				Exception e = (Exception) it.next();
+				System.err.println(e.getMessage());
+			}
+		} else {
+			// Hooray! Everything parsed nicely.
+			validPolicy = true;
+		}
+
+	}
+
+	/**
+	 * The parsing errors encountered by PolicyReader when the {@link #read()} method
+	 * was last invoked. The list of errors is reset every time <code>read()</code>
+	 * is called.
+	 * @return the list of Exception objects
+	 */
+	public List getMessages() {
+		return Collections.unmodifiableList(exceptions);
+	}
+	
+	/**
+	 * Adds an Exception to the list of parsing errors.
+	 * @param e the exception added
+	 */
+	protected void addMessage(Exception e) {
+		exceptions.add(e);
+	}
+
+	/**
+	 * Protected method that loads the policy file into memory, scrubs contents
+	 * of line breaks and extra whitespace, and returns it as a string. If
+	 * running under a SecurityManager, this method must have read access to the
+	 * file.
+	 * 
+	 * @param file the policy file to load
+	 * @throws IOException
+	 *             if the file does not exist in the file system
+	 * @throws SecurityException if the running SecurityManager denied the Permission
+	 * <code>java.io.FilePermission "<em>path-to-file</em>", "read"</code>
+	 */
+	protected void loadPolicy(final File file) throws IOException {
+		StringBuffer contents = new StringBuffer();
+		BufferedReader reader = null;
+		try {
+			reader = (BufferedReader) AccessController
+					.doPrivileged(new PrivilegedExceptionAction() {
+						public Object run() throws SecurityException, UnsupportedEncodingException {
+							try {
+								BufferedReader in = new BufferedReader(
+										new InputStreamReader( new FileInputStream(file), charset ) );
+								return in;
+							} catch (FileNotFoundException e) {
+								return null;
+							}
+						}
+					});
+		} catch (PrivilegedActionException e) {
+			throw new SecurityException("Could not open policy "
+					+ file.getAbsolutePath()
+					+ "; access was denied by the SecurityManager.");
+		}
+
+		// If reader was null, it means we could not find it in the filesystem
+		if (reader == null) {
+			throw new IOException("Could not open policy "
+					+ file.getAbsolutePath() + "; it does not exist.");
+		}
+
+		// Read the file and append its contents to a string buffer
+		int ch;
+		while ((ch = reader.read()) != NOT_FOUND) {
+			contents.append((char) ch);
+		}
+		reader.close();
+
+		// Scrub out all comments
+		Matcher matcher = COMMENTS_PATTERN.matcher(contents);
+		String contentsNoComments = matcher.replaceAll(ONE_SPACE);
+
+		// Replace line breaks with spaces
+		matcher = LINEBREAKS_PATTERN.matcher(contentsNoComments);
+		String contentsNoLineBreaks = matcher.replaceAll(ONE_SPACE);
+
+		// Replace all multi-character whitespace with one space
+		policyString = contentsNoLineBreaks.replaceAll(WHITESPACE, ONE_SPACE)
+				.trim();
+	}
+
+	/**
+	 * <p>
+	 * Returns a valid ProtectionDomain by parsing a <code>grant</code> block 
+	 * that denotes the codebase, pricipals and signers to whom permissions 
+	 * should be granted. The <code>grant</code> block is comprised of two parts,
+	 * which are passed to this method: the <em>grantee</em> string and the
+	 * <em>permissions</em> string.
+	 * </p>
+	 * </p>
+	 * The <em>grantee</em> is the codebase, principals and signers portion
+	 * of the <code>grant</code> block, minus the word "grant" itself. 
+	 * The following are all valid grantee strings:
+	 * </p>
+	 * <pre> codeBase "file:${user.home}/workspace/freshcookies-security/target-test/"
+	 * signedBy "testsigner", principal org.freshcookies.security.policy.GenericPrincipal "Foo", principal "Bar"
+	 * signedBy "testsigner"</pre>
+	 * <p>
+	 * The grantee string is processed as follows:
+	 * </p>
+	 * <ul>
+	 *   <li>If the grantee strings contains a <code>codeBase</code> token, this method
+	 * will attempt to create a {@link java.security.CodeSource} object and
+	 * stash it in the returned Grantee. It will not actually verify that the
+	 * CodeSource exists, however.</li>
+	 *   <li>If the grantee line contains a <code>signedBy</code> token, this method
+	 * will iterate through the aliases in the Keystore returned by
+	 * {@link #getKeyStore()} and attempt to find a matching signer alias. If no
+	 * match, an error message is added to the internal list.</li>
+	 * </ul>
+	 * <p>
+	 * The permission string is the portion of the <code>grant</code> statement
+	 * between braces (<code>{}</code>). Permissions are delimited with a semicolons.
+	 * The permissions string is processed as follows:
+	 * </p>
+	 * <ul>
+	 *   <li>Each Permission is parsed into the correct class name, targets and actions.</li>
+	 *   <li>After the class name is determined, this method will attempt
+	 * to load the specified permissions into memory using the current ClassLoader.</li>
+	 *   <li>If a particular permission statement contains a <code>signedBy</code>
+	 * token, this method will also attempt to verify that the Permission was 
+	 * signed by the keystore alias specified in the statement.</li>
+	 * </ul>
+	 * <p>The ProtectionDomain that is returned by this method will be constructed with
+	 * CodeSource, PermissionCollection, and Principal array parameters that correspond
+	 * to those parsed from the grantee and permission strings. The ClassLoader passed
+	 * to {@link java.security.ProtectionDomain#ProtectionDomain(CodeSource, PermissionCollection, ClassLoader, Principal[])}
+	 * will be the current ClassLoader; that is, the one that 
+	 * <p>
+	 * This method needs certain privileges to run correctly under a
+	 * SecurityManager. It requires the NetPermission
+	 * <code>specifyStreamHander</code> to construct CodeSource URLs. It will
+	 * also require permission to obtain the ProtectionDomain for loaded classes.
+	 * For example, an appropriate grant statement might look like this:
+	 * </p>
+	 * <pre>grant codeBase "file:/<em>path-to-this-jar</em>/freshcookies-security-<em>version</em>.jar" {
+	 *   permission java.lang.RuntimePermission "getProtectionDomain";
+	 *   permission java.net.NetPermission "specifyStreamHandler";
+	 *};</pre>
+	 * 
+	 * @param granteeString
+	 *            the grantee string, which is the portion of the grant block
+	 *            between the <code>grant</code> token and the opening brace (<code>{</code>)
+	 *            that begins the individual permission lines
+	 * @param permissionString
+	 *            the permission string, which is the portion of the grant block
+	 *            between opening and closing braces(<code>{}</code>). This string will 
+	 *            be split into individual permissions and parsed
+	 * @return the initialized ProtectionDomain
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class any of the following permissions:
+     * <ul>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+	 *   <li><code>java.lang.RuntimePermission "getProtectionDomain"</code></li>
+	 *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+     * </ul>
+	 */
+	protected ProtectionDomain parseProtectionDomain(String granteeString, String permissionString) {
+		
+		// Grantee variables: codebase, signers, principals
+		URL codeBaseUrl = null;
+		Certificate[] signers = null;
+		List principalsList = new ArrayList();
+
+		// Split the grantee string into tokens: one or more of codebase, signedby, principal blocks
+		String[] granteeStrings = granteeString.split(REGEX_COMMA_DELIMITER);
+		
+		// Parse each token
+		for (int i = 0; i < granteeStrings.length; i++) {
+			String grantee = granteeStrings[i].trim();
+
+			// Extract CodeBase URL, and construct
+			if (grantee.startsWith(TOKEN_CODEBASE)) {
+				codeBaseUrl = extractCodeBaseUrl(grantee);
+			}
+
+			// Extract signing certificate alias, and resolve in keystore
+			else if (grantee.startsWith(TOKEN_SIGNEDBY)) {
+				signers = extractSigningCertificates(grantee);
+			}
+
+			// Extract principals, and instantiate
+			else if (grantee.startsWith(TOKEN_PRINCIPAL)) {
+				Principal principal = extractPrincipal(grantee);
+				if (principal != null) {
+					principalsList.add(principal);
+				}
+			}
+		}
+
+		// Ok, now build a CodeSource out of the URL and cert alias
+		// We need the certs at some point...
+		CodeSource codeSource = new CodeSource(codeBaseUrl, signers);
+
+		// Turn our Principal list into an array (but zero-length means we just set it as null)
+		Principal[] principals = (Principal[]) principalsList.toArray(new Principal[principalsList.size()]);
+		if (principals.length == 0) {
+			principals = null;
+		}
+		
+		// Extract the Permissions assigned to the grantee and lock it
+		PermissionCollection permissions = extractPermissionCollection(permissionString);
+    permissions.setReadOnly();
+		
+		// Create and return the ProtectionDomain
+		ClassLoader classLoader = PolicyReader.class.getClassLoader();
+		ProtectionDomain pd = new ProtectionDomain(codeSource, permissions, classLoader, principals);
+		return pd;
+	}
+
+	/**
+	 * Returns <code>true</code> if a supplied File exists in the file system, and
+	 * the SecurityManager (if running) has granted read access to it.
+	 * @param file the file to check
+	 * @return the result
+	 * @throws SecurityException if the running SecurityManager denied the Permission
+	 * <code>java.io.FilePermission "<em>path-to-file</em>", "read"</code>
+	 */
+	protected static boolean secureExists(final File file) throws SecurityException {
+		try {
+			Boolean exists = (Boolean) AccessController.doPrivileged(
+				new PrivilegedExceptionAction() {
+					public Object run() throws SecurityException {
+						return Boolean.valueOf(file.exists());
+					}
+				});
+			return exists.booleanValue();
+		}
+		catch (PrivilegedActionException e) {
+			throw (SecurityException)e.getException();
+		}
+	}
+	
+	/**
+	 * Extracts the URL from a <code>codeBase</code> token string. 
+	 * Example: <code>codeBase "file:${user.home}/workspace/freshcookies-security/target/classes/-"</code>.
+	 * @param token the string containing the URL
+	 * @return the constructed URL
+	 */
+	protected URL extractCodeBaseUrl(String token) {
+		URL url = null;
+		try {
+			final String s = extractTarget(token, TOKEN_CODEBASE);
+			url = (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
+				public Object run() throws MalformedURLException {
+					return new URL(s);
+				}
+			});
+		} catch (PolicyException e) {
+			addMessage(e);
+		} catch (PrivilegedActionException e) {
+			addMessage(e.getException());
+		}
+		return url;
+	}
+	
+	/**
+	 * Extracts the Principal from a <code>principal</code> token string. 
+	 * Example: <code>principal org.freshcookies.security.policy.GenericPrincipal "Andrew Jaquith"</code>.
+	 * @param token the string containing the Principal
+	 * @return the constructed Principal
+	 */
+	protected Principal extractPrincipal(String token) {
+		Principal principal = null;
+		final String s = token.substring(TOKEN_PRINCIPAL.length()).trim();
+		try {
+			principal = (Principal)AccessController.doPrivileged(new PrivilegedExceptionAction() {
+				public Object run() throws AccessControlException, ClassNotFoundException {
+					return tokenFactory.getPrincipal(s);
+				}
+			});
+		}
+		catch (PrivilegedActionException e) {
+			addMessage(e.getException());
+		}
+		return principal;
+	}
+	
+	/**
+	 * Extracts and resolves signing Certificates from a <code>signedBy</code> token string. 
+	 * Example: <code>signedBy "testsigner"</code>.
+	 * @param token the string containing the certificate alias
+	 * @return the resolved certificate chain
+	 */
+	protected Certificate[] extractSigningCertificates(String token) {
+		Certificate[] signers = null;
+		
+		// If keystore file is null, then signedby doesn't mean anything
+		if (keystoreFile == null) {
+			addMessage(new PolicyException(
+					"A 'signedBy' entry exists, but no keystore was specified; ignoring."));
+		} else {
+			try {
+				String signedBy = extractTarget(token, TOKEN_SIGNEDBY);
+				signers = getKeyStore().getCertificateChain( signedBy);
+
+				// It's an error if we can't find the 'signedBy' alias
+				if (signers == null) {
+					addMessage(new PolicyException(
+							"Certificate with alias '" + signedBy
+									+ "' not found in keystore "
+									+ keystoreFile));
+				}
+			} catch (Exception e) {
+				addMessage(e);
+			}
+		}
+		return signers;
+	}
+	
+	/**
+	 * <p>Parses permissions from a <code>grant</code> block and returns a PermissionCollection.
+	 * The permissions are extracted from the string portion of the <code>grant</code> 
+	 * statement between braces (<code>{}</code>). Permissions are delimited with a semicolons.
+	 * This method will attempt to load the specified permissions into memory using the
+	 * current ClassLoader. If a particular permission statement contains a 
+	 * <code>signedBy</code> token, this method will also attempt to verify that the 
+	 * Permission was signed by the keystore alias specified in the statement.</p>
+	 * @param permissions the permissions string, which will be parsed into individual permissions
+	 * and parsed. For example, the following string will be parsed as two separate permissions:
+	 * <pre> permission java.util.PropertyPermission "java.version", "read";
+	 * permission java.util.PropertyPermission "java.vendor", "read";</pre>
+	 * @return the instantiated collection of Permissions for the Grantee
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class any of the following permissions:
+     * <ul>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+	 *   <li><code>java.lang.RuntimePermission "getProtectionDomain"</code></li>
+     * </ul>
+     * @param the 
+	 */
+	protected PermissionCollection extractPermissionCollection(String permissions) {
+		String[] p = permissions.split(REGEX_SEMICOLON_DELIMITER);
+		PermissionCollection permissionCollection = new Permissions();
+
+		for (int j = 0; j < p.length; j++) {
+
+			String item = p[j].trim();
+			if (item.startsWith(TOKEN_PERMISSION)) {
+
+				// Look and instantiate the Permisson
+				final String permissionString = item.substring(
+						TOKEN_PERMISSION.length()).trim();
+				Permission permission = null;
+				try {
+					permission = (Permission)AccessController.doPrivileged(new PrivilegedExceptionAction(){
+						public Object run() throws AccessControlException, ClassNotFoundException {
+							return tokenFactory.getPermission(permissionString);
+						}
+					});
+
+					// Verify signature if there is a 'signedBy' clause
+					try {
+						boolean isSigned = (permissionString
+								.indexOf(TOKEN_SIGNEDBY) != -1);
+						if (isSigned && permission != null) {
+							if (!isVerified(permission.getClass())) {
+								addMessage(new PolicyException(
+										"Could not verify permission class signature: "
+												+ permissionString));
+							}
+						}
+					} catch (IOException e) {
+						addMessage(new PolicyException(
+								"Could not instantiate permission: "
+										+ permissionString));
+					}
+					// Add the newly instantiated permission to the grants
+					// collection
+					permissionCollection.add(permission);
+					
+				} catch (PrivilegedActionException e) {
+					addMessage(e.getException());
+				}
+			}
+		}
+		permissionCollection.setReadOnly();
+		return permissionCollection;
+	}
+
+	/**
+	 * Returns <code>true></code> if the security policy file was parsed
+	 * correctly and validated without errors. If the {@link #read()} method has
+	 * not yet been called, this method returns <code>false</code>.
+	 * 
+	 * @return <code>true</code> if the policy file parsed correctly,
+	 * <code>false</code> otherwise
+	 */
+	public boolean isValid() {
+		return validPolicy;
+	}
+
+	/**
+	 * Returns <true>code</code> if a supplied class' {@link CodeSource} is
+	 * digitally signed, and the certificate used to sign it can be found in
+	 * this <code>PolicyReader</code>'s keystore. If the CodeSource is not
+	 * signed, or if a matching certificate cannot be found, this method returns
+	 * <code>false</code>.
+	 * 
+	 * @param clazz
+	 *            the class to verify
+	 * @return the result of the verification operation
+	 * @throws IOException
+	 *             if the keystore cannot be read
+	 * @throws SecurityException
+	 *             if the running SecurityManager denied this ProtectionDomain 
+	 *             the permission <code>java.lang.RuntimePermission "getProtectionDomain"</code>
+	 * @see #getKeyStore()
+	 */
+	public boolean isVerified(Class clazz) throws IOException {
+		Certificate cert = getSigner(clazz);
+		try {
+			Enumeration aliases = getKeyStore().aliases();
+			while (aliases.hasMoreElements()) {
+				String alias = (String) aliases.nextElement();
+				if (keystore.isKeyEntry(alias)) {
+					Certificate keystoreCert = keystore.getCertificate(alias);
+					if (cert.equals(keystoreCert)) {
+						return true;
+					}
+				}
+			}
+		} catch (KeyStoreException e) {
+			throw new IOException(e.getMessage());
+		}
+		return false;
+	}
+
+	/**
+	 * Extracts a substring starting after a given start string. The start
+	 * string <em>must</em>, in fact, start the overall string, and the
+	 * extracted string must be surrounded by double quotes. For example, if
+	 * this method is called with parameters <code>signedBy "testsigner"</code>
+	 * and <code>signedBy</code>, it will return <code>testsigner</code>.
+	 * 
+	 * @param s
+	 *            the string from which to extract the substring
+	 * @param startAfter
+	 *            the start string; if <code>null</code>, the start point
+	 *            will be position 0
+	 * @return the extracted substring
+	 * @throws PolicyException
+	 *             if the string is not well-formed
+	 */
+	private static String extractTarget(String s, String startAfter)
+			throws PolicyException {
+		String s2 = (startAfter == null) ? s : s.substring(startAfter.length())
+				.trim();
+		if (s2.startsWith(DOUBLE_QUOTE) && s2.endsWith(DOUBLE_QUOTE)
+				&& s2.length() > 2) {
+			return s2.substring(1, s2.length() - 1);
+		}
+		throw new PolicyException("Policy string \"" + s
+				+ "\" must be at least one character and surrounded by quotes.");
+	}
+
+}
diff --git a/src/org/freshcookies/security/policy/PrincipalComparator.java b/src/org/freshcookies/security/policy/PrincipalComparator.java
new file mode 100644
index 0000000..c23e9c2
--- /dev/null
+++ b/src/org/freshcookies/security/policy/PrincipalComparator.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.io.Serializable;
+import java.security.Principal;
+import java.text.Collator;
+import java.util.Comparator;
+
+/**
+ * Comparator class for sorting objects of type Principal.
+ * Used for sorting arrays or collections of Principals.
+ * The principals are sorted according to their name values. If
+ * the names are the same, the principal with the first class name
+ * wins.
+ * @author Andrew Jaquith
+ * @version $Revision: 1.1 $ $Date: 2007/02/24 17:27:43 $
+ */
+public class PrincipalComparator 
+    implements Comparator, Serializable 
+{
+    private static final long serialVersionUID = 1L;
+
+    /** Constructs a new PrincipalComparator. */
+    public PrincipalComparator() {
+    	super();
+    }
+    
+    public int compare( Object o1, Object o2 )
+    {
+        Collator collator = Collator.getInstance();
+        if ( o1 instanceof Principal && o2 instanceof Principal )
+        {
+            int comparison = collator.compare( ((Principal)o1).getName(), ((Principal)o2).getName() );
+            if ( comparison == 0 )
+            {
+              return collator.compare(o1.getClass().getName(), o2.getClass().getName());
+            }
+            return comparison;
+        }
+        throw new ClassCastException( "Objects must be of type Principal.");
+    }
+      
+}
diff --git a/src/org/freshcookies/security/policy/SecurityTokenFactory.java b/src/org/freshcookies/security/policy/SecurityTokenFactory.java
new file mode 100644
index 0000000..ded9dfe
--- /dev/null
+++ b/src/org/freshcookies/security/policy/SecurityTokenFactory.java
@@ -0,0 +1,489 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.UnresolvedPermission;
+import java.security.cert.Certificate;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.freshcookies.security.cert.JarHelper;
+
+/**
+ * <p>Utility class that dynamically looks up and returns Permission classes,
+ * Principal classes and CodeSources corresponding to supplied strings. The factory
+ * will attempt to resolve classes by consulting the parent classloader 
+ * first, after which it will consult the URLs supplied to the class 
+ * constructor {@link #SecurityTokenFactory(URL[])}. This allows the 
+ * factory to load classes from arbirary JARs, although be warned that
+ * this is a potential security hazard and should only be used in
+ * carefully controlled situations.</p>
+ * <p>If a SecurityManager is running, the security policy must grant 
+ * this ProtectionDomain's CodeSource, and all preceding callers, 
+ * the following permissions:</p>
+ * <ul>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+ *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+ *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+ * </ul>
+ * <p>...where <em>custom-permission-packages</em> and
+ * <em>custom-principal-packages</em> are the names of
+ * custom {@link java.security.Permission} and {@link java.security.Principal}
+ * classes loaded from external URLs.</p>
+ * <p>In addition, if the <code>urls</code> parameter passed to the constructor is non-<code>null</code>
+ * and has a length of 1 or more, the SecurityManager (if running) will require the
+ * ProtectionDomain for this SecurityTokenFactory and all preceding callers to be 
+ * granted these permissions:</p>
+ * <ul>
+ *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+ *   <li><code>java.io.FilePermission "<em>path-to-url.0</em>", "read"</code></li>
+ *   <li><code>java.io.FilePermission "<em>path-to-url.1</em>", "read"</code></li>
+ *   <li><code>java.io.FilePermission "<em>path-to-url.n</em>", "read"</code></li>
+ * </ul>
+ * <p>... for all file URLs whose names end in <code>.jar</code>. This is so 
+ * that the {@link #getCodeSource(String)} method can successfully resolve and 
+ * verify any jar file signatures.</p>
+ * <p>None of the methods in this class perform their actions inside 
+ * <code>doPrivileged</code> blocks, so all {@link SecurityException} errors
+ * are propagated to callers.</code></p>
+ * @author Andrew Jaquith
+ * @version $Revision: 1.3 $ $Date: 2007/04/09 02:34:52 $
+ */
+public class SecurityTokenFactory {
+
+	/** Constant that represents a single space character. */
+	private static final String ONE_SPACE = " ";
+
+	private static final int NOT_FOUND = -1;
+
+	/** Constant that represents a double-quote character. */
+	private static final String DOUBLE_QUOTE = "\"";
+
+	/**
+	 * Pattern that matches any valid Java type name, minus the
+	 * <code>.java</code> or <code>.class</code> suffix.
+	 */
+	protected static final String REGEX_JAVA_TYPE = "((?:[a-zA-Z0-9$_]+\\.)*[A-Z$_][a-zA-Z0-9$_]*)";
+
+	/**
+	 * Pattern that matches permission string <em>e.g.</em>,
+	 * <code>javax.security.auth.AuthPermission "setLoginConfiguration"</code>.
+	 */
+	protected static final Pattern PERMISSION_PATTERN = Pattern.compile("^"
+			+ REGEX_JAVA_TYPE + "(?: ?\"(.*?)\")??(?: ?, ?\"(.*?)\")??$");
+
+	private final ClassLoader classLoader;
+
+	private final Map cachedCodeSources;
+
+	private final Map cachedPermissions;
+	
+	private final Map cachedPrincipals;
+	
+	private final JarHelper jarHelper;
+	
+	private final Canonicalizer canonicalizer;
+
+	/**
+	 * <p>Constructs a new instance of this class with a supplied set of supplemental URLs for
+	 * locating classes. The supplied URLs are used in addition to the
+	 * parent ClassLoader that instantiated the SecurityTokenFactory.</p>
+	 * <p>If the <code>urls</code> parameter passed to the constructor is non-<code>null</code>
+	 * and has a length of 1 or more, the SecurityManager (if running) will require the
+	 * ProtectionDomain for this SecurityTokenFactory and all preceding callers to be 
+	 * granted these permissions:</p>
+     * <ul>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+     *   <li><code>java.io.FilePermission "<em>path-to-url.0</em>", "read"</code></li>
+     *   <li><code>java.io.FilePermission "<em>path-to-url.1</em>", "read"</code></li>
+     *   <li><code>java.io.FilePermission "<em>path-to-url.n</em>", "read"</code></li>
+     * </ul>
+	 * @param urls
+	 *            the URLs used for resolving classes
+	 * @throws SecurityException if a SecurityManager is running and any required
+	 * permissions were not granted to this Protection Domain and all preceding callers
+	 */
+	public SecurityTokenFactory(URL[] urls) {
+		if (urls != null && urls.length > 0) {
+			this.classLoader = new URLClassLoader(urls);
+		}
+		else {
+			this.classLoader = null;
+		}
+			
+		this.cachedCodeSources = new HashMap();
+		this.cachedPermissions = new HashMap();
+		this.cachedPrincipals = new HashMap();
+		this.canonicalizer = new Canonicalizer();
+		this.jarHelper = new JarHelper();
+	}
+
+	/**
+	 * <p>
+	 * Returns the Principal that corresponds to a supplied String containing
+	 * the name of the Principal class and the Principal's name, separated by
+	 * spaces. This method will attempt to instantiate the class using
+	 * reflection, passing the Principal name into the constructor. If the
+	 * Principal class is not specified, a generic Principal class will be
+	 * instantiated instead.
+	 * </p>
+	 * <p>
+	 * Principal Strings look like this:
+	 * </p>
+	 * <ul>
+	 * <li><code>com.ecyrd.jspwiki.auth.WikiPrincipal "Ernesto"</code></li>
+	 * <li><code>javax.security.auth.kerberos.KerberosPrincipal "Ernesto at example.com"</code></li>
+	 * <li><code>"Ernesto"</code></li>
+	 * </ul>
+	 * 
+	 * @param s
+	 *            the string specifying the Principal class and name
+	 * @return the instantiated Principal
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class (and of all preceding callers):
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class (and of all preceding callers):
+     * <ul>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-principal-packages</em>"</code></li>
+     * </ul>
+	 */
+	public Principal getPrincipal(String s) {
+		
+		// If found in cache, return it
+		if (cachedPrincipals.containsKey(s)) {
+			return (Principal) cachedPrincipals.get(s);
+		}
+		
+		int space = s.indexOf(ONE_SPACE);
+		int quote = s.indexOf(DOUBLE_QUOTE);
+		Principal principal = null;
+
+		// If no principal class supplied, prepend a generic principal class
+		if (space == NOT_FOUND || quote < space) {
+			s = GenericPrincipal.class.getName() + ONE_SPACE + s;
+			space = s.indexOf(ONE_SPACE);
+		}
+
+		// Next, try to instantiate principal class with a 1-arg constructor
+		String principalClass = s.substring(0, space).trim();
+		String principalName = s.substring(principalClass.length()).trim();
+		if (principalName.startsWith(DOUBLE_QUOTE)
+				&& principalName.endsWith(DOUBLE_QUOTE)
+				&& principalName.length() > 2) {
+			principalName = principalName.substring(1,
+					principalName.length() - 1);
+		}
+		try {
+			Class clazz = findClass(principalClass);
+			Constructor c = clazz.getConstructor(new Class[] { String.class });
+			Object p = c.newInstance(new Object[] { principalName });
+			principal = (Principal) p;
+		} catch (Exception e) {
+			principal = new UnresolvedPrincipal(principalClass, principalName,
+					e);
+		}
+		
+		// Stash principal and return it
+		cachedPermissions.put(s, principal);
+		return principal;
+	}
+
+	/**
+	 * Returns the number of Principal objects cached by this factory since
+	 * the last time {@link #reset()} was called.
+	 * @return the number
+	 */
+	public int getPrincipalCount() {
+		return cachedPrincipals.size();
+	}
+	
+	/**
+	 * <p>
+	 * Returns the Permission that corresponds to a supplied String, without
+	 * canonicalizing the Permission prior to returning it. 
+   * See {@link #getPermission(String, boolean)}.
+	 * @see #getPermission(String, boolean)
+	 */
+	public Permission getPermission(String permissionString)
+		throws ClassNotFoundException {
+		return getPermission(permissionString, false);
+	}
+	
+	/**
+	 * <p>
+	 * Returns the Permission that corresponds to a supplied String. The String
+	 * contains the full class name, target and actions, and is formatted
+	 * exactly like a Java policy file grant statement. Permissions must have at
+	 * least a target; actions are optional.
+	 * </p>
+	 * <p>
+	 * Permission strings look like this:
+	 * </p>
+	 * <ul>
+	 * <li><code>java.util.PropertyPermission "java.security.auth.login.config", "write"</code></li>
+	 * <li><code>javax.security.auth.AuthPermission "setLoginConfiguration"</code></li>
+	 * </ul>
+	 * <p>
+	 * Assuming the Permission string is well-formed, this method
+	 * <em>always</em> returns a Permission, even if the Permission cannot be
+	 * located by the classloader. If the Permission class cannot be loaded, the
+	 * returned Permission will be of type
+	 * {@link java.security.UnresolvedPermission}. Permission strings that
+	 * contain just one argument, for example the class name but no target or
+	 * actions, will be unresolved.
+	 * </p>
+	 * <p>If the parameter <code>canonicalize</code> is <code>true</code>, the Permission
+	 * will be canonicalized before it is returned. Specifically, if the Permission is 
+	 * of type {@link java.io.FilePermission}, its target will 
+	 * be the canonical path. Likewise, {@link java.net.SocketPermission} local host names 
+	 * 127.0.0.1 and "" will be converted to <code>localhost</code>.</p>
+	 * 
+	 * @param permissionString
+	 *            the Permission string
+	 * @param canonicalize
+	 *            whether to canonicalize the Permission before returning it
+	 * @return the instantiated Permission
+	 * @throws ClassNotFoundException
+	 *             if the Permission string is malformed
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class (and of all preceding callers):
+     * <ul>
+     *   <li><code>java.lang.RuntimePermission "createClassLoader"</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.java.,javax."</code></li>
+     *   <li><code>java.lang.RuntimePermission "accessClassInPackage.<em>custom-permission-packages</em>"</code></li>
+     * </ul>
+	 */
+	public Permission getPermission(String permissionString, boolean canonicalize)
+			throws ClassNotFoundException {
+
+		// If found in cache, return it
+		if (cachedPermissions.containsKey(permissionString)) {
+			return (Permission) cachedPermissions.get(permissionString);
+		}
+		
+		String permissionClass = null;
+		String target = null;
+		String actions = null;
+
+		// Extract the permission class name, target and actions
+		Matcher m = PERMISSION_PATTERN.matcher(permissionString);
+		if (m.find()) {
+			permissionClass = m.group(1);
+			if (m.group(3) != null) {
+				target = m.group(2);
+				actions = m.group(3);
+			} else if (m.group(2) != null) {
+				target = m.group(2);
+			}
+		} else {
+			throw new ClassNotFoundException("Malformed permission: "
+					+ permissionString);
+		}
+
+		// Try and instantiate the class... if exceptions, return an
+		// UnresolvedPermission
+		Permission perm = null;
+		try {
+			// Find the class we need
+			Class clazz = findClass(permissionClass);
+
+			// Prepare the constructor and arguments
+			Class[] constructorArgClasses = new Class[0];
+			String[] constructorArgs = new String[0];
+
+			if (actions != null) {
+				constructorArgs = new String[] { target, actions };
+				constructorArgClasses = new Class[] { String.class,
+						String.class };
+			} else if (target != null) {
+				constructorArgs = new String[] { target };
+				constructorArgClasses = new Class[] { String.class };
+			}
+			Constructor c = clazz.getConstructor(constructorArgClasses);
+
+			// Instantiate the class
+			perm = (Permission) c.newInstance(constructorArgs);
+		} catch (Exception e) {
+			perm = new UnresolvedPermission(permissionClass, target, actions,
+					null);
+		}
+		
+		// Canonicalize the permission if asked
+		if (canonicalize) {
+			perm = canonicalizer.canonicalize(perm);
+		}
+		
+		// Stash permission and return it
+		cachedPermissions.put(permissionString, perm);
+		return perm;
+	}
+
+	/**
+	 * Returns the number of Permission objects cached by this factory since
+	 * the last time {@link #reset()} was called.
+	 * @return the number
+	 */
+	public int getPermissonCount() {
+		return cachedPermissions.size();
+	}
+	
+  
+  /**
+   * <p>
+   * Returns the CodeSource that corresponds to a supplied String, without
+   * canonicalizing the path prior to returning it. 
+   * See {@link #getCodeSource(String, boolean, boolean)}.
+   * @see #getCodeSource(String, boolean, boolean)
+   */
+  public CodeSource getCodeSource(String path) throws IOException, MalformedURLException {
+    return getCodeSource(path, false);
+  }
+  
+	/**
+	 * <p>Returns the CodeSource corresponding on a specified file path. If the
+	 * path ends in <code>.jar</code>, this method will attempt to load the
+	 * Jar file and instantiate the CodeSource with its associated certificates,
+	 * if possible. To improve performance, CodeSources are cached.</p>
+   * <p>If the parameter <code>canonicalize</code> is <code>true</code>, the path
+   * will be canonicalized before it is returned.</p>
+	 * 
+	 * @param path
+	 *            the absolute path of the jar
+   * @param canonicalize
+   *            whether to canonicalize the Permission before returning it
+	 * @return the CodeSource
+	 * @throws IOException
+	 *            if the file cannot be found in the filesystem
+	 * @throws MalformedURLException
+	 *            if the URL for the CodeSource is malformed
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class (and of all preceding callers):
+     * <ul>
+     *   <li><code>java.io.FilePermission "<em>path</em>", "read"</code></li>
+     *   <li><code>java.net.NetPermission "specifyStreamHandler"</code></li>
+     * </ul>
+     *
+	 */
+	public CodeSource getCodeSource(String path, boolean canonicalize) throws IOException,
+			MalformedURLException {
+		// TODO: determine if this method is really needed...
+		
+		// Trim path to remove file: prefix
+		if (path.startsWith("file:")) {
+			path = path.substring(5);
+		}
+
+		// If found in cache, return it
+		if (cachedCodeSources.containsKey(path)) {
+			return (CodeSource) cachedCodeSources.get(path);
+		}
+
+		// Otherwise: create new code source
+		File file = new File(path);
+		if (!PolicyReader.secureExists(file)) {
+			throw new IOException("Path " + path + " does not exist.");
+		}
+
+    // Canonicalize path if requested
+    if (canonicalize) {
+      path = file.getCanonicalPath();
+    }
+    
+		// If path ends in .jar, try and load the Jar and its certificates
+		CodeSource cs = null;
+		if (path.endsWith(".jar")) {
+			JarFile jar = new JarFile(new File(path));
+			Set certSet = jarHelper.extractSigningCertificates(jar);
+			Certificate[] certs = (Certificate[]) certSet
+					.toArray(new Certificate[certSet.size()]);
+			cs = new CodeSource(new URL("file:" + path), certs);
+		} else {
+			cs = new CodeSource(new URL("file:" + path), new Certificate[0]);
+		}
+    
+		// Stash codesource and return it
+		cachedCodeSources.put(path, cs);
+		return cs;
+	}
+	
+	/**
+	 * Returns the number of CodeSource objects cached by this factory since
+	 * the last time {@link #reset()} was called.
+	 * @return the number
+	 */
+	public int getCodeSourceCount() {
+		// TODO: determine if this method is really needed...
+		return cachedCodeSources.size();
+	}
+
+	/**
+	 * Looks up and returns a Class matching a supplied fully-qualified type
+	 * name. The current ClassLoader is tried first; if not found, the classpath
+	 * supplied in the URLs used to construct this ClassResolver will be tried
+	 * next.
+	 * 
+	 * @param className
+	 *            the name of the Class to find
+	 * @return the resolved Class
+	 * @throws ClassNotFoundException
+	 *             if the class cannot be found
+	 * @throws SecurityException when the SecurityManager, if running, denies 
+	 * the protection domain of this class (and of all preceding callers)
+	 * any of these permissions: <code>java.lang.RuntimePermission "getClassLoader"</code>,
+	 * <code>java.lang.RuntimePermission "accessClassInPackage.<em>package-name-of-className"</em></code>.
+	 */
+	public Class findClass(String className) throws ClassNotFoundException {
+		Class cls = null;
+
+		// Try the parent classloader first
+		try {
+			cls = this.getClass().getClassLoader().loadClass(className);
+			return cls;
+		} catch (ClassNotFoundException e) {
+			// The parent classloader couldn't find it!
+		}
+
+		// Try the URLs supplied in this resolver
+		if (classLoader != null) {
+			return classLoader.loadClass(className);
+		}
+		throw new ClassNotFoundException("Class not found: " + className);
+	}
+	
+	/**
+	 * Flushes the SecurityTokenFactory's caches and resets all counters.
+	 */
+	public synchronized void reset() {
+		cachedCodeSources.clear();
+		cachedPermissions.clear();
+		cachedPrincipals.clear();
+	}
+
+}
diff --git a/src/org/freshcookies/security/policy/UnresolvedPrincipal.java b/src/org/freshcookies/security/policy/UnresolvedPrincipal.java
new file mode 100644
index 0000000..fd38100
--- /dev/null
+++ b/src/org/freshcookies/security/policy/UnresolvedPrincipal.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.freshcookies.security.policy;
+
+import java.security.Principal;
+
+/**
+ * Represents a Principal whose class cannot be resolved by the classloader.
+ * 
+ * @author Andrew Jaquith
+ * @version $Revision: 1.2 $ $Date: 2007/02/24 17:27:43 $
+ */
+public final class UnresolvedPrincipal implements Principal {
+
+  private final String name;
+
+  private final String clazz;
+  
+  private final Exception exception;
+
+  /**
+   * Constructs a new UnresolvedPrincipal.
+   * 
+   * @param clazz the name of the unresolved class
+   * @param name the name of the Principal
+   */
+  public UnresolvedPrincipal(String clazz, String name) {
+	  this(clazz, name, null);
+  }
+  
+  /**
+   * Constructs a new UnresolvedPrincipal.
+   * @param clazz the name of the unresolved class
+   * @param name the name of the Principal
+   * @param e the Exception indicating the reason why the Principal could not be resolved
+   */
+  public UnresolvedPrincipal(String clazz, String name, Exception e)
+  {
+	    this.clazz = clazz;
+	    this.name = name;
+	    this.exception = e;
+  }
+
+  /**
+   * Returns the Exception used to instantiate this UnresolvedPrincipal.
+   * @return the Exception, or <code>null</code> if not constructed with one.
+   */
+  public final Exception getException() {
+	  return exception;
+  }
+  
+  /**
+   * Returns the class of the unresolved Principal as a String.
+   * 
+   * @return the String representation of the unresolved Principal class
+   */
+  public final String getPrincipalClass() {
+    return clazz;
+  }
+
+  /**
+   * Returns the name of the principal.
+   * 
+   * @see java.security.Principal#getName()
+   */
+  public final String getName() {
+    return name;
+  }
+
+  /**
+   * Returns a string representation of this Principal.
+   * 
+   * @see java.lang.Object#toString()
+   */
+  public final String toString() {
+    return "(unresolved " + clazz + " " + name + ")";
+  }
+
+}
diff --git a/src/org/freshcookies/security/policy/package.html b/src/org/freshcookies/security/policy/package.html
new file mode 100644
index 0000000..4f6af6e
--- /dev/null
+++ b/src/org/freshcookies/security/policy/package.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
+<html>
+  <head>
+    <meta name="generator" content=
+    "HTML Tidy for Mac OS X (vers 1st August 2004), see www.w3.org">
+    <title>
+    </title>
+  </head>
+  <body>
+    <p>
+      Utility classes that parse and manipulate Java security policy
+      files.
+    </p>
+    <p>
+      @author Andrew R. Jaquith 
+      @version $Revision: 1.1 $ $Date: 2006/05/02 04:36:39 $
+    </p>
+  </body>
+</html>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jspwiki.git



More information about the pkg-java-commits mailing list