[Fusionforge-commits] FusionForge branch master updated. f15aa645a71cea16d036ef258067271bd788cd9b

Sylvain Beucler beuc-inria at fusionforge.org
Fri Sep 5 19:22:34 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "FusionForge".

The branch, master has been updated
       via  f15aa645a71cea16d036ef258067271bd788cd9b (commit)
       via  29fb2ae673b3c7d49fbc90d4ac02beffc773d2f6 (commit)
       via  e64e202c8676fa70380dbf14045fea9457b615ea (commit)
       via  9a4614ad5b005275092985c554e21ee75fda15b1 (commit)
      from  33544a0acb81f7d3b9dedd2e24a6a12837e6c005 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f15aa645a71cea16d036ef258067271bd788cd9b
Author: Sylvain Beucler <sylvain.beucler at inria.fr>
Date:   Fri Sep 5 18:59:51 2014 +0200

    Use external viewvc - remove bundled one

diff --git a/src/debian/plugins b/src/debian/plugins
index 0eb6176..367a7e6 100644
--- a/src/debian/plugins
+++ b/src/debian/plugins
@@ -2,7 +2,7 @@ Package: fusionforge-plugin-scmgit
 Depends: git, gitweb
 
 Package: fusionforge-plugin-scmsvn
-Depends: subversion, subversion-tools, python-subversion, openbsd-inetd | inet-superserver, update-inetd
+Depends: subversion, subversion-tools, viewvc, openbsd-inetd | inet-superserver, update-inetd
 
 Package: fusionforge-plugin-scmbzr
 Depends: bzr, libapache2-mod-wsgi, loggerhead (>= 1.19~bzr477~), python-pastedeploy
@@ -11,7 +11,7 @@ Package: fusionforge-plugin-scmarch
 Depends: tla
 
 Package: fusionforge-plugin-scmcvs
-Depends: php5-cli, rcs, cvs, python, libphp-snoopy, openbsd-inetd | inet-superserver, update-inetd, libipc-run-perl, liburi-perl, ${perl:Depends}
+Depends: php5-cli, cvs, viewvc, libphp-snoopy, openbsd-inetd | inet-superserver, update-inetd, libipc-run-perl, liburi-perl, ${perl:Depends}
 
 Package: fusionforge-plugin-scmdarcs
 Depends: fusionforge-shell, darcs, darcsweb
diff --git a/src/rpm/plugins b/src/rpm/plugins
index f202e40..5af0034 100644
--- a/src/rpm/plugins
+++ b/src/rpm/plugins
@@ -2,7 +2,7 @@
 Requires: git, gitweb
 
 %package plugin-scmsvn
-Requires: subversion
+Requires: subversion, viewvc
 
 %package plugin-scmbzr
 Requires: bazaar, mod_wsgi, loggerhead
diff --git a/src/www/scm/include/viewvc_utils.php b/src/www/scm/include/viewvc_utils.php
index 0f6600d..85b3247 100644
--- a/src/www/scm/include/viewvc_utils.php
+++ b/src/www/scm/include/viewvc_utils.php
@@ -69,7 +69,6 @@ function make_arg_cmd_safe($arg) {
 function viewcvs_execute($repos_name, $repos_type) {
 	$request_uri = getStringFromServer('REQUEST_URI');
 	$query_string = getStringFromServer('QUERY_STRING');
-	$viewcvs_path = forge_get_config('url_root').'/scm/viewvc';
 
 	// this is very important ...
 	$path = getStringFromServer('PATH_INFO');
@@ -117,8 +116,8 @@ function viewcvs_execute($repos_name, $repos_type) {
 		'REPOSITORY_TYPE="'.$repos_type.'" '.
 		'REPOSITORY_NAME="'.make_arg_cmd_safe($repos_name).'" '.
 		'HTTP_HOST="'.make_arg_cmd_safe(getStringFromServer('HTTP_HOST')).'" '.
-		'DOCROOT="/themes/'.forge_get_config('default_theme').'/viewvc" '.
-		$viewcvs_path.'/bin/cgi/viewvc.cgi 2>&1';
+		'DOCROOT="/scm/viewvc/docroot" '.
+		dirname(__FILE__).'/../viewvc/viewvc.cgi 2>&1';
 
 	ob_start();
 	passthru($command);
diff --git a/src/www/scm/viewvc.php b/src/www/scm/viewvc.php
index e273949..e708383 100644
--- a/src/www/scm/viewvc.php
+++ b/src/www/scm/viewvc.php
@@ -45,8 +45,11 @@ if (!forge_get_config('use_scm')) {
 
 // Get the project name from query
 $projectName = "";
-if(getStringFromGet('root') && strpos(getStringFromGet('root'), ';') === false) {
+if (getStringFromGet('root') && strpos(getStringFromGet('root'), ';') === false) {
 	$projectName = getStringFromGet('root');
+} elseif ($_SERVER['PATH_INFO']) {
+	$arr = explode('/', $_SERVER['PATH_INFO']);
+	$projectName = $arr[1];
 } else {
 	$queryString = getStringFromServer('QUERY_STRING');
 	if(preg_match_all('/[;]?([^\?;=]+)=([^;]+)/', $queryString, $matches, PREG_SET_ORDER)) {
@@ -127,6 +130,8 @@ if ($external_scm) {
 	$content = viewcvs_execute($unix_name, $repos_type);
 }
 
+// TODO: filter output or adapt template to avoid CSS impact on <body>
+
 // Set content type header from the value set by ViewCVS
 // No other headers are generated by ViewCVS because in generate_etags
 // is set to 0 in the ViewCVS config file
diff --git a/src/www/scm/viewvc/CHANGES b/src/www/scm/viewvc/CHANGES
deleted file mode 100644
index 20aba5c..0000000
--- a/src/www/scm/viewvc/CHANGES
+++ /dev/null
@@ -1,172 +0,0 @@
-Version 1.0 (1-May-2006)
-
-  * add support for viewing Subversion repositories
-  * add support for running on MS Windows (2003-Feb-09)
-  * generate strict XHTML output (2005-Sep-08)
-  * add support for caching by sending "Last-Modified", "Expires", 
-    "ETag", and "Cache-Control" headers (2004-Jun-03)
-  * add support for Mod_Python on Apache 2.x and ASP on IIS
-  * Several changes to standalone.py:
-    - -h commandline option to specify hostname for non local use.
-    - -r commandline option may be repeated to use more than repository
-      before actually installing ViewCVS.
-    - New GUI field to test paging.
-  * add new, better-integrated query interface (2004-Jul-17)
-  * add integrated RSS feeds (2005-Dec-22)
-  * add new "root_as_url_component" option to embed root names as
-    path components in ViewCVS URLs for a more natural URL scheme
-    in ViewCVS configurations with multiple repositories.
-    (2002-Dec-12)
-  * add new "use_localtime" option to display local times instead of
-    UTC times (2002-May-06)
-  * add new "root_parents" option to make it possible to add and
-    remove repositories without modifying the ViewCVS configuration
-    (2004-Jul-16)
-  * add new "template_dir" option to facilitate switching between
-    sets of templates (2005-Feb-08)
-  * add new "sort_group_dirs" option to disable grouping of
-    directories in directory listings (2005-Mar-07)
-  * add new "port" option to connect to a MySQL database on a nonstandard
-    port (2005-Dec-22)
-  * make "default_root" option optional. When no root is specified,
-    show a page listing all available repositories (2005-Feb-04)
-  * add "default_file_view" option to make it possible for relative
-    links and image paths in checked out HTML files to work without
-    the need for special /*checkout*/ prefixes in URLs. Deprecate
-    "checkout_magic" option and disable by default (2006-Apr-03)
-  * add "limit_changes" option to limit number of changed files shown
-    per commit by default in query results and in the Subversion revision
-    view (2005-Dec-23)
-  * hide CVS "Attic" directories and add simple toggle for showing
-    dead files in directory listings (2004-Jul-31)
-  * show Unified, Context and Side-by-side diffs in HTML instead of
-    in bare text pages (2004-Jun-22)
-  * make View/Download links work the same for all file types
-    (2004-Jan-21)
-  * add links to tip of selected branch on log page (2005-Oct-03)
-  * allow use of "Highlight" program for colorizing (2005-Dec-20)
-  * enable enscript colorizing for more file types
-  * add sorting arrows for directory views (2004-Jul-21)
-  * get rid of popup windows for checkout links (2004-Jan-21)
-  * obfuscate email addresses in html output by encoding @ symbol
-    with an HTML character reference (2004-Jul-29)
-  * add paging capability (2001-Dec-31)
-  * Improvements to templates
-    - add new template authoring guide
-    - increase coverage, use templates to produce HTML for diff pages,
-      markup pages, annotate pages, and error pages
-    - move more common page elements into includes
-    - add new template variables providing ViewCVS URLs for more 
-      links between related pages and less URL generation inside
-      templates
-  * add new [define] EZT directive for assigning variables within
-    templates (2004-Apr-21)
-  * add command line argument parsing to install script to allow 
-    non-interactive installs (2005-Jan-06)
-  * add stricter parameter validation to lower likelihood of CSS
-    vulnerabilities (2002-May-24)
-  * add support for cvsweb's "mime_type=text/x-cvsweb-markup" URLs
-    (2002-Oct-10)
-  * fix incompatibility with enscript 1.6.3 (2002-Feb-05)
-  * fix bug in parsing FreeBSD rlog output (2003-Jul-24)
-  * work around rlog assumption all two digit years in RCS files are
-    relative to the year 1900. (2005-Sep-30)
-  * change loginfo-handler to cope with spaces in filenames and
-    support a simpler command line invocation from CVS (2003-Feb-11)
-  * make cvsdbadmin work properly when invoked on CVS subdirectory
-    paths instead of top-level CVS root paths (2006-Mar-17)
-  * show diff error when comparing two binary files (2002-Jan-23)
-  * make regular expression search skip binary files (2002-Jan-17)
-  * make regular expression search skip nonversioned files in CVS
-    directories instead of choking on them (2002-Sep-27)
-  * fix tarball generator so it doesn't include forbidden modules
-    (2002-Feb-22)
-  * output "404 Not Found" errors instead of "403 Forbidden" errors
-    to not reveal whether forbidden paths exist (2005-May-17)
-  * fix sorting bug in directory view (2002-Apr-18)
-  * reset log and directory page numbers when leaving those pages
-    (2005-Jan-29)
-  * reset sort direction in directory listing when clicking new
-    columns (2004-Jul-21)
-  * fix "Accept-Language" handling for Netscape 4.x browsers
-    (2002-May-23)
-  * fix file descriptor leak in standalone server (2004-Jul-17)
-  * clean up zombie processes from running enscript (2002-Jun-15)
-  * fix mysql "Too many connections" error in cvsdbadmin (2003-Jul-24)
-  * get rid of mxDateTime dependency for query database (2003-Feb-09)
-  * store query database times in UTC instead of local time
-    (2003-Feb-09)
-  * fix daylight saving time bugs in various parts of the code
-
-Version 0.9.4 (released 17-Aug-2005)
-
-  * security fix: omit forbidden/hidden modules from query results.
-
-Version 0.9.3 (released 17-May-2005)
-
-  * security fix: disallow bad "content-type" input [CAN-2004-1062]
-  * security fix: disallow bad "sortby" and "cvsroot" input [CAN-2002-0771]
-  * security fix: omit forbidden/hidden modules from tarballs [CAN-2004-0915]
-
-Version 0.9.2 (released 15-Jan-2002)
-
-  * fix redirects to Attic for diffs
-  * fix diffs that have no changes (causing an infinite loop)
-
-Version 0.9.1 (released 26-Dec-2001)
-
-  * fix a problem with some syntax in ndiff.py which isn't compatible
-    with Python 1.5.2 (causing problems at install time)
-  * remove a debug statement left in the code which continues to
-    append lines to /tmp/log
-
-Version 0.9 (released 23-Dec-2001)
-
-  * create templates for the rest of the pages: markup pages, graphs,
-    annotation, and diff.
-  * add multiple language support and dynamic selection based on the
-    Accept-Language request header
-  * add support for key/value files to provide a way for user-defined
-    variables within templates
-  * add optional regex searching for file contents
-  * add new templates for the navigation header and the footer
-  * EZT changes:
-    - add formatting into print directives
-    - add parameters to [include] directives
-    - relax what can go in double quotes
-    - [include] directives are now relative to the current template
-    - throw an exception for unclosed blocks
-  * changes to standalone.py: add flag for regex search
-  * add more help pages
-  * change installer to optionally show diffs
-  * fix to log.ezt and log_table.ezt to select "Side by Side" properly
-  * create dir_alternate.ezt for the flipped rev/name links
-  * various UI tweaks for the directory pages
-
-
-Version 0.8 (released 10-Dec-2001)
-
-  * add EZT templating mechanism for generating output pages
-  * big update of cvs commit database
-    - updated MySQL support
-    - new CGI
-    - better database caching
-    - switch from old templates to new EZT templates (and integration
-      of look-and-feel)
-  * optional usage of CVSGraph is now builtin
-  * standalone server (for testing) is now provided
-  * shifted some options from viewcvs.conf to the templates
-  * the help at the top of the pages has been shifted to separate help
-    pages, so experienced users don't have to keep seeing it
-  * paths in viewcvs.conf don't require trailing slashes any more
-  * tweak the colorizing for Pascal and Fortran files
-  * fix file readability problem where the user had access via the
-    group, but the process' group did not match that group
-  * some Daylight Savings Time fixes in the CVS commit database
-  * fix tarball generation (the file name) for the root dir
-  * changed default human-readable-diff colors to "stoplight" metaphor
-  * web site and doc revamps
-  * fix the mime types on the download, view, etc links
-  * improved error response when the cvs root is missing
-  * don't try to process vhosts if the config section is not present
-  * various bug fixes and UI tweaks
diff --git a/src/www/scm/viewvc/COMMITTERS b/src/www/scm/viewvc/COMMITTERS
deleted file mode 100644
index a146415..0000000
--- a/src/www/scm/viewvc/COMMITTERS
+++ /dev/null
@@ -1,27 +0,0 @@
-The following people have commit access to the ViewVC sources.
-Note that this is not a full list of ViewVC's authors, however --
-for that, you'd need to look over the log messages to see all the
-patch contributors.
-
-If you have a question or comment, it's probably best to mail
-dev at viewvc.tigris.org, rather than mailing any of these people
-directly.
-
-        gstein   Greg Stein <gstein at lyra.org>
-        jpaint   Jay Painter <???>
-           akr   Tanaka Akira <???>
-       timcera   Tim Cera <???>
-          pefu   Peter Funk <???>
-       lbruand   Lucas Bruand <???>
-      cmpilato   C. Michael Pilato <cmpilato at collab.net>
-          rey4   Russell Yanofsky <rey4 at columbia.edu>
-        mharig   Mark Harig <???>
-      northeye   Takuo Kitame <???>
-        jamesh   James Henstridge <???>
-          maxb   Max Bowsher <maxb1 at ukf.net>
-            eh   Erik Hülsmann <e.huelsmann at gmx.net>
-
-## Local Variables:
-## coding:utf-8
-## End:
-## vim:encoding=utf8
diff --git a/src/www/scm/viewvc/INSTALL b/src/www/scm/viewvc/INSTALL
deleted file mode 100644
index dc91a8c..0000000
--- a/src/www/scm/viewvc/INSTALL
+++ /dev/null
@@ -1,447 +0,0 @@
-CONTENTS
---------
-  TO THE IMPATIENT
-  INSTALLING VIEWVC
-  APACHE CONFIGURATION
-  UPGRADING VIEWVC
-  SQL CHECKIN DATABASE
-  ENSCRIPT AND HIGHLIGHT CONFIGURATION
-  CVSGRAPH CONFIGURATION
-  IF YOU HAVE PROBLEMS...
-
-
-TO THE IMPATIENT
-----------------
-Congratulations on getting this far. :-)
-
-  Required Software And Configuration Needed To Run ViewVC:
-
-    For CVS Support: 
-
-      * Python 1.5.2 or later
-          (http://www.python.org/)
-      * RCS, Revision Control System
-          (http://www.cs.purdue.edu/homes/trinkle/RCS/)
-      * GNU-diff to replace diff implementations without the -u option
-          (http://www.gnu.org/software/diffutils/diffutils.html)
-      * read-only, physical access to a CVS repository
-          (See http://www.cvshome.org/ for more information)
-
-    For Subversion Support:
-
-      * Python 2.0 or later
-          (http://www.python.org/)
-      * Subversion, Version Control System, 1.2.0 or later
-          (binary installation and Python bindings)
-          (http://subversion.tigris.org/)
-
-    Optional:
-
-      * a web server capable of running CGI programs
-          (for example, Apache at http://httpd.apache.org/)
-      * MySQL 3.22 and MySQLdb 0.9.0 or later to create a commit database
-          (http://www.mysql.com/)
-          (http://sourceforge.net/projects/mysql-python)
-      * Enscript, code colorizer
-          (http://www.codento.com/people/mtr/genscript/)
-      * Highlight, code colorizer, 2.2.10 or later required, 2.4.5 or
-        later recommended for reliable line numbering
-          (http://www.andre-simon.de/)
-      * CvsGraph 1.5.0 or later, graphical CVS revision tree generator
-          (http://www.akhphd.au.dk/~bertho/cvsgraph/)
-
-  GUI Operation:
-
-    If you just want to see what your CVS repository looks like with
-    ViewVC, type "bin/standalone.py -g -r /PATH/TO/CVS/ROOT".  This
-    will start a tiny webserver serving at http://localhost:7467/.
-    PLEASE NOTE: This requires Python with thread support enabled and
-    the Tkinter GUI.  If you don't have one of these, omit the '-g' option.
-
-
-  Standard operation:
-
-    To start installing right away (on UNIX): type "./viewvc-install"
-    in the current directory and answer the prompts.  When it
-    finishes, edit the file viewvc.conf in the installation directory
-    to tell viewvc the paths to your CVS and Subversion repositories. Next,
-    configure your web server to run <INSTALL>/cgi/viewvc.cgi, as
-    appropriate for your web server.  The section `INSTALLING VIEWVC'
-    below is still recommended reading.
-
-
-INSTALLING VIEWVC
-------------------
-
-NOTE: Windows users can refer to windows/README for Windows-specific
-installation instructions.
-
-1) To get viewvc.cgi to work, make sure that you have Python installed
-   and a webserver which is capable of executing CGI scripts (either
-   based on the .cgi extension, or by placing the script within a specific
-   directory).
-
-   Note that to browse CVS repositories, the viewvc.cgi script needs to
-   have READ-ONLY, physical access to the repository (or a copy of it).
-   Therefore, rsh/ssh or pserver access to the repository will not work.
-   And you need to have the RCS utilities installed, specifically "rlog",
-   "rcsdiff", and "co".
-
-2) Installation is handled by the ./viewvc-install script.  Run this
-   script and you will be prompted for a installation root path.
-   The default is /usr/local/viewvc-VERSION, where VERSION is
-   the version of this ViewVC release.  The installer sets the install 
-   path in some of the files, and ViewVC cannot be moved to a 
-   different path after the install.
-
-   Note: while 'root' is usually required to create /usr/local/viewvc,
-   ViewVC does not have to be installed as root, nor does it run as root.
-   It is just as valid to place ViewVC in a home directory, too.
-
-   Note: viewvc-install will create directories if needed. It will
-   prompt before overwriting files that may have been modified (such
-   as viewvc.conf), thus making it safe to install over the top of
-   a previous installation. It will always overwrite program files,
-   however.
-
-3) Edit <VIEWVC_INSTALLATION_DIRECTORY>/viewvc.conf for your specific 
-   configuration.  In particular, examine the following configuration options:
-
-      cvs_roots
-      default_root
-      rcs_path
-      mime_types_file
-
-   There are some other options that are usually nice to change. See
-   viewvc.conf for more information.  ViewVC provides a working,
-   default look. However, if you want to customize the look of ViewVC
-   then edit the files in <VIEWVC_INSTALLATION_DIRECTORY>/templates.
-   You need knowledge about HTML to edit the templates.
-
-4) The CGI programs are in <VIEWVC_INSTALLATION_DIRECTORY>/www/cgi/.  You can 
-   symlink to this directory from somewhere in your published HTTP server 
-   path if your webserver is configured to follow symbolic links.  You can 
-   also copy the installed <VIEWVC_INSTALLATION_DIRECTORY>/www/cgi/*.cgi 
-   scripts after the install (unlike the other files in ViewVC, the scripts 
-   under www/ can be moved).
-
-   If you are using Apache, then see below at the section 
-   titled APACHE CONFIGURATION.
-
-   NOTE: for security reasons, it is not advisable to install ViewVC
-   directly into your published HTTP directory tree (due to the MySQL
-   passwords in viewvc.conf).
-
-5) That's it for repository browsing.  Instructions for getting the
-   SQL checkin database working are below.
-
-
-APACHE CONFIGURATION
---------------------
-
-1) Find out where the web server configuration file is kept. Typical
-   locations are /etc/httpd/httpd.conf, /etc/httpd/conf/httpd.conf,
-   and /etc/apache/httpd.conf. Depending on how apache was installed,
-   you may also look under /usr/local/etc or /etc/local. Use the vendor
-   documentation or the find utility if in doubt.
-
-Either METHOD A: 
-2) The ScriptAlias directive is very useful for pointing 
-   directly to the viewvc.cgi script.  Simply insert a line containing
-
-     ScriptAlias /viewvc <VIEWVC_INSTALLATION_DIRECTORY>/www/cgi/viewvc.cgi
-
-   into your httpd.conf file.  Choose the location in httpd.conf where 
-   also the other ScriptAlias lines reside.  Some examples:
-
-     ScriptAlias /viewvc /usr/local/viewvc-1.0/www/cgi/viewvc.cgi
-     ScriptAlias /query /usr/local/viewvc-1.0/www/cgi/query.cgi
-
-   continue with step 3).
-
-or alternatively METHOD B: 
-2) Copy the CGI scripts from 
-   <VIEWVC_INSTALLATION_DIRECTORY>/www/cgi/*.cgi
-   to the /cgi-bin/ directory configured in your httpd.conf file.
-
-   continue with step 3).
-   
-and then there's METHOD C:
-2) Copy the CGI scripts from 
-   <VIEWVC_INSTALLATION_DIRECTORY>/www/cgi/*.cgi
-   to the directory of your choosing in the Document Root adding the following
-   apache directives for the directory in httpd.conf or an .htaccess file:
-
-     Options +ExecCGI
-     AddHandler cgi-script .cgi
-     
-   (Note: For this to work mod_cgi has to be loaded. And for the .htaccess file
-   to be effective, "AllowOverride All" or "AllowOverride Options FileInfo"
-   need to have been specified for the directory.)
-   
-   continue with step 3).
-
-or if you've got Mod_Python installed you can use METHOD D:
-2) Copy the Python scripts and .htaccess file from 
-   <VIEWVC_INSTALLATION_DIRECTORY>/www/mod_python/
-   to a directory being served by apache.
-   
-   In httpd.conf, make sure that "AllowOverride All" or at least 
-   "AllowOverride FileInfo Options" are enabled for the directory
-   you copied the files to.
-   
-   Note: If you are using Mod_Python under Apache 1.3 the tarball generation
-   and enscript colorizing features may not work because they use
-   multithreading. They do work fine with Apache 2.
-   
-   continue with step 3).
-
-3) Restart apache.  The commands to do this vary.  "httpd -k restart" and 
-   "apache -k restart" are two common variants.  On RedHat Linux it is
-   done using the command "/sbin/service httpd restart" and on SuSE Linux
-   it is done with "rcapache restart" 
-
-4) Optional: Add access control.
-
-   In your httpd.conf you can control access to certain modules by adding 
-   directives like this:
-
-   <Location "<url to viewvc.cgi>/<modname_you_wish_to_access_ctl>">
-     AllowOverride None
-     AuthUserFile /path/to/passwd/file
-     AuthName "Client Access"
-     AuthType Basic
-     require valid-user
-   </Location>
-
-   WARNING: If you enable the "checkout_magic" or "allow_tar" options, you
-   will need to add additional location directives to prevent people
-   from sneaking in with URLs like:
-
-   	http://<server_name>/viewvc/*checkout*/<module_name>
-   	http://<server_name>/viewvc/~checkout~/<module_name>
-   	http://<server_name>/viewvc/<module_name>.tar.gz?view=tar
-
-
-UPGRADING VIEWVC
------------------
-
-Please read the file upgrading.html in the viewvc.org/ subdirectory or
-at <http://viewvc.org/upgrading.html>.
-
-
-SQL CHECKIN DATABASE
---------------------
-
-This feature is a clone of the Mozilla Project's Bonsai database.  It
-catalogs every commit in the CVS or Subversion repository into a SQL
-database.  In fact, the databases are 100% compatible.
-
-Various queries can be performed on the database.  After installing ViewVC,
-there are some additional steps required to get the database working.
-
-1) You need MySQL and MySQLdb (a Python DBAPI 2.0 module) installed.
-
-2) You need to create a MySQL user who has permission to create databases.
-   Optionally, you can create a second user with read-only access to the
-   database.
-
-3) Run the <VIEWVC_INSTALLATION_DIRECTORY>/make-database script.  It will 
-   prompt you for your MySQL user, password, and the name of database you 
-   want to create.  The database name defaults to "ViewVC".  This script 
-   creates the database and sets up the empty tables.  If you run this on a 
-   existing ViewVC database, you will lose all your data!
-
-4) Edit your <VIEWVC_INSTALLATION_DIRECTORY>/viewvc.conf file.  
-   There is a [cvsdb] section.  You will need to set:
-     
-      enabled = 1        # Whether to enable query support in viewvc.cgi
-      host =             # MySQL database server host
-      port =             # MySQL database server port (default is 3306)
-      database_name =    # the name of the database you created with
-                         # make-database
-      user =             # the read/write database user
-      passwd =           # password for read/write database user
-      readonly_user =    # the readonly database user -- it's pretty 
-                         # safe to use the read/write user here
-      readonly_passwd =  # password for the readonly user
-
-5) Two programs are provided for updating the checkin database from a
-   CVS repository, cvsdbadmin and loginfo-handler.  They serve two
-   different purposes.  The cvsdbadmin program walks through your CVS
-   repository and adds every commit in every file.  This is commonly
-   used for initializing the database from a repository which has been
-   in use.  The loginfo-handler script is executed by the CVS server's
-   CVSROOT/loginfo system upon each commit.  It makes real-time
-   updates to the checkin database as commits are made to the
-   repository.
-
-   To build a database of all the commits in the CVS repository /home/cvs,
-   invoke: "./cvsdbadmin rebuild /home/cvs".  If you want to update
-   the checkin database, invoke: "./cvsdbadmin update /home/cvs".  The
-   update mode checks to see if a commit is already in the database,
-   and only adds it if it is absent.
-
-   To get real-time updates, you'll want to checkout the CVSROOT module
-   from your CVS repository and edit CVSROOT/loginfo.  Add the line:
-
-     ALL <VIEWVC_INSTALLATION_DIRECTORY>/loginfo-handler %{sVv}
-
-   If you have other scripts invoked by CVSROOT/loginfo, you will want
-   to make sure to change any running under the "DEFAULT" keyword to
-   "ALL" like the loginfo handler, and probably carefully read the
-   execution rules for CVSROOT/loginfo from the CVS manual.
-
-   If you are running the Unix port of CVS-NT, you'll need to use a 
-   slightly different command line:
-   
-     ALL <VIEWVC_INSTALLATION_DIRECTORY>/loginfo-handler %{sVv} cvsnt
-     
-   The extra 'cvsnt' parameter tells the handler script to parse the 
-   commit information in a different way. 
-
-   For Subversion repositories, there is a single script called
-   svndbadmin that performs both of the above tasks.
-
-   To build a database of all the commits in the Subversion repository
-   /home/svn, invoke: "./svndbadmin rebuild /home/svn".  If you want
-   to update the checkin database, invoke: "./svndbadmin update
-   /home/svn".
-
-   To get real time updates, you will need to add a post-commit hook
-   (for the repository example above, the script should go in
-   /home/svn/hooks/post-commit).  The script should look something
-   like this:
-
-     #!/bin/sh
-     REPOS="$1"
-     REV="$2"
-     <VIEWVC_INSTALLATION_DIRECTORY>/svndbadmin rebuild "$REPOS" "$REV"
-
-   If you allow revision property changes in your repository, create a
-   post-revprop-change hook script containing the same commands as the
-   post-commit one.  This will make sure that the checkin database
-   stays consistent when you change the svn:log, svn:author or
-   svn:date revision properties.
-
-6) You should be ready to go.  Click one of the "Query revision history"
-   links in ViewVC directory listings and give it a try.
-
-
-ENSCRIPT AND HIGHLIGHT CONFIGURATION
-------------------------------------
-
-Enscript and Highlight are programs that can colorize source code for
-a lot of languages. ViewVC can be configured to use either one.
-
-1) Install Enscript or Highlight using your system's package manager
-   or downloading from the project home pages.
-
-2) Set the 'use_enscript' or 'use_highlight' options in viewvc.conf to 1.
-
-3) You may also need to set 'enscript_path' and 'highlight_path' options
-   if the executables are not located on the system PATH.
-
-4) That's it!
-
-
-CVSGRAPH CONFIGURATION
-----------------------
-
-CvsGraph is a program that can display a clickable, graphical tree
-of files in a CVS repository.
-
-WARNING: Under certain circumstances (many revisions of a file
-or many branches or both) CvsGraph can generate very huge images.
-Especially on thin clients these images may crash the Web-Browser.
-Currently there is no known way to avoid this behavior of CvsGraph.
-So you have been warned!  
-
-Nevertheless, CvsGraph can be quite helpful on repositories with 
-a reasonable number of revisions and branches.
-
-1) Install CvsGraph using your system's package manager or downloading
-   from the project home page.
-
-2) Set the 'use_cvsgraph' options in viewvc.conf to 1.
-
-3) You may also need to set the 'cvsgraph_path' option if the 
-   CvsGraph executable is not located on the system PATH.
-
-4) There is a file <VIEWVC_INSTALLATION_DIRECTORY>/cvsgraph.conf that
-   you may want to edit if desired to set color and font characteristics.
-   See the cvsgraph.conf documentation.  No edits are required in
-   cvsgraph.conf for operation with viewvc.
-
-
-SUBVERSION INTEGRATION
-----------------------
-
-ViewVC supports browsing of Subversion repositories.  To use ViewVC
-with Subversion, make sure you have both Subversion itself and
-the Subversion Python bindings installed.  See Subversion's
-installation notes for more details on how to build and install these
-items.  
-
-Generally speaking, you'll know when your installation of Subversion's
-bindings has been successful if you can import the 'svn.repos' module
-from within your Python interpreter:
-
-   % python
-   Python 2.2.2 (#1, Oct 29 2002, 02:47:30) 
-   [GCC 2.96 20000731 (Red Hat Linux 7.2 2.96-108.7.2)] on linux2
-   Type "help", "copyright", "credits" or "license" for more information.
-   >>> import svn.repos
-   >>> 
-
-Note that by default, Subversion installs its bindings in a location
-that is not in Python's default module search path (for example, on
-Linux systems the default is usually /usr/local/lib/svn-python).  You
-need to remedy this, either by adding this path to Python's module
-search path, or by relocation the bindings to some place in that
-search path.
-
-Configuration of the Subversion repositories happens in much the same
-way as with CVS repositories, only with the 'svn_roots' configuration
-variable instead of the 'cvs_roots' one.
-
-
-IF YOU HAVE PROBLEMS ...
-------------------------
-
-If you've trouble to make viewvc.cgi work:
-
-=== If nothing seems to work:
-
- o check if you can execute CGI-scripts (Apache needs to have an
-   ScriptAlias /cgi-bin or cgi-script Handler defined). Try to 
-   execute a simple CGI-script that often comes with the distribution
-   of the webserver; locate the logfiles and try to find hints
-   which explain the malfunction
-
- o view the entries in the webserver's error.log
- 
-=== If viewvc seems to work but doesn't show the expected result
-    (Typical error: you can't see any files)
-
- o check whether the CGI-script has read-permissions to your
-   CVS-Repository. The CGI-script often runs as the user 'nobody' 
-   or 'httpd' ..
-
- o does viewvc find your RCS utilities? (edit rcs_path)
-
-=== If something else happens or you can't get it to work:
-
- o check the ViewVC home page:
-
-     http://viewvc.org/
-
- o review the ViewVC mailing list archive to see if somebody else had
-   the same problem, and it was solved:
-
-     http://viewvc.tigris.org/servlets/SummarizeList?listName=users
-
- o send mail to the ViewVC mailing list: users at viewvc.tigris.org
-
-   NOTE: make sure you provide an accurate description of the problem
-         and any relevant tracebacks or error logs.
diff --git a/src/www/scm/viewvc/README b/src/www/scm/viewvc/README
deleted file mode 100644
index 26ee5de..0000000
--- a/src/www/scm/viewvc/README
+++ /dev/null
@@ -1,6 +0,0 @@
-ViewVC -- Viewing the content of CVS/SVN repositories with a Webbrowser.
-
-Please read the file INSTALL for more information.
-
-And see windows/README for more information on running ViewVC on
-Microsoft Windows.
diff --git a/src/www/scm/viewvc/TODO b/src/www/scm/viewvc/TODO
deleted file mode 100644
index c9c36e2..0000000
--- a/src/www/scm/viewvc/TODO
+++ /dev/null
@@ -1,53 +0,0 @@
-PREFACE
--------
-This file will go away soon after release 0.8.  Please use the SourceForge 
-tracker to resubmit any of the items listed below, if you think, it is 
-still an issue:  
-	http://sourceforge.net/tracker/?group_id=18760
-Before reporting please check, whether someone else has already done this.
-Working patches increase the chance to be included into the next release.
-                                                     -- PeFu / October 2001
-
-TODO ITEMS
-----------
-*) add Tamminen Eero's comments on how to make Linux directly execute
-   the Python script. From email on Feb 19.
-   [ add other examples, such as my /bin/sh hack or the teeny CGI stub 
-     importing the bulk hack ]
-
-*) insert rcs_path into PATH before calling "rcsdiff". rcsdiff might
-   use "co" and needs to find it on the path.
-
-*) show the "locked" flag (attach it to the LogEntry objects).
-   Idea from Russell Gordon <russell at hoopscotch.dhs.org>
-
-*) committing with a specific revision number:
-   http://mailman.lyra.org/pipermail/viewcvs/2000q1/000008.html
-
-*) add capability similar to cvs2cl.pl:
-     http://mailman.lyra.org/pipermail/viewcvs/2000q2/000050.html
-   suggestion from Chris Meyer <cmeyer at gatan.com>.
-
-*) add a tree view of the directory structure (and files?)
-
-*) include a ConfigParser.py to help older Python installations
-
-*) add a check for the rcs programs/paths to viewvc-install. clarify the
-   dependency on RCS in the docs.
-
-*) have a "check" mode that verifies binaries are available on rcs_path
-
-   -> alternately (probably?): use rcsparse rather than external tools
-
-KNOWN BUGS
-----------
-*) time.timezone seems to not be available on some 1.5.2 installs.
-   I was unable to verify this.  On RedHat and SuSE Linux this bug
-   is non existant.
-
-*) With old repositories containing many branches, tags or thousands
-   or revisions, the cvsgraph feature becomes unusable (see INSTALL).
-   ViewVC can't do much about this, but it might be possible to
-   investigate the number of branches, tags and revision in advance
-   and disable the cvsgraph links, if the numbers exceed a certain
-   treshold.
diff --git a/src/www/scm/viewvc/bin/asp/query.asp b/src/www/scm/viewvc/bin/asp/query.asp
deleted file mode 100644
index 1713579..0000000
--- a/src/www/scm/viewvc/bin/asp/query.asp
+++ /dev/null
@@ -1,61 +0,0 @@
-<%@ LANGUAGE = Python %>
-<%
-
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# query.asp: View CVS/SVN commit database by web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) query.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-
-if LIBRARY_DIR:
-  if not LIBRARY_DIR in sys.path:
-    sys.path.insert(0, LIBRARY_DIR)
-
-#########################################################################
-
-import sapi
-import viewvc
-import query
-
-server = sapi.AspServer(Server, Request, Response, Application)
-try:
-  cfg = viewvc.load_config(CONF_PATHNAME, server)
-  query.main(server, cfg, "viewvc.asp")
-finally:
-  s.close()
-
-%>
diff --git a/src/www/scm/viewvc/bin/asp/viewvc.asp b/src/www/scm/viewvc/bin/asp/viewvc.asp
deleted file mode 100644
index 57fa1b6..0000000
--- a/src/www/scm/viewvc/bin/asp/viewvc.asp
+++ /dev/null
@@ -1,65 +0,0 @@
-<%@ LANGUAGE = Python %>
-<%
-
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# viewvc: View CVS/SVN repositories via a web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) viewvc.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-
-if LIBRARY_DIR:
-  if not LIBRARY_DIR in sys.path:
-    sys.path.insert(0, LIBRARY_DIR)
-
-#########################################################################
-
-### add code for checking the load average
-
-#########################################################################
-
-# go do the work
-import sapi
-import viewvc
-
-server = sapi.AspServer(Server, Request, Response, Application)
-try:
-  cfg = viewvc.load_config(CONF_PATHNAME, server)
-  viewvc.main(server, cfg)
-finally:
-  s.close()
-
-%>
diff --git a/src/www/scm/viewvc/bin/cgi/query.cgi b/src/www/scm/viewvc/bin/cgi/query.cgi
deleted file mode 100755
index cbdd206..0000000
--- a/src/www/scm/viewvc/bin/cgi/query.cgi
+++ /dev/null
@@ -1,57 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# query.cgi: View CVS/SVN commit database by web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) viewvc.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-import os
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-else:
-  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0],
-                                                  "../../../lib")))
-
-#########################################################################
-
-import sapi
-import viewvc
-import query
-
-server = sapi.CgiServer()
-cfg = viewvc.load_config(CONF_PATHNAME, server)
-query.main(server, cfg, "viewvc.cgi")
diff --git a/src/www/scm/viewvc/bin/cgi/viewvc-strace.sh b/src/www/scm/viewvc/bin/cgi/viewvc-strace.sh
deleted file mode 100755
index f9606f8..0000000
--- a/src/www/scm/viewvc/bin/cgi/viewvc-strace.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-#
-# Set this script up with something like:
-#
-#   ScriptAlias /viewvc-strace /home/gstein/src/viewvc/cgi/viewvc-strace.sh
-#
-thisdir="`dirname $0`"
-exec strace -q -r -o /tmp/v-strace.log "${thisdir}/viewvc.cgi"
diff --git a/src/www/scm/viewvc/bin/cgi/viewvc.cgi b/src/www/scm/viewvc/bin/cgi/viewvc.cgi
deleted file mode 100755
index 25d374a..0000000
--- a/src/www/scm/viewvc/bin/cgi/viewvc.cgi
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# viewvc: View CVS/SVN repositories via a web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) viewvc.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-# THIS CONFIGURATION FILE HAS BEEN MODIFIED WITH THE PURPOSE OF
-# INTEGRATING VIEWVC WITH GFORGE.
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-#LIBRARY_DIR = None
-#CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-import os
-
-#if LIBRARY_DIR:
-#  sys.path.insert(0, LIBRARY_DIR)
-#else:
-#  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0],
-#                                                  "../../../lib")))
-
-sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], "../../../lib")))
-CONF_PATHNAME = os.path.abspath(os.path.join(sys.argv[0], "../../../viewvc.conf"))
-
-
-#########################################################################
-
-### add code for checking the load average
-
-#########################################################################
-
-# go do the work
-import sapi
-import viewvc
-
-server = sapi.CgiServer()
-
-# read the main configuration
-cfg = viewvc.load_config(CONF_PATHNAME, server)
-
-# BEGIN OF GForge customization
-
-# Read the repository root dir from the environment.
-# This way, we will only have ONE repository configured (the one we're browsing). This 
-# is more secure than having one (CVS|SVN) root configured with all the repositories inside
-
-if os.environ["REPOSITORY_TYPE"] == 'cvs':
-  cfg.general.cvs_roots[os.environ["REPOSITORY_NAME"]] = os.environ["REPOSITORY_ROOT"]
-elif os.environ["REPOSITORY_TYPE"] == 'svn':
-  cfg.general.svn_roots[os.environ["REPOSITORY_NAME"]] = os.environ["REPOSITORY_ROOT"]
-
-cfg.general.address = "<a href='mailto:root@"+os.environ["HTTP_HOST"]+"'>root@" + os.environ["HTTP_HOST"]+ "</a>"
-cfg.options.docroot = os.environ["DOCROOT"]
-
-# END OF GForge customization
-
-viewvc.main(server, cfg)
diff --git a/src/www/scm/viewvc/bin/cvsdbadmin b/src/www/scm/viewvc/bin/cvsdbadmin
deleted file mode 100755
index c5d0bee..0000000
--- a/src/www/scm/viewvc/bin/cvsdbadmin
+++ /dev/null
@@ -1,157 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# administrative program for CVSdb; this is primarily
-# used to add/rebuild CVS repositories to the database
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-# Adjust sys.path to include our library directory
-import sys
-import os
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-else:
-  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], "../../lib")))
-
-#########################################################################
-  
-import os
-import string
-import cvsdb
-import viewvc
-import vclib.bincvs
-
-
-def UpdateFile(db, repository, path, update):
-    try:
-        if update:
-            commit_list = cvsdb.GetUnrecordedCommitList(repository, path, db)
-        else:
-            commit_list = cvsdb.GetCommitListFromRCSFile(repository, path)
-    except cvsdb.error, e:
-        print '[ERROR] %s' % (e)
-        return
-
-    file = string.join(path, "/")
-    if update:
-       print '[%s [%d new commits]]' % (file, len(commit_list)),
-    else:
-       print '[%s [%d commits]]' % (file, len(commit_list)),
-
-    ## add the commits into the database
-    for commit in commit_list:
-        db.AddCommit(commit)
-        sys.stdout.write('.')
-        sys.stdout.flush()
-    print
-
-
-def RecurseUpdate(db, repository, directory, update):
-    for entry in repository.listdir(directory, None, {}):
-        path = directory + [entry.name]
-
-        if entry.errors:
-            continue
-
-        if entry.kind is vclib.DIR:
-            RecurseUpdate(db, repository, path, update)
-            continue
-
-        if entry.kind is vclib.FILE:
-            UpdateFile(db, repository, path, update)
-
-def RootPath(path):
-    """Break os path into cvs root path and other parts"""
-    root = os.path.abspath(path)
-    path_parts = []
-
-    p = root
-    while 1:
-        if os.path.exists(os.path.join(p, 'CVSROOT')):
-            root = p
-            print "Using repository root `%s'" % root
-            break
-
-        p, pdir = os.path.split(p)
-        if not pdir:
-            del path_parts[:]
-            print "Using repository root `%s'" % root
-            print "Warning: CVSROOT directory not found."
-            break
-
-        path_parts.append(pdir)
-
-    root = cvsdb.CleanRepository(root)
-    path_parts.reverse()
-    return root, path_parts
-
-def usage():
-    print 'Usage: %s <command> [arguments]' % (sys.argv[0])
-    print 'Performs administrative functions for the CVSdb database'
-    print 'Commands:'
-    print '  rebuild <repository>            rebuilds the CVSdb database'
-    print '                                  for all files in the repository'
-    print '  update <repository>             updates the CVSdb database for'
-    print '                                  all unrecorded commits'
-    print
-    sys.exit(1)
-
-
-## main
-if __name__ == '__main__':
-    ## check that a command was given
-    if len(sys.argv) <= 2:
-        usage()
-
-    ## set the handler function for the command
-    command = sys.argv[1]
-    if string.lower(command) == 'rebuild':
-        update = 0
-    elif string.lower(command) == 'update':
-        update = 1
-    else:
-        print 'ERROR: unknown command %s' % (command)
-        usage()
-
-    # get repository path
-    root, path_parts = RootPath(sys.argv[2])
-
-    ## run command
-    try:
-      ## connect to the database we are updating
-      cfg = viewvc.load_config(CONF_PATHNAME)
-      db = cvsdb.ConnectDatabase(cfg)
-
-      repository = vclib.bincvs.BinCVSRepository(None, root, cfg.general)
-
-      RecurseUpdate(db, repository, path_parts, update)
-
-    except KeyboardInterrupt:
-        print
-        print '** break **'
-        
-    sys.exit(0)
diff --git a/src/www/scm/viewvc/bin/loginfo-handler b/src/www/scm/viewvc/bin/loginfo-handler
deleted file mode 100755
index 3dfad38..0000000
--- a/src/www/scm/viewvc/bin/loginfo-handler
+++ /dev/null
@@ -1,275 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# updates SQL database with new commit records
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-# Adjust sys.path to include our library directory
-import sys
-import os
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-else:
-  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], "../../lib")))
-
-#########################################################################
-
-import os
-import string
-import getopt
-import re
-import cvsdb
-import viewvc
-import vclib.bincvs
-
-DEBUG_FLAG = 0
-
-## output functions
-def debug(text):
-    if DEBUG_FLAG:
-        print 'DEBUG(viewvc-loginfo):', text
-
-def warning(text):
-    print 'WARNING(viewvc-loginfo):', text
-
-def error(text):
-    print 'ERROR(viewvc-loginfo):', text
-    sys.exit(1)
-
-_re_revisions = re.compile(                            
-  r",(?P<old>(?:\d+\.\d+)(?:\.\d+\.\d+)*|NONE)"  # comma and first revision number
-  r",(?P<new>(?:\d+\.\d+)(?:\.\d+\.\d+)*|NONE)"  # comma and second revision number
-  r"(?:$| )"                                # space or end of string
-)    
-
-def HeuristicArgParse(s, repository):
-  """Current versions of CVS (except for CVSNT) do not escape spaces in file
-  and directory names that are passed to the loginfo handler. Since the input
-  to loginfo is a space separated string, this can lead to ambiguities. This
-  function attempts to guess intelligently which spaces are separators and
-  which are part of file or directory names. It disambiguates spaces in
-  filenames from the separator spaces between files by assuming that every
-  space which is preceded by two well-formed revision numbers is in fact a 
-  separator. It disambiguates the first separator space from spaces in the 
-  directory name by choosing the longest possible directory name that actually
-  exists in the repository"""
-
-  if s[-16:] == ' - New directory':
-    return None, None
-
-  if s[-19:] == r' - Imported sources':
-    return None, None
-
-  file_data_list = []
-  start = 0
-
-  while 1:
-    m = _re_revisions.search(s, start)
-
-    if start == 0:
-      if m is None: 
-        error('Argument "%s" does not contain any revision numbers' % s)
-    
-      directory, filename = FindLongestDirectory(s[:m.start()], repository)
-      if directory is None:
-        error('Argument "%s" does not start with a valid directory' % s)
-
-      debug('Directory name is "%s"' % directory)
-
-    else:
-      if m is None:
-        warning('Failed to interpret past position %i in the loginfo argument, '
-          'leftover string is "%s"' % start, pos[start:])
-      
-      filename = s[start:m.start()]
-      
-    old_version, new_version = m.group('old', 'new')
-
-    file_data_list.append((filename, old_version, new_version))
-
-    debug('File "%s", old revision %s, new revision %s' 
-      % (filename, old_version, new_version))
-
-    start = m.end()
-    
-    if start == len(s): break
-
-  return directory, file_data_list
-
-def FindLongestDirectory(s, repository):
-  """Splits the first part of the argument string into a directory name
-  and a file name, either of which may contain spaces. Returns the longest
-  possible directory name that actually exists"""
-
-  parts = string.split(s, " ")
-  
-  for i in range(len(parts)-1, 0, -1):
-    directory = string.join(parts[:i])
-    filename = string.join(parts[i:])
-    if os.path.isdir(os.path.join(repository, directory)):
-      return directory, filename
-  
-  return None, None
-
-_re_cvsnt_revisions = re.compile(                            
-  r"(?P<filename>.*)"                      # comma and first revision number
-  r",(?P<old>(?:\d+\.\d+)(?:\.\d+\.\d+)*|NONE)"  # comma and first revision number
-  r",(?P<new>(?:\d+\.\d+)(?:\.\d+\.\d+)*|NONE)"  # comma and second revision number
-  r"$"                                       # end of string
-)
-
-def CvsNtArgParse(s, repository):
-  """CVSNT escapes all spaces in filenames and directory names with 
-  backslashes"""
-
-  if s[-18:] == r' -\ New\ directory':
-    return None, None
-
-  if s[-21:] == r' -\ Imported\ sources':
-    return None, None
-
-  file_data_list = []
-
-  directory, pos = NextFile(s)
-  
-  debug('Directory name is "%s"' % directory)
-
-  while 1:
-    fileinfo, pos = NextFile(s, pos)
-    if fileinfo is None:
-      break
-
-    m = _re_cvsnt_revisions.match(fileinfo)
-    if m is None:
-      warning('Can\'t parse file information in "%s"' % fileinfo)
-      continue
-
-    file_data = m.group('filename', 'old', 'new')
-
-    debug('File "%s", old revision %s, new revision %s' % file_data)
-
-    file_data_list.append(file_data)
-
-  return directory, file_data_list
-
-def NextFile(s, pos = 0):
-  escaped = 0
-  ret = ''
-  i = pos
-  while i < len(s):
-    c = s[i]
-    if escaped:
-      ret += c
-      escaped = 0
-    elif c == '\\':
-      escaped = 1
-    elif c == ' ':
-      return ret, i + 1
-    else:
-      ret += c
-    i += 1
-
-  return ret or None, i
-
-def ProcessLoginfo(rootpath, directory, files):
-    cfg = viewvc.load_config(CONF_PATHNAME)
-    db = cvsdb.ConnectDatabase(cfg)
-    repository = vclib.bincvs.BinCVSRepository(None, rootpath, cfg.general)
-
-    # split up the directory components
-    dirpath = filter(None, string.split(os.path.normpath(directory), os.sep))
-
-    ## build a list of Commit objects
-    commit_list = []
-    for filename, old_version, new_version in files:
-        filepath = dirpath + [filename]
-
-        ## XXX: this is nasty: in the case of a removed file, we are not
-        ##      given enough information to find it in the rlog output!
-        ##      So instead, we rlog everything in the removed file, and
-        ##      add any commits not already in the database
-        if new_version == 'NONE':
-            commits = cvsdb.GetUnrecordedCommitList(repository, filepath, db)
-        else:
-            commits = cvsdb.GetCommitListFromRCSFile(repository, filepath,
-                                                     new_version)
-
-        commit_list.extend(commits)
-
-    ## add to the database
-    db.AddCommitList(commit_list)
-
-
-## MAIN
-if __name__ == '__main__':
-    ## get the repository from the environment
-    try:
-        repository = os.environ['CVSROOT']
-    except KeyError:
-        error('CVSROOT not in environment')
-
-    debug('Repository name is "%s"' % repository)
-
-    ## parse arguments
-    if len(sys.argv) > 1:
-        # the first argument should contain file version information
-        arg = sys.argv[1]
-    else:
-        # if there are no arguments, read version information from first line
-        # of input like old versions of viewcvs
-        arg = string.rstrip(sys.stdin.readline())
-
-    if len(sys.argv) > 2:
-        # if there is a second argument it indicates which parser should be
-        # used to interpret the version information
-        if sys.argv[2] == 'cvs':
-          fun = HeuristicArgParse
-        elif sys.argv[2] == 'cvsnt':
-          fun = CvsNtArgParse
-        else:
-          error('Bad arguments')
-    else:
-        # if there is no second argument, guess which parser to use based
-        # on the operating system. Since CVSNT now runs on Windows and
-        # Linux, the guess isn't neccessarily correct
-        if sys.platform == "win32":
-          fun = CvsNtArgParse
-        else:
-          fun = HeuristicArgParse
-    
-    if len(sys.argv) > 3:
-        error('Bad arguments')
-
-    repository = cvsdb.CleanRepository(repository)
-    directory, files = fun(arg, repository)
-
-    if files is None:
-      debug('Not a checkin, nothing to do')
-    else:
-      ProcessLoginfo(repository, directory, files)
-
-    sys.exit(0)
diff --git a/src/www/scm/viewvc/bin/make-database b/src/www/scm/viewvc/bin/make-database
deleted file mode 100755
index 1764c31..0000000
--- a/src/www/scm/viewvc/bin/make-database
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# administrative program for CVSdb; creates a clean database in
-# MySQL 3.22 or later
-#
-# -----------------------------------------------------------------------
-
-import os, sys, string
-import popen2
-
-INTRO_TEXT = """\
-This script creates the database and tables in MySQL used by the ViewVC
-checkin database.  You will be prompted for: database user, database user
-password, and database name.  This script will use mysql to create the
-database for you.  You will then need to set the appropriate parameters
-in your viewvc.conf file under the [cvsdb] section.
-"""
-
-DATABASE_SCRIPT="""\
-DROP DATABASE IF EXISTS <dbname>;
-CREATE DATABASE <dbname>;
-
-USE <dbname>;
-
-DROP TABLE IF EXISTS branches;
-CREATE TABLE branches (
-  id mediumint(9) NOT NULL auto_increment,
-  branch varchar(64) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE branch (branch)
-);
-
-DROP TABLE IF EXISTS checkins;
-CREATE TABLE checkins (
-  type enum('Change','Add','Remove'),
-  ci_when datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
-  whoid mediumint(9) DEFAULT '0' NOT NULL,
-  repositoryid mediumint(9) DEFAULT '0' NOT NULL,
-  dirid mediumint(9) DEFAULT '0' NOT NULL,
-  fileid mediumint(9) DEFAULT '0' NOT NULL,
-  revision varchar(32) binary DEFAULT '' NOT NULL,
-  stickytag varchar(255) binary DEFAULT '' NOT NULL,
-  branchid mediumint(9) DEFAULT '0' NOT NULL,
-  addedlines int(11) DEFAULT '0' NOT NULL,
-  removedlines int(11) DEFAULT '0' NOT NULL,
-  descid mediumint(9),
-  UNIQUE repositoryid (repositoryid,dirid,fileid,revision),
-  KEY ci_when (ci_when),
-  KEY whoid (whoid),
-  KEY repositoryid_2 (repositoryid),
-  KEY dirid (dirid),
-  KEY fileid (fileid),
-  KEY branchid (branchid)
-);
-
-DROP TABLE IF EXISTS descs;
-CREATE TABLE descs (
-  id mediumint(9) NOT NULL auto_increment,
-  description text,
-  hash bigint(20) DEFAULT '0' NOT NULL,
-  PRIMARY KEY (id),
-  KEY hash (hash)
-);
-
-DROP TABLE IF EXISTS dirs;
-CREATE TABLE dirs (
-  id mediumint(9) NOT NULL auto_increment,
-  dir varchar(255) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE dir (dir)
-);
-
-DROP TABLE IF EXISTS files;
-CREATE TABLE files (
-  id mediumint(9) NOT NULL auto_increment,
-  file varchar(255) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE file (file)
-);
-
-DROP TABLE IF EXISTS people;
-CREATE TABLE people (
-  id mediumint(9) NOT NULL auto_increment,
-  who varchar(32) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE who (who)
-);
-
-DROP TABLE IF EXISTS repositories;
-CREATE TABLE repositories (
-  id mediumint(9) NOT NULL auto_increment,
-  repository varchar(64) binary DEFAULT '' NOT NULL,
-  PRIMARY KEY (id),
-  UNIQUE repository (repository)
-);
-
-DROP TABLE IF EXISTS tags;
-CREATE TABLE tags (
-  repositoryid mediumint(9) DEFAULT '0' NOT NULL,
-  branchid mediumint(9) DEFAULT '0' NOT NULL,
-  dirid mediumint(9) DEFAULT '0' NOT NULL,
-  fileid mediumint(9) DEFAULT '0' NOT NULL,
-  revision varchar(32) binary DEFAULT '' NOT NULL,
-  UNIQUE repositoryid (repositoryid,dirid,fileid,branchid,revision),
-  KEY repositoryid_2 (repositoryid),
-  KEY dirid (dirid),
-  KEY fileid (fileid),
-  KEY branchid (branchid)
-);
-"""
-
-if __name__ == "__main__":
-    print INTRO_TEXT
-    
-    user = raw_input("MySQL User: ")
-    passwd = raw_input("MySQL Password: ")
-    dbase = raw_input("ViewVC Database Name [default: ViewVC]: ")
-    if not dbase:
-        dbase = "ViewVC"
-
-    dscript = string.replace(DATABASE_SCRIPT, "<dbname>", dbase)
-
-    if sys.platform == "win32":
-      # popen2.Popen3 is not provided on windows
-      cmd = "mysql --user=%s --password=%s" % (user, passwd)
-      mysql = os.popen(cmd, "w")
-      mysql.write(dscript)
-      status = mysql.close()
-    else:
-      cmd = "{ mysql --user=%s --password=%s ; } 2>&1" % (user, passwd)
-      pipes = popen2.Popen3(cmd)
-      pipes.tochild.write(dscript)
-      pipes.tochild.close()
-      print pipes.fromchild.read()
-      status = pipes.wait()
-
-    if status:
-        print "[ERROR] the database did not create sucessfully."
-        sys.exit(1)
-
-    print "Database created successfully."
-    sys.exit(0)
-    
diff --git a/src/www/scm/viewvc/bin/mod_python/.htaccess b/src/www/scm/viewvc/bin/mod_python/.htaccess
deleted file mode 100644
index b30e4a3..0000000
--- a/src/www/scm/viewvc/bin/mod_python/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-AddHandler python-program .py
-PythonHandler handler
-PythonDebug On
diff --git a/src/www/scm/viewvc/bin/mod_python/handler.py b/src/www/scm/viewvc/bin/mod_python/handler.py
deleted file mode 100644
index 6ccabe9..0000000
--- a/src/www/scm/viewvc/bin/mod_python/handler.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# Mod_Python handler based on mod_python.publisher
-#
-# -----------------------------------------------------------------------
-
-from mod_python import apache
-import os.path
-
-def handler(req):
-  path, module_name = os.path.split(req.filename)
-  module_name, module_ext = os.path.splitext(module_name)
-  try:
-    module = apache.import_module(module_name, path=[path])
-  except ImportError:
-    raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND
-
-  req.add_common_vars()
-  module.index(req)
-
-  return apache.OK
diff --git a/src/www/scm/viewvc/bin/mod_python/query.py b/src/www/scm/viewvc/bin/mod_python/query.py
deleted file mode 100644
index 459070a..0000000
--- a/src/www/scm/viewvc/bin/mod_python/query.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# ViewVC: View CVS/SVN repositories via a web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) viewvc.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-
-import sapi
-import viewvc
-import query
-reload(query) # need reload because initial import loads this stub file
-
-cfg = viewvc.load_config(CONF_PATHNAME)
-
-def index(req):
-  server = sapi.ModPythonServer(req)
-  try:
-    query.main(server, cfg, "viewvc.py")
-  finally:
-    server.close()
-
diff --git a/src/www/scm/viewvc/bin/mod_python/viewvc.py b/src/www/scm/viewvc/bin/mod_python/viewvc.py
deleted file mode 100644
index 496ae20..0000000
--- a/src/www/scm/viewvc/bin/mod_python/viewvc.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# viewvc: View CVS/SVN repositories via a web browser
-#
-# -----------------------------------------------------------------------
-#
-# This is a teeny stub to launch the main ViewVC app. It checks the load
-# average, then loads the (precompiled) viewvc.py file and runs it.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-#########################################################################
-#
-# Adjust sys.path to include our library directory
-#
-
-import sys
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-
-import sapi
-import viewvc
-reload(viewvc) # need reload because initial import loads this stub file
-
-
-def index(req):
-  server = sapi.ModPythonServer(req)
-  cfg = viewvc.load_config(CONF_PATHNAME, server)
-  try:
-    viewvc.main(server, cfg)
-  finally:
-    server.close()
diff --git a/src/www/scm/viewvc/bin/standalone.py b/src/www/scm/viewvc/bin/standalone.py
deleted file mode 100755
index 2f089b7..0000000
--- a/src/www/scm/viewvc/bin/standalone.py
+++ /dev/null
@@ -1,643 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""Run "standalone.py -p <port>" to start an HTTP server on a given port 
-on the local machine to generate ViewVC web pages.
-"""
-
-__author__ = "Peter Funk <pf at artcom-gmbh.de>"
-__date__ = "11 November 2001"
-__version__ = "$Revision$"
-__credits__ = """Guido van Rossum, for an excellent programming language.
-Greg Stein, for writing ViewCVS in the first place.
-Ka-Ping Yee, for the GUI code and the framework stolen from pydoc.py.
-"""
-
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-import sys
-import os
-import os.path
-import stat
-import string
-import urllib
-import rfc822
-import socket
-import select
-import BaseHTTPServer
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-else:
-  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], "../../lib")))
-
-import sapi
-import viewvc
-import compat; compat.for_standalone()
-
-
-class Options:
-    port = 7467 # default TCP/IP port used for the server
-    start_gui = 0 # No GUI unless requested.
-    repositories = {} # use default repositories specified in config
-    if sys.platform == 'mac':
-        host = '127.0.0.1' 
-    else:
-        host = 'localhost'
-    script_alias = 'viewvc'
-
-# --- web browser interface: ----------------------------------------------
-
-class StandaloneServer(sapi.CgiServer):
-    def __init__(self, handler):
-        sapi.CgiServer.__init__(self, inheritableOut = sys.platform != "win32")
-        self.handler = handler
-
-    def header(self, content_type='text/html', status=None):
-        if not self.headerSent:
-            self.headerSent = 1
-            if status is None:
-              statusCode = 200
-              statusText = 'OK'           
-            else:              
-              p = string.find(status, ' ')
-              if p < 0:
-                statusCode = int(status)
-                statusText = ''
-              else:
-                statusCode = int(status[:p])
-                statusText = status[p+1:]
-            self.handler.send_response(statusCode, statusText)
-            self.handler.send_header("Content-type", content_type)
-            for (name, value) in self.headers:
-                self.handler.send_header(name, value)
-            self.handler.end_headers()
-            
-
-def serve(host, port, callback=None):
-    """start a HTTP server on the given port.  call 'callback' when the
-    server is ready to serve"""
-
-    class ViewVC_Handler(BaseHTTPServer.BaseHTTPRequestHandler):
-         
-        def do_GET(self):
-            """Serve a GET request."""
-            if not self.path or self.path == "/":
-                self.redirect()
-            elif self.is_viewvc():
-                try:
-                    self.run_viewvc()
-                except IOError:
-                    # ignore IOError: [Errno 32] Broken pipe
-                    pass
-            else:
-                self.send_error(404)
-
-        def do_POST(self):
-            """Serve a POST request."""
-            if self.is_viewvc():
-                self.run_viewvc()
-            else:
-                self.send_error(501, "Can only POST to %s"
-                                % (options.script_alias))
-
-        def is_viewvc(self):
-            """Check whether self.path is, or is a child of, the ScriptAlias"""
-            if self.path == '/' + options.script_alias:
-                return 1
-            if self.path[:len(options.script_alias)+2] == \
-                   '/' + options.script_alias + '/':
-                return 1
-            if self.path[:len(options.script_alias)+2] == \
-                   '/' + options.script_alias + '?':
-                return 1
-            return 0
-
-        def redirect(self):
-            """redirect the browser to the viewvc URL"""
-            new_url = self.server.url + options.script_alias + '/'
-            self.send_response(301, "Moved (redirection follows)")
-            self.send_header("Content-type", "text/html")
-            self.send_header("Location", new_url)
-            self.end_headers()
-            self.wfile.write("""<html>
-<head>
-<meta http-equiv="refresh" content="1; URL=%s">
-</head>
-<body>
-<h1>Redirection to <a href="%s">ViewVC</a></h1>
-Wait a second.   You will be automatically redirected to <b>ViewVC</b>.
-If this doesn't work, please click on the link above.
-</body>
-</html>
-""" % tuple([new_url]*2))
-
-        def run_viewvc(self):
-            """This is a quick and dirty cut'n'rape from Python's 
-            standard library module CGIHTTPServer."""
-            scriptname = '/' + options.script_alias
-            assert string.find(self.path, scriptname) == 0
-            viewvc_url = self.server.url[:-1] + scriptname
-            rest = self.path[len(scriptname):]
-            i = string.rfind(rest, '?')
-            if i >= 0:
-                rest, query = rest[:i], rest[i+1:]
-            else:
-                query = ''
-            # sys.stderr.write("Debug: '"+scriptname+"' '"+rest+"' '"+query+"'\n")
-            env = os.environ
-            # Since we're going to modify the env in the parent, provide empty
-            # values to override previously set values
-            for k in env.keys():
-                if k[:5] == 'HTTP_':
-                    del env[k]
-            for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
-                      'HTTP_USER_AGENT', 'HTTP_COOKIE'):
-                if env.has_key(k): 
-                    env[k] = ""
-            # XXX Much of the following could be prepared ahead of time!
-            env['SERVER_SOFTWARE'] = self.version_string()
-            env['SERVER_NAME'] = self.server.server_name
-            env['GATEWAY_INTERFACE'] = 'CGI/1.1'
-            env['SERVER_PROTOCOL'] = self.protocol_version
-            env['SERVER_PORT'] = str(self.server.server_port)
-            env['REQUEST_METHOD'] = self.command
-            uqrest = urllib.unquote(rest)
-            env['PATH_INFO'] = uqrest
-            env['SCRIPT_NAME'] = scriptname
-            if query:
-                env['QUERY_STRING'] = query
-            env['HTTP_HOST'] = self.server.address[0]
-            host = self.address_string()
-            if host != self.client_address[0]:
-                env['REMOTE_HOST'] = host
-            env['REMOTE_ADDR'] = self.client_address[0]
-            # AUTH_TYPE
-            # REMOTE_USER
-            # REMOTE_IDENT
-            if self.headers.typeheader is None:
-                env['CONTENT_TYPE'] = self.headers.type
-            else:
-                env['CONTENT_TYPE'] = self.headers.typeheader
-            length = self.headers.getheader('content-length')
-            if length:
-                env['CONTENT_LENGTH'] = length
-            accept = []
-            for line in self.headers.getallmatchingheaders('accept'):
-                if line[:1] in string.whitespace:
-                    accept.append(string.strip(line))
-                else:
-                    accept = accept + string.split(line[7:], ',')
-            env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
-            ua = self.headers.getheader('user-agent')
-            if ua:
-                env['HTTP_USER_AGENT'] = ua
-            modified = self.headers.getheader('if-modified-since')
-            if modified:
-                env['HTTP_IF_MODIFIED_SINCE'] = modified
-            etag = self.headers.getheader('if-none-match')
-            if etag:
-                env['HTTP_IF_NONE_MATCH'] = etag
-            # XXX Other HTTP_* headers
-            decoded_query = string.replace(query, '+', ' ')
-
-            # Preserve state, because we execute script in current process:
-            save_argv = sys.argv
-            save_stdin = sys.stdin
-            save_stdout = sys.stdout
-            save_stderr = sys.stderr
-            # For external tools like enscript we also need to redirect
-            # the real stdout file descriptor. (On windows, reassigning the
-            # sys.stdout variable is sufficient because pipe_cmds makes it
-            # the standard output for child processes.)
-            if sys.platform != "win32": save_realstdout = os.dup(1) 
-            try:
-                try:
-                    sys.stdout = self.wfile
-                    if sys.platform != "win32":
-                      os.dup2(self.wfile.fileno(), 1)
-                    sys.stdin = self.rfile
-                    viewvc.main(StandaloneServer(self), cfg)
-                finally:
-                    sys.argv = save_argv
-                    sys.stdin = save_stdin
-                    sys.stdout.flush()
-                    if sys.platform != "win32":
-                      os.dup2(save_realstdout, 1)
-                      os.close(save_realstdout)
-                    sys.stdout = save_stdout
-                    sys.stderr = save_stderr
-            except SystemExit, status:
-                self.log_error("ViewVC exit status %s", str(status))
-            else:
-                self.log_error("ViewVC exited ok")
-
-    class ViewVC_Server(BaseHTTPServer.HTTPServer):
-        def __init__(self, host, port, callback):
-            self.address = (host, port)
-            self.url = 'http://%s:%d/' % (host, port)
-            self.callback = callback
-            BaseHTTPServer.HTTPServer.__init__(self, self.address,
-                                               self.handler)
-
-        def serve_until_quit(self):
-            self.quit = 0
-            while not self.quit:
-                rd, wr, ex = select.select([self.socket.fileno()], [], [], 1)
-                if rd:
-                    self.handle_request()
-
-        def server_activate(self):
-            BaseHTTPServer.HTTPServer.server_activate(self)
-            if self.callback:
-                self.callback(self)
-
-        def server_bind(self):
-            # set SO_REUSEADDR (if available on this platform)
-            if hasattr(socket, 'SOL_SOCKET') \
-               and hasattr(socket, 'SO_REUSEADDR'):
-                self.socket.setsockopt(socket.SOL_SOCKET,
-                                       socket.SO_REUSEADDR, 1)
-            BaseHTTPServer.HTTPServer.server_bind(self)
-
-    ViewVC_Server.handler = ViewVC_Handler
-
-    try:
-        # XXX Move this code out of this function.
-        # Early loading of configuration here.  Used to
-        # allow tinkering with some configuration settings:
-        handle_config()
-        if options.repositories:
-            cfg.general.default_root = "Development"
-            cfg.general.cvs_roots.update(options.repositories)
-        elif cfg.general.cvs_roots.has_key("Development") and \
-             not os.path.isdir(cfg.general.cvs_roots["Development"]):
-            sys.stderr.write("*** No repository found. Please use the -r option.\n")
-            sys.stderr.write("   Use --help for more info.\n")
-            raise KeyboardInterrupt # Hack!
-        os.close(0) # To avoid problems with shell job control
-
-        # always use default docroot location
-        cfg.options.docroot = None
-
-        # if cvsnt isn't found, fall back to rcs
-        if (cfg.conf_path is None
-            and cfg.general.cvsnt_exe_path):
-          import popen
-          cvsnt_works = 0
-          try:
-            fp = popen.popen(cfg.general.cvsnt_exe_path, ['--version'], 'rt')
-            try:
-              while 1:
-                line = fp.readline()
-                if not line: break
-                if string.find(line, "Concurrent Versions System (CVSNT)")>=0:
-                  cvsnt_works = 1
-                  while fp.read(4096):
-                    pass
-                  break
-            finally:
-              fp.close()
-          except:
-            pass
-          if not cvsnt_works:
-            cfg.cvsnt_exe_path = None
-
-        ViewVC_Server(host, port, callback).serve_until_quit()
-    except (KeyboardInterrupt, select.error):
-        pass
-    print 'server stopped'
-
-def handle_config():
-  global cfg
-  cfg = viewvc.load_config(CONF_PATHNAME)
-
-# --- graphical interface: --------------------------------------------------
-
-def nogui(missing_module):
-    sys.stderr.write(
-        "Sorry! Your Python was compiled without the %s module"%missing_module+
-        " enabled.\nI'm unable to run the GUI part.  Please omit the '-g'\n"+
-        "and '--gui' options or install another Python interpreter.\n")
-    raise SystemExit, 1
-
-def gui(host, port):
-    """Graphical interface (starts web server and pops up a control window)."""
-    class GUI:
-        def __init__(self, window, host, port):
-            self.window = window
-            self.server = None
-            self.scanner = None
-
-            try:
-                import Tkinter
-            except ImportError:
-                nogui("Tkinter")
-
-            self.server_frm = Tkinter.Frame(window)
-            self.title_lbl = Tkinter.Label(self.server_frm,
-                text='Starting server...\n ')
-            self.open_btn = Tkinter.Button(self.server_frm,
-                text='open browser', command=self.open, state='disabled')
-            self.quit_btn = Tkinter.Button(self.server_frm,
-                text='quit serving', command=self.quit, state='disabled')
-
-
-            self.window.title('ViewVC standalone')
-            self.window.protocol('WM_DELETE_WINDOW', self.quit)
-            self.title_lbl.pack(side='top', fill='x')
-            self.open_btn.pack(side='left', fill='x', expand=1)
-            self.quit_btn.pack(side='right', fill='x', expand=1)
-
-            # Early loading of configuration here.  Used to
-            # allow tinkering with configuration settings through the gui:
-            handle_config()
-            if not LIBRARY_DIR:
-                cfg.options.cvsgraph_conf = "../cgi/cvsgraph.conf.dist"
-
-            self.options_frm = Tkinter.Frame(window)
-
-            # cvsgraph toggle:
-            self.cvsgraph_ivar = Tkinter.IntVar()
-            self.cvsgraph_ivar.set(cfg.options.use_cvsgraph)
-            self.cvsgraph_toggle = Tkinter.Checkbutton(self.options_frm,
-                text="enable cvsgraph (needs binary)", var=self.cvsgraph_ivar,
-                command=self.toggle_use_cvsgraph)
-            self.cvsgraph_toggle.pack(side='top', anchor='w')
-
-            # enscript toggle:
-            self.enscript_ivar = Tkinter.IntVar()
-            self.enscript_ivar.set(cfg.options.use_enscript)
-            self.enscript_toggle = Tkinter.Checkbutton(self.options_frm,
-                text="enable enscript (needs binary)", var=self.enscript_ivar,
-                command=self.toggle_use_enscript)
-            self.enscript_toggle.pack(side='top', anchor='w')
-
-            # show_subdir_lastmod toggle:
-            self.subdirmod_ivar = Tkinter.IntVar()
-            self.subdirmod_ivar.set(cfg.options.show_subdir_lastmod)
-            self.subdirmod_toggle = Tkinter.Checkbutton(self.options_frm,
-                text="show subdir last mod (dir view)", var=self.subdirmod_ivar,
-                command=self.toggle_subdirmod)
-            self.subdirmod_toggle.pack(side='top', anchor='w')
-
-            # use_re_search toggle:
-            self.useresearch_ivar = Tkinter.IntVar()
-            self.useresearch_ivar.set(cfg.options.use_re_search)
-            self.useresearch_toggle = Tkinter.Checkbutton(self.options_frm,
-                text="allow regular expr search", var=self.useresearch_ivar,
-                command=self.toggle_useresearch)
-            self.useresearch_toggle.pack(side='top', anchor='w')
-
-            # use_localtime toggle:
-            self.use_localtime_ivar = Tkinter.IntVar()
-            self.use_localtime_ivar.set(cfg.options.use_localtime)
-            self.use_localtime_toggle = Tkinter.Checkbutton(self.options_frm,
-                text="use localtime (instead of UTC)", 
-                var=self.use_localtime_ivar,
-                command=self.toggle_use_localtime)
-            self.use_localtime_toggle.pack(side='top', anchor='w')
-
-            # use_pagesize integer var:
-            self.usepagesize_lbl = Tkinter.Label(self.options_frm,
-                text='Paging (number of items per page, 0 disables):')
-            self.usepagesize_lbl.pack(side='top', anchor='w')
-            self.use_pagesize_ivar = Tkinter.IntVar()
-            self.use_pagesize_ivar.set(cfg.options.use_pagesize)
-            self.use_pagesize_entry = Tkinter.Entry(self.options_frm,
-                width=10, textvariable=self.use_pagesize_ivar)
-            self.use_pagesize_entry.bind('<Return>', self.set_use_pagesize)
-            self.use_pagesize_entry.pack(side='top', anchor='w')
-
-            # directory view template:
-            self.dirtemplate_lbl = Tkinter.Label(self.options_frm,
-                text='Chooose HTML Template for the Directory pages:')
-            self.dirtemplate_lbl.pack(side='top', anchor='w')
-            self.dirtemplate_svar = Tkinter.StringVar()
-            self.dirtemplate_svar.set(cfg.templates.directory)
-            self.dirtemplate_entry = Tkinter.Entry(self.options_frm,
-                width = 40, textvariable=self.dirtemplate_svar)
-            self.dirtemplate_entry.bind('<Return>', self.set_templates_directory)
-            self.dirtemplate_entry.pack(side='top', anchor='w')
-            self.templates_dir = Tkinter.Radiobutton(self.options_frm,
-                text="directory.ezt", value="templates/directory.ezt", 
-                var=self.dirtemplate_svar, command=self.set_templates_directory)
-            self.templates_dir.pack(side='top', anchor='w')
-            self.templates_dir_alt = Tkinter.Radiobutton(self.options_frm,
-                text="dir_alternate.ezt", value="templates/dir_alternate.ezt", 
-                var=self.dirtemplate_svar, command=self.set_templates_directory)
-            self.templates_dir_alt.pack(side='top', anchor='w')
-
-            # log view template:
-            self.logtemplate_lbl = Tkinter.Label(self.options_frm,
-                text='Chooose HTML Template for the Log pages:')
-            self.logtemplate_lbl.pack(side='top', anchor='w')
-            self.logtemplate_svar = Tkinter.StringVar()
-            self.logtemplate_svar.set(cfg.templates.log)
-            self.logtemplate_entry = Tkinter.Entry(self.options_frm,
-                width = 40, textvariable=self.logtemplate_svar)
-            self.logtemplate_entry.bind('<Return>', self.set_templates_log)
-            self.logtemplate_entry.pack(side='top', anchor='w')
-            self.templates_log = Tkinter.Radiobutton(self.options_frm,
-                text="log.ezt", value="templates/log.ezt", 
-                var=self.logtemplate_svar, command=self.set_templates_log)
-            self.templates_log.pack(side='top', anchor='w')
-            self.templates_log_table = Tkinter.Radiobutton(self.options_frm,
-                text="log_table.ezt", value="templates/log_table.ezt", 
-                var=self.logtemplate_svar, command=self.set_templates_log)
-            self.templates_log_table.pack(side='top', anchor='w')
-
-            # query view template:
-            self.querytemplate_lbl = Tkinter.Label(self.options_frm,
-                text='Template for the database query page:')
-            self.querytemplate_lbl.pack(side='top', anchor='w')
-            self.querytemplate_svar = Tkinter.StringVar()
-            self.querytemplate_svar.set(cfg.templates.query)
-            self.querytemplate_entry = Tkinter.Entry(self.options_frm,
-                width = 40, textvariable=self.querytemplate_svar)
-            self.querytemplate_entry.bind('<Return>', self.set_templates_query)
-            self.querytemplate_entry.pack(side='top', anchor='w')
-            self.templates_query = Tkinter.Radiobutton(self.options_frm,
-                text="query.ezt", value="templates/query.ezt", 
-                var=self.querytemplate_svar, command=self.set_templates_query)
-            self.templates_query.pack(side='top', anchor='w')
-
-            # pack and set window manager hints:
-            self.server_frm.pack(side='top', fill='x')
-            self.options_frm.pack(side='top', fill='x')
-
-            self.window.update()
-            self.minwidth = self.window.winfo_width()
-            self.minheight = self.window.winfo_height()
-            self.expanded = 0
-            self.window.wm_geometry('%dx%d' % (self.minwidth, self.minheight))
-            self.window.wm_minsize(self.minwidth, self.minheight)
-
-            try:
-                import threading
-            except ImportError:
-                nogui("thread")
-            threading.Thread(target=serve, 
-                             args=(host, port, self.ready)).start()
-
-        def toggle_use_cvsgraph(self, event=None):
-            cfg.options.use_cvsgraph = self.cvsgraph_ivar.get()
-
-        def toggle_use_enscript(self, event=None):
-            cfg.options.use_enscript = self.enscript_ivar.get()
-
-        def toggle_use_localtime(self, event=None):
-            cfg.options.use_localtime = self.use_localtime_ivar.get()
-
-        def toggle_subdirmod(self, event=None):
-            cfg.options.show_subdir_lastmod = self.subdirmod_ivar.get()
-
-        def toggle_useresearch(self, event=None):
-            cfg.options.use_re_search = self.useresearch_ivar.get()
-
-        def set_use_pagesize(self, event=None):
-            cfg.options.use_pagesize = self.use_pagesize_ivar.get()
-
-        def set_templates_log(self, event=None):
-            cfg.templates.log = self.logtemplate_svar.get()
-
-        def set_templates_directory(self, event=None):
-            cfg.templates.directory = self.dirtemplate_svar.get()
-
-        def set_templates_query(self, event=None):
-            cfg.templates.query = self.querytemplate_svar.get()
-
-        def ready(self, server):
-            """used as callback parameter to the serve() function"""
-            self.server = server
-            self.title_lbl.config(
-                text='ViewVC standalone server at\n' + server.url)
-            self.open_btn.config(state='normal')
-            self.quit_btn.config(state='normal')
-
-        def open(self, event=None, url=None):
-            """opens a browser window on the local machine"""
-            url = url or self.server.url
-            try:
-                import webbrowser
-                webbrowser.open(url)
-            except ImportError: # pre-webbrowser.py compatibility
-                if sys.platform == 'win32':
-                    os.system('start "%s"' % url)
-                elif sys.platform == 'mac':
-                    try:
-                        import ic
-                        ic.launchurl(url)
-                    except ImportError: pass
-                else:
-                    rc = os.system('netscape -remote "openURL(%s)" &' % url)
-                    if rc: os.system('netscape "%s" &' % url)
-
-        def quit(self, event=None):
-            if self.server:
-                self.server.quit = 1
-            self.window.quit()
-
-    import Tkinter
-    try:
-        gui = GUI(Tkinter.Tk(), host, port)
-        Tkinter.mainloop()
-    except KeyboardInterrupt:
-        pass
-
-# --- command-line interface: ----------------------------------------------
-
-def cli(argv):
-    """Command-line interface (looks at argv to decide what to do)."""
-    import getopt
-    class BadUsage(Exception): pass
-
-    try:
-        opts, args = getopt.getopt(argv[1:], 'gp:r:h:s:', 
-            ['gui', 'port=', 'repository=', 'script-alias='])
-        for opt, val in opts:
-            if opt in ('-g', '--gui'):
-                options.start_gui = 1
-            elif opt in ('-r', '--repository'):
-                if options.repositories: # option may be used more than once:
-                    num = len(options.repositories.keys())+1
-                    symbolic_name = "Repository"+str(num)
-                    options.repositories[symbolic_name] = val
-                else:
-                    options.repositories["Development"] = val
-            elif opt in ('-p', '--port'):
-                try:
-                    options.port = int(val)
-                except ValueError:
-                    raise BadUsage
-            elif opt in ('-h', '--host'):
-                options.host = val
-            elif opt in ('-s', '--script-alias'):
-                options.script_alias = \
-                    string.join(filter(None, string.split(val, '/')), '/')
-        if options.start_gui:
-            gui(options.host, options.port)
-            return
-        elif options.port:
-            def ready(server):
-                print 'server ready at %s%s' % (server.url,
-                                                options.script_alias)
-            serve(options.host, options.port, ready)
-            return
-        raise BadUsage
-    except (getopt.error, BadUsage):
-        cmd = os.path.basename(sys.argv[0])
-        port = options.port
-        host = options.host
-        script_alias = options.script_alias
-        print """ViewVC standalone - a simple standalone HTTP-Server
-
-Usage: %(cmd)s [OPTIONS]
-
-Available Options:
-
--h <host>, --host=<host>:
-    Start the HTTP server listening on <host>.  You need to provide
-    the hostname if you want to access the standalone server from a
-    remote machine.  [default: %(host)s]
-
--p <port>, --port=<port>:
-    Start an HTTP server on the given port.  [default: %(port)d]
-
--r <path>, --repository=<path>:
-    Specify a path for a CVS repository.  Repository definitions are
-    typically read from the viewvc.conf file, if available.  This
-    option may be used more than once.
-
--s <path>, --script-alias=<path>:
-    Specify the ScriptAlias, the artificial path location that at
-    which ViewVC appears to be located.  For example, if your
-    ScriptAlias is "cgi-bin/viewvc", then ViewVC will appear to be
-    accessible at the URL "http://%(host)s:%(port)s/cgi-bin/viewvc".
-    [default: %(script_alias)s]
-    
--g, --gui:
-    Pop up a graphical interface for serving and testing ViewVC.
-    NOTE: this requires a valid X11 display connection.
-""" % locals()
-
-if __name__ == '__main__':
-    options = Options()
-    cli(sys.argv)
diff --git a/src/www/scm/viewvc/bin/svndbadmin b/src/www/scm/viewvc/bin/svndbadmin
deleted file mode 100755
index 7e2522a..0000000
--- a/src/www/scm/viewvc/bin/svndbadmin
+++ /dev/null
@@ -1,311 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 2004 James Henstridge
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# administrative program for loading Subversion revision information
-# into the checkin database.  It can be used to add a single revision
-# to the database, or rebuild/update all revisions.
-#
-# To add all the checkins from a Subversion repository to the checkin
-# database, run the following:
-#    /path/to/svndbadmin rebuild /path/to/repo
-#
-# This script can also be called from the Subversion post-commit hook,
-# something like this:
-#    REPOS="$1"
-#    REV="$2"
-#    /path/to/svndbadmin update "$REPOS" "$REV"
-#
-# If you allow changes to revision properties in your repository, you
-# might also want to set up something similar in the
-# post-revprop-change hook using "rebuild" instead of "update" to keep
-# the checkin database consistent with the repository.
-#
-# -----------------------------------------------------------------------
-#
-
-#########################################################################
-#
-# INSTALL-TIME CONFIGURATION
-#
-# These values will be set during the installation process. During
-# development, they will remain None.
-#
-
-LIBRARY_DIR = None
-CONF_PATHNAME = None
-
-# Adjust sys.path to include our library directory
-import sys
-import os
-
-if LIBRARY_DIR:
-  sys.path.insert(0, LIBRARY_DIR)
-else:
-  sys.path.insert(0, os.path.abspath(os.path.join(sys.argv[0], "../../lib")))
-
-#########################################################################
-
-import os
-import string
-import re
-
-import svn.core
-import svn.repos
-import svn.fs
-import svn.delta
-
-import cvsdb
-import viewvc
-
-class SvnRepo:
-    """Class used to manage a connection to a SVN repository."""
-    def __init__(self, path, pool):
-        self.scratch_pool = svn.core.svn_pool_create(pool)
-        self.path = path
-        self.repo = svn.repos.svn_repos_open(path, pool)
-        self.fs = svn.repos.svn_repos_fs(self.repo)
-        # youngest revision of base of file system is highest revision number
-        self.rev_max = svn.fs.youngest_rev(self.fs, pool)
-    def __getitem__(self, rev):
-        if rev is None:
-            rev = self.rev_max
-        elif rev < 0:
-            rev = rev + self.rev_max + 1
-        assert 0 <= rev <= self.rev_max
-        rev = SvnRev(self, rev, self.scratch_pool)
-        svn.core.svn_pool_clear(self.scratch_pool)
-        return rev
-
-_re_diff_change_command = re.compile('(\d+)(?:,(\d+))?([acd])(\d+)(?:,(\d+))?')
-
-def _get_diff_counts(diff_fp):
-    """Calculate the plus/minus counts by parsing the output of a
-    normal diff.  The reasons for choosing Normal diff format are:
-      - the output is short, so should be quicker to parse.
-      - only the change commands need be parsed to calculate the counts.
-      - All file data is prefixed, so won't be mistaken for a change
-        command.
-    This code is based on the description of the format found in the
-    GNU diff manual."""
-
-    plus, minus = 0, 0
-    line = diff_fp.readline()
-    while line:
-        match = re.match(_re_diff_change_command, line)
-        if match:
-            # size of first range
-            if match.group(2):
-                count1 = int(match.group(2)) - int(match.group(1)) + 1
-            else:
-                count1 = 1
-            cmd = match.group(3)
-            # size of second range
-            if match.group(5):
-                count2 = int(match.group(5)) - int(match.group(4)) + 1
-            else:
-                count2 = 1
-
-            if cmd == 'a':
-                # LaR - insert after line L of file1 range R of file2
-                plus = plus + count2
-            elif cmd == 'c':
-                # FcT - replace range F of file1 with range T of file2
-                minus = minus + count1
-                plus = plus + count2
-            elif cmd == 'd':
-                # RdL - remove range R of file1, which would have been
-                #       at line L of file2
-                minus = minus + count1
-        line = diff_fp.readline()
-    return plus, minus
-
-
-class SvnRev:
-    """Class used to hold information about a particular revision of
-    the repository."""
-    def __init__(self, repo, rev, pool):
-        self.repo = repo
-        self.rev = rev
-        self.pool = pool
-        self.rev_roots = {} # cache of revision roots
-
-        subpool = svn.core.svn_pool_create(pool)
-
-        # revision properties ...
-        properties = svn.fs.revision_proplist(repo.fs, rev, pool)
-        self.author = str(properties.get(svn.core.SVN_PROP_REVISION_AUTHOR,''))
-        self.date = str(properties.get(svn.core.SVN_PROP_REVISION_DATE, ''))
-        self.log = str(properties.get(svn.core.SVN_PROP_REVISION_LOG, ''))
-
-        # convert the date string to seconds since epoch ...
-        self.date = svn.core.secs_from_timestr(self.date, pool)
-
-        # get a root for the current revisions
-        fsroot = self._get_root_for_rev(rev)
-        
-        # find changes in the revision
-        editor = svn.repos.RevisionChangeCollector(repo.fs, rev, pool)
-        e_ptr, e_baton = svn.delta.make_editor(editor, pool)
-        svn.repos.svn_repos_replay(fsroot, e_ptr, e_baton, pool)
-
-        self.changes = []
-        for path, change in editor.changes.items():
-
-            # clear the iteration subpool
-            svn.core.svn_pool_clear(subpool)
-
-            # skip non-file changes
-            if change.item_kind != svn.core.svn_node_file: continue
-
-            # deal with the change types we handle
-            base_root = None
-            if change.base_path:
-                base_root = self._get_root_for_rev(change.base_rev)
-                
-            if not change.path:
-                action = 'remove'
-            elif change.added:
-                action = 'add'
-            else:
-                action = 'change'
-
-            diffobj = svn.fs.FileDiff(base_root and base_root or None,
-                                      base_root and change.base_path or None,
-                                      change.path and fsroot or None,
-                                      change.path and change.path or None,
-                                      subpool, [])
-            diff_fp = diffobj.get_pipe()
-            plus, minus = _get_diff_counts(diff_fp)
-            self.changes.append((path, action, plus, minus))
-
-    def _get_root_for_rev(self, rev):
-        """Fetch a revision root from a cache of such, or a fresh root
-        (which is then cached for later use."""
-        if not self.rev_roots.has_key(rev):
-            self.rev_roots[rev] = svn.fs.revision_root(self.repo.fs, rev,
-                                                       self.pool)
-        return self.rev_roots[rev]
-
-
-def handle_revision(db, command, repo, rev, verbose):
-    """Adds a particular revision of the repository to the checkin database."""
-    revision = repo[rev]
-    committed = 0
-
-    if verbose: print "Building commit info for revision %d..." % (rev),
-
-    if not revision.changes:
-        if verbose: print "skipped (no changes)."
-        return
-
-    for (path, action, plus, minus) in revision.changes:
-        directory, file = os.path.split(path)
-        commit = cvsdb.CreateCommit()
-        commit.SetRepository(repo.path)
-        commit.SetDirectory(directory)
-        commit.SetFile(file)
-        commit.SetRevision(str(rev))
-        commit.SetAuthor(revision.author)
-        commit.SetDescription(revision.log)
-        commit.SetTime(revision.date)
-        commit.SetPlusCount(plus)
-        commit.SetMinusCount(minus)
-        commit.SetBranch(None)
-
-        if action == 'add':
-            commit.SetTypeAdd()
-        elif action == 'remove':
-            commit.SetTypeRemove()
-        elif action == 'change':
-            commit.SetTypeChange()
-
-        if command == 'update':
-            result = db.CheckCommit(commit)
-            if result:
-                continue # already recorded
-
-        # commit to database
-        db.AddCommit(commit)
-        committed = 1
-
-    if verbose:
-        if committed:
-            print "done."
-        else:
-            print "skipped (already recorded)."
-
-def main(pool, command, repository, rev=None, verbose=0):
-    cfg = viewvc.load_config(CONF_PATHNAME)
-    db = cvsdb.ConnectDatabase(cfg)
-
-    repo = SvnRepo(repository, pool)
-    if rev:
-        handle_revision(db, command, repo, rev, verbose)
-    else:
-        for rev in range(repo.rev_max+1):
-            handle_revision(db, command, repo, rev, verbose)
-
-def usage():
-    cmd = os.path.basename(sys.argv[0])
-    sys.stderr.write("""
-Usage: 1. %s [-v] rebuild REPOSITORY [REVISION]
-       2. %s [-v] update REPOSITORY [REVISION]
-
-1.  Rebuild the commit database information for REPOSITORY across all revisions
-    or, optionally, only for the specified REVISION.
-
-2.  Update the commit database information for REPOSITORY across all revisions
-    or, optionally, only for the specified REVISION.  This is just like
-    rebuilding, except that no commit information will be stored for
-    commits already present in the database.
-
-Use the -v flag to cause this script to give progress information as it works.
-""" % (cmd, cmd))
-    sys.exit(1)
-
-if __name__ == '__main__':
-    verbose = 0
-    
-    args = sys.argv
-    try:
-        index = args.index('-v')
-        verbose = 1
-        del args[index]
-    except ValueError:
-        pass
-        
-    if len(args) < 3:
-        usage()
-
-    command = string.lower(args[1])
-    if command not in ('rebuild', 'update'):
-        sys.stderr.write('ERROR: unknown command %s\n' % command)
-        usage()
-
-    repository = args[2]
-    if not os.path.exists(repository):
-        sys.stderr.write('ERROR: could not find repository %s\n' % repository)
-        usage()
-
-    if len(sys.argv) > 3:
-        rev = sys.argv[3]
-        try:
-            rev = int(rev)
-        except ValueError:
-            sys.stderr.write('ERROR: revision "%s" is not numeric\n' % rev)
-            usage()
-    else:
-        rev = None
-
-    repository = cvsdb.CleanRepository(os.path.abspath(repository))
-    svn.core.run_app(main, command, repository, rev, verbose)
diff --git a/src/www/scm/viewvc/cvsgraph.conf.dist b/src/www/scm/viewvc/cvsgraph.conf.dist
deleted file mode 100644
index dc97078..0000000
--- a/src/www/scm/viewvc/cvsgraph.conf.dist
+++ /dev/null
@@ -1,394 +0,0 @@
-# CvsGraph configuration
-#
-# - Empty lines and whitespace are ignored.
-#
-# - Comments start with '#' and everything until
-#   end of line is ignored.
-#
-# - Strings are C-style strings in which characters
-#   may be escaped with '\' and written in octal
-#   and hex escapes. Note that '\' must be escaped
-#   if it is to be entered as a character.
-#
-# - Some strings are expanded with printf like
-#   conversions which start with '%'. Not all
-#   are applicable at all times, in which case they
-#   will expand to nothing.
-#	%c = cvsroot (with trailing '/')
-#	%C = cvsroot (*without* trailing '/')
-#	%m = module (with trailing '/')
-#	%M = module (*without* trailing '/')
-#	%f = filename without path
-#	%F = filename without path and with ",v" stripped
-#	%p = path part of filename (with trailing '/')
-#	%r = number of revisions
-#	%b = number of branches
-#	%% = '%'
-#	%R = the revision number (e.g. '1.2.4.4')
-#	%P = previous revision number
-#	%B = the branch number (e.g. '1.2.4')
-#	%d = date of revision
-#	%a = author of revision
-#	%s = state of revision
-#	%t = current tag of branch or revision
-#	%0..%9 = command-line argument -0 .. -9
-#	%l = HTMLized log entry of the revision
-#		NOTE: %l is obsolete. See %(%) and cvsgraph.conf(5) for
-#		more details.
-#	%L = log entry of revision
-#		The log entry expansion takes an optional argument to
-#		specify maximum length of the expansion like %L[25].
-#	%(...%) = HTMLize the string within the parenthesis.
-#   ViewVC currently uses the following four command-line arguments to
-#   pass URL information to cvsgraph:
-#       -3 link to current file's log page
-#       -4 link to current file's checkout page minus "rev" parameter
-#       -5 link to current file's diff page minus "r1" and "r2" parameters
-#       -6 link to current directory page minus "pathrev" parameter
-#
-# - Numbers may be entered as octal, decimal or
-#   hex as in 0117, 79 and 0x4f respectively.
-#
-# - Fonts are numbered 0..4 (defined as in libgd)
-#	0 = tiny
-#	1 = small
-#	2 = medium (bold)
-#	3 = large
-#	4 = giant
-#
-# - Colors are a string like HTML type colors in
-#   the form "#rrggbb" with parts written in hex
-#	rr = red (00..ff)
-#	gg = green (00-ff)
-#	bb = blue (00-ff)
-#
-# - There are several reserved words besides of the
-#   feature-keywords. These additional reserved words
-#   expand to numerical values:
-#	* false	 = 0
-#	* true	 = 1
-#	* not	 = -1
-#	* left	 = 0
-#	* center = 1
-#	* right	 = 2
-#	* gif	 = 0
-#	* png	 = 1
-#	* jpeg	 = 2
-#	* tiny	 = 0
-#	* small	 = 1
-#	* medium = 2
-#	* large	 = 3
-#	* giant	 = 4
-#
-# - Booleans have three possible arguments: true, false
-#   and not. `Not' means inverse of what it was (logical
-#   negation) and is represented by the value -1.
-#   For the configuration file that means that the default
-#   value is negated.
-#
-
-# cvsroot <string>
-#	The *absolute* base directory where the
-#	CVS/RCS repository can be found
-# cvsmodule <string>
-#
-cvsroot		= "--unused--"; # unused with ViewVC, will be overridden
-cvsmodule	= "";  # unused with ViewVC -- please leave it blank
-
-# color_bg <color>
-#	The background color of the image
-# transparent_bg <boolean>
-#	Make color_bg the transparent color (only useful with PNG)
-color_bg	= "#ffffff";
-transparent_bg	= false;
-
-# date_format <string>
-#	The strftime(3) format string for date and time
-date_format	= "%d-%b-%Y %H:%M:%S";
-
-# box_shadow <boolean>
-#	Add a shadow around the boxes
-# upside_down <boolean>
-#	Reverse the order of the revisions
-# left_right <boolean>
-#	Draw the image left to right instead of top down,
-#	or right to left is upside_down is set simultaneously.
-# strip_untagged <boolean>
-#	Remove all untagged revisions except the first, last and tagged ones
-# strip_first_rev <boolean>
-#	Also remove the first revision if untagged
-# auto_stretch <boolean>
-#	Try to reformat the tree to minimize image size
-# use_ttf <boolean>
-#	Use TrueType fonts for text
-# anti_alias <boolean>
-#	Enable pretty TrueType anti-alias drawing
-# thick_lines <number>
-#	Draw all connector lines thicker (range: 1..11)
-box_shadow	= true;
-upside_down	= false;
-left_right	= false;
-strip_untagged	= false;
-strip_first_rev	= false;
-#auto_stretch	= true;		# not yet stable.
-use_ttf		= false;
-anti_alias	= true;
-thick_lines	= 1;
-
-# msg_color <color>
-#	Sets the error/warning message color
-# msg_font <number>
-# msg_ttfont <string>
-# msg_ttsize <float>
-#	Sets the error/warning message font
-msg_color	= "#800000";
-msg_font	= medium;
-msg_ttfont	= "/dos/windows/fonts/ariali.ttf";
-msg_ttsize	= 11.0;
-
-# parse_logs <boolean>
-#	Enable the parsing of the *entire* ,v file to read the
-#	log-entries between revisions. This is necessary for
-#	the %L expansion to work, but slows down parsing by
-#	a very large factor. You're warned.
-parse_logs	= false;
-
-# tag_font <number>
-#	The font of the tag text
-# tag_color <color>
-#	The color of the tag text
-# tag_ignore <string>
-#	A extended regular expression to exclude certain tags from view.
-#	See regex(7) for details on the format.
-#	Note 1: tags matched in merge_from/merge_to are always displayed unless
-#		tag_ignore_merge is set to true.
-#	Note 2: normal string rules apply and special characters must be
-#		escaped.
-# tag_ignore_merge <boolean>
-#	If set to true, allows tag_ignore to also hide merge_from and merge_to
-#	tags.
-# tag_nocase <boolean>
-#	Ignore the case is tag_ignore expressions
-# tag_negate <boolean>
-#	Negate the matching criteria of tag_ignore. When true, only matching
-#	tags will be shown.
-#	Note: tags matched with merge_from/merge_to will still be displayed.
-tag_font	= medium;
-#tag_ttfont	= "/dos/windows/fonts/ariali.ttf";
-#tag_ttsize	= 11.0;
-tag_color	= "#007000";
-#tag_ignore	= "(test|alpha)_release";
-#tag_ignore_merge = false;
-#tag_nocase	= false;
-#tag_negate	= false;
-
-# rev_hidenumber <boolean>
-#	If set to true no revision numbers will be printed in the graph.
-#rev_hidenumber = false;
-rev_font	= giant;
-#rev_ttfont	= "/dos/windows/fonts/arial.ttf";
-#rev_ttsize	= 12.0;
-rev_color	= "#000000";
-rev_bgcolor	= "#f0f0f0";
-rev_separator	= 1;
-rev_minline	= 15;
-rev_maxline	= 75;
-rev_lspace	= 5;
-rev_rspace	= 5;
-rev_tspace	= 3;
-rev_bspace	= 3;
-rev_text	= "%d";	# or "%d\n%a, %s" for author and state too
-rev_text_font	= tiny;
-#rev_text_ttfont	= "/dos/windows/fonts/times.ttf";
-#rev_text_ttsize	= 9.0;
-rev_text_color	= "#500020";
-rev_maxtags	= 25;
-
-# merge_color <color>
-#	The color of the line connecting merges
-# merge_front <boolean>
-#	If true, draw the merge-lines on top if the image
-# merge_nocase <boolean>
-#	Ignore case in regular expressions
-# merge_from <string>
-#	A regex describing a tag that is used as the merge source
-# merge_to <string>
-#	A regex describing a tag that is the target of the merge
-# merge_findall <boolean>
-#	Try to match all merge_to targets possible. This can result in
-#	multiple lines originating from one tag.
-# merge_arrows <boolean>
-#	Use arrows to point to the merge destination. Default is true.
-# merge_cvsnt <boolean>
-#	Use CVSNT's mergepoint registration for merges
-# merge_cvsnt_color <color>
-#	The color of the line connecting merges from/to registered
-#	mergepoints.
-# arrow_width <number>
-# arrow_length <number>
-#	Specify the size of the arrows. Default is 3 wide and 12 long.
-#
-# NOTE:
-# - The merge_from is an extended regular expression as described in
-#   regex(7) and POSIX 1003.2 (see also Single Unix Specification at
-#   http://www.opengroup.com).
-# - The merge_to is an extended regular expression with a twist. All
-#   subexpressions from the merge_from are expanded into merge_to
-#   using %[1-9] (in contrast to \[1-9] for backreferences). Care is
-#   taken to escape the constructed expression.
-# - A '$' at the end of the merge_to expression can be important to
-#   prevent 'near match' references. Normally, you want the destination
-#   to be a good representation of the source. However, this depends
-#   on how well you defined the tags in the first place.
-#
-# Example:
-#	merge_from = "^f_(.*)";
-#	merge_to = "^t_%1$";
-#	tags: f_foo, f_bar, f_foobar, t_foo, t_bar
-#	result:
-#		f_foo	-> "^t_foo$"	-> t_foo
-#		f_bar	-> "^t_bar$"	-> t_bar
-#		f_foobar-> "^t_foobar$"	-> <no match>
-#
-merge_color	= "#a000a0";
-merge_front	= false;
-merge_nocase	= false;
-merge_from	= "^f_(.*)";
-merge_to	= "^t_%1$";
-merge_findall	= false;
-
-#merge_arrows	= true;
-#arrow_width	= 3;
-#arrow_length	= 12;
-
-merge_cvsnt	= true;
-merge_cvsnt_color = "#606000";
-
-# branch_font <number>
-#	The font of the number and tags
-# branch_color <color>
-#	All branch element's color
-# branch_[lrtb]space <number>
-#	Interior spacing (margin)
-# branch_margin <number>
-#	Exterior spacing
-# branch_connect <number>
-#	Length of the vertical connector
-# branch_dupbox <boolean>
-#	Add the branch-tag also at the bottom/top of the trunk
-# branch_fold <boolean>
-#	Fold empty branches in one box to save space
-# branch_foldall <boolean>
-#	Put all empty branches in one box, even if they
-#	were interspaced with branches with revisions.
-# branch_resort <boolean>
-#	Resort the branches by the number of revisions to save space
-# branch_subtree <string>
-#	Only show the branch denoted or all branches that sprout
-#	from the denoted revision. The argument may be a symbolic
-#	tag. This option you would normally want to set from the
-#	command line with the -O option.
-branch_font	= medium;
-#branch_ttfont	= "/dos/windows/fonts/arialbd.ttf";
-#branch_ttsize	= 18.0;
-branch_tag_color= "#000080";
-branch_tag_font	= medium;
-#branch_tag_ttfont = "/dos/windows/fonts/arialbi.ttf";
-#branch_tag_ttsize = 14.0;
-branch_color	= "#0000c0";
-branch_bgcolor	= "#ffffc0";
-branch_lspace	= 5;
-branch_rspace	= 5;
-branch_tspace	= 3;
-branch_bspace	= 3;
-branch_margin	= 15;
-branch_connect	= 8;
-branch_dupbox	= false;
-branch_fold	= true;
-branch_foldall	= false;
-branch_resort	= false;
-#branch_subtree	= "1.2.4";
-
-# title <string>
-#	The title string is expanded (see above for details)
-# title_[xy] <number>
-#	Position of title
-# title_font <number>
-#	The font
-# title_align <number>
-#	0 = left
-#	1 = center
-#	2 = right
-# title_color <color>
-title		= "%c%p%f\nRevisions: %r, Branches: %b";
-title_x		= 10;
-title_y		= 5;
-title_font	= small;
-#title_ttfont	= "/dos/windows/fonts/times.ttf";
-#title_ttsize	= 10.0;
-title_align	= left;
-title_color	= "#800000";
-
-# Margins of the image
-# Note: the title is outside the margin
-margin_top	= 35;
-margin_bottom	= 10;
-margin_left	= 10;
-margin_right	= 10;
-
-# Image format(s)
-# image_type <number|{gif,jpeg,png}>
-#	gif  (0) = Create gif image
-#	png  (1) = Create png image
-#	jpeg (2) = Create jpeg image
-#	Image types are available if they can be found in
-#	the gd library. Newer versions of gd do not have
-#	gif anymore. CvsGraph will automatically generate
-#	png images instead.
-# image_quality <number>
-#	The quality of a jpeg image (1..100)
-# image_compress <number>
-#	Set the compression of a PNG image (gd version >= 2.0.12).
-#	Values range from -1 to 9 where:
-#	- -1	default compression (usually 3)
-#	-  0	no compression
-#	-  1	lowest level compression
-#	- ...	...
-#	-  9	highest level of compression
-# image_interlace <boolean>
-#	Write interlaces PNG/JPEG images for progressive loading.
-image_type	= png;
-image_quality	= 75;
-image_compress	= 3;
-image_interlace	= true;
-
-# HTML image map generation
-# map_name <string>
-#	The name= attribute in <map name="mapname">...</map>
-# map_branch_href <string>
-# map_branch_alt <string>
-# map_rev_href <string>
-# map_rev_alt <string>
-# map_diff_href <string>
-# map_diff_alt <string>
-# map_merge_href <string>
-# map_merge_alt <string>
-#	These are the href= and alt= attributes in the <area>
-#	tags of HTML. The strings are expanded (see above).
-map_name	= "MyMapName\" name=\"MyMapName";
-map_branch_href	= "href=\"%6pathrev=%(%t%)\"";
-map_branch_alt	= "alt=\"%0 %(%t%) (%B)\"";
-# You might want to experiment with the following setting:
-# 1. The default setting will take you to a ViewVC generated page displaying 
-#    that revision of the file, if you click into a revision box:
-map_rev_href	= "href=\"%4rev=%R\"";
-# 2. This alternative setting will take you to the anchor representing this
-#    revision on a ViewVC generated Log page for that file:
-# map_rev_href   = "href=\"%3#rev%R\"";
-#
-map_rev_alt	= "alt=\"%1 %(%t%) (%R)\"";
-map_diff_href	= "href=\"%5r1=%P&r2=%R\"";
-map_diff_alt	= "alt=\"%2 %P <-> %R\"";
-map_merge_href	= "href=\"%5r1=%P&r2=%R\"";
-map_merge_alt	= "alt=\"%2 %P <-> %R\"";
-
diff --git a/src/www/scm/viewvc/templates/docroot/help.css b/src/www/scm/viewvc/docroot/help.css
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/help.css
rename to src/www/scm/viewvc/docroot/help.css
diff --git a/src/www/scm/viewvc/templates/docroot/help_dirview.html b/src/www/scm/viewvc/docroot/help_dirview.html
similarity index 90%
rename from src/www/scm/viewvc/templates/docroot/help_dirview.html
rename to src/www/scm/viewvc/docroot/help_dirview.html
index 1b3a3d8..f86cb4a 100644
--- a/src/www/scm/viewvc/templates/docroot/help_dirview.html
+++ b/src/www/scm/viewvc/docroot/help_dirview.html
@@ -4,31 +4,23 @@
 <head>
   <title>ViewVC Help: Directory View</title>
   <link rel="stylesheet" href="help.css" type="text/css" />
+  <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 </head>
 <body>
+  <div><a href="http://viewvc.org/index.html"><img src="images/viewvc-logo.png" alt="ViewVC logotype" /></a></div>
   <table>
     <col class="menu" />
     <col />
-    <tr>
-      <td><a href="http://viewvc.org/index.html"><img
-	     src="images/logo.png" alt="ViewVC logotype" /></a>
-      </td>
-      <td>
-	<h1>ViewVC Help: Directory View</h1>
-      </td>
-    </tr>
     <tr><td>
        <h3>Help</h3>
        <a href="help_rootview.html">General</a><br />
        <strong>Directory View</strong><br />
        <a href="help_log.html">Log View</a><br />
+       <a href="help_query.html">Query Database</a><br />
+    </td><td>
 
-       <h3>Internet</h3>
-       <a href="http://viewvc.org/index.html">Home</a><br />
-       <a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
-       <a href="http://viewvc.org/contributing.html">Contributing</a><br />
-       <a href="http://viewvc.org/license-1.html">License</a><br />
-    </td><td colspan="2">
+    <h1>ViewVC Help: Directory View</h1>
 
     <p>The directory listing view should be a familiar sight to any
     computer user. It shows the path of the current directory being viewed
diff --git a/src/www/themes/funky-wOw/viewvc/help_log.html b/src/www/scm/viewvc/docroot/help_log.html
similarity index 83%
rename from src/www/themes/funky-wOw/viewvc/help_log.html
rename to src/www/scm/viewvc/docroot/help_log.html
index 308c248..5ddf0d4 100644
--- a/src/www/themes/funky-wOw/viewvc/help_log.html
+++ b/src/www/scm/viewvc/docroot/help_log.html
@@ -4,37 +4,28 @@
 <head>
   <title>ViewVC Help: Log View</title>
   <link rel="stylesheet" href="help.css" type="text/css" />
+  <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
   <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 </head>
 <body>
+  <div><a href="http://viewvc.org/index.html"><img src="images/viewvc-logo.png" alt="ViewVC logotype" /></a></div>
   <table>
     <col class="menu" />
     <col />
-    <tr>
-      <td><a href="http://viewvc.org/index.html"><img
-	     src="images/logo.png" alt="ViewVC logotype" /></a>
-      </td>
-      <td>
-	<h1>ViewVC Help: Log View</h1>
-      </td>
-    </tr>
     <tr><td>
        <h3>Help</h3>
        <a href="help_rootview.html">General</a><br />
        <a href="help_dirview.html">Directory View</a><br />
        <strong>Log View</strong><br />
+       <a href="help_query.html">Query Database</a><br />
+    </td><td>
+
+    <h1>ViewVC Help: Log View</h1>
 
-       <h3>Internet</h3>
-       <a href="http://viewvc.org/index.html">Home</a><br />
-       <a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
-       <a href="http://viewvc.org/contributing.html">Contributing</a><br />
-       <a href="http://viewvc.org/license-1.html">License</a><br />
-    </td><td colspan="2">
     <p>
       The log view displays the revision history of the selected source
       file or directory. For each revision the following information is
       displayed:
-    </p>
 
       <ul>
         <li>The revision number. In Subversion repositories, this is a
diff --git a/src/www/scm/viewvc/docroot/help_query.html b/src/www/scm/viewvc/docroot/help_query.html
new file mode 100644
index 0000000..9bab797
--- /dev/null
+++ b/src/www/scm/viewvc/docroot/help_query.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>ViewVC Help: Query The Commit Database</title>
+  <link rel="stylesheet" href="help.css" type="text/css" />
+  <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+</head>
+<body>
+  <div><a href="http://viewvc.org/index.html"><img src="images/viewvc-logo.png" alt="ViewVC logotype" /></a></div>
+  <table>
+    <col class="menu" />
+    <col />
+    <tr><td>
+       <h3>Help:</h3>
+       <a href="help_rootview.html">General</a><br />
+       <a href="help_dirview.html">Directory View</a><br />
+       <a href="help_log.html">Log View</a><br />
+       <strong>Query Database</strong>
+    </td><td>
+  
+    <h1>ViewVC Help: Query The Commit Database</h1>
+  
+    <p> 
+      Select your parameters for querying the CVS commit database in the
+      form at the top of the page.  You
+      can search for multiple matches by typing a comma-seperated list
+      into the text fields.  Regular expressions, and wildcards are also
+      supported.  Blank text input fields are treated as wildcards.
+    </p>
+    <p>
+      Any of the text entry fields can take a comma-seperated list of
+      search arguments.  For example, to search for all commits from
+      authors <em>jpaint</em> and <em>gstein</em>, just type: <code>jpaint,
+      gstein</code> in the <em>Author</em> input box.  If you are searching
+      for items containing spaces or quotes, you will need to quote your
+      request.  For example, the same search above with quotes is:
+      <code>"jpaint", "gstein"</code>.
+    </p>
+    <p>                           
+      Wildcard and regular expression searches are entered in a similar
+      way to the quoted requests.  You must quote any wildcard or
+      regular expression request, and a command character preceeds the
+      first quote.  The command character <code>l</code>(lowercase L) is for wildcard
+      searches, and the wildcard character is a percent (<code>%</code>).  The
+      command character for regular expressions is <code>r</code>, and is
+      passed directly to MySQL, so you'll need to refer to the MySQL
+      manual for the exact regex syntax.  It is very similar to Perl.  A
+      wildard search for all files with a <em>.py</em> extention is:
+      <code>l"%.py"</code> in the <em>File</em> input box.  The same search done
+      with a regular expression is: <code>r".*\.py"</code>.
+    </p>
+    <p>                  
+      All search types can be mixed, as long as they are seperated by
+      commas.
+    </p>                                                    
+    </td></tr></table>
+  <hr />
+  <address><a href="mailto:users at viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
+  </body>
+</html>
diff --git a/src/www/scm/viewvc/docroot/help_rootview.html b/src/www/scm/viewvc/docroot/help_rootview.html
new file mode 100644
index 0000000..24457e9
--- /dev/null
+++ b/src/www/scm/viewvc/docroot/help_rootview.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
+    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+  <title>ViewVC Help: General</title>
+  <link rel="stylesheet" href="help.css" type="text/css" />
+  <link rel="shortcut icon" href="images/favicon.ico" type="image/x-icon" />
+  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+</head>
+<body>
+  <div><a href="http://viewvc.org/index.html"><img src="images/viewvc-logo.png" alt="ViewVC logotype" /></a></div>
+  <table>
+    <col class="menu" />
+    <col />
+    <tr><td>
+       <h3>Help</h3>
+       <strong>General</strong><br />
+       <a href="help_dirview.html">Directory View</a><br />
+       <a href="help_log.html">Log View</a><br />
+       <a href="help_query.html">Query Database</a><br />
+    </td><td>
+
+    <h1>ViewVC Help: General</h1>
+
+    <p><em>ViewVC</em> is a WWW interface for CVS and Subversion
+    repositories. It allows you to browse the files and directories in a
+    repository while showing you metadata from the repository history: log
+    messages, modification dates, author names, revision numbers, copy
+    history, and so on. It provides several different views of repository
+    data to help you find the information you are looking for:</p>
+  
+    <ul>
+      <li><a name="multiple-repositories"><strong>Root Listing
+      View</strong></a> - Show a list of repositories configured for
+      display in ViewVC.</li>
+  
+      <li><a name="view-dir" href="help_dirview.html"><strong>Directory
+      View</strong></a> - Shows a list of files and subdirectories in a
+      directory of the repository, along with metadata like author names and
+      log entries.</li>
+  
+      <li><a name="view-log" href="help_log.html"><strong>Log
+      View</strong></a> - Shows a revision by revision list of all the
+      changes that have made to a file or directory in the repository, with
+      metadata and links to views of each revision.</li>
+  
+      <li><a name="view-checkout"><strong>File Download (Checkout
+      View)</strong></a> - Retrieves the unaltered contents of a file
+      revision. Browsers may try to display the file, or just save it
+      to disk.  <em>This view is disabled in the default ViewVC
+      configuration.</em></li>
+  
+      <li><a name="view-annotate"><a name="view-markup"><strong>File
+      Contents View</strong></a></a> - Shows the contents of a file at
+      a particular revision, with revision information at the top of
+      the page. File revisions which are GIF, PNG, or JPEG images are
+      displayed inline on the page. Other file types are displayed as
+      marked up text. The markup may be limited to turning URLs and
+      email addresses into links, or configured to show colorized
+      source code.  This view can optionally show line-based
+      annotation data for the file, containing the revision number
+      where each line was last modified, along with links and other
+      information.  <em>This view is disabled in some ViewVC
+      configurations.</em></li>
+  
+      <li><a name="view-diff"><strong>File Diff View</strong></a> - Shows
+      the changes made between two revisions of a file</li>
+  
+      <li><a name="view-tarball"><strong>Directory Tarball View</strong> -
+      Retrieves a gzipped tar archive containing the contents of a
+      directory.<em>This view is disabled in the default ViewVC
+      configuration.</em></li>
+  
+      <li><a name="view-query"><strong>Directory Query View</strong></a> -
+      Shows information about changes made to all subdirectories and files
+      under a parent directory, sorted and filtered by criteria you specify.
+      <em>This view is disabled in the default ViewVC configuration.</em>
+      </li>
+  
+      <li><a name="view-rev"><strong>Revision View</strong> - Shows
+      information about a revision including log message, author, and a list
+      of changed paths. <em>For Subversion repositories only.</em></li>
+  
+      <li><a name="view-graph"><strong>Graph View</strong></a> - Shows a
+      graphical representation of a file's revisions and branches complete
+      with tag and author names and links to markup and diff pages.
+      <em>For CVS repositories only, and disabled in the default
+      configuration.</em></li>
+    </ul>
+  
+    <h3><a name="sticky-revision-tag">Sticky Revision and Tag</a></h3>
+  
+    <p>By default, ViewVC will show the files and directories and revisions
+    that currently exist in the repository. But it's also possible to browse
+    the contents of a repository at a point in its past history by choosing
+    a "sticky tag" (in CVS) or a "sticky revision" (in Subversion) from the
+    forms at the top of directory and log pages. They're called sticky
+    because once they're chosen, they stick around when you navigate to
+    other pages, until you reset them. When they're set, directory and log
+    pages only show revisions preceding the specified point in history. In
+    CVS, when a tag refers to a branch or a revision on a branch, only
+    revisions from the branch history are shown, including branch points and
+    their preceding revisions.</p>
+  
+    <h3><a name="dead-files">Dead Files</a></h3>
+  
+    <p>In CVS directory listings, ViewVC can optionally display dead files.
+    Dead files are files which used to be in a directory but are currently
+    deleted, or files which just don't exist in the currently selected
+    <a href="#sticky-revision-tag">sticky tag</a>. Dead files cannot be
+    shown in Subversion repositories. The only way to see a deleted file in
+    a Subversion directory is to navigate to a sticky revision where the
+    file previously existed.</p>
+  
+    <h3><a name="artificial-tags">Artificial Tags</a></h3>
+  
+    <p>In CVS Repositories, ViewVC adds artificial tags <em>HEAD</em> and
+    <em>MAIN</em> to tag listings and accepts them in place of revision
+    numbers and real tag names in all URLs. <em>MAIN</em> acts like a branch
+    tag pointing at the default branch, while <em>HEAD</em> acts like a
+    revision tag pointing to the latest revision on the default branch. The
+    default branch is usually just the trunk, but may be set to other
+    branches inside individual repository files. CVS will always check out
+    revisions from a file's default branch when no other branch is specified
+    on the command line.</p>
+  
+    <h3><a name="more-information">More Information</a></h3>
+  
+    <p>More information about <em>ViewVC</em> is available from
+    <a href="http://viewvc.org/">viewvc.org</a>.
+    See the links below for guides to CVS and Subversion</p>
+  
+    <h4>Documentation about CVS</h4>
+    <blockquote>
+      <p>
+        <a href="http://cvsbook.red-bean.com/"><em>Open Source
+        Development with CVS</em></a><br />
+        <a href="http://www.loria.fr/~molli/cvs/doc/cvs_toc.html">CVS
+        User's Guide</a><br />
+        <a href="http://cellworks.washington.edu/pub/docs/cvs/tutorial/cvs_tutorial_1.html">Another CVS tutorial</a><br />
+        <a href="http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/">Yet another CVS tutorial (a little old, but nice)</a><br />
+        <a href="http://www.cs.utah.edu/dept/old/texinfo/cvs/FAQ.txt">An old but very useful FAQ about CVS</a>
+      </p>
+    </blockquote>
+  
+    <h4>Documentation about Subversion</h3>
+    <blockquote>
+      <p>
+        <a href="http://svnbook.red-bean.com/"><em>Version Control with
+        Subversion</em></a><br />
+      </p>
+    </blockquote>
+  </td></tr></table>
+  <hr />
+  <address><a href="mailto:users at viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
+  </body>
+</html>
diff --git a/src/www/scm/viewvc/templates/docroot/images/annotate.png b/src/www/scm/viewvc/docroot/images/annotate.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/annotate.png
rename to src/www/scm/viewvc/docroot/images/annotate.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/back.png b/src/www/scm/viewvc/docroot/images/back.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/back.png
rename to src/www/scm/viewvc/docroot/images/back.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/back_small.png b/src/www/scm/viewvc/docroot/images/back_small.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/back_small.png
rename to src/www/scm/viewvc/docroot/images/back_small.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/broken.png b/src/www/scm/viewvc/docroot/images/broken.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/broken.png
rename to src/www/scm/viewvc/docroot/images/broken.png
diff --git a/src/www/themes/funky-wOw/viewvc/images/chalk.jpg b/src/www/scm/viewvc/docroot/images/chalk.jpg
similarity index 100%
rename from src/www/themes/funky-wOw/viewvc/images/chalk.jpg
rename to src/www/scm/viewvc/docroot/images/chalk.jpg
diff --git a/src/www/scm/viewvc/templates/docroot/images/cvsgraph_16x16.png b/src/www/scm/viewvc/docroot/images/cvsgraph_16x16.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/cvsgraph_16x16.png
rename to src/www/scm/viewvc/docroot/images/cvsgraph_16x16.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/cvsgraph_32x32.png b/src/www/scm/viewvc/docroot/images/cvsgraph_32x32.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/cvsgraph_32x32.png
rename to src/www/scm/viewvc/docroot/images/cvsgraph_32x32.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/diff.png b/src/www/scm/viewvc/docroot/images/diff.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/diff.png
rename to src/www/scm/viewvc/docroot/images/diff.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/dir.png b/src/www/scm/viewvc/docroot/images/dir.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/dir.png
rename to src/www/scm/viewvc/docroot/images/dir.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/down.png b/src/www/scm/viewvc/docroot/images/down.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/down.png
rename to src/www/scm/viewvc/docroot/images/down.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/download.png b/src/www/scm/viewvc/docroot/images/download.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/download.png
rename to src/www/scm/viewvc/docroot/images/download.png
diff --git a/src/www/scm/viewvc/docroot/images/favicon.ico b/src/www/scm/viewvc/docroot/images/favicon.ico
new file mode 100644
index 0000000..9ba7f80
Binary files /dev/null and b/src/www/scm/viewvc/docroot/images/favicon.ico differ
diff --git a/src/www/themes/funky-wOw/viewvc/images/feed-icon-16x16.jpg b/src/www/scm/viewvc/docroot/images/feed-icon-16x16.jpg
similarity index 100%
rename from src/www/themes/funky-wOw/viewvc/images/feed-icon-16x16.jpg
rename to src/www/scm/viewvc/docroot/images/feed-icon-16x16.jpg
diff --git a/src/www/scm/viewvc/templates/docroot/images/forward.png b/src/www/scm/viewvc/docroot/images/forward.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/forward.png
rename to src/www/scm/viewvc/docroot/images/forward.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/list.png b/src/www/scm/viewvc/docroot/images/list.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/list.png
rename to src/www/scm/viewvc/docroot/images/list.png
diff --git a/src/www/scm/viewvc/docroot/images/lock.png b/src/www/scm/viewvc/docroot/images/lock.png
new file mode 100644
index 0000000..9e3bf42
Binary files /dev/null and b/src/www/scm/viewvc/docroot/images/lock.png differ
diff --git a/src/www/scm/viewvc/templates/docroot/images/log.png b/src/www/scm/viewvc/docroot/images/log.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/log.png
rename to src/www/scm/viewvc/docroot/images/log.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/text.png b/src/www/scm/viewvc/docroot/images/text.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/text.png
rename to src/www/scm/viewvc/docroot/images/text.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/up.png b/src/www/scm/viewvc/docroot/images/up.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/up.png
rename to src/www/scm/viewvc/docroot/images/up.png
diff --git a/src/www/scm/viewvc/templates/docroot/images/view.png b/src/www/scm/viewvc/docroot/images/view.png
similarity index 100%
rename from src/www/scm/viewvc/templates/docroot/images/view.png
rename to src/www/scm/viewvc/docroot/images/view.png
diff --git a/src/www/scm/viewvc/docroot/images/viewvc-logo.png b/src/www/scm/viewvc/docroot/images/viewvc-logo.png
new file mode 100644
index 0000000..6e16f3b
Binary files /dev/null and b/src/www/scm/viewvc/docroot/images/viewvc-logo.png differ
diff --git a/src/www/scm/viewvc/docroot/styles.css b/src/www/scm/viewvc/docroot/styles.css
new file mode 100644
index 0000000..2abc752
--- /dev/null
+++ b/src/www/scm/viewvc/docroot/styles.css
@@ -0,0 +1,282 @@
+/*******************************/
+/***  ViewVC CSS Stylesheet ***/
+/*******************************/
+
+/*** Standard Tags ***/
+html, body {
+  color: #000000;
+  background-color: #ffffff;
+  font-family: sans-serif;
+}
+
+a:link    { color: #0000ff; }
+a:visited { color: #880088; }
+a:active  { color: #0000ff; }
+
+img { border: none; }
+table {
+  width: 100%;
+  margin: 0; 
+  border: none;
+}
+table.auto {
+  width: auto;
+}
+table.fixed {
+  width: 100%;
+  table-layout: fixed;
+}
+table.fixed td {
+  overflow: hidden; 
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+tr, td, th { vertical-align: top; }
+th { white-space: nowrap; }
+form { margin: 0; }
+
+
+/*** Icons ***/
+.vc_icon {
+  width: 16px;
+  height: 16px;
+  border: none;
+  padding: 0 1px;
+}
+
+
+/*** Navigation Headers ***/
+.vc_navheader {
+  background-color: #cccccc;
+  padding: .25em;
+}
+.vc_navheader .pathdiv {
+  padding: 0 3px;
+}
+
+
+/*** Table Headers ***/
+.vc_header {
+  text-align: left;
+  vertical-align: top;
+  background-color: #cccccc;
+}
+.vc_header_sort {
+  text-align: left;
+  background-color: #88ff88;
+}
+
+
+/*** Table Rows ***/
+.vc_row_even {
+  background-color: #ffffff;
+}
+.vc_row_odd {
+  background-color: #f0f0f0;
+}
+.vc_row_special {
+  background-color: #ffff7f;
+}
+
+
+/*** Log messages ***/
+.vc_log {
+  /* unfortunately, white-space: pre-wrap isn't widely supported ... */
+  white-space: -moz-pre-wrap; /* Mozilla based browsers */
+  white-space: -pre-wrap;     /* Opera 4 - 6 */
+  white-space: -o-pre-wrap;   /* Opera >= 7 */
+  white-space: pre-wrap;      /* CSS3 */
+  word-wrap: break-word;      /* IE 5.5+ */
+}
+
+
+/*** Properties Listing ***/
+.vc_properties {
+  margin: 1em 0;
+}
+
+
+/*** File Content Markup Styles ***/
+.vc_summary {
+  background-color: #eeeeee;
+}
+#vc_file td {
+  border-right-style: solid;
+  border-right-color: #505050;
+  text-decoration: none;
+  font-weight: normal;
+  font-style: normal;
+  padding: 1px 5px;
+}
+.vc_file_line_number {
+  border-right-width: 1px;
+  background-color: #eeeeee;
+  color: #505050;
+  text-align: right;
+}
+.vc_file_line_author, .vc_file_line_rev {
+  border-right-width: 1px;
+  text-align: right;
+}
+.vc_file_line_text {
+  border-right-width: 0px;
+  background-color: white;
+  font-family: monospace;
+  text-align: left;
+  white-space: pre;
+  width: 100%;
+}
+.pygments-c { color: #408080; font-style: italic } /* Comment */
+.pygments-err { border: 1px solid #FF0000 } /* Error */
+.pygments-k { color: #008000; font-weight: bold } /* Keyword */
+.pygments-o { color: #666666 } /* Operator */
+.pygments-cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.pygments-cp { color: #BC7A00 } /* Comment.Preproc */
+.pygments-c1 { color: #408080; font-style: italic } /* Comment.Single */
+.pygments-cs { color: #408080; font-style: italic } /* Comment.Special */
+.pygments-gd { color: #A00000 } /* Generic.Deleted */
+.pygments-ge { font-style: italic } /* Generic.Emph */
+.pygments-gr { color: #FF0000 } /* Generic.Error */
+.pygments-gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.pygments-gi { color: #00A000 } /* Generic.Inserted */
+.pygments-go { color: #808080 } /* Generic.Output */
+.pygments-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.pygments-gs { font-weight: bold } /* Generic.Strong */
+.pygments-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.pygments-gt { color: #0040D0 } /* Generic.Traceback */
+.pygments-kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.pygments-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.pygments-kp { color: #008000 } /* Keyword.Pseudo */
+.pygments-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.pygments-kt { color: #B00040 } /* Keyword.Type */
+.pygments-m { color: #666666 } /* Literal.Number */
+.pygments-s { color: #BA2121 } /* Literal.String */
+.pygments-na { color: #7D9029 } /* Name.Attribute */
+.pygments-nb { color: #008000 } /* Name.Builtin */
+.pygments-nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.pygments-no { color: #880000 } /* Name.Constant */
+.pygments-nd { color: #AA22FF } /* Name.Decorator */
+.pygments-ni { color: #999999; font-weight: bold } /* Name.Entity */
+.pygments-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.pygments-nf { color: #0000FF } /* Name.Function */
+.pygments-nl { color: #A0A000 } /* Name.Label */
+.pygments-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.pygments-nt { color: #008000; font-weight: bold } /* Name.Tag */
+.pygments-nv { color: #19177C } /* Name.Variable */
+.pygments-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.pygments-w { color: #bbbbbb } /* Text.Whitespace */
+.pygments-mf { color: #666666 } /* Literal.Number.Float */
+.pygments-mh { color: #666666 } /* Literal.Number.Hex */
+.pygments-mi { color: #666666 } /* Literal.Number.Integer */
+.pygments-mo { color: #666666 } /* Literal.Number.Oct */
+.pygments-sb { color: #BA2121 } /* Literal.String.Backtick */
+.pygments-sc { color: #BA2121 } /* Literal.String.Char */
+.pygments-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.pygments-s2 { color: #BA2121 } /* Literal.String.Double */
+.pygments-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.pygments-sh { color: #BA2121 } /* Literal.String.Heredoc */
+.pygments-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.pygments-sx { color: #008000 } /* Literal.String.Other */
+.pygments-sr { color: #BB6688 } /* Literal.String.Regex */
+.pygments-s1 { color: #BA2121 } /* Literal.String.Single */
+.pygments-ss { color: #19177C } /* Literal.String.Symbol */
+.pygments-bp { color: #008000 } /* Name.Builtin.Pseudo */
+.pygments-vc { color: #19177C } /* Name.Variable.Class */
+.pygments-vg { color: #19177C } /* Name.Variable.Global */
+.pygments-vi { color: #19177C } /* Name.Variable.Instance */
+.pygments-il { color: #666666 } /* Literal.Number.Integer.Long */
+
+
+/*** Diff Styles ***/
+.vc_diff_header {
+  background-color: #ffffff;
+}
+.vc_diff_chunk_header {
+  background-color: #99cccc;
+}
+.vc_diff_chunk_extra {
+  font-size: smaller;
+}
+.vc_diff_empty {
+  background-color: #cccccc;
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_add {
+  background-color: #aaffaa;
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_remove {
+  background-color: #ffaaaa;
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_change {
+  background-color: #ffff77;
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_change_empty {
+  background-color: #eeee77;
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_nochange {
+  font-family: sans-serif;
+  font-size: smaller;
+}
+.vc_diff_line_number {
+}
+.vc_raw_diff {
+  background-color: #cccccc;
+  font-size: smaller;
+}
+
+
+/*** Intraline Diff Styles ***/
+.vc_idiff_add {
+  background-color: #aaffaa;
+}
+.vc_idiff_change {
+  background-color:#ffff77;
+}
+.vc_idiff_remove {
+  background-color:#ffaaaa;
+}
+.vc_idiff_empty {
+  background-color:#e0e0e0;
+}
+table.vc_idiff col.content { 
+  width: 50%;
+}
+table.vc_idiff tbody {
+  font-family: monospace; 
+  /* unfortunately, white-space: pre-wrap isn't widely supported ... */
+  white-space: -moz-pre-wrap; /* Mozilla based browsers */
+  white-space: -pre-wrap;     /* Opera 4 - 6 */
+  white-space: -o-pre-wrap;   /* Opera >= 7 */
+  white-space: pre-wrap;      /* CSS3 */
+  word-wrap: break-word;      /* IE 5.5+ */
+}
+table.vc_idiff tbody th {
+  background-color:#e0e0e0;
+  text-align:right;
+}
+
+
+/*** Query Form ***/
+.vc_query_form {
+  background-color: #e6e6e6;
+}
+
+
+/*** Warning! ***/
+.vc_warning {
+  border-width: 1px 2px 2px 2px;
+  border-color: black;
+  border-style: solid;
+  background-color: red;
+  color: white;
+  padding: 0.5em;
+}
diff --git a/src/www/scm/viewvc/lib/PyFontify.py b/src/www/scm/viewvc/lib/PyFontify.py
deleted file mode 100644
index d700bc4..0000000
--- a/src/www/scm/viewvc/lib/PyFontify.py
+++ /dev/null
@@ -1,173 +0,0 @@
-"""Module to analyze Python source code; for syntax coloring tools.
-
-Interface:
-
-    tags = fontify(pytext, searchfrom, searchto)
-
-The PYTEXT argument is a string containing Python source code.  The
-(optional) arguments SEARCHFROM and SEARCHTO may contain a slice in
-PYTEXT.
-
-The returned value is a list of tuples, formatted like this:
-
-    [('keyword', 0, 6, None),
-     ('keyword', 11, 17, None),
-     ('comment', 23, 53, None),
-     ...
-    ]
-    
-The tuple contents are always like this:
-
-    (tag, startindex, endindex, sublist)
-    
-TAG is one of 'keyword', 'string', 'comment' or 'identifier'
-SUBLIST is not used, hence always None.
-"""
-
-# Based on FontText.py by Mitchell S. Chapman,
-# which was modified by Zachary Roadhouse,
-# then un-Tk'd by Just van Rossum.
-# Many thanks for regular expression debugging & authoring are due to:
-#    Tim (the-incredib-ly y'rs) Peters and Cristian Tismer
-# So, who owns the copyright? ;-) How about this:
-# Copyright 1996-1997: 
-#    Mitchell S. Chapman,
-#    Zachary Roadhouse,
-#    Tim Peters,
-#    Just van Rossum
-
-__version__ = "0.3.1"
-
-import string, re
-
-
-# This list of keywords is taken from ref/node13.html of the
-# Python 1.3 HTML documentation. ("access" is intentionally omitted.)
-
-keywordsList = ["and", "assert", "break", "class", "continue", "def",
-                "del", "elif", "else", "except", "exec", "finally",
-                "for", "from", "global", "if", "import", "in", "is",
-                "lambda", "not", "or", "pass", "print", "raise",
-                "return", "try", "while",
-                ]
-
-# First a little helper, since I don't like to repeat things. (Tismer speaking)
-def replace(where, what, whatwith):
-    return string.join(string.split(where, what), whatwith)
-
-# A regexp for matching Python comments.
-commentPat = "#.*"
-
-# A regexp for matching simple quoted strings.
-pat = "q[^q\\n]*(\\[\000-\377][^q\\n]*)*q"
-quotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
-
-# A regexp for matching multi-line tripled-quoted strings.  (Way to go, Tim!)
-pat = """
-    qqq
-    [^q]*
-    (
-        (    \\[\000-\377]
-        |    q
-            (    \\[\000-\377]
-            |    [^q]
-            |    q
-                (    \\[\000-\377]
-                |    [^q]
-                )
-            )
-        )
-        [^q]*
-    )*
-    qqq
-"""
-pat = string.join(string.split(pat), '')   # get rid of whitespace
-tripleQuotePat = replace(pat, "q", "'") + "|" + replace(pat, 'q', '"')
-
-# A regexp which matches all and only Python keywords. This will let
-# us skip the uninteresting identifier references.
-nonKeyPat = "(^|[^a-zA-Z0-9_.\"'])"   # legal keyword-preceding characters
-keyPat = nonKeyPat + "(" + string.join(keywordsList, "|") + ")" + nonKeyPat
-
-# Our final syntax-matching regexp is the concatation of the regexp's we
-# constructed above.
-syntaxPat = keyPat + \
-            "|" + commentPat + \
-            "|" + tripleQuotePat + \
-            "|" + quotePat
-syntaxRE = re.compile(syntaxPat)
-
-# Finally, we construct a regexp for matching indentifiers (with
-# optional leading whitespace).
-idKeyPat = "[ \t]*[A-Za-z_][A-Za-z_0-9.]*"
-idRE = re.compile(idKeyPat)
-
-
-def fontify(pytext, searchfrom=0, searchto=None):
-    if searchto is None:
-        searchto = len(pytext)
-    tags = []
-    commentTag = 'comment'
-    stringTag = 'string'
-    keywordTag = 'keyword'
-    identifierTag = 'identifier'
-    
-    start = 0
-    end = searchfrom
-    while 1:
-        # Look for some syntax token we're interested in.  If find
-        # nothing, we're done.
-        matchobj = syntaxRE.search(pytext, end)
-        if not matchobj:
-            break
-
-        # If we found something outside our search area, it doesn't
-        # count (and we're done).
-        start = matchobj.start()
-        if start >= searchto:
-            break
-
-        match = matchobj.group(0)
-        end = start + len(match)
-        c = match[0]
-        if c == '#':
-            # We matched a comment.
-            tags.append((commentTag, start, end, None))
-        elif c == '"' or c == '\'':
-            # We matched a string.
-            tags.append((stringTag, start, end, None))
-        else:
-            # We matched a keyword.
-            if start != searchfrom:
-                # there's still a redundant char before and after it, strip!
-                match = match[1:-1]
-                start = start + 1
-            else:
-                # This is the first keyword in the text.
-                # Only a space at the end.
-                match = match[:-1]
-            end = end - 1
-            tags.append((keywordTag, start, end, None))
-            # If this was a defining keyword, look ahead to the
-            # following identifier.
-            if match in ["def", "class"]:
-                matchobj = idRE.search(pytext, end)
-                if matchobj:
-                    start = matchobj.start()
-                    if start == end and start < searchto:
-                        end = start + len(matchobj.group(0))
-                        tags.append((identifierTag, start, end, None))
-    return tags
-
-
-def test(path):
-    f = open(path)
-    text = f.read()
-    f.close()
-    tags = fontify(text)
-    for tag, start, end, sublist in tags:
-        print tag, `text[start:end]`
-
-if __name__ == "__main__":
-    import sys
-    test(sys.argv[0])
diff --git a/src/www/scm/viewvc/lib/accept.py b/src/www/scm/viewvc/lib/accept.py
deleted file mode 100644
index 0980287..0000000
--- a/src/www/scm/viewvc/lib/accept.py
+++ /dev/null
@@ -1,236 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# accept.py: parse/handle the various Accept headers from the client
-#
-# -----------------------------------------------------------------------
-
-import re
-import string
-
-
-def language(hdr):
-  "Parse an Accept-Language header."
-
-  # parse the header, storing results in a _LanguageSelector object
-  return _parse(hdr, _LanguageSelector())
-
-# -----------------------------------------------------------------------
-
-_re_token = re.compile(r'\s*([^\s;,"]+|"[^"]*")+\s*')
-_re_param = re.compile(r';\s*([^;,"]+|"[^"]*")+\s*')
-_re_split_param = re.compile(r'([^\s=])\s*=\s*(.*)')
-
-def _parse(hdr, result):
-  # quick exit for empty or not-supplied header
-  if not hdr:
-    return result
-
-  pos = 0
-  while pos < len(hdr):
-    name = _re_token.match(hdr, pos)
-    if not name:
-      raise AcceptParseError()
-    a = result.item_class(string.lower(name.group(1)))
-    pos = name.end()
-    while 1:
-      # are we looking at a parameter?
-      match = _re_param.match(hdr, pos)
-      if not match:
-        break
-      param = match.group(1)
-      pos = match.end()
-
-      # split up the pieces of the parameter
-      match = _re_split_param.match(param)
-      if not match:
-        # the "=" was probably missing
-        continue
-
-      pname = string.lower(match.group(1))
-      if pname == 'q' or pname == 'qs':
-        try:
-          a.quality = float(match.group(2))
-        except ValueError:
-          # bad float literal
-          pass
-      elif pname == 'level':
-        try:
-          a.level = float(match.group(2))
-        except ValueError:
-          # bad float literal
-          pass
-      elif pname == 'charset':
-        a.charset = string.lower(match.group(2))
-
-    result.append(a)
-    if hdr[pos:pos+1] == ',':
-      pos = pos + 1
-
-  return result
-
-class _AcceptItem:
-  def __init__(self, name):
-    self.name = name
-    self.quality = 1.0
-    self.level = 0.0
-    self.charset = ''
-
-  def __str__(self):
-    s = self.name
-    if self.quality != 1.0:
-      s = '%s;q=%.3f' % (s, self.quality)
-    if self.level != 0.0:
-      s = '%s;level=%.3f' % (s, self.level)
-    if self.charset:
-      s = '%s;charset=%s' % (s, self.charset)
-    return s
-
-class _LanguageRange(_AcceptItem):
-  def matches(self, tag):
-    "Match the tag against self. Returns the qvalue, or None if non-matching."
-    if tag == self.name:
-      return self.quality
-
-    # are we a prefix of the available language-tag
-    name = self.name + '-'
-    if tag[:len(name)] == name:
-      return self.quality
-    return None
-
-class _LanguageSelector:
-  """Instances select an available language based on the user's request.
-
-  Languages found in the user's request are added to this object with the
-  append() method (they should be instances of _LanguageRange). After the
-  languages have been added, then the caller can use select_from() to
-  determine which user-request language(s) best matches the set of
-  available languages.
-
-  Strictly speaking, this class is pretty close for more than just
-  language matching. It has been implemented to enable q-value based
-  matching between requests and availability. Some minor tweaks may be
-  necessary, but simply using a new 'item_class' should be sufficient
-  to allow the _parse() function to construct a selector which holds
-  the appropriate item implementations (e.g. _LanguageRange is the
-  concrete _AcceptItem class that handles matching of language tags).
-  """
-
-  item_class = _LanguageRange
-
-  def __init__(self):
-    self.requested = [ ]
-
-  def select_from(self, avail):
-    """Select one of the available choices based on the request.
-
-    Note: if there isn't a match, then the first available choice is
-    considered the default. Also, if a number of matches are equally
-    relevant, then the first-requested will be used.
-
-    avail is a list of language-tag strings of available languages
-    """
-
-    # tuples of (qvalue, language-tag)
-    matches = [ ]
-
-    # try matching all pairs of desired vs available, recording the
-    # resulting qvalues. we also need to record the longest language-range
-    # that matches since the most specific range "wins"
-    for tag in avail:
-      longest = 0
-      final = 0.0
-
-      # check this tag against the requests from the user
-      for want in self.requested:
-        qvalue = want.matches(tag)
-        #print 'have %s. want %s. qvalue=%s' % (tag, want.name, qvalue)
-        if qvalue is not None and len(want.name) > longest:
-          # we have a match and it is longer than any we may have had.
-          # the final qvalue should be from this tag.
-          final = qvalue
-          longest = len(want.name)
-
-      # a non-zero qvalue is a potential match
-      if final:
-        matches.append((final, tag))
-
-    # if there are no matches, then return the default language tag
-    if not matches:
-      return avail[0]
-
-    # get the highest qvalue and its corresponding tag
-    matches.sort()
-    qvalue, tag = matches[-1]
-
-    # if the qvalue is zero, then we have no valid matches. return the
-    # default language tag.
-    if not qvalue:
-      return avail[0]
-
-    # if there are two or more matches, and the second-highest has a
-    # qvalue equal to the best, then we have multiple "best" options.
-    # select the one that occurs first in self.requested
-    if len(matches) >= 2 and matches[-2][0] == qvalue:
-      # remove non-best matches
-      while matches[0][0] != qvalue:
-        del matches[0]
-      #print "non-deterministic choice", matches
-
-      # sequence through self.requested, in order
-      for want in self.requested:
-        # try to find this one in our best matches
-        for qvalue, tag in matches:
-          if want.matches(tag):
-            # this requested item is one of the "best" options
-            ### note: this request item could match *other* "best" options,
-            ### so returning *this* one is rather non-deterministic.
-            ### theoretically, we could go further here, and do another
-            ### search based on the ordering in 'avail'. however, note
-            ### that this generally means that we are picking from multiple
-            ### *SUB* languages, so I'm all right with the non-determinism
-            ### at this point. stupid client should send a qvalue if they
-            ### want to refine.
-            return tag
-
-      # NOTREACHED
-
-    # return the best match
-    return tag
-
-  def append(self, item):
-    self.requested.append(item)
-
-class AcceptParseError(Exception):
-  pass
-
-def _test():
-  s = language('en')
-  assert s.select_from(['en']) == 'en'
-  assert s.select_from(['en', 'de']) == 'en'
-  assert s.select_from(['de', 'en']) == 'en'
-
-  # Netscape 4.x and early version of Mozilla may not send a q value
-  s = language('en, ja')
-  assert s.select_from(['en', 'ja']) == 'en'
-
-  s = language('fr, de;q=0.9, en-gb;q=0.7, en;q=0.6, en-gb-foo;q=0.8')
-  assert s.select_from(['en']) == 'en'
-  assert s.select_from(['en-gb-foo']) == 'en-gb-foo'
-  assert s.select_from(['de', 'fr']) == 'fr'
-  assert s.select_from(['de', 'en-gb']) == 'de'
-  assert s.select_from(['en-gb', 'en-gb-foo']) == 'en-gb-foo'
-  assert s.select_from(['en-bar']) == 'en-bar'
-  assert s.select_from(['en-gb-bar', 'en-gb-foo']) == 'en-gb-foo'
-
-  # non-deterministic. en-gb;q=0.7 matches both avail tags.
-  #assert s.select_from(['en-gb-bar', 'en-gb']) == 'en-gb'
diff --git a/src/www/scm/viewvc/lib/blame.py b/src/www/scm/viewvc/lib/blame.py
deleted file mode 100644
index e8134b9..0000000
--- a/src/www/scm/viewvc/lib/blame.py
+++ /dev/null
@@ -1,177 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-# Copyright (C) 2000 Curt Hagenlocher <curt at hagenlocher.org>
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# blame.py: Annotate each line of a CVS file with its author,
-#           revision #, date, etc.
-#
-# -----------------------------------------------------------------------
-#
-# This file is based on the cvsblame.pl portion of the Bonsai CVS tool,
-# developed by Steve Lamm for Netscape Communications Corporation.  More
-# information about Bonsai can be found at
-#    http://www.mozilla.org/bonsai.html
-#
-# cvsblame.pl, in turn, was based on Scott Furman's cvsblame script
-#
-# -----------------------------------------------------------------------
-
-import string
-import os
-import re
-import time
-import math
-import cgi
-import vclib
-import vclib.ccvs.blame
-
-
-re_includes = re.compile('\\#(\\s*)include(\\s*)"(.*?)"')
-
-def link_includes(text, repos, path_parts, include_url):
-  match = re_includes.match(text)
-  if match:
-    incfile = match.group(3)
-
-    # check current directory and parent directory for file
-    for depth in (-1, -2):
-      include_path = path_parts[:depth] + [incfile]
-      try:
-        # will throw if path doesn't exist
-        if repos.itemtype(include_path, None) == vclib.FILE:
-          break
-      except vclib.ItemNotFound:
-        pass
-    else:
-      include_path = None
-
-    if include_path:
-        url = string.replace(include_url, '/WHERE/', 
-                             string.join(include_path, '/'))
-        return '#%sinclude%s<a href="%s">"%s"</a>' % \
-               (match.group(1), match.group(2), url, incfile)
-       
-  return text
-
-
-class HTMLBlameSource:
-  """Wrapper around a the object by the vclib.annotate() which does
-  HTML escaping, diff URL generation, and #include linking."""
-  def __init__(self, repos, path_parts, diff_url, include_url, opt_rev=None):
-    self.repos = repos
-    self.path_parts = path_parts
-    self.diff_url = diff_url
-    self.include_url = include_url
-    self.annotation, self.revision = self.repos.annotate(path_parts, opt_rev)
-
-  def __getitem__(self, idx):
-    item = self.annotation.__getitem__(idx)
-    diff_url = None
-    if item.prev_rev:
-      diff_url = '%sr1=%s&r2=%s' % (self.diff_url, item.prev_rev, item.rev)
-    thisline = link_includes(cgi.escape(item.text), self.repos,
-                             self.path_parts, self.include_url)
-    return _item(text=thisline, line_number=item.line_number,
-                 rev=item.rev, prev_rev=item.prev_rev,
-                 diff_url=diff_url, date=item.date, author=item.author)
-
-
-def blame(repos, path_parts, diff_url, include_url, opt_rev=None):
-  source = HTMLBlameSource(repos, path_parts, diff_url, include_url, opt_rev)
-  return source, source.revision
-
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
-
-
-def make_html(root, rcs_path):
-  bs = vclib.ccvs.blame.BlameSource(os.path.join(root, rcs_path))
-
-  count = bs.num_lines
-  if count == 0:
-    count = 1
-
-  line_num_width = int(math.log10(count)) + 1
-  revision_width = 3
-  author_width = 5
-  line = 0
-  old_revision = 0
-  row_color = ''
-  inMark = 0
-  rev_count = 0
-
-  open_table_tag = '<table cellpadding="0" cellspacing="0">'
-  startOfRow = '<tr><td colspan="3"%s><pre>'
-  endOfRow = '</td></tr>'
-
-  print open_table_tag + (startOfRow % '')
-
-  for line_data in bs:
-    revision = line_data.rev
-    thisline = line_data.text
-    line = line_data.line_number
-    author = line_data.author
-    prev_rev = line_data.prev_rev
-    
-    output = ''
-
-    if old_revision != revision and line != 1:
-      if row_color == '':
-        row_color = ' style="background-color:#e7e7e7"'
-      else:
-        row_color = ''
-
-      if not inMark:
-        output = output + endOfRow + (startOfRow % row_color)
-
-    output = output + '<a name="%d">%*d</a>' % (line, line_num_width, line)
-
-    if old_revision != revision or rev_count > 20:
-      revision_width = max(revision_width, len(revision))
-      output = output + ' '
-      author_width = max(author_width, len(author))
-      output = output + ('%-*s ' % (author_width, author))
-      output = output + revision
-      if prev_rev:
-        output = output + '</a>'
-      output = output + (' ' * (revision_width - len(revision) + 1))
-
-      old_revision = revision
-      rev_count = 0
-    else:
-      output = output + '   ' + (' ' * (author_width + revision_width))
-    rev_count = rev_count + 1
-
-    output = output + thisline
-
-    # Close the highlighted section
-    #if (defined $mark_cmd and mark_cmd != 'begin'):
-    #	chop($output)
-    #	output = output + endOfRow + (startOfRow % row_color)
-    #	inMark = 0
-
-    print output
-  print endOfRow + '</table>'
-
-
-def main():
-  import sys
-  if len(sys.argv) != 3:
-    print 'USAGE: %s cvsroot rcs-file' % sys.argv[0]
-    sys.exit(1)
-  make_html(sys.argv[1], sys.argv[2])
-
-if __name__ == '__main__':
-  main()
diff --git a/src/www/scm/viewvc/lib/compat.py b/src/www/scm/viewvc/lib/compat.py
deleted file mode 100644
index eebbc60..0000000
--- a/src/www/scm/viewvc/lib/compat.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# compat.py: compatibility functions for operation across Python 1.5.x to 2.2.x
-#
-# -----------------------------------------------------------------------
-
-import urllib
-import string
-import time
-import calendar
-import re
-import os
-import rfc822
-import tempfile
-import errno
-
-#
-# urllib.urlencode() is new to Python 1.5.2
-#
-try:
-  urlencode = urllib.urlencode
-except AttributeError:
-  def urlencode(dict):
-    "Encode a dictionary as application/x-url-form-encoded."
-    if not dict:
-      return ''
-    quote = urllib.quote_plus
-    keyvalue = [ ]
-    for key, value in dict.items():
-      keyvalue.append(quote(key) + '=' + quote(str(value)))
-    return string.join(keyvalue, '&')
-
-#
-# time.strptime() is new to Python 1.5.2
-#
-if hasattr(time, 'strptime'):
-  def cvs_strptime(timestr):
-    'Parse a CVS-style date/time value.'
-    return time.strptime(timestr, '%Y/%m/%d %H:%M:%S')[:-1] + (0,)
-else:
-  _re_rev_date = re.compile('([0-9]{4})/([0-9][0-9])/([0-9][0-9]) '
-                            '([0-9][0-9]):([0-9][0-9]):([0-9][0-9])')
-  def cvs_strptime(timestr):
-    'Parse a CVS-style date/time value.'
-    match = _re_rev_date.match(timestr)
-    if match:
-      return tuple(map(int, match.groups())) + (0, 1, 0)
-    else:
-      raise ValueError('date is not in cvs format')
-
-#
-# os.makedirs() is new to Python 1.5.2
-#
-try:
-  makedirs = os.makedirs
-except AttributeError:
-  def makedirs(path, mode=0777):
-    head, tail = os.path.split(path)
-    if head and tail and not os.path.exists(head):
-      makedirs(head, mode)
-    os.mkdir(path, mode)
-
-#
-# rfc822.formatdate() is new to Python 1.6
-#
-try:
-  formatdate = rfc822.formatdate
-except AttributeError:
-  def formatdate(timeval):
-    if timeval is None:
-      timeval = time.time()
-    timeval = time.gmtime(timeval)
-    return "%s, %02d %s %04d %02d:%02d:%02d GMT" % (
-            ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"][timeval[6]],
-            timeval[2],
-            ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
-             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][timeval[1]-1],
-                                timeval[0], timeval[3], timeval[4], timeval[5])
-
-# 
-# calendar.timegm() is new to Python 2.x and 
-# calendar.leapdays() was wrong in Python 1.5.2
-#
-try:
-  timegm = calendar.timegm 
-except AttributeError:
-  def leapdays(year1, year2):
-    """Return number of leap years in range [year1, year2).
-       Assume year1 <= year2."""
-    year1 = year1 - 1
-    year2 = year2 - 1
-    return (year2/4 - year1/4) - (year2/100 - 
-                                  year1/100) + (year2/400 - year1/400)
-
-  EPOCH = 1970
-  def timegm(tuple):
-    """Unrelated but handy function to calculate Unix timestamp from GMT."""
-    year, month, day, hour, minute, second = tuple[:6]
-    # assert year >= EPOCH
-    # assert 1 <= month <= 12
-    days = 365*(year-EPOCH) + leapdays(EPOCH, year)
-    for i in range(1, month):
-      days = days + calendar.mdays[i]
-    if month > 2 and calendar.isleap(year):
-      days = days + 1
-    days = days + day - 1
-    hours = days*24 + hour
-    minutes = hours*60 + minute
-    seconds = minutes*60 + second
-    return seconds
-
-#
-# tempfile.mkdtemp() is new to Python 2.3
-#
-try:
-  mkdtemp = tempfile.mkdtemp
-except AttributeError:
-  def mkdtemp():
-    for i in range(10):
-      dir = tempfile.mktemp()
-      try:
-        os.mkdir(dir, 0700)
-        return dir
-      except OSError, e:
-        if e.errno == errno.EEXIST:
-          continue # try again
-        raise
-
-    raise IOError, (errno.EEXIST, "No usable temporary directory name found")
-
-# 
-# the following stuff is *ONLY* needed for standalone.py.
-# For that reason I've encapsulated it into a function.
-#
-
-def for_standalone():
-  import SocketServer
-  if not hasattr(SocketServer.TCPServer, "close_request"):
-    #
-    # method close_request() was missing until Python 2.1
-    #
-    class TCPServer(SocketServer.TCPServer):
-      def process_request(self, request, client_address):
-        """Call finish_request.
-
-        Overridden by ForkingMixIn and ThreadingMixIn.
-
-        """
-        self.finish_request(request, client_address)
-        self.close_request(request)
-
-      def close_request(self, request):
-        """Called to clean up an individual request."""
-        request.close()
-
-    SocketServer.TCPServer = TCPServer
diff --git a/src/www/scm/viewvc/lib/compat_difflib.py b/src/www/scm/viewvc/lib/compat_difflib.py
deleted file mode 100755
index 9dfecf4..0000000
--- a/src/www/scm/viewvc/lib/compat_difflib.py
+++ /dev/null
@@ -1,786 +0,0 @@
-#! /usr/bin/env python
-# Backported to Python 1.5.2 for the ViewCVS project by pf at artcom-gmbh.de
-# 24-Dec-2001, original version "stolen" from Python-2.1.1
-"""
-Module difflib -- helpers for computing deltas between objects.
-
-Function get_close_matches(word, possibilities, n=3, cutoff=0.6):
-
-    Use SequenceMatcher to return list of the best "good enough" matches.
-
-    word is a sequence for which close matches are desired (typically a
-    string).
-
-    possibilities is a list of sequences against which to match word
-    (typically a list of strings).
-
-    Optional arg n (default 3) is the maximum number of close matches to
-    return.  n must be > 0.
-
-    Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
-    that don't score at least that similar to word are ignored.
-
-    The best (no more than n) matches among the possibilities are returned
-    in a list, sorted by similarity score, most similar first.
-
-    >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
-    ['apple', 'ape']
-    >>> import keyword
-    >>> get_close_matches("wheel", keyword.kwlist)
-    ['while']
-    >>> get_close_matches("apple", keyword.kwlist)
-    []
-    >>> get_close_matches("accept", keyword.kwlist)
-    ['except']
-
-Class SequenceMatcher
-
-SequenceMatcher is a flexible class for comparing pairs of sequences of any
-type, so long as the sequence elements are hashable.  The basic algorithm
-predates, and is a little fancier than, an algorithm published in the late
-1980's by Ratcliff and Obershelp under the hyperbolic name "gestalt pattern
-matching".  The basic idea is to find the longest contiguous matching
-subsequence that contains no "junk" elements (R-O doesn't address junk).
-The same idea is then applied recursively to the pieces of the sequences to
-the left and to the right of the matching subsequence.  This does not yield
-minimal edit sequences, but does tend to yield matches that "look right"
-to people.
-
-Example, comparing two strings, and considering blanks to be "junk":
-
->>> s = SequenceMatcher(lambda x: x == " ",
-...                     "private Thread currentThread;",
-...                     "private volatile Thread currentThread;")
->>>
-
-.ratio() returns a float in [0, 1], measuring the "similarity" of the
-sequences.  As a rule of thumb, a .ratio() value over 0.6 means the
-sequences are close matches:
-
->>> print round(s.ratio(), 3)
-0.866
->>>
-
-If you're only interested in where the sequences match,
-.get_matching_blocks() is handy:
-
->>> for block in s.get_matching_blocks():
-...     print "a[%d] and b[%d] match for %d elements" % block
-a[0] and b[0] match for 8 elements
-a[8] and b[17] match for 6 elements
-a[14] and b[23] match for 15 elements
-a[29] and b[38] match for 0 elements
-
-Note that the last tuple returned by .get_matching_blocks() is always a
-dummy, (len(a), len(b), 0), and this is the only case in which the last
-tuple element (number of elements matched) is 0.
-
-If you want to know how to change the first sequence into the second, use
-.get_opcodes():
-
->>> for opcode in s.get_opcodes():
-...     print "%6s a[%d:%d] b[%d:%d]" % opcode
- equal a[0:8] b[0:8]
-insert a[8:8] b[8:17]
- equal a[8:14] b[17:23]
- equal a[14:29] b[23:38]
-
-See Tools/scripts/ndiff.py for a fancy human-friendly file differencer,
-which uses SequenceMatcher both to view files as sequences of lines, and
-lines as sequences of characters.
-
-See also function get_close_matches() in this module, which shows how
-simple code building on SequenceMatcher can be used to do useful work.
-
-Timing:  Basic R-O is cubic time worst case and quadratic time expected
-case.  SequenceMatcher is quadratic time for the worst case and has
-expected-case behavior dependent in a complicated way on how many
-elements the sequences have in common; best case time is linear.
-
-SequenceMatcher methods:
-
-__init__(isjunk=None, a='', b='')
-    Construct a SequenceMatcher.
-
-    Optional arg isjunk is None (the default), or a one-argument function
-    that takes a sequence element and returns true iff the element is junk.
-    None is equivalent to passing "lambda x: 0", i.e. no elements are
-    considered to be junk.  For example, pass
-        lambda x: x in " \\t"
-    if you're comparing lines as sequences of characters, and don't want to
-    synch up on blanks or hard tabs.
-
-    Optional arg a is the first of two sequences to be compared.  By
-    default, an empty string.  The elements of a must be hashable.
-
-    Optional arg b is the second of two sequences to be compared.  By
-    default, an empty string.  The elements of b must be hashable.
-
-set_seqs(a, b)
-    Set the two sequences to be compared.
-
-    >>> s = SequenceMatcher()
-    >>> s.set_seqs("abcd", "bcde")
-    >>> s.ratio()
-    0.75
-
-set_seq1(a)
-    Set the first sequence to be compared.
-
-    The second sequence to be compared is not changed.
-
-    >>> s = SequenceMatcher(None, "abcd", "bcde")
-    >>> s.ratio()
-    0.75
-    >>> s.set_seq1("bcde")
-    >>> s.ratio()
-    1.0
-    >>>
-
-    SequenceMatcher computes and caches detailed information about the
-    second sequence, so if you want to compare one sequence S against many
-    sequences, use .set_seq2(S) once and call .set_seq1(x) repeatedly for
-    each of the other sequences.
-
-    See also set_seqs() and set_seq2().
-
-set_seq2(b)
-    Set the second sequence to be compared.
-
-    The first sequence to be compared is not changed.
-
-    >>> s = SequenceMatcher(None, "abcd", "bcde")
-    >>> s.ratio()
-    0.75
-    >>> s.set_seq2("abcd")
-    >>> s.ratio()
-    1.0
-    >>>
-
-    SequenceMatcher computes and caches detailed information about the
-    second sequence, so if you want to compare one sequence S against many
-    sequences, use .set_seq2(S) once and call .set_seq1(x) repeatedly for
-    each of the other sequences.
-
-    See also set_seqs() and set_seq1().
-
-find_longest_match(alo, ahi, blo, bhi)
-    Find longest matching block in a[alo:ahi] and b[blo:bhi].
-
-    If isjunk is not defined:
-
-    Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
-        alo <= i <= i+k <= ahi
-        blo <= j <= j+k <= bhi
-    and for all (i',j',k') meeting those conditions,
-        k >= k'
-        i <= i'
-        and if i == i', j <= j'
-
-    In other words, of all maximal matching blocks, return one that starts
-    earliest in a, and of all those maximal matching blocks that start
-    earliest in a, return the one that starts earliest in b.
-
-    >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
-    >>> s.find_longest_match(0, 5, 0, 9)
-    (0, 4, 5)
-
-    If isjunk is defined, first the longest matching block is determined as
-    above, but with the additional restriction that no junk element appears
-    in the block.  Then that block is extended as far as possible by
-    matching (only) junk elements on both sides.  So the resulting block
-    never matches on junk except as identical junk happens to be adjacent
-    to an "interesting" match.
-
-    Here's the same example as before, but considering blanks to be junk.
-    That prevents " abcd" from matching the " abcd" at the tail end of the
-    second sequence directly.  Instead only the "abcd" can match, and
-    matches the leftmost "abcd" in the second sequence:
-
-    >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
-    >>> s.find_longest_match(0, 5, 0, 9)
-    (1, 0, 4)
-
-    If no blocks match, return (alo, blo, 0).
-
-    >>> s = SequenceMatcher(None, "ab", "c")
-    >>> s.find_longest_match(0, 2, 0, 1)
-    (0, 0, 0)
-
-get_matching_blocks()
-    Return list of triples describing matching subsequences.
-
-    Each triple is of the form (i, j, n), and means that
-    a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in i
-    and in j.
-
-    The last triple is a dummy, (len(a), len(b), 0), and is the only triple
-    with n==0.
-
-    >>> s = SequenceMatcher(None, "abxcd", "abcd")
-    >>> s.get_matching_blocks()
-    [(0, 0, 2), (3, 2, 2), (5, 4, 0)]
-
-get_opcodes()
-    Return list of 5-tuples describing how to turn a into b.
-
-    Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple has
-    i1 == j1 == 0, and remaining tuples have i1 == the i2 from the tuple
-    preceding it, and likewise for j1 == the previous j2.
-
-    The tags are strings, with these meanings:
-
-    'replace':  a[i1:i2] should be replaced by b[j1:j2]
-    'delete':   a[i1:i2] should be deleted.
-                Note that j1==j2 in this case.
-    'insert':   b[j1:j2] should be inserted at a[i1:i1].
-                Note that i1==i2 in this case.
-    'equal':    a[i1:i2] == b[j1:j2]
-
-    >>> a = "qabxcd"
-    >>> b = "abycdf"
-    >>> s = SequenceMatcher(None, a, b)
-    >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
-    ...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
-    ...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
-     delete a[0:1] (q) b[0:0] ()
-      equal a[1:3] (ab) b[0:2] (ab)
-    replace a[3:4] (x) b[2:3] (y)
-      equal a[4:6] (cd) b[3:5] (cd)
-     insert a[6:6] () b[5:6] (f)
-
-ratio()
-    Return a measure of the sequences' similarity (float in [0,1]).
-
-    Where T is the total number of elements in both sequences, and M is the
-    number of matches, this is 2,0*M / T. Note that this is 1 if the
-    sequences are identical, and 0 if they have nothing in common.
-
-    .ratio() is expensive to compute if you haven't already computed
-    .get_matching_blocks() or .get_opcodes(), in which case you may want to
-    try .quick_ratio() or .real_quick_ratio() first to get an upper bound.
-
-    >>> s = SequenceMatcher(None, "abcd", "bcde")
-    >>> s.ratio()
-    0.75
-    >>> s.quick_ratio()
-    0.75
-    >>> s.real_quick_ratio()
-    1.0
-
-quick_ratio()
-    Return an upper bound on .ratio() relatively quickly.
-
-    This isn't defined beyond that it is an upper bound on .ratio(), and
-    is faster to compute.
-
-real_quick_ratio():
-    Return an upper bound on ratio() very quickly.
-
-    This isn't defined beyond that it is an upper bound on .ratio(), and
-    is faster to compute than either .ratio() or .quick_ratio().
-"""
-
-TRACE = 0
-
-class SequenceMatcher:
-    def __init__(self, isjunk=None, a='', b=''):
-        """Construct a SequenceMatcher.
-
-        Optional arg isjunk is None (the default), or a one-argument
-        function that takes a sequence element and returns true iff the
-        element is junk. None is equivalent to passing "lambda x: 0", i.e.
-        no elements are considered to be junk.  For example, pass
-            lambda x: x in " \\t"
-        if you're comparing lines as sequences of characters, and don't
-        want to synch up on blanks or hard tabs.
-
-        Optional arg a is the first of two sequences to be compared.  By
-        default, an empty string.  The elements of a must be hashable.  See
-        also .set_seqs() and .set_seq1().
-
-        Optional arg b is the second of two sequences to be compared.  By
-        default, an empty string.  The elements of b must be hashable. See
-        also .set_seqs() and .set_seq2().
-        """
-
-        # Members:
-        # a
-        #      first sequence
-        # b
-        #      second sequence; differences are computed as "what do
-        #      we need to do to 'a' to change it into 'b'?"
-        # b2j
-        #      for x in b, b2j[x] is a list of the indices (into b)
-        #      at which x appears; junk elements do not appear
-        # b2jhas
-        #      b2j.has_key
-        # fullbcount
-        #      for x in b, fullbcount[x] == the number of times x
-        #      appears in b; only materialized if really needed (used
-        #      only for computing quick_ratio())
-        # matching_blocks
-        #      a list of (i, j, k) triples, where a[i:i+k] == b[j:j+k];
-        #      ascending & non-overlapping in i and in j; terminated by
-        #      a dummy (len(a), len(b), 0) sentinel
-        # opcodes
-        #      a list of (tag, i1, i2, j1, j2) tuples, where tag is
-        #      one of
-        #          'replace'   a[i1:i2] should be replaced by b[j1:j2]
-        #          'delete'    a[i1:i2] should be deleted
-        #          'insert'    b[j1:j2] should be inserted
-        #          'equal'     a[i1:i2] == b[j1:j2]
-        # isjunk
-        #      a user-supplied function taking a sequence element and
-        #      returning true iff the element is "junk" -- this has
-        #      subtle but helpful effects on the algorithm, which I'll
-        #      get around to writing up someday <0.9 wink>.
-        #      DON'T USE!  Only __chain_b uses this.  Use isbjunk.
-        # isbjunk
-        #      for x in b, isbjunk(x) == isjunk(x) but much faster;
-        #      it's really the has_key method of a hidden dict.
-        #      DOES NOT WORK for x in a!
-
-        self.isjunk = isjunk
-        self.a = self.b = None
-        self.set_seqs(a, b)
-
-    def set_seqs(self, a, b):
-        """Set the two sequences to be compared.
-
-        >>> s = SequenceMatcher()
-        >>> s.set_seqs("abcd", "bcde")
-        >>> s.ratio()
-        0.75
-        """
-
-        self.set_seq1(a)
-        self.set_seq2(b)
-
-    def set_seq1(self, a):
-        """Set the first sequence to be compared.
-
-        The second sequence to be compared is not changed.
-
-        >>> s = SequenceMatcher(None, "abcd", "bcde")
-        >>> s.ratio()
-        0.75
-        >>> s.set_seq1("bcde")
-        >>> s.ratio()
-        1.0
-        >>>
-
-        SequenceMatcher computes and caches detailed information about the
-        second sequence, so if you want to compare one sequence S against
-        many sequences, use .set_seq2(S) once and call .set_seq1(x)
-        repeatedly for each of the other sequences.
-
-        See also set_seqs() and set_seq2().
-        """
-
-        if a is self.a:
-            return
-        self.a = a
-        self.matching_blocks = self.opcodes = None
-
-    def set_seq2(self, b):
-        """Set the second sequence to be compared.
-
-        The first sequence to be compared is not changed.
-
-        >>> s = SequenceMatcher(None, "abcd", "bcde")
-        >>> s.ratio()
-        0.75
-        >>> s.set_seq2("abcd")
-        >>> s.ratio()
-        1.0
-        >>>
-
-        SequenceMatcher computes and caches detailed information about the
-        second sequence, so if you want to compare one sequence S against
-        many sequences, use .set_seq2(S) once and call .set_seq1(x)
-        repeatedly for each of the other sequences.
-
-        See also set_seqs() and set_seq1().
-        """
-
-        if b is self.b:
-            return
-        self.b = b
-        self.matching_blocks = self.opcodes = None
-        self.fullbcount = None
-        self.__chain_b()
-
-    # For each element x in b, set b2j[x] to a list of the indices in
-    # b where x appears; the indices are in increasing order; note that
-    # the number of times x appears in b is len(b2j[x]) ...
-    # when self.isjunk is defined, junk elements don't show up in this
-    # map at all, which stops the central find_longest_match method
-    # from starting any matching block at a junk element ...
-    # also creates the fast isbjunk function ...
-    # note that this is only called when b changes; so for cross-product
-    # kinds of matches, it's best to call set_seq2 once, then set_seq1
-    # repeatedly
-
-    def __chain_b(self):
-        # Because isjunk is a user-defined (not C) function, and we test
-        # for junk a LOT, it's important to minimize the number of calls.
-        # Before the tricks described here, __chain_b was by far the most
-        # time-consuming routine in the whole module!  If anyone sees
-        # Jim Roskind, thank him again for profile.py -- I never would
-        # have guessed that.
-        # The first trick is to build b2j ignoring the possibility
-        # of junk.  I.e., we don't call isjunk at all yet.  Throwing
-        # out the junk later is much cheaper than building b2j "right"
-        # from the start.
-        b = self.b
-        self.b2j = b2j = {}
-        self.b2jhas = b2jhas = b2j.has_key
-        for i in xrange(len(b)):
-            elt = b[i]
-            if b2jhas(elt):
-                b2j[elt].append(i)
-            else:
-                b2j[elt] = [i]
-
-        # Now b2j.keys() contains elements uniquely, and especially when
-        # the sequence is a string, that's usually a good deal smaller
-        # than len(string).  The difference is the number of isjunk calls
-        # saved.
-        isjunk, junkdict = self.isjunk, {}
-        if isjunk:
-            for elt in b2j.keys():
-                if isjunk(elt):
-                    junkdict[elt] = 1   # value irrelevant; it's a set
-                    del b2j[elt]
-
-        # Now for x in b, isjunk(x) == junkdict.has_key(x), but the
-        # latter is much faster.  Note too that while there may be a
-        # lot of junk in the sequence, the number of *unique* junk
-        # elements is probably small.  So the memory burden of keeping
-        # this dict alive is likely trivial compared to the size of b2j.
-        self.isbjunk = junkdict.has_key
-
-    def find_longest_match(self, alo, ahi, blo, bhi):
-        """Find longest matching block in a[alo:ahi] and b[blo:bhi].
-
-        If isjunk is not defined:
-
-        Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
-            alo <= i <= i+k <= ahi
-            blo <= j <= j+k <= bhi
-        and for all (i',j',k') meeting those conditions,
-            k >= k'
-            i <= i'
-            and if i == i', j <= j'
-
-        In other words, of all maximal matching blocks, return one that
-        starts earliest in a, and of all those maximal matching blocks that
-        start earliest in a, return the one that starts earliest in b.
-
-        >>> s = SequenceMatcher(None, " abcd", "abcd abcd")
-        >>> s.find_longest_match(0, 5, 0, 9)
-        (0, 4, 5)
-
-        If isjunk is defined, first the longest matching block is
-        determined as above, but with the additional restriction that no
-        junk element appears in the block.  Then that block is extended as
-        far as possible by matching (only) junk elements on both sides.  So
-        the resulting block never matches on junk except as identical junk
-        happens to be adjacent to an "interesting" match.
-
-        Here's the same example as before, but considering blanks to be
-        junk.  That prevents " abcd" from matching the " abcd" at the tail
-        end of the second sequence directly.  Instead only the "abcd" can
-        match, and matches the leftmost "abcd" in the second sequence:
-
-        >>> s = SequenceMatcher(lambda x: x==" ", " abcd", "abcd abcd")
-        >>> s.find_longest_match(0, 5, 0, 9)
-        (1, 0, 4)
-
-        If no blocks match, return (alo, blo, 0).
-
-        >>> s = SequenceMatcher(None, "ab", "c")
-        >>> s.find_longest_match(0, 2, 0, 1)
-        (0, 0, 0)
-        """
-
-        # CAUTION:  stripping common prefix or suffix would be incorrect.
-        # E.g.,
-        #    ab
-        #    acab
-        # Longest matching block is "ab", but if common prefix is
-        # stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
-        # strip, so ends up claiming that ab is changed to acab by
-        # inserting "ca" in the middle.  That's minimal but unintuitive:
-        # "it's obvious" that someone inserted "ac" at the front.
-        # Windiff ends up at the same place as diff, but by pairing up
-        # the unique 'b's and then matching the first two 'a's.
-
-        a, b, b2j, isbjunk = self.a, self.b, self.b2j, self.isbjunk
-        besti, bestj, bestsize = alo, blo, 0
-        # find longest junk-free match
-        # during an iteration of the loop, j2len[j] = length of longest
-        # junk-free match ending with a[i-1] and b[j]
-        j2len = {}
-        nothing = []
-        for i in xrange(alo, ahi):
-            # look at all instances of a[i] in b; note that because
-            # b2j has no junk keys, the loop is skipped if a[i] is junk
-            j2lenget = j2len.get
-            newj2len = {}
-            for j in b2j.get(a[i], nothing):
-                # a[i] matches b[j]
-                if j < blo:
-                    continue
-                if j >= bhi:
-                    break
-                k = newj2len[j] = j2lenget(j-1, 0) + 1
-                if k > bestsize:
-                    besti, bestj, bestsize = i-k+1, j-k+1, k
-            j2len = newj2len
-
-        # Now that we have a wholly interesting match (albeit possibly
-        # empty!), we may as well suck up the matching junk on each
-        # side of it too.  Can't think of a good reason not to, and it
-        # saves post-processing the (possibly considerable) expense of
-        # figuring out what to do with it.  In the case of an empty
-        # interesting match, this is clearly the right thing to do,
-        # because no other kind of match is possible in the regions.
-        while besti > alo and bestj > blo and \
-              isbjunk(b[bestj-1]) and \
-              a[besti-1] == b[bestj-1]:
-            besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
-        while besti+bestsize < ahi and bestj+bestsize < bhi and \
-              isbjunk(b[bestj+bestsize]) and \
-              a[besti+bestsize] == b[bestj+bestsize]:
-            bestsize = bestsize + 1
-
-        if TRACE:
-            print "get_matching_blocks", alo, ahi, blo, bhi
-            print "    returns", besti, bestj, bestsize
-        return besti, bestj, bestsize
-
-    def get_matching_blocks(self):
-        """Return list of triples describing matching subsequences.
-
-        Each triple is of the form (i, j, n), and means that
-        a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
-        i and in j.
-
-        The last triple is a dummy, (len(a), len(b), 0), and is the only
-        triple with n==0.
-
-        >>> s = SequenceMatcher(None, "abxcd", "abcd")
-        >>> s.get_matching_blocks()
-        [(0, 0, 2), (3, 2, 2), (5, 4, 0)]
-        """
-
-        if self.matching_blocks is not None:
-            return self.matching_blocks
-        self.matching_blocks = []
-        la, lb = len(self.a), len(self.b)
-        self.__helper(0, la, 0, lb, self.matching_blocks)
-        self.matching_blocks.append( (la, lb, 0) )
-        if TRACE:
-            print '*** matching blocks', self.matching_blocks
-        return self.matching_blocks
-
-    # builds list of matching blocks covering a[alo:ahi] and
-    # b[blo:bhi], appending them in increasing order to answer
-
-    def __helper(self, alo, ahi, blo, bhi, answer):
-        i, j, k = x = self.find_longest_match(alo, ahi, blo, bhi)
-        # a[alo:i] vs b[blo:j] unknown
-        # a[i:i+k] same as b[j:j+k]
-        # a[i+k:ahi] vs b[j+k:bhi] unknown
-        if k:
-            if alo < i and blo < j:
-                self.__helper(alo, i, blo, j, answer)
-            answer.append(x)
-            if i+k < ahi and j+k < bhi:
-                self.__helper(i+k, ahi, j+k, bhi, answer)
-
-    def get_opcodes(self):
-        """Return list of 5-tuples describing how to turn a into b.
-
-        Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
-        has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
-        tuple preceding it, and likewise for j1 == the previous j2.
-
-        The tags are strings, with these meanings:
-
-        'replace':  a[i1:i2] should be replaced by b[j1:j2]
-        'delete':   a[i1:i2] should be deleted.
-                    Note that j1==j2 in this case.
-        'insert':   b[j1:j2] should be inserted at a[i1:i1].
-                    Note that i1==i2 in this case.
-        'equal':    a[i1:i2] == b[j1:j2]
-
-        >>> a = "qabxcd"
-        >>> b = "abycdf"
-        >>> s = SequenceMatcher(None, a, b)
-        >>> for tag, i1, i2, j1, j2 in s.get_opcodes():
-        ...    print ("%7s a[%d:%d] (%s) b[%d:%d] (%s)" %
-        ...           (tag, i1, i2, a[i1:i2], j1, j2, b[j1:j2]))
-         delete a[0:1] (q) b[0:0] ()
-          equal a[1:3] (ab) b[0:2] (ab)
-        replace a[3:4] (x) b[2:3] (y)
-          equal a[4:6] (cd) b[3:5] (cd)
-         insert a[6:6] () b[5:6] (f)
-        """
-
-        if self.opcodes is not None:
-            return self.opcodes
-        i = j = 0
-        self.opcodes = answer = []
-        for ai, bj, size in self.get_matching_blocks():
-            # invariant:  we've pumped out correct diffs to change
-            # a[:i] into b[:j], and the next matching block is
-            # a[ai:ai+size] == b[bj:bj+size].  So we need to pump
-            # out a diff to change a[i:ai] into b[j:bj], pump out
-            # the matching block, and move (i,j) beyond the match
-            tag = ''
-            if i < ai and j < bj:
-                tag = 'replace'
-            elif i < ai:
-                tag = 'delete'
-            elif j < bj:
-                tag = 'insert'
-            if tag:
-                answer.append( (tag, i, ai, j, bj) )
-            i, j = ai+size, bj+size
-            # the list of matching blocks is terminated by a
-            # sentinel with size 0
-            if size:
-                answer.append( ('equal', ai, i, bj, j) )
-        return answer
-
-    def ratio(self):
-        """Return a measure of the sequences' similarity (float in [0,1]).
-
-        Where T is the total number of elements in both sequences, and
-        M is the number of matches, this is 2,0*M / T.
-        Note that this is 1 if the sequences are identical, and 0 if
-        they have nothing in common.
-
-        .ratio() is expensive to compute if you haven't already computed
-        .get_matching_blocks() or .get_opcodes(), in which case you may
-        want to try .quick_ratio() or .real_quick_ratio() first to get an
-        upper bound.
-
-        >>> s = SequenceMatcher(None, "abcd", "bcde")
-        >>> s.ratio()
-        0.75
-        >>> s.quick_ratio()
-        0.75
-        >>> s.real_quick_ratio()
-        1.0
-        """
-
-        matches = reduce(lambda sum, triple: sum + triple[-1],
-                         self.get_matching_blocks(), 0)
-        return 2.0 * matches / (len(self.a) + len(self.b))
-
-    def quick_ratio(self):
-        """Return an upper bound on ratio() relatively quickly.
-
-        This isn't defined beyond that it is an upper bound on .ratio(), and
-        is faster to compute.
-        """
-
-        # viewing a and b as multisets, set matches to the cardinality
-        # of their intersection; this counts the number of matches
-        # without regard to order, so is clearly an upper bound
-        if self.fullbcount is None:
-            self.fullbcount = fullbcount = {}
-            for elt in self.b:
-                fullbcount[elt] = fullbcount.get(elt, 0) + 1
-        fullbcount = self.fullbcount
-        # avail[x] is the number of times x appears in 'b' less the
-        # number of times we've seen it in 'a' so far ... kinda
-        avail = {}
-        availhas, matches = avail.has_key, 0
-        for elt in self.a:
-            if availhas(elt):
-                numb = avail[elt]
-            else:
-                numb = fullbcount.get(elt, 0)
-            avail[elt] = numb - 1
-            if numb > 0:
-                matches = matches + 1
-        return 2.0 * matches / (len(self.a) + len(self.b))
-
-    def real_quick_ratio(self):
-        """Return an upper bound on ratio() very quickly.
-
-        This isn't defined beyond that it is an upper bound on .ratio(), and
-        is faster to compute than either .ratio() or .quick_ratio().
-        """
-
-        la, lb = len(self.a), len(self.b)
-        # can't have more matches than the number of elements in the
-        # shorter sequence
-        return 2.0 * min(la, lb) / (la + lb)
-
-def get_close_matches(word, possibilities, n=3, cutoff=0.6):
-    """Use SequenceMatcher to return list of the best "good enough" matches.
-
-    word is a sequence for which close matches are desired (typically a
-    string).
-
-    possibilities is a list of sequences against which to match word
-    (typically a list of strings).
-
-    Optional arg n (default 3) is the maximum number of close matches to
-    return.  n must be > 0.
-
-    Optional arg cutoff (default 0.6) is a float in [0, 1].  Possibilities
-    that don't score at least that similar to word are ignored.
-
-    The best (no more than n) matches among the possibilities are returned
-    in a list, sorted by similarity score, most similar first.
-
-    >>> get_close_matches("appel", ["ape", "apple", "peach", "puppy"])
-    ['apple', 'ape']
-    >>> import keyword
-    >>> get_close_matches("wheel", keyword.kwlist)
-    ['while']
-    >>> get_close_matches("apple", keyword.kwlist)
-    []
-    >>> get_close_matches("accept", keyword.kwlist)
-    ['except']
-    """
-
-    if not n >  0:
-        raise ValueError("n must be > 0: " + `n`)
-    if not 0.0 <= cutoff <= 1.0:
-        raise ValueError("cutoff must be in [0.0, 1.0]: " + `cutoff`)
-    result = []
-    s = SequenceMatcher()
-    s.set_seq2(word)
-    for x in possibilities:
-        s.set_seq1(x)
-        if s.real_quick_ratio() >= cutoff and \
-           s.quick_ratio() >= cutoff and \
-           s.ratio() >= cutoff:
-            result.append((s.ratio(), x))
-    # Sort by score.
-    result.sort()
-    # Retain only the best n.
-    result = result[-n:]
-    # Move best-scorer to head of list.
-    result.reverse()
-    # Strip scores.
-    # Python 2.x list comprehensions: return [x for score, x in result]
-    return_result = []
-    for score, x in result:
-        return_result.append(x)
-    return return_result
-
-def _test():
-    import doctest, difflib
-    return doctest.testmod(difflib)
-
-if __name__ == "__main__":
-    _test()
diff --git a/src/www/scm/viewvc/lib/compat_ndiff.py b/src/www/scm/viewvc/lib/compat_ndiff.py
deleted file mode 100644
index 543354e..0000000
--- a/src/www/scm/viewvc/lib/compat_ndiff.py
+++ /dev/null
@@ -1,346 +0,0 @@
-#! /usr/bin/env python
-
-# Module ndiff version 1.6.0
-# Released to the public domain 08-Dec-2000,
-# by Tim Peters (tim.one at home.com).
-
-# Backported to Python 1.5.2 for ViewCVS by pf at artcom-gmbh.de, 24-Dec-2001
-
-# Provided as-is; use at your own risk; no warranty; no promises; enjoy!
-
-"""ndiff [-q] file1 file2
-    or
-ndiff (-r1 | -r2) < ndiff_output > file1_or_file2
-
-Print a human-friendly file difference report to stdout.  Both inter-
-and intra-line differences are noted.  In the second form, recreate file1
-(-r1) or file2 (-r2) on stdout, from an ndiff report on stdin.
-
-In the first form, if -q ("quiet") is not specified, the first two lines
-of output are
-
--: file1
-+: file2
-
-Each remaining line begins with a two-letter code:
-
-    "- "    line unique to file1
-    "+ "    line unique to file2
-    "  "    line common to both files
-    "? "    line not present in either input file
-
-Lines beginning with "? " attempt to guide the eye to intraline
-differences, and were not present in either input file.  These lines can be
-confusing if the source files contain tab characters.
-
-The first file can be recovered by retaining only lines that begin with
-"  " or "- ", and deleting those 2-character prefixes; use ndiff with -r1.
-
-The second file can be recovered similarly, but by retaining only "  " and
-"+ " lines; use ndiff with -r2; or, on Unix, the second file can be
-recovered by piping the output through
-
-    sed -n '/^[+ ] /s/^..//p'
-
-See module comments for details and programmatic interface.
-"""
-
-__version__ = 1, 6, 1
-
-# SequenceMatcher tries to compute a "human-friendly diff" between
-# two sequences (chiefly picturing a file as a sequence of lines,
-# and a line as a sequence of characters, here).  Unlike e.g. UNIX(tm)
-# diff, the fundamental notion is the longest *contiguous* & junk-free
-# matching subsequence.  That's what catches peoples' eyes.  The
-# Windows(tm) windiff has another interesting notion, pairing up elements
-# that appear uniquely in each sequence.  That, and the method here,
-# appear to yield more intuitive difference reports than does diff.  This
-# method appears to be the least vulnerable to synching up on blocks
-# of "junk lines", though (like blank lines in ordinary text files,
-# or maybe "<P>" lines in HTML files).  That may be because this is
-# the only method of the 3 that has a *concept* of "junk" <wink>.
-#
-# Note that ndiff makes no claim to produce a *minimal* diff.  To the
-# contrary, minimal diffs are often counter-intuitive, because they
-# synch up anywhere possible, sometimes accidental matches 100 pages
-# apart.  Restricting synch points to contiguous matches preserves some
-# notion of locality, at the occasional cost of producing a longer diff.
-#
-# With respect to junk, an earlier version of ndiff simply refused to
-# *start* a match with a junk element.  The result was cases like this:
-#     before: private Thread currentThread;
-#     after:  private volatile Thread currentThread;
-# If you consider whitespace to be junk, the longest contiguous match
-# not starting with junk is "e Thread currentThread".  So ndiff reported
-# that "e volatil" was inserted between the 't' and the 'e' in "private".
-# While an accurate view, to people that's absurd.  The current version
-# looks for matching blocks that are entirely junk-free, then extends the
-# longest one of those as far as possible but only with matching junk.
-# So now "currentThread" is matched, then extended to suck up the
-# preceding blank; then "private" is matched, and extended to suck up the
-# following blank; then "Thread" is matched; and finally ndiff reports
-# that "volatile " was inserted before "Thread".  The only quibble
-# remaining is that perhaps it was really the case that " volatile"
-# was inserted after "private".  I can live with that <wink>.
-#
-# NOTE on junk:  the module-level names
-#    IS_LINE_JUNK
-#    IS_CHARACTER_JUNK
-# can be set to any functions you like.  The first one should accept
-# a single string argument, and return true iff the string is junk.
-# The default is whether the regexp r"\s*#?\s*$" matches (i.e., a
-# line without visible characters, except for at most one splat).
-# The second should accept a string of length 1 etc.  The default is
-# whether the character is a blank or tab (note: bad idea to include
-# newline in this!).
-#
-# After setting those, you can call fcompare(f1name, f2name) with the
-# names of the files you want to compare.  The difference report
-# is sent to stdout.  Or you can call main(args), passing what would
-# have been in sys.argv[1:] had the cmd-line form been used.
-
-from compat_difflib import SequenceMatcher
-
-TRACE = 0
-
-# define what "junk" means
-import re
-
-def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
-    return pat(line) is not None
-
-def IS_CHARACTER_JUNK(ch, ws=" \t"):
-    return ch in ws
-
-del re
-
-# meant for dumping lines
-def dump(tag, x, lo, hi):
-    for i in xrange(lo, hi):
-        print tag, x[i],
-
-def plain_replace(a, alo, ahi, b, blo, bhi):
-    assert alo < ahi and blo < bhi
-    # dump the shorter block first -- reduces the burden on short-term
-    # memory if the blocks are of very different sizes
-    if bhi - blo < ahi - alo:
-        dump('+', b, blo, bhi)
-        dump('-', a, alo, ahi)
-    else:
-        dump('-', a, alo, ahi)
-        dump('+', b, blo, bhi)
-
-# When replacing one block of lines with another, this guy searches
-# the blocks for *similar* lines; the best-matching pair (if any) is
-# used as a synch point, and intraline difference marking is done on
-# the similar pair.  Lots of work, but often worth it.
-
-def fancy_replace(a, alo, ahi, b, blo, bhi):
-    if TRACE:
-        print '*** fancy_replace', alo, ahi, blo, bhi
-        dump('>', a, alo, ahi)
-        dump('<', b, blo, bhi)
-
-    # don't synch up unless the lines have a similarity score of at
-    # least cutoff; best_ratio tracks the best score seen so far
-    best_ratio, cutoff = 0.74, 0.75
-    cruncher = SequenceMatcher(IS_CHARACTER_JUNK)
-    eqi, eqj = None, None   # 1st indices of equal lines (if any)
-
-    # search for the pair that matches best without being identical
-    # (identical lines must be junk lines, & we don't want to synch up
-    # on junk -- unless we have to)
-    for j in xrange(blo, bhi):
-        bj = b[j]
-        cruncher.set_seq2(bj)
-        for i in xrange(alo, ahi):
-            ai = a[i]
-            if ai == bj:
-                if eqi is None:
-                    eqi, eqj = i, j
-                continue
-            cruncher.set_seq1(ai)
-            # computing similarity is expensive, so use the quick
-            # upper bounds first -- have seen this speed up messy
-            # compares by a factor of 3.
-            # note that ratio() is only expensive to compute the first
-            # time it's called on a sequence pair; the expensive part
-            # of the computation is cached by cruncher
-            if cruncher.real_quick_ratio() > best_ratio and \
-                  cruncher.quick_ratio() > best_ratio and \
-                  cruncher.ratio() > best_ratio:
-                best_ratio, best_i, best_j = cruncher.ratio(), i, j
-    if best_ratio < cutoff:
-        # no non-identical "pretty close" pair
-        if eqi is None:
-            # no identical pair either -- treat it as a straight replace
-            plain_replace(a, alo, ahi, b, blo, bhi)
-            return
-        # no close pair, but an identical pair -- synch up on that
-        best_i, best_j, best_ratio = eqi, eqj, 1.0
-    else:
-        # there's a close pair, so forget the identical pair (if any)
-        eqi = None
-
-    # a[best_i] very similar to b[best_j]; eqi is None iff they're not
-    # identical
-    if TRACE:
-        print '*** best_ratio', best_ratio, best_i, best_j
-        dump('>', a, best_i, best_i+1)
-        dump('<', b, best_j, best_j+1)
-
-    # pump out diffs from before the synch point
-    fancy_helper(a, alo, best_i, b, blo, best_j)
-
-    # do intraline marking on the synch pair
-    aelt, belt = a[best_i], b[best_j]
-    if eqi is None:
-        # pump out a '-', '?', '+', '?' quad for the synched lines
-        atags = btags = ""
-        cruncher.set_seqs(aelt, belt)
-        for tag, ai1, ai2, bj1, bj2 in cruncher.get_opcodes():
-            la, lb = ai2 - ai1, bj2 - bj1
-            if tag == 'replace':
-                atags = atags + '^' * la
-                btags = btags + '^' * lb
-            elif tag == 'delete':
-                atags = atags + '-' * la
-            elif tag == 'insert':
-                btags = btags + '+' * lb
-            elif tag == 'equal':
-                atags = atags + ' ' * la
-                btags = btags + ' ' * lb
-            else:
-                raise ValueError, 'unknown tag ' + `tag`
-        printq(aelt, belt, atags, btags)
-    else:
-        # the synch pair is identical
-        print ' ', aelt,
-
-    # pump out diffs from after the synch point
-    fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi)
-
-def fancy_helper(a, alo, ahi, b, blo, bhi):
-    if alo < ahi:
-        if blo < bhi:
-            fancy_replace(a, alo, ahi, b, blo, bhi)
-        else:
-            dump('-', a, alo, ahi)
-    elif blo < bhi:
-        dump('+', b, blo, bhi)
-
-# Crap to deal with leading tabs in "?" output.  Can hurt, but will
-# probably help most of the time.
-
-def printq(aline, bline, atags, btags):
-    common = min(count_leading(aline, "\t"),
-                 count_leading(bline, "\t"))
-    common = min(common, count_leading(atags[:common], " "))
-    print "-", aline,
-    if count_leading(atags, " ") < len(atags):
-        print "?", "\t" * common + atags[common:]
-    print "+", bline,
-    if count_leading(btags, " ") < len(btags):
-        print "?", "\t" * common + btags[common:]
-
-def count_leading(line, ch):
-    i, n = 0, len(line)
-    while i < n and line[i] == ch:
-        i = i+1
-    return i
-
-def fail(msg):
-    import sys
-    out = sys.stderr.write
-    out(msg + "\n\n")
-    out(__doc__)
-    return 0
-
-# open a file & return the file object; gripe and return 0 if it
-# couldn't be opened
-def fopen(fname):
-    try:
-        return open(fname, 'r')
-    except IOError, detail:
-        return fail("couldn't open " + fname + ": " + str(detail))
-
-# open two files & spray the diff to stdout; return false iff a problem
-def fcompare(f1name, f2name):
-    f1 = fopen(f1name)
-    f2 = fopen(f2name)
-    if not f1 or not f2:
-        return 0
-
-    a = f1.readlines(); f1.close()
-    b = f2.readlines(); f2.close()
-
-    cruncher = SequenceMatcher(IS_LINE_JUNK, a, b)
-    for tag, alo, ahi, blo, bhi in cruncher.get_opcodes():
-        if tag == 'replace':
-            fancy_replace(a, alo, ahi, b, blo, bhi)
-        elif tag == 'delete':
-            dump('-', a, alo, ahi)
-        elif tag == 'insert':
-            dump('+', b, blo, bhi)
-        elif tag == 'equal':
-            dump(' ', a, alo, ahi)
-        else:
-            raise ValueError, 'unknown tag ' + `tag`
-
-    return 1
-
-# crack args (sys.argv[1:] is normal) & compare;
-# return false iff a problem
-
-def main(args):
-    import getopt
-    try:
-        opts, args = getopt.getopt(args, "qr:")
-    except getopt.error, detail:
-        return fail(str(detail))
-    noisy = 1
-    qseen = rseen = 0
-    for opt, val in opts:
-        if opt == "-q":
-            qseen = 1
-            noisy = 0
-        elif opt == "-r":
-            rseen = 1
-            whichfile = val
-    if qseen and rseen:
-        return fail("can't specify both -q and -r")
-    if rseen:
-        if args:
-            return fail("no args allowed with -r option")
-        if whichfile in "12":
-            restore(whichfile)
-            return 1
-        return fail("-r value must be 1 or 2")
-    if len(args) != 2:
-        return fail("need 2 filename args")
-    f1name, f2name = args
-    if noisy:
-        print '-:', f1name
-        print '+:', f2name
-    return fcompare(f1name, f2name)
-
-def restore(which):
-    import sys
-    tag = {"1": "- ", "2": "+ "}[which]
-    prefixes = ("  ", tag)
-    for line in sys.stdin.readlines():
-        if line[:2] in prefixes:
-            print line[2:],
-
-if __name__ == '__main__':
-    import sys
-    args = sys.argv[1:]
-    if "-profile" in args:
-        import profile, pstats
-        args.remove("-profile")
-        statf = "ndiff.pro"
-        profile.run("main(args)", statf)
-        stats = pstats.Stats(statf)
-        stats.strip_dirs().sort_stats('time').print_stats()
-    else:
-        main(args)
diff --git a/src/www/scm/viewvc/lib/config.py b/src/www/scm/viewvc/lib/config.py
deleted file mode 100644
index 7dc277d..0000000
--- a/src/www/scm/viewvc/lib/config.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# config.py: configuration utilities
-#
-# -----------------------------------------------------------------------
-
-import sys
-import os
-import string
-import ConfigParser
-import fnmatch
-
-
-#########################################################################
-#
-# CONFIGURATION
-#
-# There are three forms of configuration:
-#
-#       1) edit the viewvc.conf created by the viewvc-install(er)
-#       2) as (1), but delete all unchanged entries from viewvc.conf
-#       3) do not use viewvc.conf and just edit the defaults in this file
-#
-# Most users will want to use (1), but there are slight speed advantages
-# to the other two options. Note that viewvc.conf values are a bit easier
-# to work with since it is raw text, rather than python literal values.
-#
-#########################################################################
-
-class Config:
-  _sections = ('general', 'options', 'cvsdb', 'templates')
-  _force_multi_value = ('cvs_roots', 'forbidden',
-                        'svn_roots', 'languages', 'kv_files',
-                        'root_parents')
-
-  def __init__(self):
-    for section in self._sections:
-      setattr(self, section, _sub_config())
-
-  def load_config(self, pathname, vhost=None):
-    self.conf_path = os.path.isfile(pathname) and pathname or None
-    self.base = os.path.dirname(pathname)
-
-    parser = ConfigParser.ConfigParser()
-    parser.read(pathname)
-
-    for section in self._sections:
-      if parser.has_section(section):
-        self._process_section(parser, section, section)
-
-    if vhost and parser.has_section('vhosts'):
-      self._process_vhost(parser, vhost)
-
-  def load_kv_files(self, language):
-    kv = _sub_config()
-
-    for fname in self.general.kv_files:
-      if fname[0] == '[':
-        idx = string.index(fname, ']')
-        parts = string.split(fname[1:idx], '.')
-        fname = string.strip(fname[idx+1:])
-      else:
-        parts = [ ]
-      fname = string.replace(fname, '%lang%', language)
-
-      parser = ConfigParser.ConfigParser()
-      parser.read(os.path.join(self.base, fname))
-      for section in parser.sections():
-        for option in parser.options(section):
-          full_name = parts + [section]
-          ob = kv
-          for name in full_name:
-            try:
-              ob = getattr(ob, name)
-            except AttributeError:
-              c = _sub_config()
-              setattr(ob, name, c)
-              ob = c
-          setattr(ob, option, parser.get(section, option))
-
-    return kv
-
-  def _process_section(self, parser, section, subcfg_name):
-    sc = getattr(self, subcfg_name)
-
-    for opt in parser.options(section):
-      value = parser.get(section, opt)
-      if opt in self._force_multi_value:
-        value = map(string.strip, filter(None, string.split(value, ',')))
-      else:
-        try:
-          value = int(value)
-        except ValueError:
-          pass
-
-      if opt == 'cvs_roots' or opt == 'svn_roots':
-        value = _parse_roots(opt, value)
-
-      setattr(sc, opt, value)
-
-  def _process_vhost(self, parser, vhost):
-    canon_vhost = self._find_canon_vhost(parser, vhost)
-    if not canon_vhost:
-      # none of the vhost sections matched
-      return
-
-    cv = canon_vhost + '-'
-    lcv = len(cv)
-    for section in parser.sections():
-      if section[:lcv] == cv:
-        self._process_section(parser, section, section[lcv:])
-
-  def _find_canon_vhost(self, parser, vhost):
-    vhost = string.lower(vhost)
-    # Strip (ignore) port number:
-    vhost = string.split(vhost, ':')[0]
-
-    for canon_vhost in parser.options('vhosts'):
-      value = parser.get('vhosts', canon_vhost)
-      patterns = map(string.lower, map(string.strip,
-                                       filter(None, string.split(value, ','))))
-      for pat in patterns:
-        if fnmatch.fnmatchcase(vhost, pat):
-          return canon_vhost
-
-    return None
-
-  def set_defaults(self):
-    "Set some default values in the configuration."
-
-    self.general.cvs_roots = { }
-    self.general.svn_roots = { }
-    self.general.root_parents = []
-    self.general.default_root = ''
-    self.general.rcs_path = ''
-    if sys.platform == "win32":
-      self.general.cvsnt_exe_path = 'cvs'
-    else:
-      self.general.cvsnt_exe_path = None
-    self.general.use_rcsparse = 0
-    self.general.svn_path = ''
-    self.general.mime_types_file = ''
-    self.general.address = '<a href="mailto:user at insert.your.domain.here">No admin address has been configured</a>'
-    self.general.forbidden = ()
-    self.general.kv_files = [ ]
-    self.general.languages = ['en-us']
-
-    self.templates.directory = None
-    self.templates.log = None
-    self.templates.query = None
-    self.templates.diff = None
-    self.templates.graph = None
-    self.templates.annotate = None
-    self.templates.markup = None
-    self.templates.error = None
-    self.templates.query_form = None
-    self.templates.query_results = None
-    self.templates.roots = None
-
-    self.cvsdb.enabled = 0
-    self.cvsdb.host = ''
-    self.cvsdb.port = 3306
-    self.cvsdb.database_name = ''
-    self.cvsdb.user = ''
-    self.cvsdb.passwd = ''
-    self.cvsdb.readonly_user = ''
-    self.cvsdb.readonly_passwd = '' 
-    self.cvsdb.row_limit = 1000
-    self.cvsdb.rss_row_limit = 100
-
-    self.options.root_as_url_component = 0
-    self.options.default_file_view = "log"
-    self.options.checkout_magic = 0
-    self.options.sort_by = 'file'
-    self.options.sort_group_dirs = 1
-    self.options.hide_attic = 1
-    self.options.log_sort = 'date'
-    self.options.diff_format = 'h'
-    self.options.hide_cvsroot = 1
-    self.options.hr_breakable = 1
-    self.options.hr_funout = 1
-    self.options.hr_ignore_white = 1
-    self.options.hr_ignore_keyword_subst = 1
-    self.options.hr_intraline = 0
-    self.options.allow_annotate = 1
-    self.options.allow_markup = 1
-    self.options.allow_compress = 1
-    self.options.template_dir = "templates"
-    self.options.docroot = None
-    self.options.show_subdir_lastmod = 0
-    self.options.show_logs = 1
-    self.options.show_log_in_markup = 1
-    self.options.cross_copies = 0
-    self.options.py2html_path = '.'
-    self.options.short_log_len = 80
-    self.options.use_enscript = 0
-    self.options.enscript_path = ''
-    self.options.use_highlight = 0
-    self.options.highlight_path = ''
-    self.options.highlight_line_numbers = 1
-    self.options.highlight_convert_tabs = 2
-    self.options.use_php = 0
-    self.options.php_exe_path = 'php'
-    self.options.allow_tar = 0
-    self.options.use_cvsgraph = 0
-    self.options.cvsgraph_path = ''
-    self.options.cvsgraph_conf = "cvsgraph.conf"
-    self.options.use_re_search = 0
-    self.options.use_pagesize = 0
-    self.options.limit_changes = 100
-    self.options.use_localtime = 0
-    self.options.http_expiration_time = 600
-    self.options.generate_etags = 1
-
-  def is_forbidden(self, module):
-    if not module:
-      return 0
-    default = 0
-    for pat in self.general.forbidden:
-      if pat[0] == '!':
-        default = 1
-        if fnmatch.fnmatchcase(module, pat[1:]):
-          return 0
-      elif fnmatch.fnmatchcase(module, pat):
-        return 1
-    return default
-
-
-def _parse_roots(config_name, config_value):
-  roots = { }
-  for root in config_value:
-    pos = string.find(root, ':')
-    if pos < 0:
-      raise MalformedRoot(config_name, root)
-    name, path = map(string.strip, (root[:pos], root[pos+1:]))
-    roots[name] = path
-  return roots
-
-
-class MalformedRoot(Exception):
-  def __init__(self, config_name, value_given):
-    Exception.__init__(self, config_name, value_given)
-    self.config_name = config_name
-    self.value_given = value_given
-  def __str__(self):
-    return "malformed configuration: '%s' uses invalid syntax: %s" \
-           % (self.config_name, self.value_given)
-
-
-class _sub_config:
-  pass
-
-if not hasattr(sys, 'hexversion'):
-  # Python 1.5 or 1.5.1. fix the syntax for ConfigParser options.
-  import regex
-  ConfigParser.option_cre = regex.compile('^\([-A-Za-z0-9._]+\)\(:\|['
-                                          + string.whitespace
-                                          + ']*=\)\(.*\)$')
diff --git a/src/www/scm/viewvc/lib/cvsdb.py b/src/www/scm/viewvc/lib/cvsdb.py
deleted file mode 100644
index 350b280..0000000
--- a/src/www/scm/viewvc/lib/cvsdb.py
+++ /dev/null
@@ -1,789 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-import os
-import sys
-import string
-import time
-import fnmatch
-import re
-
-import dbi
-
-
-## error
-error = "cvsdb error"
-
-## cached (active) database connections
-gCheckinDatabase = None
-gCheckinDatabaseReadOnly = None
-
-
-## CheckinDatabase provides all interfaces needed to the SQL database
-## back-end; it needs to be subclassed, and have its "Connect" method
-## defined to actually be complete; it should run well off of any DBI 2.0
-## complient database interface
-
-class CheckinDatabase:
-    def __init__(self, host, port, user, passwd, database, row_limit):
-        self._host = host
-        self._port = port
-        self._user = user
-        self._passwd = passwd
-        self._database = database
-        self._row_limit = row_limit
-
-        ## database lookup caches
-        self._get_cache = {}
-        self._get_id_cache = {}
-        self._desc_id_cache = {}
-
-    def Connect(self):
-        self.db = dbi.connect(
-            self._host, self._port, self._user, self._passwd, self._database)
-
-    def sql_get_id(self, table, column, value, auto_set):
-        sql = "SELECT id FROM %s WHERE %s=%%s" % (table, column)
-        sql_args = (value, )
-        
-        cursor = self.db.cursor()
-        cursor.execute(sql, sql_args)
-        try:
-            (id, ) = cursor.fetchone()
-        except TypeError:
-            if not auto_set:
-                return None
-        else:
-            return str(int(id))
-   
-        ## insert the new identifier
-        sql = "INSERT INTO %s(%s) VALUES(%%s)" % (table, column)
-        sql_args = (value, )
-        cursor.execute(sql, sql_args)
-
-        return self.sql_get_id(table, column, value, 0)
-
-    def get_id(self, table, column, value, auto_set):
-        ## attempt to retrieve from cache
-        try:
-            return self._get_id_cache[table][column][value]
-        except KeyError:
-            pass
-
-        id = self.sql_get_id(table, column, value, auto_set)
-        if id == None:
-            return None
-
-        ## add to cache
-        try:
-            temp = self._get_id_cache[table]
-        except KeyError:
-            temp = self._get_id_cache[table] = {}
-
-        try:
-            temp2 = temp[column]
-        except KeyError:
-            temp2 = temp[column] = {}
-
-        temp2[value] = id
-        return id
-
-    def sql_get(self, table, column, id):
-        sql = "SELECT %s FROM %s WHERE id=%%s" % (column, table)
-        sql_args = (id, )
-
-        cursor = self.db.cursor()
-        cursor.execute(sql, sql_args)
-        try:
-            (value, ) = cursor.fetchone()
-        except TypeError:
-            return None
-
-        return value
-
-    def get(self, table, column, id):
-        ## attempt to retrieve from cache
-        try:
-            return self._get_cache[table][column][id]
-        except KeyError:
-            pass
-
-        value = self.sql_get(table, column, id)
-        if value == None:
-            return None
-
-        ## add to cache
-        try:
-            temp = self._get_cache[table]
-        except KeyError:
-            temp = self._get_cache[table] = {}
-
-        try:
-            temp2 = temp[column]
-        except KeyError:
-            temp2 = temp[column] = {}
-
-        temp2[id] = value
-        return value
-        
-    def get_list(self, table, field_index):
-        sql = "SELECT * FROM %s" % (table)
-        cursor = self.db.cursor()
-        cursor.execute(sql)
-
-        list = []
-        while 1:
-            row = cursor.fetchone()
-            if row == None:
-                break
-            list.append(row[field_index])
-
-        return list
-
-    def GetBranchID(self, branch, auto_set = 1):
-        return self.get_id("branches", "branch", branch, auto_set)
-
-    def GetBranch(self, id):
-        return self.get("branches", "branch", id)
-
-    def GetDirectoryID(self, dir, auto_set = 1):
-        return self.get_id("dirs", "dir", dir, auto_set)
-
-    def GetDirectory(self, id):
-        return self.get("dirs", "dir", id)
-
-    def GetFileID(self, file, auto_set = 1):
-        return self.get_id("files", "file", file, auto_set)
-
-    def GetFile(self, id):
-        return self.get("files", "file", id)
-    
-    def GetAuthorID(self, author, auto_set = 1):
-        return self.get_id("people", "who", author, auto_set)
-
-    def GetAuthor(self, id):
-        return self.get("people", "who", id)
-    
-    def GetRepositoryID(self, repository, auto_set = 1):
-        return self.get_id("repositories", "repository", repository, auto_set)
-
-    def GetRepository(self, id):
-        return self.get("repositories", "repository", id)
-
-    def SQLGetDescriptionID(self, description, auto_set = 1):
-        ## lame string hash, blame Netscape -JMP
-        hash = len(description)
-
-        sql = "SELECT id FROM descs WHERE hash=%s AND description=%s"
-        sql_args = (hash, description)
-        
-        cursor = self.db.cursor()
-        cursor.execute(sql, sql_args)
-        try:
-            (id, ) = cursor.fetchone()
-        except TypeError:
-            if not auto_set:
-                return None
-        else:
-            return str(int(id))
-
-        sql = "INSERT INTO descs (hash,description) values (%s,%s)"
-        sql_args = (hash, description)
-        cursor.execute(sql, sql_args)
-        
-        return self.GetDescriptionID(description, 0)
-
-    def GetDescriptionID(self, description, auto_set = 1):
-        ## attempt to retrieve from cache
-        hash = len(description)
-        try:
-            return self._desc_id_cache[hash][description]
-        except KeyError:
-            pass
-
-        id = self.SQLGetDescriptionID(description, auto_set)
-        if id == None:
-            return None
-
-        ## add to cache
-        try:
-            temp = self._desc_id_cache[hash]
-        except KeyError:
-            temp = self._desc_id_cache[hash] = {}
-
-        temp[description] = id
-        return id
-
-    def GetDescription(self, id):
-        return self.get("descs", "description", id)
-
-    def GetRepositoryList(self):
-        return self.get_list("repositories", 1)
-
-    def GetBranchList(self):
-        return self.get_list("branches", 1)
-
-    def GetAuthorList(self):
-        return self.get_list("people", 1)
-
-    def AddCommitList(self, commit_list):
-        for commit in commit_list:
-            self.AddCommit(commit)
-
-    def AddCommit(self, commit):
-        ci_when = dbi.DateTimeFromTicks(commit.GetTime())
-        ci_type = commit.GetTypeString()
-        who_id = self.GetAuthorID(commit.GetAuthor())
-        repository_id = self.GetRepositoryID(commit.GetRepository())
-        directory_id = self.GetDirectoryID(commit.GetDirectory())
-        file_id = self.GetFileID(commit.GetFile())
-        revision = commit.GetRevision()
-        sticky_tag = "NULL"
-        branch_id = self.GetBranchID(commit.GetBranch())
-        plus_count = commit.GetPlusCount()
-        minus_count = commit.GetMinusCount()
-        description_id = self.GetDescriptionID(commit.GetDescription())
-
-        sql = "REPLACE INTO checkins"\
-              "  (type,ci_when,whoid,repositoryid,dirid,fileid,revision,"\
-              "   stickytag,branchid,addedlines,removedlines,descid)"\
-              "VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"
-        sql_args = (ci_type, ci_when, who_id, repository_id,
-                    directory_id, file_id, revision, sticky_tag, branch_id,
-                    plus_count, minus_count, description_id)
-
-        cursor = self.db.cursor()
-        cursor.execute(sql, sql_args)
-
-    def SQLQueryListString(self, field, query_entry_list):
-        sqlList = []
-
-        for query_entry in query_entry_list:
-            data = query_entry.data
-            ## figure out the correct match type
-            if query_entry.match == "exact":
-                match = "="
-            elif query_entry.match == "like":
-                match = " LIKE "
-            elif query_entry.match == "glob":
-                match = " REGEXP "
-                # use fnmatch to translate the glob into a regexp
-                data = fnmatch.translate(data)
-                if data[0] != '^': data = '^' + data
-            elif query_entry.match == "regex":
-                match = " REGEXP "
-            elif query_entry.match == "notregex":
-                match = " NOT REGEXP "
-
-            sqlList.append("%s%s%s" % (field, match, self.db.literal(data)))
-
-        return "(%s)" % (string.join(sqlList, " OR "))
-
-    def CreateSQLQueryString(self, query):
-        tableList = [("checkins", None)]
-        condList = []
-
-        if len(query.repository_list):
-            tableList.append(("repositories",
-                              "(checkins.repositoryid=repositories.id)"))
-            temp = self.SQLQueryListString("repositories.repository",
-                                           query.repository_list)
-            condList.append(temp)
-
-        if len(query.branch_list):
-            tableList.append(("branches", "(checkins.branchid=branches.id)"))
-            temp = self.SQLQueryListString("branches.branch",
-                                           query.branch_list)
-            condList.append(temp)
-
-        if len(query.directory_list):
-            tableList.append(("dirs", "(checkins.dirid=dirs.id)"))
-            temp = self.SQLQueryListString("dirs.dir", query.directory_list)
-            condList.append(temp)
-            
-        if len(query.file_list):
-            tableList.append(("files", "(checkins.fileid=files.id)"))
-            temp = self.SQLQueryListString("files.file", query.file_list)
-            condList.append(temp)
-            
-        if len(query.author_list):
-            tableList.append(("people", "(checkins.whoid=people.id)"))
-            temp = self.SQLQueryListString("people.who", query.author_list)
-            condList.append(temp)
-            
-        if query.from_date:
-            temp = "(checkins.ci_when>=\"%s\")" % (str(query.from_date))
-            condList.append(temp)
-
-        if query.to_date:
-            temp = "(checkins.ci_when<=\"%s\")" % (str(query.to_date))
-            condList.append(temp)
-
-        if query.sort == "date":
-            order_by = "ORDER BY checkins.ci_when DESC,descid"
-        elif query.sort == "author":
-            tableList.append(("people", "(checkins.whoid=people.id)"))
-            order_by = "ORDER BY people.who,descid"
-        elif query.sort == "file":
-            tableList.append(("files", "(checkins.fileid=files.id)"))
-            order_by = "ORDER BY files.file,descid"
-
-        ## exclude duplicates from the table list, and split out join
-        ## conditions from table names.  In future, the join conditions
-        ## might be handled by INNER JOIN statements instead of WHERE
-        ## clauses, but MySQL 3.22 apparently doesn't support them well.
-        tables = []
-        joinConds = []
-        for (table, cond) in tableList:
-            if table not in tables:
-                tables.append(table)
-                if cond is not None: joinConds.append(cond)
-
-        tables = string.join(tables, ",")
-        conditions = string.join(joinConds + condList, " AND ")
-        conditions = conditions and "WHERE %s" % conditions
-
-        ## limit the number of rows requested or we could really slam
-        ## a server with a large database
-        limit = ""
-        if query.limit:
-            limit = "LIMIT %s" % (str(query.limit))
-        elif self._row_limit:
-            limit = "LIMIT %s" % (str(self._row_limit))
-
-        sql = "SELECT checkins.* FROM %s %s %s %s" % (
-            tables, conditions, order_by, limit)
-
-        return sql
-    
-    def RunQuery(self, query):
-        sql = self.CreateSQLQueryString(query)
-        cursor = self.db.cursor()
-        cursor.execute(sql)
-        
-        while 1:
-            row = cursor.fetchone()
-            if not row:
-                break
-            
-            (dbType, dbCI_When, dbAuthorID, dbRepositoryID, dbDirID,
-             dbFileID, dbRevision, dbStickyTag, dbBranchID, dbAddedLines,
-             dbRemovedLines, dbDescID) = row
-
-            commit = LazyCommit(self)
-            if dbType == 'Add':
-              commit.SetTypeAdd()
-            elif dbType == 'Remove':
-              commit.SetTypeRemove()
-            else:
-              commit.SetTypeChange()
-            commit.SetTime(dbi.TicksFromDateTime(dbCI_When))
-            commit.SetFileID(dbFileID)
-            commit.SetDirectoryID(dbDirID)
-            commit.SetRevision(dbRevision)
-            commit.SetRepositoryID(dbRepositoryID)
-            commit.SetAuthorID(dbAuthorID)
-            commit.SetBranchID(dbBranchID)
-            commit.SetPlusCount(dbAddedLines)
-            commit.SetMinusCount(dbRemovedLines)
-            commit.SetDescriptionID(dbDescID)
-
-            query.AddCommit(commit)
-
-    def CheckCommit(self, commit):
-        repository_id = self.GetRepositoryID(commit.GetRepository(), 0)
-        if repository_id == None:
-            return None
-
-        dir_id = self.GetDirectoryID(commit.GetDirectory(), 0)
-        if dir_id == None:
-            return None
-
-        file_id = self.GetFileID(commit.GetFile(), 0)
-        if file_id == None:
-            return None
-
-        sql = "SELECT * FROM checkins WHERE "\
-              "  repositoryid=%s AND dirid=%s AND fileid=%s AND revision=%s"
-        sql_args = (repository_id, dir_id, file_id, commit.GetRevision())
-
-        cursor = self.db.cursor()
-        cursor.execute(sql, sql_args)
-        try:
-            (ci_type, ci_when, who_id, repository_id,
-             dir_id, file_id, revision, sticky_tag, branch_id,
-             plus_count, minus_count, description_id) = cursor.fetchone()
-        except TypeError:
-            return None
-
-        return commit
-
-## the Commit class holds data on one commit, the representation is as
-## close as possible to how it should be committed and retrieved to the
-## database engine
-class Commit:
-    ## static constants for type of commit
-    CHANGE = 0
-    ADD = 1
-    REMOVE = 2
-    
-    def __init__(self):
-        self.__directory = ''
-        self.__file = ''
-        self.__repository = ''
-        self.__revision = ''
-        self.__author = ''
-        self.__branch = ''
-        self.__pluscount = ''
-        self.__minuscount = ''
-        self.__description = ''
-        self.__gmt_time = 0.0
-        self.__type = Commit.CHANGE
-
-    def SetRepository(self, repository):
-        self.__repository = repository
-
-    def GetRepository(self):
-        return self.__repository
-        
-    def SetDirectory(self, dir):
-        self.__directory = dir
-
-    def GetDirectory(self):
-        return self.__directory
-
-    def SetFile(self, file):
-        self.__file = file
-
-    def GetFile(self):
-        return self.__file
-        
-    def SetRevision(self, revision):
-        self.__revision = revision
-
-    def GetRevision(self):
-        return self.__revision
-
-    def SetTime(self, gmt_time):
-        self.__gmt_time = float(gmt_time)
-
-    def GetTime(self):
-        return self.__gmt_time
-
-    def SetAuthor(self, author):
-        self.__author = author
-
-    def GetAuthor(self):
-        return self.__author
-
-    def SetBranch(self, branch):
-        self.__branch = branch or ''
-
-    def GetBranch(self):
-        return self.__branch
-
-    def SetPlusCount(self, pluscount):
-        self.__pluscount = pluscount
-
-    def GetPlusCount(self):
-        return self.__pluscount
-
-    def SetMinusCount(self, minuscount):
-        self.__minuscount = minuscount
-
-    def GetMinusCount(self):
-        return self.__minuscount
-
-    def SetDescription(self, description):
-        self.__description = description
-
-    def GetDescription(self):
-        return self.__description
-
-    def SetTypeChange(self):
-        self.__type = Commit.CHANGE
-
-    def SetTypeAdd(self):
-        self.__type = Commit.ADD
-
-    def SetTypeRemove(self):
-        self.__type = Commit.REMOVE
-
-    def GetType(self):
-        return self.__type
-
-    def GetTypeString(self):
-        if self.__type == Commit.CHANGE:
-            return 'Change'
-        elif self.__type == Commit.ADD:
-            return 'Add'
-        elif self.__type == Commit.REMOVE:
-            return 'Remove'
-
-## LazyCommit overrides a few methods of Commit to only retrieve
-## it's properties as they are needed
-class LazyCommit(Commit):
-  def __init__(self, db):
-    Commit.__init__(self)
-    self.__db = db
-
-  def SetFileID(self, dbFileID):
-    self.__dbFileID = dbFileID
-
-  def GetFileID(self):
-    return self.__dbFileID
-
-  def GetFile(self):
-    return self.__db.GetFile(self.__dbFileID)
-
-  def SetDirectoryID(self, dbDirID):
-    self.__dbDirID = dbDirID
-
-  def GetDirectoryID(self):
-    return self.__dbDirID
-
-  def GetDirectory(self):
-    return self.__db.GetDirectory(self.__dbDirID)
-
-  def SetRepositoryID(self, dbRepositoryID):
-    self.__dbRepositoryID = dbRepositoryID
-
-  def GetRepositoryID(self):
-    return self.__dbRepositoryID
-
-  def GetRepository(self):
-    return self.__db.GetRepository(self.__dbRepositoryID)
-
-  def SetAuthorID(self, dbAuthorID):
-    self.__dbAuthorID = dbAuthorID
-
-  def GetAuthorID(self):
-    return self.__dbAuthorID
-
-  def GetAuthor(self):
-    return self.__db.GetAuthor(self.__dbAuthorID)
-
-  def SetBranchID(self, dbBranchID):
-    self.__dbBranchID = dbBranchID
-
-  def GetBranchID(self):
-    return self.__dbBranchID
-
-  def GetBranch(self):
-    return self.__db.GetBranch(self.__dbBranchID)
-
-  def SetDescriptionID(self, dbDescID):
-    self.__dbDescID = dbDescID
-
-  def GetDescriptionID(self):
-    return self.__dbDescID
-
-  def GetDescription(self):
-    return self.__db.GetDescription(self.__dbDescID)
-
-## QueryEntry holds data on one match-type in the SQL database
-## match is: "exact", "like", or "regex"
-class QueryEntry:
-    def __init__(self, data, match):
-        self.data = data
-        self.match = match
-
-## CheckinDatabaseQueryData is a object which contains the search parameters
-## for a query to the CheckinDatabase
-class CheckinDatabaseQuery:
-    def __init__(self):
-        ## sorting
-        self.sort = "date"
-        
-        ## repository to query
-        self.repository_list = []
-        self.branch_list = []
-        self.directory_list = []
-        self.file_list = []
-        self.author_list = []
-
-        ## date range in DBI 2.0 timedate objects
-        self.from_date = None
-        self.to_date = None
-
-        ## limit on number of rows to return
-        self.limit = None
-
-        ## list of commits -- filled in by CVS query
-        self.commit_list = []
-
-        ## commit_cb provides a callback for commits as they
-        ## are added
-        self.commit_cb = None
-
-    def SetRepository(self, repository, match = "exact"):
-        self.repository_list.append(QueryEntry(repository, match))
-
-    def SetBranch(self, branch, match = "exact"):
-        self.branch_list.append(QueryEntry(branch, match))
-
-    def SetDirectory(self, directory, match = "exact"):
-        self.directory_list.append(QueryEntry(directory, match))
-
-    def SetFile(self, file, match = "exact"):
-        self.file_list.append(QueryEntry(file, match))
-
-    def SetAuthor(self, author, match = "exact"):
-        self.author_list.append(QueryEntry(author, match))
-
-    def SetSortMethod(self, sort):
-        self.sort = sort
-
-    def SetFromDateObject(self, ticks):
-        self.from_date = dbi.DateTimeFromTicks(ticks)
-
-    def SetToDateObject(self, ticks):
-        self.to_date = dbi.DateTimeFromTicks(ticks)
-
-    def SetFromDateHoursAgo(self, hours_ago):
-        ticks = time.time() - (3600 * hours_ago)
-        self.from_date = dbi.DateTimeFromTicks(ticks)
-        
-    def SetFromDateDaysAgo(self, days_ago):
-        ticks = time.time() - (86400 * days_ago)
-        self.from_date = dbi.DateTimeFromTicks(ticks)
-
-    def SetToDateDaysAgo(self, days_ago):
-        ticks = time.time() - (86400 * days_ago)
-        self.to_date = dbi.DateTimeFromTicks(ticks)
-
-    def SetLimit(self, limit):
-        self.limit = limit;
-
-    def AddCommit(self, commit):
-        self.commit_list.append(commit)
-
-
-##
-## entrypoints
-##
-def CreateCommit():
-    return Commit()
-    
-def CreateCheckinQuery():
-    return CheckinDatabaseQuery()
-
-def ConnectDatabaseReadOnly(cfg):
-    global gCheckinDatabaseReadOnly
-    
-    if gCheckinDatabaseReadOnly:
-        return gCheckinDatabaseReadOnly
-    
-    gCheckinDatabaseReadOnly = CheckinDatabase(
-        cfg.cvsdb.host,
-        cfg.cvsdb.port,
-        cfg.cvsdb.readonly_user,
-        cfg.cvsdb.readonly_passwd,
-        cfg.cvsdb.database_name,
-        cfg.cvsdb.row_limit)
-    
-    gCheckinDatabaseReadOnly.Connect()
-    return gCheckinDatabaseReadOnly
-
-def ConnectDatabase(cfg):
-    global gCheckinDatabase
-
-    if gCheckinDatabase:
-        return gCheckinDatabase
-
-    gCheckinDatabase = CheckinDatabase(
-        cfg.cvsdb.host,
-        cfg.cvsdb.port,
-        cfg.cvsdb.user,
-        cfg.cvsdb.passwd,
-        cfg.cvsdb.database_name,
-        cfg.cvsdb.row_limit)
-    
-    gCheckinDatabase.Connect()
-    return gCheckinDatabase
-
-def GetCommitListFromRCSFile(repository, path_parts, revision=None):
-    commit_list = []
-
-    directory = string.join(path_parts[:-1], "/")
-    file = path_parts[-1]
-
-    revs = repository.itemlog(path_parts, revision, {"cvs_pass_rev": 1})
-    for rev in revs:
-        commit = CreateCommit()
-        commit.SetRepository(repository.rootpath)
-        commit.SetDirectory(directory)
-        commit.SetFile(file)
-        commit.SetRevision(rev.string)
-        commit.SetAuthor(rev.author)
-        commit.SetDescription(rev.log)
-        commit.SetTime(rev.date)
-
-        if rev.changed:
-            # extract the plus/minus and drop the sign
-            plus, minus = string.split(rev.changed)
-            commit.SetPlusCount(plus[1:])
-            commit.SetMinusCount(minus[1:])
-
-            if rev.dead:
-                commit.SetTypeRemove()
-            else:
-                commit.SetTypeChange()
-        else:
-            commit.SetTypeAdd()
-
-        commit_list.append(commit)
-
-        # if revision is on a branch which has at least one tag
-        if len(rev.number) > 2 and rev.branches:
-            commit.SetBranch(rev.branches[0].name)
-
-    return commit_list
-
-def GetUnrecordedCommitList(repository, path_parts, db):
-    commit_list = GetCommitListFromRCSFile(repository, path_parts)
-
-    unrecorded_commit_list = []
-    for commit in commit_list:
-        result = db.CheckCommit(commit)
-        if not result:
-            unrecorded_commit_list.append(commit)
-
-    return unrecorded_commit_list
-
-_re_likechars = re.compile(r"([_%\\])")
-
-def EscapeLike(literal):
-  """Escape literal string for use in a MySQL LIKE pattern"""
-  return re.sub(_re_likechars, r"\\\1", literal)
-
-def FindRepository(db, path):
-  """Find repository path in database given path to subdirectory
-  Returns normalized repository path and relative directory path"""
-  path = os.path.normpath(path)
-  dirs = []
-  while path:
-    rep = os.path.normcase(path)
-    if db.GetRepositoryID(rep, 0) is None:
-      path, pdir = os.path.split(path)
-      if not pdir:
-        return None, None
-      dirs.append(pdir)
-    else:
-      break
-  dirs.reverse()
-  return rep, dirs
-
-def CleanRepository(path):
-  """Return normalized top-level repository path"""
-  return os.path.normcase(os.path.normpath(path))
-
diff --git a/src/www/scm/viewvc/lib/dbi.py b/src/www/scm/viewvc/lib/dbi.py
deleted file mode 100644
index 1f28dce..0000000
--- a/src/www/scm/viewvc/lib/dbi.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-import sys
-import time
-import types
-import re
-import compat
-import MySQLdb
-
-# set to 1 to store commit times in UTC, or 0 to use the ViewVC machine's
-# local timezone. Using UTC is recommended because it ensures that the 
-# database will remain valid even if it is moved to another machine or the host
-# computer's time zone is changed. UTC also avoids the ambiguity associated
-# with daylight saving time (for example if a computer in New York recorded the
-# local time 2002/10/27 1:30 am, there would be no way to tell whether the
-# actual time was recorded before or after clocks were rolled back). Use local
-# times for compatibility with databases used by ViewCVS 0.92 and earlier 
-# versions.
-utc_time = 1
-
-def DateTimeFromTicks(ticks):
-  """Return a MySQL DATETIME value from a unix timestamp"""
-
-  if utc_time:
-    t = time.gmtime(ticks)
-  else:
-    t = time.localtime(ticks)
-  return "%04d-%02d-%02d %02d:%02d:%02d" % t[:6]
-
-_re_datetime = re.compile('([0-9]{4})-([0-9][0-9])-([0-9][0-9]) '
-                          '([0-9][0-9]):([0-9][0-9]):([0-9][0-9])')
-
-def TicksFromDateTime(datetime):
-  """Return a unix timestamp from a MySQL DATETIME value"""
-
-  if type(datetime) == types.StringType:
-    # datetime is a MySQL DATETIME string
-    matches = _re_datetime.match(datetime).groups()
-    t = tuple(map(int, matches)) + (0, 0, 0)
-  elif hasattr(datetime, "timetuple"):
-    # datetime is a Python >=2.3 datetime.DateTime object
-    t = datetime.timetuple()
-  else:
-    # datetime is an eGenix mx.DateTime object
-    t = datetime.tuple()
-
-  if utc_time:
-    return compat.timegm(t)
-  else:
-    return time.mktime(t[:8] + (-1,))
-    
-def connect(host, port, user, passwd, db):
-    return MySQLdb.connect(host=host, port=port, user=user, passwd=passwd, db=db)
diff --git a/src/www/scm/viewvc/lib/debug.py b/src/www/scm/viewvc/lib/debug.py
deleted file mode 100644
index f3657b1..0000000
--- a/src/www/scm/viewvc/lib/debug.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-#
-# Note: a t_start/t_end pair consumes about 0.00005 seconds on a P3/700.
-#       the lambda form (when debugging is disabled) should be even faster.
-#
-
-import sys
-
-
-SHOW_TIMES = 0
-SHOW_CHILD_PROCESSES = 0
-
-if SHOW_TIMES:
-
-  import time
-
-  _timers = { }
-  _times = { }
-
-  def t_start(which):
-    _timers[which] = time.time()
-
-  def t_end(which):
-    t = time.time() - _timers[which]
-    if _times.has_key(which):
-      _times[which] = _times[which] + t
-    else:
-      _times[which] = t
-
-  def dump():
-    for name, value in _times.items():
-      print '%s: %.6f<br />' % (name, value)
-
-else:
-
-  t_start = t_end = dump = lambda *args: None
-
-
-class ViewVCException:
-  def __init__(self, msg, status=None):
-    self.msg = msg
-    self.status = status
-
-  def __str__(self):
-    if self.status:
-      return '%s: %s' % (self.status, self.msg)
-    return "ViewVC Unrecoverable Error: %s" % self.msg
-
-
-def PrintException(server, exc_data):
-  status = exc_data['status']
-  msg = exc_data['msg']
-  tb = exc_data['stacktrace']
-  
-  server.header(status=status)
-  server.write("<h3>An Exception Has Occurred</h3>\n")
-
-  s = ''
-  if msg:
-    s = '<p><pre>%s</pre></p>' % server.escape(msg)
-  if status:
-    s = s + ('<h4>HTTP Response Status</h4>\n<p><pre>\n%s</pre></p><hr />\n'
-             % status)
-  server.write(s)
-
-  server.write("<h4>Python Traceback</h4>\n<p><pre>")
-  server.write(server.escape(tb))
-  server.write("</pre></p>\n")
-
-
-def GetExceptionData():
-  # capture the exception before doing anything else
-  exc_type, exc, exc_tb = sys.exc_info()
-
-  exc_dict = {
-    'status' : None,
-    'msg' : None,
-    'stacktrace' : None,
-    }
-  
-  try:
-    import traceback, string
-
-    if isinstance(exc, ViewVCException):
-      exc_dict['msg'] = exc.msg
-      exc_dict['status'] = exc.status
-    
-    tb = string.join(traceback.format_exception(exc_type, exc, exc_tb), '')
-    exc_dict['stacktrace'] = tb
-
-  finally:
-    # prevent circular reference. sys.exc_info documentation warns
-    # "Assigning the traceback return value to a local variable in a function
-    # that is handling an exception will cause a circular reference..."
-    # This is all based on 'exc_tb', and we're now done with it. Toss it.
-    del exc_tb
-
-  return exc_dict
-
-
-if SHOW_CHILD_PROCESSES:
-  class Process:
-    def __init__(self, command, inStream, outStream, errStream):
-      self.command = command
-      self.debugIn = inStream
-      self.debugOut = outStream
-      self.debugErr = errStream
-
-      import sapi
-      if not sapi.server is None:
-        if not sapi.server.pageGlobals.has_key('processes'):
-          sapi.server.pageGlobals['processes'] = [self]
-        else:
-          sapi.server.pageGlobals['processes'].append(self)
-
-  def DumpChildren(server):
-    import os
-
-    if not server.pageGlobals.has_key('processes'):
-      return
-    
-    server.header()
-    lastOut = None
-    i = 0
-
-    for k in server.pageGlobals['processes']:
-      i = i + 1
-      server.write("<table>\n")
-      server.write("<tr><td colspan=\"2\">Child Process%i</td></tr>" % i)
-      server.write("<tr>\n  <td style=\"vertical-align:top\">Command Line</td>  <td><pre>")
-      server.write(server.escape(k.command))
-      server.write("</pre></td>\n</tr>\n")
-      server.write("<tr>\n  <td style=\"vertical-align:top\">Standard In:</td>  <td>")
-
-      if k.debugIn is lastOut and not lastOut is None:
-        server.write("<em>Output from process %i</em>" % (i - 1))
-      elif k.debugIn:
-        server.write("<pre>")
-        server.write(server.escape(k.debugIn.getvalue()))
-        server.write("</pre>")
-        
-      server.write("</td>\n</tr>\n")
-      
-      if k.debugOut is k.debugErr:
-        server.write("<tr>\n  <td style=\"vertical-align:top\">Standard Out & Error:</td>  <td><pre>")
-        if k.debugOut:
-          server.write(server.escape(k.debugOut.getvalue()))
-        server.write("</pre></td>\n</tr>\n")
-        
-      else:
-        server.write("<tr>\n  <td style=\"vertical-align:top\">Standard Out:</td>  <td><pre>")
-        if k.debugOut:
-          server.write(server.escape(k.debugOut.getvalue()))
-        server.write("</pre></td>\n</tr>\n")
-        server.write("<tr>\n  <td style=\"vertical-align:top\">Standard Error:</td>  <td><pre>")
-        if k.debugErr:
-          server.write(server.escape(k.debugErr.getvalue()))
-        server.write("</pre></td>\n</tr>\n")
-
-      server.write("</table>\n")
-      server.flush()
-      lastOut = k.debugOut
-
-    server.write("<table>\n")
-    server.write("<tr><td colspan=\"2\">Environment Variables</td></tr>")
-    for k, v in os.environ.items():
-      server.write("<tr>\n  <td style=\"vertical-align:top\"><pre>")
-      server.write(server.escape(k))
-      server.write("</pre></td>\n  <td style=\"vertical-align:top\"><pre>")
-      server.write(server.escape(v))
-      server.write("</pre></td>\n</tr>")
-    server.write("</table>")
-         
-else:
-
-  def DumpChildren(server):
-    pass
-    
diff --git a/src/www/scm/viewvc/lib/ezt.py b/src/www/scm/viewvc/lib/ezt.py
deleted file mode 100644
index ac93aba..0000000
--- a/src/www/scm/viewvc/lib/ezt.py
+++ /dev/null
@@ -1,823 +0,0 @@
-#!/usr/bin/env python
-"""ezt.py -- easy templating
-
-ezt templates are simply text files in whatever format you so desire
-(such as XML, HTML, etc.) which contain directives sprinkled
-throughout.  With these directives it is possible to generate the
-dynamic content from the ezt templates.
-
-These directives are enclosed in square brackets.  If you are a
-C-programmer, you might be familar with the #ifdef directives of the C
-preprocessor 'cpp'.  ezt provides a similar concept.  Additionally EZT
-has a 'for' directive, which allows it to iterate (repeat) certain
-subsections of the template according to sequence of data items
-provided by the application.
-
-The final rendering is performed by the method generate() of the Template
-class.  Building template instances can either be done using external
-EZT files (convention: use the suffix .ezt for such files):
-
-    >>> template = Template("../templates/log.ezt")
-
-or by calling the parse() method of a template instance directly with 
-a EZT template string:
-
-    >>> template = Template()
-    >>> template.parse('''<html><head>
-    ... <title>[title_string]</title></head>
-    ... <body><h1>[title_string]</h1>
-    ...    [for a_sequence] <p>[a_sequence]</p>
-    ...    [end] <hr />
-    ...    The [person] is [if-any state]in[else]out[end].
-    ... </body>
-    ... </html>
-    ... ''')
-
-The application should build a dictionary 'data' and pass it together
-with the output fileobject to the templates generate method:
-
-    >>> data = {'title_string' : "A Dummy Page",
-    ...         'a_sequence' : ['list item 1', 'list item 2', 'another element'],
-    ...         'person': "doctor",
-    ...         'state' : None }
-    >>> import sys
-    >>> template.generate(sys.stdout, data)
-    <html><head>
-    <title>A Dummy Page</title></head>
-    <body><h1>A Dummy Page</h1>
-     <p>list item 1</p>
-     <p>list item 2</p>
-     <p>another element</p>
-     <hr />
-    The doctor is out.
-    </body>
-    </html>
-
-Template syntax error reporting should be improved.  Currently it is 
-very sparse (template line numbers would be nice):
-
-    >>> Template().parse("[if-any where] foo [else] bar [end unexpected args]")
-    Traceback (innermost last):
-      File "<stdin>", line 1, in ?
-      File "ezt.py", line 220, in parse
-        self.program = self._parse(text)
-      File "ezt.py", line 275, in _parse
-        raise ArgCountSyntaxError(str(args[1:]))
-    ArgCountSyntaxError: ['unexpected', 'args']
-    >>> Template().parse("[if unmatched_end]foo[end]")
-    Traceback (innermost last):
-      File "<stdin>", line 1, in ?
-      File "ezt.py", line 206, in parse
-        self.program = self._parse(text)
-      File "ezt.py", line 266, in _parse
-        raise UnmatchedEndError()
-    UnmatchedEndError
-
-
-Directives
-==========
-
- Several directives allow the use of dotted qualified names refering to objects
- or attributes of objects contained in the data dictionary given to the 
- .generate() method.
-
- Qualified names
- ---------------
-
-   Qualified names have two basic forms: a variable reference, or a string
-   constant. References are a name from the data dictionary with optional
-   dotted attributes (where each intermediary is an object with attributes,
-   of course).
-
-   Examples:
-
-     [varname]
-
-     [ob.attr]
-
-     ["string"]
-
- Simple directives
- -----------------
-
-   [QUAL_NAME]
-
-   This directive is simply replaced by the value of the qualified name.
-   If the value is a number it's converted to a string before being 
-   outputted. If it is None, nothing is outputted. If it is a python file
-   object (i.e. any object with a "read" method), it's contents are
-   outputted. If it is a callback function (any callable python object
-   is assumed to be a callback function), it is invoked and passed an EZT
-   Context object as an argument.
-
-   [QUAL_NAME QUAL_NAME ...]
-
-   If the first value is a callback function, it is invoked with an EZT
-   Context object as a first argument, and the rest of the values as
-   additional arguments.
-
-   Otherwise, the first value defines a substitution format, specifying
-   constant text and indices of the additional arguments. The arguments
-   are substituted and the result is inserted into the output stream.
-
-   Example:
-     ["abc %0 def %1 ghi %0" foo bar.baz]
-
-   Note that the first value can be any type of qualified name -- a string
-   constant or a variable reference. Use %% to substitute a percent sign.
-   Argument indices are 0-based.
-
-   [include "filename"]  or [include QUAL_NAME]
-
-   This directive is replaced by content of the named include file. Note
-   that a string constant is more efficient -- the target file is compiled
-   inline. In the variable form, the target file is compiled and executed
-   at runtime.
-
- Block directives
- ----------------
-
-   [for QUAL_NAME] ... [end]
-   
-   The text within the [for ...] directive and the corresponding [end]
-   is repeated for each element in the sequence referred to by the
-   qualified name in the for directive.  Within the for block this
-   identifiers now refers to the actual item indexed by this loop
-   iteration.
-
-   [if-any QUAL_NAME [QUAL_NAME2 ...]] ... [else] ... [end]
-
-   Test if any QUAL_NAME value is not None or an empty string or list.
-   The [else] clause is optional.  CAUTION: Numeric values are
-   converted to string, so if QUAL_NAME refers to a numeric value 0,
-   the then-clause is substituted!
-
-   [if-index INDEX_FROM_FOR odd] ... [else] ... [end]
-   [if-index INDEX_FROM_FOR even] ... [else] ... [end]
-   [if-index INDEX_FROM_FOR first] ... [else] ... [end]
-   [if-index INDEX_FROM_FOR last] ... [else] ... [end]
-   [if-index INDEX_FROM_FOR NUMBER] ... [else] ... [end]
-
-   These five directives work similar to [if-any], but are only useful
-   within a [for ...]-block (see above).  The odd/even directives are
-   for example useful to choose different background colors for
-   adjacent rows in a table.  Similar the first/last directives might
-   be used to remove certain parts (for example "Diff to previous"
-   doesn't make sense, if there is no previous).
-
-   [is QUAL_NAME STRING] ... [else] ... [end]
-   [is QUAL_NAME QUAL_NAME] ... [else] ... [end]
-
-   The [is ...] directive is similar to the other conditional
-   directives above.  But it allows to compare two value references or
-   a value reference with some constant string.
-
-   [define VARIABLE] ... [end]
-
-   The [define ...] directive allows you to create and modify template
-   variables from within the template itself.  Essentially, any data
-   between inside the [define ...] and its matching [end] will be
-   expanded using the other template parsing and output generation
-   rules, and then stored as a string value assigned to the variable
-   VARIABLE.  The new (or changed) variable is then available for use
-   with other mechanisms such as [is ...] or [if-any ...], as long as
-   they appear later in the template.
-
-   [format STRING] ... [end]
-
-   The format directive controls how the values substituted into
-   templates are escaped before they are put into the output stream. It
-   has no effect on the literal text of the templates, only the output
-   from [QUAL_NAME ...] directives. STRING can be one of "raw" "html" 
-   or "xml". The "raw" mode leaves the output unaltered. The "html" and
-   "xml" modes escape special characters using entity escapes (like
-   " and >)
-
-   [format CALLBACK]
- 
-   Python applications using EZT can provide custom formatters as callback
-   variables. "[format CALLBACK][QUAL_NAME][end]" is in most cases
-   equivalent to "[CALLBACK QUAL_NAME]"
-"""
-#
-# Copyright (C) 2001-2005 Greg Stein. 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. 
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
-# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
-# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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.
-#
-#
-# This software is maintained by Greg and is available at:
-#    http://svn.webdav.org/repos/projects/ezt/trunk/
-#
-
-import string
-import re
-from types import StringType, IntType, FloatType, LongType, TupleType
-import os
-import cgi
-try:
-  import cStringIO
-except ImportError:
-  import StringIO
-  cStringIO = StringIO
-
-#
-# Formatting types
-#
-FORMAT_RAW = 'raw'
-FORMAT_HTML = 'html'
-FORMAT_XML = 'xml'
-
-#
-# This regular expression matches three alternatives:
-#   expr: DIRECTIVE | BRACKET | COMMENT
-#   DIRECTIVE: '[' ITEM (whitespace ITEM)* ']
-#   ITEM: STRING | NAME
-#   STRING: '"' (not-slash-or-dquote | '\' anychar)* '"'
-#   NAME: (alphanum | '_' | '-' | '.')+
-#   BRACKET: '[[]'
-#   COMMENT: '[#' not-rbracket* ']'
-#
-# When used with the split() method, the return value will be composed of
-# non-matching text and the two paren groups (DIRECTIVE and BRACKET). Since
-# the COMMENT matches are not placed into a group, they are considered a
-# "splitting" value and simply dropped.
-#
-_item = r'(?:"(?:[^\\"]|\\.)*"|[-\w.]+)'
-_re_parse = re.compile(r'\[(%s(?: +%s)*)\]|(\[\[\])|\[#[^\]]*\]' % (_item, _item))
-
-_re_args = re.compile(r'"(?:[^\\"]|\\.)*"|[-\w.]+')
-
-# block commands and their argument counts
-_block_cmd_specs = { 'if-index':2, 'for':1, 'is':2, 'define':1, 'format':1 }
-_block_cmds = _block_cmd_specs.keys()
-
-# two regular expresssions for compressing whitespace. the first is used to
-# compress any whitespace including a newline into a single newline. the
-# second regex is used to compress runs of whitespace into a single space.
-_re_newline = re.compile('[ \t\r\f\v]*\n\\s*')
-_re_whitespace = re.compile(r'\s\s+')
-
-# this regex is used to substitute arguments into a value. we split the value,
-# replace the relevant pieces, and then put it all back together. splitting
-# will produce a list of: TEXT ( splitter TEXT )*. splitter will be '%' or
-# an integer.
-_re_subst = re.compile('%(%|[0-9]+)')
-
-class Template:
-
-  def __init__(self, fname=None, compress_whitespace=1,
-               base_format=FORMAT_RAW):
-    self.compress_whitespace = compress_whitespace
-    if fname:
-      self.parse_file(fname, base_format)
-
-  def parse_file(self, fname, base_format=FORMAT_RAW):
-    "fname -> a string object with pathname of file containg an EZT template."
-
-    self.parse(_FileReader(fname), base_format)
-
-  def parse(self, text_or_reader, base_format=FORMAT_RAW):
-    """Parse the template specified by text_or_reader.
-
-    The argument should be a string containing the template, or it should
-    specify a subclass of ezt.Reader which can read templates. The base
-    format for printing values is given by base_format.
-    """
-    if not isinstance(text_or_reader, Reader):
-      # assume the argument is a plain text string
-      text_or_reader = _TextReader(text_or_reader)
-
-    self.program = self._parse(text_or_reader, base_format=base_format)
-
-  def generate(self, fp, data):
-    if hasattr(data, '__getitem__') or callable(getattr(data, 'keys', None)):
-      # a dictionary-like object was passed. convert it to an
-      # attribute-based object.
-      class _data_ob:
-        def __init__(self, d):
-          vars(self).update(d)
-      data = _data_ob(data)
-
-    ctx = Context(fp)
-    ctx.data = data
-    ctx.for_iterators = { }
-    ctx.defines = { }
-    self._execute(self.program, ctx)
-
-  def _parse(self, reader, for_names=None, file_args=(), base_format=None):
-    """text -> string object containing the template.
-
-    This is a private helper function doing the real work for method parse.
-    It returns the parsed template as a 'program'.  This program is a sequence
-    made out of strings or (function, argument) 2-tuples.
-
-    Note: comment directives [# ...] are automatically dropped by _re_parse.
-    """
-
-    # parse the template program into: (TEXT DIRECTIVE BRACKET)* TEXT
-    parts = _re_parse.split(reader.text)
-
-    program = [ ]
-    stack = [ ]
-    if not for_names:
-      for_names = [ ]
-
-    if base_format:
-      program.append((self._cmd_format, _printers[base_format]))
-
-    for i in range(len(parts)):
-      piece = parts[i]
-      which = i % 3  # discriminate between: TEXT DIRECTIVE BRACKET
-      if which == 0:
-        # TEXT. append if non-empty.
-        if piece:
-          if self.compress_whitespace:
-            piece = _re_whitespace.sub(' ', _re_newline.sub('\n', piece))
-          program.append(piece)
-      elif which == 2:
-        # BRACKET directive. append '[' if present.
-        if piece:
-          program.append('[')
-      elif piece:
-        # DIRECTIVE is present.
-        args = _re_args.findall(piece)
-        cmd = args[0]
-        if cmd == 'else':
-          if len(args) > 1:
-            raise ArgCountSyntaxError(str(args[1:]))
-          ### check: don't allow for 'for' cmd
-          idx = stack[-1][1]
-          true_section = program[idx:]
-          del program[idx:]
-          stack[-1][3] = true_section
-        elif cmd == 'end':
-          if len(args) > 1:
-            raise ArgCountSyntaxError(str(args[1:]))
-          # note: true-section may be None
-          try:
-            cmd, idx, args, true_section = stack.pop()
-          except IndexError:
-            raise UnmatchedEndError()
-          else_section = program[idx:]
-          if cmd == 'format':
-            program.append((self._cmd_end_format, None))
-          else:
-            func = getattr(self, '_cmd_' + re.sub('-', '_', cmd))
-            program[idx:] = [ (func, (args, true_section, else_section)) ]
-            if cmd == 'for':
-              for_names.pop()
-        elif cmd in _block_cmds:
-          if len(args) > _block_cmd_specs[cmd] + 1:
-            raise ArgCountSyntaxError(str(args[1:]))
-          ### this assumes arg1 is always a ref unless cmd is 'define'
-          if cmd != 'define':
-            args[1] = _prepare_ref(args[1], for_names, file_args)
-
-          # handle arg2 for the 'is' command
-          if cmd == 'is':
-            args[2] = _prepare_ref(args[2], for_names, file_args)
-          elif cmd == 'for':
-            for_names.append(args[1][0])  # append the refname
-          elif cmd == 'format':
-            if args[1][0]:
-              # argument is a variable reference
-              printer = args[1]
-            else:
-              # argument is a string constant referring to built-in printer
-              printer = _printers.get(args[1][1])
-              if not printer:
-                raise UnknownFormatConstantError(str(args[1:]))
-            program.append((self._cmd_format, printer))
-
-          # remember the cmd, current pos, args, and a section placeholder
-          stack.append([cmd, len(program), args[1:], None])
-        elif cmd == 'include':
-          if args[1][0] == '"':
-            include_filename = args[1][1:-1]
-            f_args = [ ]
-            for arg in args[2:]:
-              f_args.append(_prepare_ref(arg, for_names, file_args))
-            program.extend(self._parse(reader.read_other(include_filename),
-                                       for_names, f_args))
-          else:
-            if len(args) != 2:
-              raise ArgCountSyntaxError(str(args))
-            program.append((self._cmd_include,
-                            (_prepare_ref(args[1], for_names, file_args),
-                             reader)))
-        elif cmd == 'if-any':
-          f_args = [ ]
-          for arg in args[1:]:
-            f_args.append(_prepare_ref(arg, for_names, file_args))
-          stack.append(['if-any', len(program), f_args, None])
-        else:
-          # implied PRINT command
-          f_args = [ ]
-          for arg in args:
-            f_args.append(_prepare_ref(arg, for_names, file_args))
-          program.append((self._cmd_print, f_args))
-
-    if stack:
-      ### would be nice to say which blocks...
-      raise UnclosedBlocksError()
-    return program
-
-  def _execute(self, program, ctx):
-    """This private helper function takes a 'program' sequence as created
-    by the method '_parse' and executes it step by step.  strings are written
-    to the file object 'fp' and functions are called.
-    """
-    for step in program:
-      if isinstance(step, StringType):
-        ctx.fp.write(step)
-      else:
-        step[0](step[1], ctx)
-
-  def _cmd_print(self, valrefs, ctx):
-    value = _get_value(valrefs[0], ctx)
-    args = map(lambda valref, ctx=ctx: _get_value(valref, ctx), valrefs[1:])
-    _write_value(value, args, ctx)
-
-  def _cmd_format(self, printer, ctx):
-    if type(printer) is TupleType:
-      printer = _get_value(printer, ctx)
-    ctx.printers.append(printer)
-
-  def _cmd_end_format(self, valref, ctx):
-    ctx.printers.pop()
-
-  def _cmd_include(self, (valref, reader), ctx):
-    fname = _get_value(valref, ctx)
-    ### note: we don't have the set of for_names to pass into this parse.
-    ### I don't think there is anything to do but document it.
-    self._execute(self._parse(reader.read_other(fname)), ctx)
-
-  def _cmd_if_any(self, args, ctx):
-    "If any value is a non-empty string or non-empty list, then T else F."
-    (valrefs, t_section, f_section) = args
-    value = 0
-    for valref in valrefs:
-      if _get_value(valref, ctx):
-        value = 1
-        break
-    self._do_if(value, t_section, f_section, ctx)
-
-  def _cmd_if_index(self, args, ctx):
-    ((valref, value), t_section, f_section) = args
-    iterator = ctx.for_iterators[valref[0]]
-    if value == 'even':
-      value = iterator.index % 2 == 0
-    elif value == 'odd':
-      value = iterator.index % 2 == 1
-    elif value == 'first':
-      value = iterator.index == 0
-    elif value == 'last':
-      value = iterator.is_last()
-    else:
-      value = iterator.index == int(value)
-    self._do_if(value, t_section, f_section, ctx)
-
-  def _cmd_is(self, args, ctx):
-    ((left_ref, right_ref), t_section, f_section) = args
-    value = _get_value(right_ref, ctx)
-    value = string.lower(_get_value(left_ref, ctx)) == string.lower(value)
-    self._do_if(value, t_section, f_section, ctx)
-
-  def _do_if(self, value, t_section, f_section, ctx):
-    if t_section is None:
-      t_section = f_section
-      f_section = None
-    if value:
-      section = t_section
-    else:
-      section = f_section
-    if section is not None:
-      self._execute(section, ctx)
-
-  def _cmd_for(self, args, ctx):
-    ((valref,), unused, section) = args
-    list = _get_value(valref, ctx)
-    if isinstance(list, StringType):
-      raise NeedSequenceError()
-    refname = valref[0]
-    ctx.for_iterators[refname] = iterator = _iter(list)
-    for unused in iterator:
-      self._execute(section, ctx)
-    del ctx.for_iterators[refname]
-
-  def _cmd_define(self, args, ctx):
-    ((name,), unused, section) = args
-    origfp = ctx.fp
-    ctx.fp = cStringIO.StringIO()
-    if section is not None:
-      self._execute(section, ctx)
-    ctx.defines[name] = ctx.fp.getvalue()
-    ctx.fp = origfp
-
-def boolean(value):
-  "Return a value suitable for [if-any bool_var] usage in a template."
-  if value:
-    return 'yes'
-  return None
-
-
-def _prepare_ref(refname, for_names, file_args):
-  """refname -> a string containing a dotted identifier. example:"foo.bar.bang"
-  for_names -> a list of active for sequences.
-
-  Returns a `value reference', a 3-tuple made out of (refname, start, rest), 
-  for fast access later.
-  """
-  # is the reference a string constant?
-  if refname[0] == '"':
-    return None, refname[1:-1], None
-
-  parts = string.split(refname, '.')
-  start = parts[0]
-  rest = parts[1:]
-
-  # if this is an include-argument, then just return the prepared ref
-  if start[:3] == 'arg':
-    try:
-      idx = int(start[3:])
-    except ValueError:
-      pass
-    else:
-      if idx < len(file_args):
-        orig_refname, start, more_rest = file_args[idx]
-        if more_rest is None:
-          # the include-argument was a string constant
-          return None, start, None
-
-        # prepend the argument's "rest" for our further processing
-        rest[:0] = more_rest
-
-        # rewrite the refname to ensure that any potential 'for' processing
-        # has the correct name
-        ### this can make it hard for debugging include files since we lose
-        ### the 'argNNN' names
-        if not rest:
-          return start, start, [ ]
-        refname = start + '.' + string.join(rest, '.')
-
-  if for_names:
-    # From last to first part, check if this reference is part of a for loop
-    for i in range(len(parts), 0, -1):
-      name = string.join(parts[:i], '.')
-      if name in for_names:
-        return refname, name, parts[i:]
-
-  return refname, start, rest
-
-def _get_value((refname, start, rest), ctx):
-  """(refname, start, rest) -> a prepared `value reference' (see above).
-  ctx -> an execution context instance.
-
-  Does a name space lookup within the template name space.  Active 
-  for blocks take precedence over data dictionary members with the 
-  same name.
-  """
-  if rest is None:
-    # it was a string constant
-    return start
-
-  # get the starting object
-  if ctx.for_iterators.has_key(start):
-    ob = ctx.for_iterators[start].last_item
-  elif ctx.defines.has_key(start):
-    ob = ctx.defines[start]
-  elif hasattr(ctx.data, start):
-    ob = getattr(ctx.data, start)
-  else:
-    raise UnknownReference(refname)
-
-  # walk the rest of the dotted reference
-  for attr in rest:
-    try:
-      ob = getattr(ob, attr)
-    except AttributeError:
-      raise UnknownReference(refname)
-
-  # make sure we return a string instead of some various Python types
-  if isinstance(ob, IntType) \
-         or isinstance(ob, LongType) \
-         or isinstance(ob, FloatType):
-    return str(ob)
-  if ob is None:
-    return ''
-
-  # string or a sequence
-  return ob
-
-def _write_value(value, args, ctx):
-  # value is a callback function, generates its own output
-  if callable(value):
-    apply(value, [ctx] + list(args))
-    return
-
-  # pop printer in case it recursively calls _write_value
-  printer = ctx.printers.pop()
-
-  try:
-    # if the value has a 'read' attribute, then it is a stream: copy it
-    if hasattr(value, 'read'):
-      while 1:
-        chunk = value.read(16384)
-        if not chunk:
-          break
-        printer(ctx, chunk)
-
-    # value is a substitution pattern
-    elif args:
-      parts = _re_subst.split(value)
-      for i in range(len(parts)):
-        piece = parts[i]
-        if i%2 == 1 and piece != '%':
-          idx = int(piece)
-          if idx < len(args):
-            piece = args[idx]
-          else:
-            piece = '<undef>'
-          printer(ctx, piece)
-
-    # plain old value, write to output
-    else:
-      printer(ctx, value)
-
-  finally:
-    ctx.printers.append(printer)
-
-
-class Context:
-  """A container for the execution context"""
-  def __init__(self, fp):
-    self.fp = fp
-    self.printers = []
-  def write(self, value, args=()):
-    _write_value(value, args, self)
-
-class Reader:
-  "Abstract class which allows EZT to detect Reader objects."
-
-class _FileReader(Reader):
-  """Reads templates from the filesystem."""
-  def __init__(self, fname):
-    self.text = open(fname, 'rb').read()
-    self._dir = os.path.dirname(fname)
-  def read_other(self, relative):
-    return _FileReader(os.path.join(self._dir, relative))
-
-class _TextReader(Reader):
-  """'Reads' a template from provided text."""
-  def __init__(self, text):
-    self.text = text
-  def read_other(self, relative):
-    raise BaseUnavailableError()
-
-class _Iterator:
-  """Specialized iterator for EZT that counts items and can look ahead
-
-  Implements standard iterator interface and provides an is_last() method
-  and two public members:
-
-    index - integer index of the current item
-    last_item - last item returned by next()"""
-
-  def __init__(self, sequence):
-    self._iter = iter(sequence)
-
-  def next(self):
-    if hasattr(self, '_next_item'):
-      self.last_item = self._next_item
-      del self._next_item
-    else:
-      self.last_item = self._iter.next() # may raise StopIteration
-
-    if hasattr(self, 'index'):
-      self.index = self.index + 1
-    else:
-      self.index = 0
-
-    return self.last_item
-
-  def is_last(self):
-    """Return true if the current item is the last in the sequence"""
-    # the only way we can tell if the current item is last is to call next()
-    # and store the return value so it doesn't get lost
-    if not hasattr(self, '_next_item'):
-      try:
-        self._next_item = self._iter.next()
-      except StopIteration:
-        return 1
-    return 0
-
-  def __iter__(self):
-    return self
-
-class _OldIterator:
-  """Alternate implemention of _Iterator for old Pythons without iterators
-
-  This class implements the sequence protocol, instead of the iterator
-  interface, so it's really not an iterator at all. But it can be used in
-  python "for" loops as a drop-in replacement for _Iterator. It also provides
-  the is_last() method and "last_item" and "index" members described in the
-  _Iterator docstring."""
-
-  def __init__(self, sequence):
-    self._seq = sequence
-
-  def __getitem__(self, index):
-    self.last_item = self._seq[index] # may raise IndexError
-    self.index = index
-    return self.last_item
-
-  def is_last(self):
-    return self.index + 1 >= len(self._seq)
-
-try:
-  iter
-except NameError:
-  _iter = _OldIterator
-else:
-  _iter = _Iterator
-
-class EZTException(Exception):
-  """Parent class of all EZT exceptions."""
-
-class ArgCountSyntaxError(EZTException):
-  """A bracket directive got the wrong number of arguments."""
-
-class UnknownReference(EZTException):
-  """The template references an object not contained in the data dictionary."""
-
-class NeedSequenceError(EZTException):
-  """The object dereferenced by the template is no sequence (tuple or list)."""
-
-class UnclosedBlocksError(EZTException):
-  """This error may be simply a missing [end]."""
-
-class UnmatchedEndError(EZTException):
-  """This error may be caused by a misspelled if directive."""
-
-class BaseUnavailableError(EZTException):
-  """Base location is unavailable, which disables includes."""
-
-class UnknownFormatConstantError(EZTException):
-  """The format specifier is an unknown value."""
-
-def _raw_printer(ctx, s):
-  ctx.fp.write(s)
-  
-def _html_printer(ctx, s):
-  ctx.fp.write(cgi.escape(s))
-
-_printers = {
-  FORMAT_RAW  : _raw_printer,
-  FORMAT_HTML : _html_printer,
-  FORMAT_XML  : _html_printer,
-}
-
-# --- standard test environment ---
-def test_parse():
-  assert _re_parse.split('[a]') == ['', '[a]', None, '']
-  assert _re_parse.split('[a] [b]') == \
-         ['', '[a]', None, ' ', '[b]', None, '']
-  assert _re_parse.split('[a c] [b]') == \
-         ['', '[a c]', None, ' ', '[b]', None, '']
-  assert _re_parse.split('x [a] y [b] z') == \
-         ['x ', '[a]', None, ' y ', '[b]', None, ' z']
-  assert _re_parse.split('[a "b" c "d"]') == \
-         ['', '[a "b" c "d"]', None, '']
-  assert _re_parse.split(r'["a \"b[foo]" c.d f]') == \
-         ['', '["a \\"b[foo]" c.d f]', None, '']
-
-def _test(argv):
-  import doctest, ezt           
-  verbose = "-v" in argv
-  return doctest.testmod(ezt, verbose=verbose)
-
-if __name__ == "__main__":
-  # invoke unit test for this module:
-  import sys
-  sys.exit(_test(sys.argv)[0])
diff --git a/src/www/scm/viewvc/lib/idiff.py b/src/www/scm/viewvc/lib/idiff.py
deleted file mode 100644
index b4cf36e..0000000
--- a/src/www/scm/viewvc/lib/idiff.py
+++ /dev/null
@@ -1,190 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# idiff: display differences between files highlighting intraline changes
-#
-# -----------------------------------------------------------------------
-
-from __future__ import generators
-
-import difflib
-import sys
-import re
-import ezt
-import cgi
-
-def sidebyside(fromlines, tolines, context):
-  """Generate side by side diff"""
-
-  ### for some reason mdiff chokes on \n's in input lines
-  line_strip = lambda line: line.rstrip("\n")
-  fromlines = map(line_strip, fromlines)
-  tolines = map(line_strip, tolines)
-
-  gap = False
-  for fromdata, todata, flag in difflib._mdiff(fromlines, tolines, context):
-    if fromdata is None and todata is None and flag is None:
-      gap = True
-    else:
-      from_item = _mdiff_split(flag, fromdata)
-      to_item = _mdiff_split(flag, todata)
-      yield _item(gap=ezt.boolean(gap), columns=(from_item, to_item))
-      gap = False
-
-_re_mdiff = re.compile("\0([+-^])(.*?)\1")
-
-def _mdiff_split(flag, (line_number, text)):
-  """Break up row from mdiff output into segments"""
-  segments = []
-  pos = 0
-  while True:
-    m = _re_mdiff.search(text, pos)
-    if not m:
-      segments.append(_item(text=cgi.escape(text[pos:]), type=None))
-      break
-
-    if m.start() > pos:
-      segments.append(_item(text=cgi.escape(text[pos:m.start()]), type=None))
-
-    if m.group(1) == "+":
-      segments.append(_item(text=cgi.escape(m.group(2)), type="add"))
-    elif m.group(1) == "-":
-      segments.append(_item(text=cgi.escape(m.group(2)), type="remove"))
-    elif m.group(1) == "^":
-      segments.append(_item(text=cgi.escape(m.group(2)), type="change"))
-
-    pos = m.end()
-
-  return _item(segments=segments, line_number=line_number)  
-
-def unified(fromlines, tolines, context):
-  """Generate unified diff"""
-
-  diff = difflib.Differ().compare(fromlines, tolines)
-  lastrow = None
-
-  for row in _trim_context(diff, context):
-    if row[0].startswith("? "):
-      yield _differ_split(lastrow, row[0])
-      lastrow = None
-    else:
-      if lastrow:
-        yield _differ_split(lastrow, None)
-      lastrow = row
-
-  if lastrow:
-    yield _differ_split(lastrow, None)
-
-def _trim_context(lines, context_size):
-  """Trim context lines that don't surround changes from Differ results
-
-  yields (line, leftnum, rightnum, gap) tuples"""
-
-  # circular buffer to hold context lines
-  context_buffer = [None] * (context_size or 0)
-  context_start = context_len = 0
-
-  # number of context lines left to print after encountering a change
-  context_owed = 0
-
-  # current line numbers
-  leftnum = rightnum = 0
-
-  # whether context lines have been dropped
-  gap = False
-
-  for line in lines:
-    row = save = None
-
-    if line.startswith("- "):
-      leftnum = leftnum + 1
-      row = line, leftnum, None
-      context_owed = context_size
-
-    elif line.startswith("+ "):
-      rightnum = rightnum + 1
-      row = line, None, rightnum
-      context_owed = context_size
-
-    else:
-      if line.startswith("  "):
-        leftnum = leftnum = leftnum + 1
-        rightnum = rightnum = rightnum + 1
-        if context_owed > 0:
-          context_owed = context_owed - 1
-        elif context_size is not None:
-          save = True
-
-      row = line, leftnum, rightnum
-
-    if save:
-      # don't yield row right away, store it in buffer
-      context_buffer[(context_start + context_len) % context_size] = row
-      if context_len == context_size:
-        context_start = (context_start + 1) % context_size
-        gap = True
-      else:
-        context_len = context_len + 1
-    else:
-      # yield row, but first drain stuff in buffer
-      context_len == context_size
-      while context_len:
-        yield context_buffer[context_start] + (gap,)
-        gap = False
-        context_start = (context_start + 1) % context_size
-        context_len = context_len - 1
-      yield row + (gap,)
-      gap = False
-
-_re_differ = re.compile(r"[+-^]+")
-
-def _differ_split(row, guide):
-  """Break row into segments using guide line"""
-  line, left_number, right_number, gap = row
-
-  if left_number and right_number:
-    type = "" 
-  elif left_number:
-    type = "remove"
-  elif right_number:
-    type = "add"
-
-  segments = []  
-  pos = 2
-
-  if guide:
-    assert guide.startswith("? ")
-
-    for m in _re_differ.finditer(guide, pos):
-      if m.start() > pos:
-        segments.append(_item(text=cgi.escape(line[pos:m.start()]), type=None))
-      segments.append(_item(text=cgi.escape(line[m.start():m.end()]),
-                            type="change"))
-      pos = m.end()
-
-  segments.append(_item(text=cgi.escape(line[pos:]), type=None))
-
-  return _item(gap=ezt.boolean(gap), type=type, segments=segments,
-               left_number=left_number, right_number=right_number)
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
-
-try:
-  ### Using difflib._mdiff function here was the easiest way of obtaining
-  ### intraline diffs for use in ViewVC, but it doesn't exist prior to
-  ### Python 2.4 and is not part of the public difflib API, so for now
-  ### fall back if it doesn't exist.
-  difflib._mdiff
-except AttributeError:
-  sidebyside = None
diff --git a/src/www/scm/viewvc/lib/popen.py b/src/www/scm/viewvc/lib/popen.py
deleted file mode 100644
index 5065852..0000000
--- a/src/www/scm/viewvc/lib/popen.py
+++ /dev/null
@@ -1,379 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# popen.py: a replacement for os.popen()
-#
-# This implementation of popen() provides a cmd + args calling sequence,
-# rather than a system() type of convention. The shell facilities are not
-# available, but that implies we can avoid worrying about shell hacks in
-# the arguments.
-#
-# -----------------------------------------------------------------------
-
-import os
-import sys
-import sapi
-import threading
-import string
-
-if sys.platform == "win32":
-  import win32popen
-  import win32event
-  import win32process
-  import debug
-  import StringIO
-
-def popen(cmd, args, mode, capture_err=1):
-  if sys.platform == "win32":
-    command = win32popen.CommandLine(cmd, args)
-
-    if string.find(mode, 'r') >= 0:
-      hStdIn = None
-
-      if debug.SHOW_CHILD_PROCESSES:
-        dbgIn, dbgOut = None, StringIO.StringIO()
-
-        handle, hStdOut = win32popen.MakeSpyPipe(0, 1, (dbgOut,))
-
-        if capture_err:
-          hStdErr = hStdOut
-          dbgErr = dbgOut
-        else:
-          dbgErr = StringIO.StringIO()
-          x, hStdErr = win32popen.MakeSpyPipe(None, 1, (dbgErr,))
-      else:
-        handle, hStdOut = win32popen.CreatePipe(0, 1)
-        if capture_err:
-          hStdErr = hStdOut
-        else:
-          hStdErr = win32popen.NullFile(1)
-
-    else:
-      if debug.SHOW_CHILD_PROCESSES:
-        dbgIn, dbgOut, dbgErr = StringIO.StringIO(), StringIO.StringIO(), StringIO.StringIO()
-        hStdIn, handle = win32popen.MakeSpyPipe(1, 0, (dbgIn,))
-        x, hStdOut = win32popen.MakeSpyPipe(None, 1, (dbgOut,))
-        x, hStdErr = win32popen.MakeSpyPipe(None, 1, (dbgErr,))
-      else:
-        hStdIn, handle = win32popen.CreatePipe(0, 1)
-        hStdOut = None
-        hStdErr = None
-
-    phandle, pid, thandle, tid = win32popen.CreateProcess(command, hStdIn, hStdOut, hStdErr)
-
-    if debug.SHOW_CHILD_PROCESSES:
-      debug.Process(command, dbgIn, dbgOut, dbgErr)
-
-    return _pipe(win32popen.File2FileObject(handle, mode), phandle)
-
-  # flush the stdio buffers since we are about to change the FD under them
-  sys.stdout.flush()
-  sys.stderr.flush()
-
-  r, w = os.pipe()
-  pid = os.fork()
-  if pid:
-    # in the parent
-
-    # close the descriptor that we don't need and return the other one.
-    if string.find(mode, 'r') >= 0:
-      os.close(w)
-      return _pipe(os.fdopen(r, mode), pid)
-    os.close(r)
-    return _pipe(os.fdopen(w, mode), pid)
-
-  # in the child
-
-  # we'll need /dev/null for the discarded I/O
-  null = os.open('/dev/null', os.O_RDWR)
-
-  if string.find(mode, 'r') >= 0:
-    # hook stdout/stderr to the "write" channel
-    os.dup2(w, 1)
-    # "close" stdin; the child shouldn't use it
-    ### this isn't quite right... we may want the child to read from stdin
-    os.dup2(null, 0)
-    # what to do with errors?
-    if capture_err:
-      os.dup2(w, 2)
-    else:
-      os.dup2(null, 2)
-  else:
-    # hook stdin to the "read" channel
-    os.dup2(r, 0)
-    # "close" stdout/stderr; the child shouldn't use them
-    ### this isn't quite right... we may want the child to write to these
-    os.dup2(null, 1)
-    os.dup2(null, 2)
-
-  # don't need these FDs any more
-  os.close(null)
-  os.close(r)
-  os.close(w)
-
-  # the stdin/stdout/stderr are all set up. exec the target
-  try:
-    os.execvp(cmd, (cmd,) + tuple(args))
-  except:
-    # aid debugging, if the os.execvp above fails for some reason:
-    print "<h2>exec failed:</h2><pre>", cmd, string.join(args), "</pre>"
-    raise
-
-  # crap. shouldn't be here.
-  sys.exit(127)
-
-def pipe_cmds(cmds, out=None):
-  """Executes a sequence of commands. The output of each command is directed to
-  the input of the next command. A _pipe object is returned for writing to the
-  first command's input. The output of the last command is directed to the
-  "out" file object or the standard output if "out" is None. If "out" is not an
-  OS file descriptor, a separate thread will be spawned to send data to its
-  write() method."""
-
-  if out is None:
-    out = sys.stdout
-
-  if sys.platform == "win32":
-    ### FIXME: windows implementation ignores "out" argument, always
-    ### writing last command's output to standard out
-
-    if debug.SHOW_CHILD_PROCESSES:
-      dbgIn = StringIO.StringIO()
-      hStdIn, handle = win32popen.MakeSpyPipe(1, 0, (dbgIn,))
-
-      i = 0
-      for cmd in cmds:
-        i = i + 1
-
-        dbgOut, dbgErr = StringIO.StringIO(), StringIO.StringIO()
-
-        if i < len(cmds):
-          nextStdIn, hStdOut = win32popen.MakeSpyPipe(1, 1, (dbgOut,))
-          x, hStdErr = win32popen.MakeSpyPipe(None, 1, (dbgErr,))
-        else:
-          ehandle = win32event.CreateEvent(None, 1, 0, None)
-          nextStdIn, hStdOut = win32popen.MakeSpyPipe(None, 1, (dbgOut, sapi.server.file()), ehandle)
-          x, hStdErr = win32popen.MakeSpyPipe(None, 1, (dbgErr,))
-
-        command = win32popen.CommandLine(cmd[0], cmd[1:])
-        phandle, pid, thandle, tid = win32popen.CreateProcess(command, hStdIn, hStdOut, hStdErr)
-        if debug.SHOW_CHILD_PROCESSES:
-          debug.Process(command, dbgIn, dbgOut, dbgErr)
-
-        dbgIn = dbgOut
-        hStdIn = nextStdIn
-
-
-    else:
-
-      hStdIn, handle = win32popen.CreatePipe(1, 0)
-      spool = None
-
-      i = 0
-      for cmd in cmds:
-        i = i + 1
-        if i < len(cmds):
-          nextStdIn, hStdOut = win32popen.CreatePipe(1, 1)
-        else:
-          # very last process
-          nextStdIn = None
-
-          if sapi.server.inheritableOut:
-            # send child output to standard out
-            hStdOut = win32popen.MakeInheritedHandle(win32popen.FileObject2File(sys.stdout),0)
-            ehandle = None
-          else:
-            ehandle = win32event.CreateEvent(None, 1, 0, None)
-            x, hStdOut = win32popen.MakeSpyPipe(None, 1, (sapi.server.file(),), ehandle)
-
-        command = win32popen.CommandLine(cmd[0], cmd[1:])
-        phandle, pid, thandle, tid = win32popen.CreateProcess(command, hStdIn, hStdOut, None)
-        hStdIn = nextStdIn
-
-    return _pipe(win32popen.File2FileObject(handle, 'wb'), phandle, ehandle)
-
-  # flush the stdio buffers since we are about to change the FD under them
-  sys.stdout.flush()
-  sys.stderr.flush()
-
-  prev_r, parent_w = os.pipe()
-
-  null = os.open('/dev/null', os.O_RDWR)
-
-  child_pids = []
-
-  for cmd in cmds[:-1]:
-    r, w = os.pipe()
-    pid = os.fork()
-    if not pid:
-      # in the child
-
-      # hook up stdin to the "read" channel
-      os.dup2(prev_r, 0)
-
-      # hook up stdout to the output channel
-      os.dup2(w, 1)
-
-      # toss errors
-      os.dup2(null, 2)
-
-      # close these extra descriptors
-      os.close(prev_r)
-      os.close(parent_w)
-      os.close(null)
-      os.close(r)
-      os.close(w)
-
-      # time to run the command
-      try:
-        os.execvp(cmd[0], cmd)
-      except:
-        pass
-
-      sys.exit(127)
-
-    # in the parent
-    child_pids.append(pid)
-
-    # we don't need these any more
-    os.close(prev_r)
-    os.close(w)
-
-    # the read channel of this pipe will feed into to the next command
-    prev_r = r
-
-  # no longer needed
-  os.close(null)
-
-  # done with most of the commands. set up the last command to write to "out"
-  if not hasattr(out, 'fileno'):
-    r, w = os.pipe()
-
-  pid = os.fork()
-  if not pid:
-    # in the child (the last command)
-
-    # hook up stdin to the "read" channel
-    os.dup2(prev_r, 0)
-
-    # hook up stdout to "out"
-    if hasattr(out, 'fileno'):
-      if out.fileno() != 1:
-        os.dup2(out.fileno(), 1)
-        out.close()
-
-    else:
-      # "out" can't be hooked up directly, so use a pipe and a thread
-      os.dup2(w, 1)
-      os.close(r)
-      os.close(w)
-
-    # close these extra descriptors
-    os.close(prev_r)
-    os.close(parent_w)
-
-    # run the last command
-    try:
-      os.execvp(cmds[-1][0], cmds[-1])
-    except:
-      pass
-
-    sys.exit(127)
-
-  child_pids.append(pid)
-  # not needed any more
-  os.close(prev_r)
-
-  if not hasattr(out, 'fileno'):
-    os.close(w)
-    thread = _copy(r, out)
-    thread.start()
-  else:
-    thread = None
-
-  # write into the first pipe, wait on the final process
-  return _pipe(os.fdopen(parent_w, 'w'), child_pids, thread=thread)
-
-class _copy(threading.Thread):
-  def __init__(self, srcfd, destfile):
-    self.srcfd = srcfd
-    self.destfile = destfile
-    threading.Thread.__init__(self)
-
-  def run(self):
-    try:
-      while 1:
-        s = os.read(self.srcfd, 1024)
-        if not s:
-          break
-        self.destfile.write(s)
-    finally:
-      os.close(self.srcfd)
-
-class _pipe:
-  "Wrapper for a file which can wait() on a child process at close time."
-
-  def __init__(self, file, child_pid, done_event = None, thread = None):
-    self.file = file
-    self.child_pid = child_pid
-    if sys.platform == "win32":
-      if done_event:
-        self.wait_for = (child_pid, done_event)
-      else:
-        self.wait_for = (child_pid,)
-    else:
-      self.thread = thread
-
-  def eof(self):
-    ### should be calling file.eof() here instead of file.close(), there
-    ### may be data in the pipe or buffer after the process exits
-    if sys.platform == "win32":
-      r = win32event.WaitForMultipleObjects(self.wait_for, 1, 0)
-      if r == win32event.WAIT_OBJECT_0:
-        self.file.close()
-        self.file = None
-        return win32process.GetExitCodeProcess(self.child_pid)
-      return None
-
-    if self.thread and self.thread.isAlive():
-      return None
-
-    pid, status = os.waitpid(self.child_pid, os.WNOHANG)
-    if pid:
-      self.file.close()
-      self.file = None
-      return status
-    return None
-
-  def close(self):
-    if self.file:
-      self.file.close()
-      self.file = None
-      if sys.platform == "win32":
-        win32event.WaitForMultipleObjects(self.wait_for, 1, win32event.INFINITE)
-        return win32process.GetExitCodeProcess(self.child_pid)
-      else:
-        if self.thread:
-          self.thread.join()
-	if type(self.child_pid) == type([]):
-          for pid in self.child_pid:
-            exit = os.waitpid(pid, 0)[1]
-          return exit
-	else:
-            return os.waitpid(self.child_pid, 0)[1]
-    return None
-
-  def __getattr__(self, name):
-    return getattr(self.file, name)
-
-  def __del__(self):
-    self.close()
diff --git a/src/www/scm/viewvc/lib/py2html.py b/src/www/scm/viewvc/lib/py2html.py
deleted file mode 100755
index 3c8c991..0000000
--- a/src/www/scm/viewvc/lib/py2html.py
+++ /dev/null
@@ -1,541 +0,0 @@
-#!/usr/bin/python -u
-
-""" Python Highlighter                                    Version: 0.8
-
-    py2html.py [options] files...
-
-    options:
-     -h             print help
-     -              read from stdin, write to stdout
-     -stdout        read from files, write to stdout
-     -files         read from files, write to filename+'.html' (default)
-     -format:
-       html         output XHTML page (default)
-       rawhtml      output pure XHTML (without headers, titles, etc.)
-     -mode:
-       color        output in color (default)
-       mono         output b/w (for printing)
-     -title:Title   use 'Title' as title of the generated page
-     -bgcolor:color use color as background-color for page
-     -header:file   use contents of file as header
-     -footer:file   use contents of file as footer
-     -URL           replace all occurances of 'URL: link' with
-                    '<a href="link">link</a>'; this is always enabled
-                    in CGI mode
-     -v             verbose
-
-    Takes the input, assuming it is Python code and formats it into
-    colored XHTML. When called without parameters the script tries to
-    work in CGI mode. It looks for a field 'script=URL' and tries to
-    use that URL as input file. If it can't find this field, the path
-    info (the part of the URL following the CGI script name) is
-    tried. In case no host is given, the host where the CGI script
-    lives and HTTP are used.
- 
-    * Uses Just van Rossum's PyFontify version 0.3 to tag Python scripts.
-      You can get it via his homepage on starship:
-        URL: http://starship.python.net/crew/just
-"""
-__comments__ = """
-
-    The following snippet is a small shell script I use for viewing
-    Python scripts via less on Unix:
-
-pyless:
-#!/bin/sh
-# Browse pretty printed Python code using ANSI codes for highlighting
-py2html -stdout -format:ansi -mode:color $* | less -r
-
-    History:
-
-    0.8: Added patch by Patrick Lynch to have py2html.py use style
-         sheets for markup
-    0.7: Added patch by Ville Skyttä to make py2html.py output
-         valid XHTML.
-    0.6: Fixed a bug in .escape_html(); thanks to Vespe Savikko for
-         finding this one.
-    0.5: Added a few suggestions by Kevin Ng to make the CGI version
-         a little more robust.
-
-"""
-__copyright__ = """\
-    Copyright (c) 1998-2000, Marc-Andre Lemburg; mailto:mal at lemburg.com
-    Copyright (c) 2000-2002, eGenix.com Software GmbH; mailto:info at egenix.com
-    Distributed under the terms and conditions of the eGenix.com Public
-    License. See http://www.egenix.com/files/python/mxLicense.html for
-    details, or contact the author. All Rights Reserved.\
-"""
-
-__version__ = '0.8'
-
-__cgifooter__ = ('\n<pre># code highlighted using <a href='
-                 '"http://www.lemburg.com/files/python/">py2html.py</a> '
-                 'version %s</pre>\n' % __version__)
-
-import sys,string,re
-
-# Adjust path so that PyFontify is found...
-sys.path.append('.')
-
-### Constants
-
-# URL of the input form the user is redirected to in case no script=xxx
-# form field is given. The URL *must* be absolute. Leave blank to
-# have the script issue an error instead.
-INPUT_FORM = 'http://www.lemburg.com/files/python/SoftwareDescriptions.html#py2html.py'
-
-# HTML DOCTYPE and XML namespace
-HTML_DOCTYPE = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
-HTML_XMLNS = ' xmlns="http://www.w3.org/1999/xhtml"'
-
-### Helpers
-
-def fileio(file, mode='rb', data=None, close=0):
-
-    if type(file) == type(''):
-        f = open(file,mode)
-        close = 1
-    else:
-        f = file
-    if data:
-        f.write(data)
-    else:
-        data = f.read()
-    if close: f.close()
-    return data
-
-### Converter class
-
-class PrettyPrint:
-
-    """ generic Pretty Printer class
-
-        * supports tagging Python scripts in the following ways: 
-
-          # format/mode |  color  mono
-          # --------------------------
-          # rawhtml     |    x     x   (HTML without headers, etc.)
-          # html        |    x     x   (a HTML page with HEAD&BODY:)
-          # ansi        |    x     x   (with Ansi-escape sequences)
-
-        * interfaces:
-
-           file_filter -- takes two files: input & output (may be stdin/stdout)
-           filter -- takes a string and returns the highlighted version
-
-        * to create an instance use:
-
-          c = PrettyPrint(tagfct,format,mode)
-
-          where format and mode must be strings according to the
-          above table if you plan to use PyFontify.fontify as
-          tagfct
-
-        * the tagfct has to take one argument, text, and return a taglist
-          (format: [(id,left,right,sublist),...], where id is the
-          "name" given to the slice left:right in text and sublist is a
-          taglist for tags inside the slice or None)
-
-    """
-
-    # misc settings
-    title = ''
-    bgcolor = '#FFFFFF'
-    css = ''
-    header = ''
-    footer = ''
-    replace_URLs = 0
-    # formats to be used
-    formats = {}
-
-    def __init__(self,tagfct=None,format='html',mode='color'):
-
-        self.tag = tagfct
-        self.set_mode = getattr(self,'set_mode_%s_%s' % (format, mode))
-        self.filter = getattr(self,'filter_%s' % format)
-
-    def file_filter(self,infile,outfile):
-
-        self.set_mode()
-        text = fileio(infile,'r')
-        if type(infile) == type('') and self.title == '':
-            self.title = infile
-        fileio(outfile,'w',self.filter(text))
-
-    ### Set pre- and postfixes for formats & modes
-    #
-    # These methods must set self.formats to a dictionary having
-    # an entry for every tag returned by the tagging function.
-    #
-    # The format used is simple:
-    #  tag:(prefix,postfix)
-    # where prefix and postfix are either strings or callable objects,
-    # that return a string (they are called with the matching tag text
-    # as only parameter). prefix is inserted in front of the tag, postfix
-    # is inserted right after the tag.
-
-    def set_mode_html_color(self):
-
-        self.css = """
-        <STYLE TYPE="text/css">
-          <!--
-            body{ background: %s; }
-            .PY_KEYWORD{ color: #0000C0; font-weight: bold; }
-            .PY_COMMENT{ color: #000080; }
-            .PY_PARAMETER{ color: #C00000; }
-            .PY_IDENTIFIER{ color: #C00000; font-weight: bold; }
-            .PY_STRING{ color: #008000; }
-          -->
-        </STYLE> """ % self.bgcolor
-
-        self.formats = {
-            'all':('<pre>','</pre>'),
-            'comment':('<span class="PY_COMMENT">','</span>'),
-            'keyword':('<span class="PY_KEYWORD">','</span>'),
-            'parameter':('<span class="PY_PARAMETER">','</span>'),
-            'identifier':( lambda x,strip=string.strip:
-                           '<a name="%s"><span class="PY_IDENTIFIER">' % (strip(x)),
-                           '</span></a>'),
-            'string':('<span class="PY_STRING">','</span>')
-            }
-
-    set_mode_rawhtml_color = set_mode_html_color
-
-    def set_mode_html_mono(self):
-
-        self.css = """
-        <STYLE TYPE="text/css">
-          <!--
-            body{ background-color: %s }
-            .PY_KEYWORD{ text-decoration: underline }
-            .PY_COMMENT{ }
-            .PY_PARAMETER{ }
-            .PY_IDENTIFIER{ font-weight: bold}
-            .PY_STRING{ font-style: italic}
-          -->
-        </STYLE> """ % self.bgcolor
-
-        self.formats = {
-            'all':('<pre>','</pre>'),
-            'comment':('<span class="PY_COMMENT">','</span>'),
-            'keyword':( '<span class="PY_KEYWORD">','</span>'),
-            'parameter':('<span class="PY_PARAMETER">','</span>'),
-            'identifier':( lambda x,strip=string.strip:
-                           '<a name="%s"><span class="PY_IDENTIFIER">' % (strip(x)),
-                           '</span></a>'),
-            'string':('<span class="PY_STRING">','</span>')
-            }
-
-    set_mode_rawhtml_mono = set_mode_html_mono
-
-    def set_mode_ansi_mono(self):
-
-        self.formats = {
-            'all':('',''),
-            'comment':('\033[2m','\033[m'),
-            'keyword':('\033[4m','\033[m'),
-            'parameter':('',''),
-            'identifier':('\033[1m','\033[m'),
-            'string':('','')
-            }
-
-    def set_mode_ansi_color(self):
-
-        self.formats = {
-            'all':('',''),
-            'comment':('\033[34;2m','\033[m'),
-            'keyword':('\033[1;34m','\033[m'),
-            'parameter':('',''),
-            'identifier':('\033[1;31m','\033[m'),
-            'string':('\033[32;2m','\033[m')
-            }
-
-    ### Filters for Python scripts given as string
-
-    def escape_html(self,text):
-
-        t = (('&','&'),('<','<'),('>','>'))
-        for x,y in t:
-            text = string.join(string.split(text,x),y)
-        return text
-
-    def filter_html(self,text):
-
-        output = self.fontify(self.escape_html(text))
-        if self.replace_URLs:
-            output = re.sub('URL:([ \t]+)([^ \n\r<]+)',
-                            'URL:\\1<a href="\\2">\\2</a>',output)
-        html = """%s<html%s>
-                  <head>
-                  <title>%s</title>
-                  <!--css-->
-                  %s
-                  </head>
-                  <body>
-                  <!--header-->
-                  %s
-                  <!--script-->
-                  %s
-                  <!--footer-->
-                  %s
-                  </body></html>\n"""%(HTML_DOCTYPE,
-                                       HTML_XMLNS,
-                                       self.title,
-                                       self.css,
-                                       self.header,
-                                       output,
-                                       self.footer)
-        return html
-
-    def filter_rawhtml(self,text):
-
-        output = self.fontify(self.escape_html(text))
-        if self.replace_URLs:
-            output = re.sub('URL:([ \t]+)([^ \n\r<]+)',
-                            'URL:\\1<a href="\\2">\\2</a>',output)
-        return self.header + output + self.footer
-
-    def filter_ansi(self,text):
-
-        output = self.fontify(text)
-        return self.header + output + self.footer
-
-    ### Fontify engine
-
-    def fontify(self,pytext):
-
-        # parse
-        taglist = self.tag(pytext)
-
-        # prepend special 'all' tag:
-        taglist[:0] = [('all',0,len(pytext),None)]
-
-        # prepare splitting
-        splits = []
-        addsplits(splits,pytext,self.formats,taglist)
-
-        # do splitting & inserting
-        splits.sort()
-        l = []
-        li = 0
-        for ri,dummy,insert in splits:
-            if ri > li: l.append(pytext[li:ri])
-            l.append(insert)
-            li = ri
-        if li < len(pytext): l.append(pytext[li:])
-
-        return string.join(l,'')
-
-def addsplits(splits,text,formats,taglist):
-
-    """ Helper for .fontify()
-    """
-    for id,left,right,sublist in taglist:
-        try:
-            pre,post = formats[id]
-        except KeyError:
-            # sys.stderr.write('Warning: no format for %s specified\n'%repr(id))
-            pre,post = '',''
-        if type(pre) != type(''):
-            pre = pre(text[left:right])
-        if type(post) != type(''):
-            post = post(text[left:right])
-        # len(splits) is a dummy used to make sorting stable
-        splits.append((left,len(splits),pre))
-        if sublist:
-            addsplits(splits,text,formats,sublist)
-        splits.append((right,len(splits),post))
-
-def write_html_error(titel,text):
-
-    print """\
-%s<html%s><head><title>%s</title></head>
-<body>
-<h2>%s</h2>
-%s
-</body></html>
-""" % (HTML_DOCTYPE,HTML_XMLNS,titel,titel,text)
-
-def redirect_to(url):
-
-    sys.stdout.write('Content-Type: text/html\r\n')
-    sys.stdout.write('Status: 302\r\n')
-    sys.stdout.write('Location: %s\r\n\r\n' % url)
-    print """
-%s<html%s><head>
-<title>302 Moved Temporarily</title>
-</head><body>
-<h1>302 Moved Temporarily</h1>
-The document has moved to <a href="%s">%s</a>.<p></p>
-</body></html>
-""" % (HTML_DOCTYPE,HTML_XMLNS,url,url)
-
-def main(cmdline):
-
-    """ main(cmdline) -- process cmdline as if it were sys.argv 
-    """
-    # parse options/files
-    options = []
-    optvalues = {}
-    for o in cmdline[1:]:
-        if o[0] == '-':
-            if ':' in o:
-                k,v = tuple(string.split(o,':'))
-                optvalues[k] = v
-                options.append(k)
-            else:
-                options.append(o)
-        else:
-            break
-    files = cmdline[len(options)+1:]
-
-    ### create converting object
-
-    # load fontifier
-    if '-marcs' in options:
-        # use mxTextTool's tagging engine as fontifier
-        from mx.TextTools import tag
-        from mx.TextTools.Examples.Python import python_script
-        tagfct = lambda text,tag=tag,pytable=python_script: \
-                 tag(text,pytable)[1]
-        print "Py2HTML: using Marc's tagging engine"
-    else:
-        # load Just's fontifier
-        try:
-            import PyFontify
-            if PyFontify.__version__ < '0.3': raise ValueError
-            tagfct = PyFontify.fontify
-        except:
-            print """
-    Sorry, but this script needs the PyFontify.py module version 0.3;
-    You can download it from Just's homepage at
-
-       URL: http://starship.python.net/crew/just
-"""
-            sys.exit()
-
-
-    if '-format' in options:
-        format = optvalues['-format']
-    else:
-        # use default
-        format = 'html'
-
-    if '-mode' in options:
-        mode = optvalues['-mode']
-    else:
-        # use default
-        mode = 'color'
-
-    c = PrettyPrint(tagfct,format,mode)
-    convert = c.file_filter
-
-    ### start working
-
-    if '-title' in options:
-        c.title = optvalues['-title']
-
-    if '-bgcolor' in options:
-        c.bgcolor = optvalues['-bgcolor']
-
-    if '-header' in options:
-        try:
-            f = open(optvalues['-header'])
-            c.header = f.read()
-            f.close()
-        except IOError:
-            if verbose: print 'IOError: header file not found'
-
-    if '-footer' in options:
-        try:
-            f = open(optvalues['-footer'])
-            c.footer = f.read()
-            f.close()
-        except IOError:
-            if verbose: print 'IOError: footer file not found'
-
-    if '-URL' in options:
-        c.replace_URLs = 1
-
-    if '-' in options:
-        convert(sys.stdin,sys.stdout)
-        sys.exit()
-
-    if '-h' in options:
-        print __doc__
-        sys.exit()
-
-    if len(files) == 0:
-        # Turn URL processing on
-        c.replace_URLs = 1
-        # Try CGI processing...
-        import cgi,urllib,urlparse,os
-        form = cgi.FieldStorage()
-        if not form.has_key('script'):
-            # Ok, then try pathinfo
-            if not os.environ.has_key('PATH_INFO'):
-                if INPUT_FORM:
-                    redirect_to(INPUT_FORM)
-                else:
-                    sys.stdout.write('Content-Type: text/html\r\n\r\n')
-                    write_html_error('Missing Parameter',
-                                     'Missing script=URL field in request')
-                sys.exit(1)
-            url = os.environ['PATH_INFO'][1:] # skip the leading slash
-        else:
-            url = form['script'].value
-        sys.stdout.write('Content-Type: text/html\r\n\r\n')
-        scheme, host, path, params, query, frag = urlparse.urlparse(url)
-        if not host:
-            scheme = 'http'
-            if os.environ.has_key('HTTP_HOST'):
-                host = os.environ['HTTP_HOST']
-            else:
-                host = 'localhost'
-            url = urlparse.urlunparse((scheme, host, path, params, query, frag))
-        #print url; sys.exit()
-        network = urllib.URLopener()
-        try:
-            tempfile,headers = network.retrieve(url)
-        except IOError,reason:
-            write_html_error('Error opening "%s"' % url,
-                             'The given URL could not be opened. Reason: %s' %\
-                             str(reason))
-            sys.exit(1)
-        f = open(tempfile,'rb')
-        c.title = url
-        c.footer = __cgifooter__
-        convert(f,sys.stdout)
-        f.close()
-        network.close()
-        sys.exit()
-
-    if '-stdout' in options:
-        filebreak = '-'*72
-        for f in files:
-            try:
-                if len(files) > 1:
-                    print filebreak
-                    print 'File:',f
-                    print filebreak
-                convert(f,sys.stdout)
-            except IOError:
-                pass
-    else:
-        verbose = ('-v' in options)
-        if verbose:
-            print 'Py2HTML: working on',
-        for f in files:
-            try:
-                if verbose: print f,
-                convert(f,f+'.html')
-            except IOError:
-                if verbose: print '(IOError!)',
-        if verbose:
-            print
-            print 'Done.'
-
-if __name__=='__main__':
-    main(sys.argv)
-
-
diff --git a/src/www/scm/viewvc/lib/query.py b/src/www/scm/viewvc/lib/query.py
deleted file mode 100644
index 5fb38b4..0000000
--- a/src/www/scm/viewvc/lib/query.py
+++ /dev/null
@@ -1,428 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# CGI script to process and display queries to CVSdb
-#
-# This script is part of the ViewVC package. More information can be
-# found at http://viewvc.org
-#
-# -----------------------------------------------------------------------
-
-import os
-import sys
-import string
-import time
-
-import cvsdb
-import viewvc
-import ezt
-import debug
-import urllib
-
-class FormData:
-    def __init__(self, form):
-        self.valid = 0
-        
-        self.repository = ""
-        self.branch = ""
-        self.directory = ""
-        self.file = ""
-        self.who = ""
-        self.sortby = ""
-        self.date = ""
-        self.hours = 0
-
-        self.decode_thyself(form)
-        
-    def decode_thyself(self, form):
-        try:
-            self.repository = string.strip(form["repository"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        else:
-            self.valid = 1
-        
-        try:
-            self.branch = string.strip(form["branch"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        else:
-            self.valid = 1
-            
-        try:
-            self.directory = string.strip(form["directory"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        else:
-            self.valid = 1
-            
-        try:
-            self.file = string.strip(form["file"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        else:
-            self.valid = 1
-            
-        try:
-            self.who = string.strip(form["who"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        else:
-            self.valid = 1
-            
-        try:
-            self.sortby = string.strip(form["sortby"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        
-        try:
-            self.date = string.strip(form["date"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        
-        try:
-            self.hours = int(form["hours"].value)
-        except KeyError:
-            pass
-        except TypeError:
-            pass
-        except ValueError:
-            pass
-        else:
-            self.valid = 1
-        
-## returns a tuple-list (mod-str, string)
-def listparse_string(str):
-    return_list = []
-
-    cmd = ""
-    temp = ""
-    escaped = 0
-    state = "eat leading whitespace"
-
-    for c in str:
-        ## handle escaped charactors
-        if not escaped and c == "\\":
-            escaped = 1
-            continue
-
-        ## strip leading white space
-        if state == "eat leading whitespace":
-            if c in string.whitespace:
-                continue
-            else:
-                state = "get command or data"
-
-        ## parse to '"' or ","
-        if state == "get command or data":
-
-            ## just add escaped charactors
-            if escaped:
-                escaped = 0
-                temp = temp + c
-                continue
-
-            ## the data is in quotes after the command
-            elif c == "\"":
-                cmd = temp
-                temp = ""
-                state = "get quoted data"
-                continue
-
-            ## this tells us there was no quoted data, therefore no
-            ## command; add the command and start over
-            elif c == ",":
-                ## strip ending whitespace on un-quoted data
-                temp = string.rstrip(temp)
-                return_list.append( ("", temp) )
-                temp = ""
-                state = "eat leading whitespace"
-                continue
-
-            ## record the data
-            else:
-                temp = temp + c
-                continue
-                
-        ## parse until ending '"'
-        if state == "get quoted data":
-            
-            ## just add escaped charactors
-            if escaped:
-                escaped = 0
-                temp = temp + c
-                continue
-
-            ## look for ending '"'
-            elif c == "\"":
-                return_list.append( (cmd, temp) )
-                cmd = ""
-                temp = ""
-                state = "eat comma after quotes"
-                continue
-
-            ## record the data
-            else:
-                temp = temp + c
-                continue
-
-        ## parse until ","
-        if state == "eat comma after quotes":
-            if c in string.whitespace:
-                continue
-
-            elif c == ",":
-                state = "eat leading whitespace"
-                continue
-
-            else:
-                print "format error"
-                sys.exit(1)
-
-    if cmd or temp:
-        return_list.append((cmd, temp))
-
-    return return_list
-
-def decode_command(cmd):
-    if cmd == "r":
-        return "regex"
-    elif cmd == "l":
-        return "like"
-    else:
-        return "exact"
-
-def form_to_cvsdb_query(form_data):
-    query = cvsdb.CreateCheckinQuery()
-
-    if form_data.repository:
-        for cmd, str in listparse_string(form_data.repository):
-            cmd = decode_command(cmd)
-            query.SetRepository(str, cmd)
-        
-    if form_data.branch:
-        for cmd, str in listparse_string(form_data.branch):
-            cmd = decode_command(cmd)
-            query.SetBranch(str, cmd)
-        
-    if form_data.directory:
-        for cmd, str in listparse_string(form_data.directory):
-            cmd = decode_command(cmd)
-            query.SetDirectory(str, cmd)
-
-    if form_data.file:
-        for cmd, str in listparse_string(form_data.file):
-            cmd = decode_command(cmd)
-            query.SetFile(str, cmd)
-
-    if form_data.who:
-        for cmd, str in listparse_string(form_data.who):
-            cmd = decode_command(cmd)
-            query.SetAuthor(str, cmd)
-
-    if form_data.sortby == "author":
-        query.SetSortMethod("author")
-    elif form_data.sortby == "file":
-        query.SetSortMethod("file")
-    else:
-        query.SetSortMethod("date")
-
-    if form_data.date:
-        if form_data.date == "hours" and form_data.hours:
-            query.SetFromDateHoursAgo(form_data.hours)
-        elif form_data.date == "day":
-            query.SetFromDateDaysAgo(1)
-        elif form_data.date == "week":
-            query.SetFromDateDaysAgo(7)
-        elif form_data.date == "month":
-            query.SetFromDateDaysAgo(31)
-            
-    return query
-
-def prev_rev(rev):
-    '''Returns a string representing the previous revision of the argument.'''
-    r = string.split(rev, '.')
-    # decrement final revision component
-    r[-1] = str(int(r[-1]) - 1)
-    # prune if we pass the beginning of the branch
-    if len(r) > 2 and r[-1] == '0':
-        r = r[:-2]
-    return string.join(r, '.')
-
-def build_commit(server, cfg, desc, files, cvsroots, viewvc_link):
-    ob = _item(num_files=len(files), files=[])
-    
-    if desc:
-        ob.log = string.replace(server.escape(desc), '\n', '<br />')
-    else:
-        ob.log = ' '
-
-    for commit in files:
-        dir_parts = filter(None, string.split(commit.GetDirectory(), '/'))
-        if dir_parts \
-               and ((dir_parts[0] == 'CVSROOT' and cfg.options.hide_cvsroot) \
-                    or cfg.is_forbidden(dir_parts[0])):
-            continue
-
-        ctime = commit.GetTime()
-        if not ctime:
-            ctime = " "
-        else:
-          if (cfg.options.use_localtime):
-            ctime = time.strftime("%y/%m/%d %H:%M %Z", time.localtime(ctime))
-          else:
-            ctime = time.strftime("%y/%m/%d %H:%M", time.gmtime(ctime)) \
-                  + ' UTC'
-        
-        ## make the file link
-        repository = commit.GetRepository()
-        directory = commit.GetDirectory()
-        file = (directory and directory + "/") + commit.GetFile()
-        cvsroot_name = cvsroots.get(repository)
-
-        ## if we couldn't find the cvsroot path configured in the 
-        ## viewvc.conf file, then don't make the link
-        if cvsroot_name:
-            flink = '[%s] <a href="%s/%s?root=%s">%s</a>' % (
-                    cvsroot_name, viewvc_link, urllib.quote(file),
-                    cvsroot_name, file)
-            if commit.GetType() == commit.CHANGE:
-                dlink = '%s/%s?root=%s&view=diff&r1=%s&r2=%s' % (
-                    viewvc_link, urllib.quote(file), cvsroot_name,
-                    prev_rev(commit.GetRevision()), commit.GetRevision())
-            else:
-                dlink = None
-        else:
-            flink = '[%s] %s' % (repository, file)
-            dlink = None
-
-        ob.files.append(_item(date=ctime,
-                              author=commit.GetAuthor(),
-                              link=flink,
-                              rev=commit.GetRevision(),
-                              branch=commit.GetBranch(),
-                              plus=int(commit.GetPlusCount()),
-                              minus=int(commit.GetMinusCount()),
-                              type=commit.GetTypeString(),
-                              difflink=dlink,
-                              ))
-
-    return ob
-
-def run_query(server, cfg, form_data, viewvc_link):
-    query = form_to_cvsdb_query(form_data)
-    db = cvsdb.ConnectDatabaseReadOnly(cfg)
-    db.RunQuery(query)
-
-    if not query.commit_list:
-        return [ ]
-
-    commits = [ ]
-    files = [ ]
-
-    cvsroots = {}
-    rootitems = cfg.general.cvs_roots.items() + cfg.general.svn_roots.items()
-    for key, value in rootitems:
-        cvsroots[cvsdb.CleanRepository(value)] = key
-
-    current_desc = query.commit_list[0].GetDescription()
-    for commit in query.commit_list:
-        desc = commit.GetDescription()
-        if current_desc == desc:
-            files.append(commit)
-            continue
-
-        commits.append(build_commit(server, cfg, current_desc, files,
-                                    cvsroots, viewvc_link))
-
-        files = [ commit ]
-        current_desc = desc
-
-    ## add the last file group to the commit list
-    commits.append(build_commit(server, cfg, current_desc, files,
-                                cvsroots, viewvc_link))
-
-    return commits
-
-def main(server, cfg, viewvc_link):
-  try:
-
-    form = server.FieldStorage()
-    form_data = FormData(form)
-
-    if form_data.valid:
-        commits = run_query(server, cfg, form_data, viewvc_link)
-        query = None
-    else:
-        commits = [ ]
-        query = 'skipped'
-
-    script_name = server.getenv('SCRIPT_NAME', '')
-
-    data = {
-      'cfg' : cfg,
-      'address' : cfg.general.address,
-      'vsn' : viewvc.__version__,
-
-      'repository' : server.escape(form_data.repository, 1),
-      'branch' : server.escape(form_data.branch, 1),
-      'directory' : server.escape(form_data.directory, 1),
-      'file' : server.escape(form_data.file, 1),
-      'who' : server.escape(form_data.who, 1),
-      'docroot' : cfg.options.docroot is None \
-                  and viewvc_link + '/' + viewvc.docroot_magic_path \
-                  or cfg.options.docroot,
-
-      'sortby' : form_data.sortby,
-      'date' : form_data.date,
-
-      'query' : query,
-      'commits' : commits,
-      'num_commits' : len(commits),
-      }
-
-    if form_data.hours:
-      data['hours'] = form_data.hours
-    else:
-      data['hours'] = 2
-
-    server.header()
-
-    # generate the page
-    template = viewvc.get_view_template(cfg, "query")
-    template.generate(sys.stdout, data)
-
-  except SystemExit, e:
-    pass
-  except:
-    exc_info = debug.GetExceptionData()
-    server.header(status=exc_info['status'])
-    debug.PrintException(server, exc_info) 
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
diff --git a/src/www/scm/viewvc/lib/sapi.py b/src/www/scm/viewvc/lib/sapi.py
deleted file mode 100644
index 10f0338..0000000
--- a/src/www/scm/viewvc/lib/sapi.py
+++ /dev/null
@@ -1,388 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# generic server api - currently supports normal cgi, mod_python, and
-# active server pages
-#
-# -----------------------------------------------------------------------
-
-import types
-import string
-import os
-import sys
-import re
-
-
-# global server object. It will be either a CgiServer or a proxy to
-# an AspServer or ModPythonServer object.
-server = None
-
-
-class Server:
-  def __init__(self):
-    self.pageGlobals = {}
-
-  def self(self):
-    return self
-
-  def close(self):
-    pass
-
-
-class ThreadedServer(Server):
-  def __init__(self):
-    Server.__init__(self)
-
-    self.inheritableOut = 0
-
-    global server
-    if not isinstance(server, ThreadedServerProxy):
-      server = ThreadedServerProxy()
-    if not isinstance(sys.stdout, File):
-      sys.stdout = File(server)
-    server.registerThread(self)
-
-  def file(self):
-    return File(self)
-
-  def close(self):
-    server.unregisterThread()
-
-
-class ThreadedServerProxy:
-  """In a multithreaded server environment, ThreadedServerProxy stores the
-  different server objects being used to display pages and transparently
-  forwards access to them based on the current thread id."""
-
-  def __init__(self):
-    self.__dict__['servers'] = { }
-    global thread
-    import thread
-
-  def registerThread(self, server):
-    self.__dict__['servers'][thread.get_ident()] = server
-
-  def unregisterThread(self):
-    del self.__dict__['servers'][thread.get_ident()]
-
-  def self(self):
-    """This function bypasses the getattr and setattr trickery and returns
-    the actual server object."""
-    return self.__dict__['servers'][thread.get_ident()]
-
-  def __getattr__(self, key):
-    return getattr(self.self(), key)
-
-  def __setattr__(self, key, value):
-    setattr(self.self(), key, value)
-
-  def __delattr__(self, key):
-    delattr(self.self(), key)
-
-
-class File:
-  def __init__(self, server):
-    self.closed = 0
-    self.mode = 'w'
-    self.name = "<AspFile file>"
-    self.softspace = 0
-    self.server = server
-
-  def write(self, s):
-    self.server.write(s)
-
-  def writelines(self, list):
-    for s in list:
-      self.server.write(s)
-
-  def flush(self):
-    self.server.flush()
-
-  def truncate(self, size):
-    pass
-
-  def close(self):
-    pass
-
-
-class CgiServer(Server):
-  def __init__(self, inheritableOut = 1):
-    Server.__init__(self)
-    self.headerSent = 0
-    self.headers = []
-    self.inheritableOut = inheritableOut
-    self.iis = os.environ.get('SERVER_SOFTWARE', '')[:13] == 'Microsoft-IIS'
-
-    if sys.platform == "win32" and inheritableOut:
-      import msvcrt
-      msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-    global server
-    server = self
-
-    global cgi
-    import cgi
-
-  def addheader(self, name, value):
-    self.headers.append((name, value))
-
-  def header(self, content_type='text/html', status=None):
-    if not self.headerSent:
-      self.headerSent = 1
-
-      extraheaders = ''
-      for (name, value) in self.headers:
-        extraheaders = extraheaders + '%s: %s\r\n' % (name, value)
-
-      # The only way ViewVC pages and error messages are visible under 
-      # IIS is if a 200 error code is returned. Otherwise IIS instead
-      # sends the static error page corresponding to the code number.
-      if status is None or (status[:3] != '304' and self.iis):
-        status = ''
-      else:
-        status = 'Status: %s\r\n' % status
-
-      sys.stdout.write('%sContent-Type: %s\r\n%s\r\n'
-                       % (status, content_type, extraheaders))
-
-  def redirect(self, url):
-    if self.iis: url = fix_iis_url(self, url)
-    self.addheader('Location', url)
-    self.header(status='301 Moved')
-    print 'This document is located <a href="%s">here</a>.' % url
-    sys.exit(0)
-
-  def escape(self, s, quote = None):
-    return cgi.escape(s, quote)
-
-  def getenv(self, name, value=None):
-    ret = os.environ.get(name, value)
-    if self.iis and name == 'PATH_INFO' and ret:
-      ret = fix_iis_path_info(self, ret)
-    return ret
-
-  def params(self):
-    return cgi.parse()
-
-  def FieldStorage(fp=None, headers=None, outerboundary="",
-                 environ=os.environ, keep_blank_values=0, strict_parsing=0):
-    return cgi.FieldStorage(fp, headers, outerboundary, environ,
-      keep_blank_values, strict_parsing)
-
-  def write(self, s):
-    sys.stdout.write(s)
-
-  def flush(self):
-    sys.stdout.flush()
-
-  def file(self):
-    return sys.stdout
-
-
-class AspServer(ThreadedServer):
-  def __init__(self, Server, Request, Response, Application):
-    ThreadedServer.__init__(self)
-    self.headerSent = 0
-    self.server = Server
-    self.request = Request
-    self.response = Response
-    self.application = Application
-
-  def addheader(self, name, value):
-    self.response.AddHeader(name, value)
-
-  def header(self, content_type=None, status=None):
-    # Normally, setting self.response.ContentType after headers have already
-    # been sent simply results in an AttributeError exception, but sometimes
-    # it leads to a fatal ASP error. For this reason I'm keeping the
-    # self.headerSent member and only checking for the exception as a
-    # secondary measure
-    if not self.headerSent:
-      try:
-        self.headerSent = 1
-        if content_type is not None: self.response.ContentType = content_type
-        if status is not None: self.response.Status = status
-      except AttributeError:
-        pass
-
-  def redirect(self, url):
-    self.response.Redirect(url)
-    sys.exit()
-
-  def escape(self, s, quote = None):
-    return self.server.HTMLEncode(str(s))
-
-  def getenv(self, name, value = None):
-    ret = self.request.ServerVariables(name)()
-    if not type(ret) is types.UnicodeType:
-      return value
-    ret = str(ret)
-    if name == 'PATH_INFO':
-      ret = fix_iis_path_info(self, ret)
-    return ret
-
-  def params(self):
-    p = {}
-    for i in self.request.Form:
-      p[str(i)] = map(str, self.request.Form[i])
-    for i in self.request.QueryString:
-      p[str(i)] = map(str, self.request.QueryString[i])
-    return p
-
-  def FieldStorage(self, fp=None, headers=None, outerboundary="",
-                 environ=os.environ, keep_blank_values=0, strict_parsing=0):
-
-    # Code based on a very helpful usenet post by "Max M" (maxm at mxm.dk)
-    # Subject "Re: Help! IIS and Python"
-    # http://groups.google.com/groups?selm=3C7C0AB6.2090307%40mxm.dk
-
-    from StringIO import StringIO
-    from cgi import FieldStorage
-
-    environ = {}
-    for i in self.request.ServerVariables:
-      environ[str(i)] = str(self.request.ServerVariables(i)())
-
-    # this would be bad for uploaded files, could use a lot of memory
-    binaryContent, size = self.request.BinaryRead(int(environ['CONTENT_LENGTH']))
-
-    fp = StringIO(str(binaryContent))
-    fs = FieldStorage(fp, None, "", environ, keep_blank_values, strict_parsing)
-    fp.close()
-    return fs
-
-  def write(self, s):
-    t = type(s)
-    if t is types.StringType:
-      s = buffer(s)
-    elif not t is types.BufferType:
-      s = buffer(str(s))
-
-    self.response.BinaryWrite(s)
-
-  def flush(self):
-    self.response.Flush()
-
-
-_re_status = re.compile("\\d+")
-
-
-class ModPythonServer(ThreadedServer):
-  def __init__(self, request):
-    ThreadedServer.__init__(self)
-    self.request = request
-    self.headerSent = 0
-    
-    global cgi
-    import cgi
-
-  def addheader(self, name, value):
-    self.request.headers_out.add(name, value)
-
-  def header(self, content_type=None, status=None):
-    if content_type is None: 
-      self.request.content_type = 'text/html'
-    else:
-      self.request.content_type = content_type
-    self.headerSent = 1
-
-    if status is not None:
-      m = _re_status.match(status)
-      if not m is None:
-        self.request.status = int(m.group())
-
-  def redirect(self, url):
-    import mod_python.apache
-    self.request.headers_out['Location'] = url
-    self.request.status = mod_python.apache.HTTP_MOVED_TEMPORARILY
-    self.request.write("You are being redirected to <a href=\"%s\">%s</a>"
-      % (url, url))
-    sys.exit()
-
-  def escape(self, s, quote = None):
-    return cgi.escape(s, quote)
-
-  def getenv(self, name, value = None):
-    try:
-      return self.request.subprocess_env[name]
-    except KeyError:
-      return value
-
-  def params(self):
-    import mod_python.util
-    if self.request.args is None:
-      return {}
-    else:
-      return mod_python.util.parse_qs(self.request.args)
-
-  def FieldStorage(self, fp=None, headers=None, outerboundary="",
-                 environ=os.environ, keep_blank_values=0, strict_parsing=0):
-    import mod_python.util
-    return mod_python.util.FieldStorage(self.request, keep_blank_values, strict_parsing)
-
-  def write(self, s):
-    self.request.write(s)
-
-  def flush(self):
-    pass
-
-
-def fix_iis_url(server, url):
-  """When a CGI application under IIS outputs a "Location" header with a url
-  beginning with a forward slash, IIS tries to optimise the redirect by not
-  returning any output from the original CGI script at all and instead just
-  returning the new page in its place. Because of this, the browser does
-  not know it is getting a different page than it requested. As a result,
-  The address bar that appears in the browser window shows the wrong location
-  and if the new page is in a different folder than the old one, any relative
-  links on it will be broken.
-
-  This function can be used to circumvent the IIS "optimization" of local
-  redirects. If it is passed a location that begins with a forward slash it
-  will return a URL constructed with the information in CGI environment.
-  If it is passed a URL or any location that doens't begin with a forward slash
-  it will return just argument unaltered.
-  """
-  if url[0] == '/':
-    if server.getenv('HTTPS') == 'on':
-      dport = "443"
-      prefix = "https://"
-    else:
-      dport = "80"
-      prefix = "http://"
-    prefix = prefix + server.getenv('HTTP_HOST')
-    if server.getenv('SERVER_PORT') != dport:
-      prefix = prefix + ":" + server.getenv('SERVER_PORT')
-    return prefix + url
-  return url
-
-
-def fix_iis_path_info(server, path_info):
-  """Fix the PATH_INFO value in IIS"""
-  # If the viewvc cgi's are in the /viewvc/ folder on the web server and a
-  # request looks like
-  #
-  #      /viewvc/viewvc.cgi/myproject/?someoption
-  #
-  # The CGI environment variables on IIS will look like this:
-  #
-  #      SCRIPT_NAME  =  /viewvc/viewvc.cgi
-  #      PATH_INFO    =  /viewvc/viewvc.cgi/myproject/
-  #
-  # Whereas on Apache they look like:
-  #
-  #      SCRIPT_NAME  =  /viewvc/viewvc.cgi
-  #      PATH_INFO    =  /myproject/
-  #
-  # This function converts the IIS PATH_INFO into the nonredundant form
-  # expected by ViewVC
-  return path_info[len(server.getenv('SCRIPT_NAME', '')):]
diff --git a/src/www/scm/viewvc/lib/vclib/__init__.py b/src/www/scm/viewvc/lib/vclib/__init__.py
deleted file mode 100644
index ee4923e..0000000
--- a/src/www/scm/viewvc/lib/vclib/__init__.py
+++ /dev/null
@@ -1,264 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""Version Control lib is an abstract API to access versioning systems
-such as CVS.
-"""
-
-import string
-import types
-
-
-# item types returned by Repository.itemtype().
-FILE = 'FILE'
-DIR = 'DIR'
-
-# diff types recognized by Repository.rawdiff().
-UNIFIED = 1
-CONTEXT = 2
-SIDE_BY_SIDE = 3
-
-# ======================================================================
-#
-class Repository:
-  """Abstract class representing a repository."""
-
-  def itemtype(self, path_parts, rev):
-    """Return the type of the item (file or dir) at the given path and revision
-
-    The result will be vclib.DIR or vclib.FILE
-
-    The path is specified as a list of components, relative to the root
-    of the repository. e.g. ["subdir1", "subdir2", "filename"]
-
-    rev is the revision of the item to check
-    """
-    pass
-
-  def openfile(self, path_parts, rev):
-    """Open a file object to read file contents at a given path and revision.
-
-    The return value is a 2-tuple of containg the file object and revision
-    number in canonical form.
-
-    The path is specified as a list of components, relative to the root
-    of the repository. e.g. ["subdir1", "subdir2", "filename"]
-
-    rev is the revision of the file to check out
-    """
-
-  def listdir(self, path_parts, rev, options):
-    """Return list of files in a directory
-
-    The result is a list of DirEntry objects
-
-    The path is specified as a list of components, relative to the root
-    of the repository. e.g. ["subdir1", "subdir2", "filename"]
-
-    rev is the revision of the directory to list
-
-    options is a dictionary of implementation specific options
-    """
-
-  def dirlogs(self, path_parts, rev, entries, options):
-    """Augment directory entries with log information
-
-    New properties will be set on all of the DirEntry objects in the entries
-    list. At the very least, a "rev" property will be set to a revision
-    number or None if the entry doesn't have a number. Other properties that
-    may be set include "date", "author", and "log".
-
-    The path is specified as a list of components, relative to the root
-    of the repository. e.g. ["subdir1", "subdir2", "filename"]
-
-    rev is the revision of the directory listing and will effect which log
-    messages are returned
-
-    entries is a list of DirEntry objects returned from a previous call to
-    the listdir() method
-
-    options is a dictionary of implementation specific options
-    """
-  
-  def itemlog(self, path_parts, rev, options):
-    """Retrieve an item's log information
-
-    The result is a list of Revision objects
-
-    The path is specified as a list of components, relative to the root
-    of the repository. e.g. ["subdir1", "subdir2", "filename"]
-
-    rev is the revision of the item to return information about
-
-    options is a dictionary of implementation specific options
-    """
-
-  def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
-    """Return a diff (in GNU diff format) of two file revisions
-
-    type is the requested diff type (UNIFIED, CONTEXT, etc)
-
-    options is a dictionary that can contain the following options plus
-    implementation-specific options
-
-      context - integer, number of context lines to include
-      funout - boolean, include C function names
-      ignore_white - boolean, ignore whitespace
-
-    Return value is a python file object
-    """
-
-  def annotate(self, path_parts, rev):
-    """Return a list of annotate file content lines and a revision.
-
-    The annotated lines are an collection of objects with the
-    following addressable members:
-
-       text        - raw text of a line of file contents
-       line_number - line number on which the line is found
-       rev         - revision in which the line was last modified
-       prev_rev    - revision prior to 'rev'
-       author      - author who last modified the line
-       date        - date on which the line was last modified, in seconds
-                     since the epoch, GMT
-
-    These object are sort by their line_number components.
-    """
-    
-
-# ======================================================================
-class DirEntry:
-  "Instances represent items in a directory listing"
-
-  def __init__(self, name, kind, errors=[]):
-    self.name = name
-    self.kind = kind
-    self.errors = errors
-
-class Revision:
-  """Instances holds information about revisions of versioned resources"""
-
-  """Create a new Revision() item:
-        NUMBER:  Revision in an integer-based, sortable format
-        STRING:  Revision as a string
-        DATE:  Seconds since Epoch (GMT) that this revision was created
-        AUTHOR:  Author of the revision
-        CHANGED:  Lines-changed (contextual diff) information
-        LOG:  Log message associated with the creation of this revision
-        SIZE:  Size (in bytes) of this revision's fulltext (files only)
-  """
-  def __init__(self, number, string, date, author, changed, log, size):
-    self.number = number
-    self.string = string
-    self.date = date
-    self.author = author
-    self.changed = changed
-    self.log = log
-    self.size = size
-
-  def __cmp__(self, other):
-    return cmp(self.number, other.number)
-
-# ======================================================================
-
-class Error(Exception):
-  pass
-class ReposNotFound(Error):
-  pass
-class ItemNotFound(Error):
-  def __init__(self, path):
-    # use '/' rather than os.sep because this is for user consumption, and
-    # it was defined using URL separators
-    if type(path) in (types.TupleType, types.ListType):
-      path = string.join(path, '/')
-    Error.__init__(self, path)
-class InvalidRevision(Error):
-  def __init__(self, revision=None):
-    if revision is None:
-      Error.__init__(self, "Invalid revision")
-    else:
-      Error.__init__(self, "Invalid revision " + str(revision))
-
-# ======================================================================
-# Implementation code used by multiple vclib modules
-
-import popen
-import os
-import time
-
-def _diff_args(type, options):
-  """generate argument list to pass to diff or rcsdiff"""
-  args = []
-  if type == CONTEXT:
-    if options.has_key('context'):
-      args.append('--context=%i' % options['context'])
-    else:
-      args.append('-c')
-  elif type == UNIFIED:
-    if options.has_key('context'):
-      args.append('--unified=%i' % options['context'])
-    else:
-      args.append('-u')
-  elif type == SIDE_BY_SIDE:
-    args.append('--side-by-side')
-    args.append('--width=164')
-  else:
-    raise NotImplementedError
-
-  if options.get('funout', 0):
-    args.append('-p')
-
-  if options.get('ignore_white', 0):
-    args.append('-w')
-
-  return args
-
-class _diff_fp:
-  """File object reading a diff between temporary files, cleaning up
-  on close"""
-
-  def __init__(self, temp1, temp2, info1=None, info2=None, diff_opts=[]):
-    self.temp1 = temp1
-    self.temp2 = temp2
-    args = diff_opts[:]
-    if info1 and info2:
-      args.extend(["-L", self._label(info1), "-L", self._label(info2)])
-    args.extend([temp1, temp2])
-    self.fp = popen.popen("diff", args, "r")
-
-  def read(self, bytes):
-    return self.fp.read(bytes)
-
-  def readline(self):
-    return self.fp.readline()
-
-  def close(self):
-    try:
-      if self.fp:
-        self.fp.close()
-        self.fp = None
-    finally:
-      try:
-        if self.temp1:
-          os.remove(self.temp1)
-          self.temp1 = None
-      finally:
-        if self.temp2:
-          os.remove(self.temp2)
-          self.temp2 = None
-
-  def __del__(self):
-    self.close()
-
-  def _label(self, (path, date, rev)):
-    date = date and time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(date))
-    return "%s\t%s\t%s" % (path, date, rev)
diff --git a/src/www/scm/viewvc/lib/vclib/bincvs/__init__.py b/src/www/scm/viewvc/lib/vclib/bincvs/__init__.py
deleted file mode 100644
index 42861d4..0000000
--- a/src/www/scm/viewvc/lib/vclib/bincvs/__init__.py
+++ /dev/null
@@ -1,1107 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"Version Control lib driver for locally accessible cvs-repositories."
-
-import vclib
-import os
-import os.path
-import sys
-import stat
-import string
-import re
-import time
-
-# ViewVC libs
-import compat
-import popen
-
-class CVSRepository(vclib.Repository):
-  def __init__(self, name, rootpath):
-    if not os.path.isdir(rootpath):
-      raise vclib.ReposNotFound(name)
-
-    self.name = name
-    self.rootpath = rootpath
-
-  def itemtype(self, path_parts, rev):
-    basepath = self._getpath(path_parts)
-    if os.path.isdir(basepath):
-      return vclib.DIR
-    if os.path.isfile(basepath + ',v'):
-      return vclib.FILE
-    atticpath = self._getpath(self._atticpath(path_parts))
-    if os.path.isfile(atticpath + ',v'):
-      return vclib.FILE
-    raise vclib.ItemNotFound(path_parts)
-
-  def listdir(self, path_parts, rev, options):
-    # Only RCS files (*,v) and subdirs are returned.
-    data = [ ]
-
-    full_name = self._getpath(path_parts)
-    for file in os.listdir(full_name):
-      kind, errors = _check_path(os.path.join(full_name, file))
-      if kind == vclib.FILE:
-        if file[-2:] == ',v':
-          data.append(CVSDirEntry(file[:-2], kind, errors, 0))
-      elif kind == vclib.DIR:
-        if file != 'Attic' and file != 'CVS': # CVS directory is for fileattr
-          data.append(CVSDirEntry(file, kind, errors, 0))
-      else:
-        data.append(CVSDirEntry(file, kind, errors, 0))
-
-    full_name = os.path.join(full_name, 'Attic')
-    if os.path.isdir(full_name):
-      for file in os.listdir(full_name):
-        kind, errors = _check_path(os.path.join(full_name, file))
-        if kind == vclib.FILE:
-          if file[-2:] == ',v':
-            data.append(CVSDirEntry(file[:-2], kind, errors, 1))
-        elif kind != vclib.DIR:
-          data.append(CVSDirEntry(file, kind, errors, 1))
-
-    return data
-    
-  def _getpath(self, path_parts):
-    return apply(os.path.join, (self.rootpath,) + tuple(path_parts))
-
-  def _atticpath(self, path_parts):
-    return path_parts[:-1] + ['Attic'] + path_parts[-1:]
-
-  def rcsfile(self, path_parts, root=0, v=1):
-    "Return path to RCS file"
-
-    ret_parts = path_parts
-    ret_file = self._getpath(ret_parts)
-    if not os.path.isfile(ret_file + ',v'):
-      ret_parts = self._atticpath(path_parts)
-      ret_file = self._getpath(ret_parts)
-      if not os.path.isfile(ret_file + ',v'):
-        raise vclib.ItemNotFound(path_parts)
-
-    if root:
-      ret = ret_file
-    else:
-      ret = string.join(ret_parts, "/")
-
-    if v:
-      ret = ret + ",v"
-
-    return ret
-
-class BinCVSRepository(CVSRepository):
-  def __init__(self, name, rootpath, rcs_paths):
-    CVSRepository.__init__(self, name, rootpath)
-    self.rcs_paths = rcs_paths
-
-  def _get_tip_revision(self, rcs_file, rev=None):
-    """Get the (basically) youngest revision (filtered by REV)."""
-    args = rcs_file,
-    fp = self.rcs_popen('rlog', args, 'rt', 0)
-    filename, default_branch, tags, msg, eof = _parse_log_header(fp)
-    revs = []
-    while not eof:
-      revision, eof = _parse_log_entry(fp)
-      if revision:
-        revs.append(revision)
-    revs = _file_log(revs, tags, default_branch, rev)
-    if revs:
-      return revs[-1]
-    return None
-
-  def openfile(self, path_parts, rev):
-    if not rev or rev == 'HEAD' or rev == 'MAIN':
-      rev_flag = '-p'
-    else:
-      rev_flag = '-p' + rev
-    full_name = self.rcsfile(path_parts, root=1, v=0)
-
-    used_rlog = 0
-    tip_rev = None  # used only if we have to fallback to using rlog
-
-    fp = self.rcs_popen('co', (rev_flag, full_name), 'rb') 
-    try:
-      filename, revision = _parse_co_header(fp)
-    except COMissingRevision:
-      # We got a "revision X.Y.Z absent" error from co.  This could be
-      # because we were asked to find a tip of a branch, which co
-      # doesn't seem to handle.  So we do rlog-gy stuff to figure out
-      # which revision the tip of the branch currently maps to.
-      ### TODO: Only do this when 'rev' is a branch symbol name?
-      if not used_rlog:
-        tip_rev = self._get_tip_revision(full_name + ',v', rev)
-        used_rlog = 1
-      if not tip_rev:
-        raise vclib.Error("Unable to find valid revision")
-      fp = self.rcs_popen('co', ('-p' + tip_rev.string, full_name), 'rb') 
-      filename, revision = _parse_co_header(fp)
-      
-    if filename is None:
-      # CVSNT's co exits without any output if a dead revision is requested.
-      # Bug at http://www.cvsnt.org/cgi-bin/bugzilla/show_bug.cgi?id=190
-      # As a workaround, we invoke rlog to find the first non-dead revision
-      # that precedes it and check out that revision instead.  Of course, 
-      # if we've already invoked rlog above, we just reuse its output.
-      if not used_rlog:
-        tip_rev = self._get_tip_revision(full_name + ',v', rev)
-        used_rlog = 1
-      if not (tip_rev and tip_rev.undead):
-        raise vclib.Error(
-          'Could not find non-dead revision preceding "%s"' % rev)
-      fp = self.rcs_popen('co', ('-p' + tip_rev.undead.string,
-                                 full_name), 'rb') 
-      filename, revision = _parse_co_header(fp)
-
-    if filename is None:
-      raise vclib.Error('Missing output from co (filename = "%s")' % full_name)
-
-    if not _paths_eq(filename, full_name):
-      raise vclib.Error(
-        'The filename from co ("%s") did not match (expected "%s")'
-        % (filename, full_name))
-
-    return fp, revision
-
-  def dirlogs(self, path_parts, rev, entries, options):
-    """see vclib.Repository.dirlogs docstring
-
-    rev can be a tag name or None. if set only information from revisions
-    matching the tag will be retrieved
-
-    Option values recognized by this implementation:
-
-      cvs_subdirs
-        boolean. true to fetch logs of the most recently modified file in each
-        subdirectory
-
-    Option values returned by this implementation:
-
-      cvs_tags, cvs_branches
-        lists of tag and branch names encountered in the directory
-    """
-    subdirs = options.get('cvs_subdirs', 0)
-
-    dirpath = self._getpath(path_parts)
-    alltags = _get_logs(self, dirpath, entries, rev, subdirs)
-
-    branches = options['cvs_branches'] = []
-    tags = options['cvs_tags'] = []
-    for name, rev in alltags.items():
-      if Tag(None, rev).is_branch:
-        branches.append(name)
-      else:
-        tags.append(name)
-
-  def itemlog(self, path_parts, rev, options):
-    """see vclib.Repository.itemlog docstring
-
-    rev parameter can be a revision number, a branch number, a tag name,
-    or None. If None, will return information about all revisions, otherwise,
-    will only return information about the specified revision or branch.
-
-    Option values recognized by this implementation:
-
-      cvs_pass_rev
-        boolean, default false. set to true to pass rev parameter as -r
-        argument to rlog, this is more efficient but causes less
-        information to be returned
-
-    Option values returned by this implementation:
-
-      cvs_tags
-        dictionary of Tag objects for all tags encountered
-    """
-
-    # Invoke rlog
-    rcsfile = self.rcsfile(path_parts, 1)
-    if rev and options.get('cvs_pass_rev', 0):
-      args = '-r' + rev, rcsfile
-    else:
-      args = rcsfile,
-
-    fp = self.rcs_popen('rlog', args, 'rt', 0)
-    filename, default_branch, tags, msg, eof = _parse_log_header(fp)
-
-    # Retrieve revision objects
-    revs = []
-    while not eof:
-      revision, eof = _parse_log_entry(fp)
-      if revision:
-        revs.append(revision)
-
-    filtered_revs = _file_log(revs, tags, default_branch, rev)
-
-    options['cvs_tags'] = tags
-    return filtered_revs
-
-  def rcs_popen(self, rcs_cmd, rcs_args, mode, capture_err=1):
-    if self.rcs_paths.cvsnt_exe_path:
-      cmd = self.rcs_paths.cvsnt_exe_path
-      args = ['rcsfile', rcs_cmd]
-      args.extend(list(rcs_args))
-    else:
-      cmd = os.path.join(self.rcs_paths.rcs_path, rcs_cmd)
-      args = rcs_args
-    return popen.popen(cmd, args, mode, capture_err)
-
-  def annotate(self, path_parts, rev=None):
-    from vclib.ccvs import blame
-    source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
-    return source, source.revision
-
-  def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
-    """see vclib.Repository.rawdiff docstring
-
-    Option values recognized by this implementation:
-
-      ignore_keyword_subst - boolean, ignore keyword substitution
-    """
-    args = vclib._diff_args(type, options)
-    if options.get('ignore_keyword_subst', 0):
-      args.append('-kk')
-
-    rcsfile = self.rcsfile(path_parts1, 1)
-    if path_parts1 != path_parts2:
-      raise NotImplementedError, "cannot diff across paths in cvs"
-    args.extend(['-r' + rev1, '-r' + rev2, rcsfile])
-    
-    fp = self.rcs_popen('rcsdiff', args, 'rt')
-
-    # Eat up the non-GNU-diff-y headers.
-    while 1:
-      line = fp.readline()
-      if not line or line[0:5] == 'diff ':
-        break
-    return fp
-  
-
-class CVSDirEntry(vclib.DirEntry):
-  def __init__(self, name, kind, errors, in_attic):
-    vclib.DirEntry.__init__(self, name, kind, errors)
-    self.in_attic = in_attic
-
-class Revision(vclib.Revision):
-  def __init__(self, revstr, date=None, author=None, dead=None,
-               changed=None, log=None):
-    vclib.Revision.__init__(self, _revision_tuple(revstr), revstr,
-                            date, author, changed, log, None)
-    self.dead = dead
-
-class Tag:
-  def __init__(self, name, revstr):
-    self.name = name
-    self.number = _tag_tuple(revstr)
-    self.is_branch = len(self.number) % 2 == 1 or not self.number
-
-
-# ======================================================================
-# Functions for dealing with Revision and Tag objects
-
-def _match_revs_tags(revlist, taglist):
-  """Match up a list of Revision objects with a list of Tag objects
-
-  Sets the following properties on each Revision in revlist:
-    "tags"
-      list of non-branch tags which refer to this revision
-      example: if revision is 1.2.3.4, tags is a list of all 1.2.3.4 tags
-
-    "branches"
-      list of branch tags which refer to this revision's branch
-      example: if revision is 1.2.3.4, branches is a list of all 1.2.3 tags
-
-    "branch_points"
-      list of branch tags which branch off of this revision
-      example: if revision is 1.2, it's a list of tags like 1.2.3 and 1.2.4
-
-    "prev"
-      reference to the previous revision, possibly None
-      example: if revision is 1.2.3.4, prev is 1.2.3.3
-
-    "next"
-      reference to next revision, possibly None
-      example: if revision is 1.2.3.4, next is 1.2.3.5
-
-    "parent"
-      reference to revision this one branches off of, possibly None
-      example: if revision is 1.2.3.4, parent is 1.2
-
-    "undead"
-      If the revision is dead, then this is a reference to the first 
-      previous revision which isn't dead, otherwise it's a reference
-      to itself. If all the previous revisions are dead it's None. 
-
-    "branch_number"
-      tuple representing branch number or empty tuple if on trunk
-      example: if revision is 1.2.3.4, branch_number is (1, 2, 3)
-
-  Each tag in taglist gets these properties set:
-    "co_rev"
-      reference to revision that would be retrieved if tag were checked out
-
-    "branch_rev"
-      reference to revision branched off of, only set for branch tags
-      example: if tag is 1.2.3, branch_rev points to 1.2 revision
-
-    "aliases"
-      list of tags that have the same number
-  """
-
-  # map of branch numbers to lists of corresponding branch Tags
-  branch_dict = {}
-
-  # map of revision numbers to lists of non-branch Tags
-  tag_dict = {}
-
-  # map of revision numbers to lists of branch Tags
-  branch_point_dict = {}
-
-  # toss tags into "branch_dict", "tag_dict", and "branch_point_dict"
-  # set "aliases" property and default "co_rev" and "branch_rev" values
-  for tag in taglist:
-    tag.co_rev = None
-    if tag.is_branch:
-      tag.branch_rev = None
-      _dict_list_add(branch_point_dict, tag.number[:-1], tag)
-      tag.aliases = _dict_list_add(branch_dict, tag.number, tag)
-    else:
-      tag.aliases = _dict_list_add(tag_dict, tag.number, tag)
-
-  # sort the revisions so the loop below can work properly
-  revlist.sort()
-
-  # array of the most recently encountered revision objects indexed by depth
-  history = []
-
-  # loop through revisions, setting properties and storing state in "history"
-  for rev in revlist:
-    depth = len(rev.number) / 2 - 1
-
-    # set "prev" and "next" properties
-    rev.prev = rev.next = None
-    if depth < len(history):
-      prev = history[depth]
-      if prev and (depth == 0 or rev.number[:-1] == prev.number[:-1]):
-        rev.prev = prev
-        prev.next = rev
-
-    # set "parent"
-    rev.parent = None
-    if depth and depth <= len(history):
-      parent = history[depth-1]
-      if parent and parent.number == rev.number[:-2]:
-        rev.parent = history[depth-1]
-
-    # set "undead"
-    if rev.dead:
-      prev = rev.prev or rev.parent
-      rev.undead = prev and prev.undead
-    else:
-      rev.undead = rev
-
-    # set "tags" and "branch_points"
-    rev.tags = tag_dict.get(rev.number, [])
-    rev.branch_points = branch_point_dict.get(rev.number, [])
-
-    # set "branches" and "branch_number"
-    if rev.prev:
-      rev.branches = rev.prev.branches
-      rev.branch_number = rev.prev.branch_number
-    else:
-      rev.branch_number = depth and rev.number[:-1] or ()
-      try:
-        rev.branches = branch_dict[rev.branch_number]
-      except KeyError:
-        rev.branches = []
-
-    # set "co_rev" and "branch_rev"
-    for tag in rev.tags:
-      tag.co_rev = rev
-
-    for tag in rev.branch_points:
-      tag.co_rev = rev
-      tag.branch_rev = rev
-
-    # This loop only needs to be run for revisions at the heads of branches,
-    # but for the simplicity's sake, it actually runs for every revision on
-    # a branch. The later revisions overwrite values set by the earlier ones.
-    for branch in rev.branches:
-      branch.co_rev = rev
-
-    # end of outer loop, store most recent revision in "history" array
-    while len(history) <= depth:
-      history.append(None)
-    history[depth] = rev
-
-def _add_tag(tag_name, revision):
-  """Create a new tag object and associate it with a revision"""
-  if revision:
-    tag = Tag(tag_name, revision.string)
-    tag.aliases = revision.tags
-    revision.tags.append(tag)
-  else:
-    tag = Tag(tag_name, None)
-    tag.aliases = []
-  tag.co_rev = revision
-  tag.is_branch = 0
-  return tag
-
-def _remove_tag(tag):
-  """Remove a tag's associations"""
-  tag.aliases.remove(tag)
-  if tag.is_branch and tag.branch_rev:
-    tag.branch_rev.branch_points.remove(tag)
-
-def _revision_tuple(revision_string):
-  """convert a revision number into a tuple of integers"""
-  t = tuple(map(int, string.split(revision_string, '.')))
-  if len(t) % 2 == 0:
-    return t
-  raise ValueError
-
-def _tag_tuple(revision_string):
-  """convert a revision number or branch number into a tuple of integers"""
-  if revision_string:
-    t = map(int, string.split(revision_string, '.'))
-    l = len(t)
-    if l == 1:
-      raise ValueError
-    if l > 2 and t[-2] == 0 and l % 2 == 0:
-      del t[-2]
-    return tuple(t)
-  return ()
-
-def _dict_list_add(dict, idx, elem):
-  try:
-    list = dict[idx]
-  except KeyError:
-    list = dict[idx] = [elem]
-  else:
-    list.append(elem)
-  return list
-
-
-# ======================================================================
-# Functions for parsing output from RCS utilities
-
-
-class COMalformedOutput(vclib.Error):
-  pass
-class COMissingRevision(vclib.Error):
-  pass
-
-### suck up other warnings in _re_co_warning?
-_re_co_filename = re.compile(r'^(.*),v\s+-->\s+(?:(?:standard output)|(?:stdout))\s*\n?$')
-_re_co_warning = re.compile(r'^.*co: .*,v: warning: Unknown phrases like .*\n$')
-_re_co_missing_rev = re.compile(r'^.*co: .*,v: revision.*absent\n$')
-_re_co_side_branches = re.compile(r'^.*co: .*,v: no side branches present for [\d\.]+\n$')
-_re_co_revision = re.compile(r'^revision\s+([\d\.]+)\s*\n$')
-
-def _parse_co_header(fp):
-  """Parse RCS co header.
-
-  fp is a file (pipe) opened for reading the co standard error stream.
-
-  Returns: (filename, revision) or (None, None) if output is empty
-  """
-
-  # header from co:
-  #
-  #/home/cvsroot/mod_dav/dav_shared_stub.c,v  -->  standard output
-  #revision 1.1
-  #
-  # Sometimes, the following line might occur at line 2:
-  #co: INSTALL,v: warning: Unknown phrases like `permissions ...;' are present.
-
-  # parse the output header
-  filename = None
-
-  # look for a filename in the first line (if there is a first line).
-  line = fp.readline()
-  if not line:
-    return None, None
-  match = _re_co_filename.match(line)
-  if not match:
-    raise COMalformedOutput, "Unable to find filename in co output stream"
-  filename = match.group(1)
-
-  # look for a revision in the second line.
-  line = fp.readline()
-  if not line:
-    raise COMalformedOutput, "Missing second line from co output stream"
-  match = _re_co_revision.match(line)
-  if match:
-    return filename, match.group(1)
-  elif _re_co_missing_rev.match(line) or _re_co_side_branches.match(line):
-    raise COMissingRevision, "Got missing revision error from co output stream"
-  elif _re_co_warning.match(line):
-    pass
-  else:
-    raise COMalformedOutput, "Unable to find revision in co output stream"
-    
-  # if we get here, the second line wasn't a revision, but it was a
-  # warning we can ignore.  look for a revision in the third line.
-  line = fp.readline()
-  if not line:
-    raise COMalformedOutput, "Missing third line from co output stream"
-  match = _re_co_revision.match(line)
-  if match:
-    return filename, match.group(1)
-  raise COMalformedOutput, "Unable to find revision in co output stream"
-
-
-# if your rlog doesn't use 77 '=' characters, then this must change
-LOG_END_MARKER = '=' * 77 + '\n'
-ENTRY_END_MARKER = '-' * 28 + '\n'
-
-_EOF_FILE = 'end of file entries'       # no more entries for this RCS file
-_EOF_LOG = 'end of log'                 # hit the true EOF on the pipe
-_EOF_ERROR = 'error message found'      # rlog issued an error
-
-# rlog error messages look like
-#
-#   rlog: filename/goes/here,v: error message
-#   rlog: filename/goes/here,v:123: error message
-#
-# so we should be able to match them with a regex like
-#
-#   ^rlog\: (.*)(?:\:\d+)?\: (.*)$
-#
-# But for some reason the windows version of rlog omits the "rlog: " prefix
-# for the first error message when the standard error stream has been 
-# redirected to a file or pipe. (the prefix is present in subsequent errors
-# and when rlog is run from the console). So the expression below is more
-# complicated
-_re_log_error = re.compile(r'^(?:rlog\: )*(.*,v)(?:\:\d+)?\: (.*)$')
-
-# CVSNT error messages look like:
-# cvs rcsfile: `C:/path/to/file,v' does not appear to be a valid rcs file
-# cvs [rcsfile aborted]: C:/path/to/file,v: No such file or directory
-# cvs [rcsfile aborted]: cannot open C:/path/to/file,v: Permission denied
-_re_cvsnt_error = re.compile(r'^(?:cvs rcsfile\: |cvs \[rcsfile aborted\]: )'
-                             r'(?:\`(.*,v)\' |cannot open (.*,v)\: |(.*,v)\: |)'
-                             r'(.*)$')
-
-def _parse_log_header(fp):
-  """Parse and RCS/CVS log header.
-
-  fp is a file (pipe) opened for reading the log information.
-
-  On entry, fp should point to the start of a log entry.
-  On exit, fp will have consumed the separator line between the header and
-  the first revision log.
-
-  If there is no revision information (e.g. the "-h" switch was passed to
-  rlog), then fp will consumed the file separator line on exit.
-
-  Returns: filename, default branch, tag dictionary, rlog error message, 
-  and eof flag
-  """
-  filename = head = branch = msg = ""
-  taginfo = { }         # tag name => number
-
-  parsing_tags = 0
-  eof = None
-
-  while 1:
-    line = fp.readline()
-    if not line:
-      # the true end-of-file
-      eof = _EOF_LOG
-      break
-
-    if parsing_tags:
-      if line[0] == '\t':
-        [ tag, rev ] = map(string.strip, string.split(line, ':'))
-        taginfo[tag] = rev
-      else:
-        # oops. this line isn't tag info. stop parsing tags.
-        parsing_tags = 0
-
-    if not parsing_tags:
-      if line[:9] == 'RCS file:':
-        filename = line[10:-1]
-      elif line[:5] == 'head:':
-        head = line[6:-1]
-      elif line[:7] == 'branch:':
-        branch = line[8:-1]
-      elif line[:14] == 'symbolic names':
-        # start parsing the tag information
-        parsing_tags = 1
-      elif line == ENTRY_END_MARKER:
-        # end of the headers
-        break
-      elif line == LOG_END_MARKER:
-        # end of this file's log information
-        eof = _EOF_FILE
-        break
-      else:
-        error = _re_cvsnt_error.match(line)
-        if error:
-          p1, p2, p3, msg = error.groups()
-          filename = p1 or p2 or p3
-          if not filename:
-            raise vclib.Error("Could not get filename from CVSNT error:\n%s"
-                               % line)
-          eof = _EOF_ERROR
-          break
-
-        error = _re_log_error.match(line)
-        if error:
-          filename, msg = error.groups()
-          if msg[:30] == 'warning: Unknown phrases like ':
-            # don't worry about this warning. it can happen with some RCS
-            # files that have unknown fields in them (e.g. "permissions 644;"
-            continue
-          eof = _EOF_ERROR
-          break
-
-  return filename, branch, taginfo, msg, eof
-
-_re_log_info = re.compile(r'^date:\s+([^;]+);'
-                          r'\s+author:\s+([^;]+);'
-                          r'\s+state:\s+([^;]+);'
-                          r'(\s+lines:\s+([0-9\s+-]+);?)?'
-                          r'(\s+commitid:\s+([a-zA-Z0-9]+))?\n$')
-### _re_rev should be updated to extract the "locked" flag
-_re_rev = re.compile(r'^revision\s+([0-9.]+).*')
-def _parse_log_entry(fp):
-  """Parse a single log entry.
-
-  On entry, fp should point to the first line of the entry (the "revision"
-  line).
-  On exit, fp will have consumed the log separator line (dashes) or the
-  end-of-file marker (equals).
-
-  Returns: Revision object and eof flag (see _EOF_*)
-  """
-  rev = None
-  line = fp.readline()
-  if not line:
-    return None, _EOF_LOG
-  if line == LOG_END_MARKER:
-    # Needed because some versions of RCS precede LOG_END_MARKER
-    # with ENTRY_END_MARKER
-    return None, _EOF_FILE
-  if line[:8] == 'revision':
-    match = _re_rev.match(line)
-    if not match:
-      return None, _EOF_LOG
-    rev = match.group(1)
-
-    line = fp.readline()
-    if not line:
-      return None, _EOF_LOG
-    match = _re_log_info.match(line)
-
-  eof = None
-  log = ''
-  while 1:
-    line = fp.readline()
-    if not line:
-      # true end-of-file
-      eof = _EOF_LOG
-      break
-    if line[:9] == 'branches:':
-      continue
-    if line == ENTRY_END_MARKER:
-      break
-    if line == LOG_END_MARKER:
-      # end of this file's log information
-      eof = _EOF_FILE
-      break
-
-    log = log + line
-
-  if not rev or not match:
-    # there was a parsing error
-    return None, eof
-
-  # parse out a time tuple for the local time
-  tm = compat.cvs_strptime(match.group(1))
-
-  # rlog seems to assume that two-digit years are 1900-based (so, "04"
-  # comes out as "1904", not "2004").
-  EPOCH = 1970
-  if tm[0] < EPOCH:
-    tm = list(tm)
-    if (tm[0] - 1900) < 70:
-      tm[0] = tm[0] + 100
-    if tm[0] < EPOCH:
-      raise ValueError, 'invalid year'
-  date = compat.timegm(tm)
-
-  return Revision(rev, date,
-                  # author, state, lines changed
-                  match.group(2), match.group(3) == "dead", match.group(5),
-                  log), eof
-
-def _skip_file(fp):
-  "Skip the rest of a file's log information."
-  while 1:
-    line = fp.readline()
-    if not line:
-      break
-    if line == LOG_END_MARKER:
-      break
-
-def _paths_eq(path1, path2):
-  "See if two path strings are the same"
-  # This function is neccessary because CVSNT (since version 2.0.29)
-  # converts paths passed as arguments to use upper case drive
-  # letter and forward slashes
-  return os.path.normcase(path1) == os.path.normcase(path2)
-
-
-# ======================================================================
-# Functions for interpreting and manipulating log information
-
-def _file_log(revs, taginfo, cur_branch, filter):
-  """Augment list of Revisions and a dictionary of Tags"""
-
-  # Add artificial ViewVC tag MAIN. If the file has a default branch, then
-  # MAIN acts like a branch tag pointing to that branch. Otherwise MAIN acts
-  # like a branch tag that points to the trunk. (Note: A default branch is
-  # just a branch number specified in an RCS file that tells CVS and RCS
-  # what branch to use for checkout and update operations by default, when
-  # there's no revision argument or sticky branch to override it. Default
-  # branches get set by "cvs import" to point to newly created vendor
-  # branches. Sometimes they are also set manually with "cvs admin -b")
-  taginfo['MAIN'] = cur_branch
-
-  # Create tag objects
-  for name, num in taginfo.items():
-    taginfo[name] = Tag(name, num)
-  tags = taginfo.values()
-
-  # Set view_tag to a Tag object in order to filter results. We can filter by
-  # revision number or branch number
-  if filter:
-    try:
-      view_tag = Tag(None, filter)
-    except ValueError:
-      view_tag = None
-    else:
-      tags.append(view_tag)  
-
-  # Match up tags and revisions
-  _match_revs_tags(revs, tags)
-
-  # Add artificial ViewVC tag HEAD, which acts like a non-branch tag pointing
-  # at the latest revision on the MAIN branch. The HEAD revision doesn't have
-  # anything to do with the "head" revision number specified in the RCS file
-  # and in rlog output. HEAD refers to the revision that the CVS and RCS co
-  # commands will check out by default, whereas the "head" field just refers
-  # to the highest revision on the trunk.  
-  taginfo['HEAD'] = _add_tag('HEAD', taginfo['MAIN'].co_rev)
-
-  # Determine what revisions to return
-  if filter:
-    # If view_tag isn't set, it means filter is not a valid revision or
-    # branch number. Check taginfo to see if filter is set to a valid tag
-    # name. If so, filter by that tag, otherwise raise an error.
-    if not view_tag:
-      try:
-        view_tag = taginfo[filter]
-      except KeyError:
-        raise vclib.Error('Invalid tag or revision number "%s"' % filter)
-    filtered_revs = [ ]
-
-    # only include revisions on the tag branch or it's parent branches
-    if view_tag.is_branch:
-      branch = view_tag.number
-    elif len(view_tag.number) > 2:
-      branch = view_tag.number[:-1]
-    else:
-      branch = ()
-
-    # for a normal tag, include all tag revision and all preceding revisions.
-    # for a branch tag, include revisions on branch, branch point revision,
-    # and all preceding revisions
-    for rev in revs:
-      if (rev.number == view_tag.number
-          or rev.branch_number == view_tag.number
-          or (rev.number < view_tag.number
-              and rev.branch_number == branch[:len(rev.branch_number)])):
-        filtered_revs.append(rev)
-
-    # get rid of the view_tag if it was only created for filtering
-    if view_tag.name is None:
-      _remove_tag(view_tag)
-  else:
-    filtered_revs = revs
-  
-  return filtered_revs
-
-def _get_logs(repos, dirpath, entries, view_tag, get_dirs):
-  alltags = {           # all the tags seen in the files of this dir
-    'MAIN' : '',
-    'HEAD' : '1.1'
-    }
-
-  entries_idx = 0
-  entries_len = len(entries)
-  max_args = 100
-
-  while 1:
-    chunk = []
-
-    while len(chunk) < max_args and entries_idx < entries_len:
-      entry = entries[entries_idx]
-      path = _log_path(entry, dirpath, get_dirs)
-      if path:
-        entry.path = path
-        entry.idx = entries_idx
-        chunk.append(entry)
-
-      # set properties even if we don't retrieve logs
-      entry.rev = entry.date = entry.author = entry.dead = entry.log = None
-
-      entries_idx = entries_idx + 1
-
-    if not chunk:
-      return alltags
-
-    args = []
-    if not view_tag:
-      # NOTE: can't pass tag on command line since a tag may contain "-"
-      #       we'll search the output for the appropriate revision
-      # fetch the latest revision on the default branch
-      args.append('-r')
-    args.extend(map(lambda x: x.path, chunk))
-    rlog = repos.rcs_popen('rlog', args, 'rt')
-
-    # consume each file found in the resulting log
-    chunk_idx = 0
-    while chunk_idx < len(chunk):
-      file = chunk[chunk_idx]
-      filename, default_branch, taginfo, msg, eof = _parse_log_header(rlog)
-
-      if eof == _EOF_LOG:
-        # the rlog output ended early. this can happen on errors that rlog 
-        # thinks are so serious that it stops parsing the current file and
-        # refuses to parse any of the files that come after it. one of the
-        # errors that triggers this obnoxious behavior looks like:
-        #
-        # rlog: c:\cvsroot\dir\file,v:8: unknown expand mode u
-        # rlog aborted
-
-        # if current file has errors, restart on the next one
-        if file.errors:
-          chunk_idx = chunk_idx + 1
-          if chunk_idx < len(chunk):
-            entries_idx = chunk[chunk_idx].idx
-          break
-
-        # otherwise just error out
-        raise vclib.Error('Rlog output ended early. Expected RCS file "%s"'
-                          % file.path)
-
-      # if rlog filename doesn't match current file and we already have an
-      # error message about this file, move on to the next file
-      while not (file and _paths_eq(file.path, filename)):
-        if file and file.errors:
-          chunk_idx = chunk_idx + 1
-          file = chunk_idx < len(chunk) and chunk[chunk_idx] or None
-          continue
-
-        raise vclib.Error('Error parsing rlog output. Expected RCS file %s'
-                          ', found %s' % (file and file.path, filename))
-
-      # if we get an rlog error message, restart loop without advancing
-      # chunk_idx cause there might be more output about the same file
-      if eof == _EOF_ERROR:
-        file.errors.append("rlog error: %s" % msg)
-        continue
-
-      if view_tag == 'MAIN' or view_tag == 'HEAD':
-        tag = Tag(None, default_branch)
-      elif taginfo.has_key(view_tag):
-        tag = Tag(None, taginfo[view_tag])
-      elif view_tag:
-        # the tag wasn't found, so skip this file
-        _skip_file(rlog)
-        eof = 1
-      else:
-        tag = None
-
-      # we don't care about the specific values -- just the keys and whether
-      # the values point to branches or revisions. this the fastest way to 
-      # merge the set of keys and keep values that allow us to make the 
-      # distinction between branch tags and normal tags
-      alltags.update(taginfo)
-
-      # read all of the log entries until we find the revision we want
-      wanted_entry = None
-      while not eof:
-
-        # fetch one of the log entries
-        entry, eof = _parse_log_entry(rlog)
-
-        if not entry:
-          # parsing error
-          break
-
-        # A perfect match is a revision on the branch being viewed or
-        # a revision having the tag being viewed or any revision
-        # when nothing is being viewed. When there's a perfect match
-        # we set the wanted_entry value and break out of the loop.
-        # An imperfect match is a revision at the branch point of a
-        # branch being viewed. When there's an imperfect match we
-        # also set the wanted_entry value but keep looping in case
-        # something better comes along.
-        perfect = not tag or entry.number == tag.number or       \
-                  (len(entry.number) == 2 and not tag.number) or \
-                  entry.number[:-1] == tag.number
-        if perfect or entry.number == tag.number[:-1]:
-          wanted_entry = entry
-          if perfect:
-            break
-
-      if wanted_entry:
-        file.rev = wanted_entry.string
-        file.date = wanted_entry.date
-        file.author = wanted_entry.author
-        file.dead = file.kind == vclib.FILE and wanted_entry.dead
-        file.log = wanted_entry.log
-        # suppress rlog errors if we find a usable revision in the end
-        del file.errors[:]
-      elif file.kind == vclib.FILE:
-        file.dead = 1
-        file.errors.append("No revisions exist on %s" % (view_tag or "MAIN"))
-
-      # done with this file now, skip the rest of this file's revisions
-      if not eof:
-        _skip_file(rlog)
-
-      # end of while loop, advance index
-      chunk_idx = chunk_idx + 1
-
-    rlog.close()
-
-def _log_path(entry, dirpath, getdirs):
-  path = name = None
-  if not entry.errors:
-    if entry.kind == vclib.FILE:
-      path = entry.in_attic and 'Attic' or ''
-      name = entry.name
-    elif entry.kind == vclib.DIR and getdirs:
-      entry.newest_file = _newest_file(os.path.join(dirpath, entry.name))
-      if entry.newest_file:
-        path = entry.name
-        name = entry.newest_file
-
-  if name:
-    return os.path.join(dirpath, path, name + ',v')
-  return None
-
-
-# ======================================================================
-# Functions for dealing with the filesystem
-
-if sys.platform == "win32":
-  def _check_path(path):
-    kind = None
-    errors = []
-
-    if os.path.isfile(path):
-      kind = vclib.FILE
-    elif os.path.isdir(path):
-      kind = vclib.DIR
-    else:
-      errors.append("error: path is not a file or directory")
-
-    if not os.access(path, os.R_OK):
-      errors.append("error: path is not accessible")
-
-    return kind, errors
-
-else:
-  _uid = os.getuid()
-  _gid = os.getgid()
-
-  def _check_path(pathname):
-    try:
-      info = os.stat(pathname)
-    except os.error, e:
-      return None, ["stat error: %s" % e]
-
-    kind = None
-    errors = []
-
-    mode = info[stat.ST_MODE]
-    isdir = stat.S_ISDIR(mode)
-    isreg = stat.S_ISREG(mode)
-    if isreg or isdir:
-      #
-      # Quick version of access() where we use existing stat() data.
-      #
-      # This might not be perfect -- the OS may return slightly different
-      # results for some bizarre reason. However, we make a good show of
-      # "can I read this file/dir?" by checking the various perm bits.
-      #
-      # NOTE: if the UID matches, then we must match the user bits -- we
-      # cannot defer to group or other bits. Similarly, if the GID matches,
-      # then we must have read access in the group bits.
-      #
-      # If the UID or GID don't match, we need to check the
-      # results of an os.access() call, in case the web server process
-      # is in the group that owns the directory.
-      #
-      if isdir:
-        mask = stat.S_IROTH | stat.S_IXOTH
-      else:
-        mask = stat.S_IROTH
-
-      if info[stat.ST_UID] == _uid:
-        if ((mode >> 6) & mask) != mask:
-          errors.append("error: path is not accessible to user %i" % _uid)
-      elif info[stat.ST_GID] == _gid:
-        if ((mode >> 3) & mask) != mask:
-          errors.append("error: path is not accessible to group %i" % _gid)
-      # If the process running the web server is a member of
-      # the group stat.ST_GID access may be granted.
-      # so the fall back to os.access is needed to figure this out.
-      elif (mode & mask) != mask:
-        if not os.access(pathname, isdir and (os.R_OK | os.X_OK) or os.R_OK):
-          errors.append("error: path is not accessible")
-
-      if isdir:
-        kind = vclib.DIR
-      else:
-        kind = vclib.FILE
-
-    else:
-      errors.append("error: path is not a file or directory")
-
-    return kind, errors
-
-def _newest_file(dirpath):
-  """Find the last modified RCS file in a directory"""
-  newest_file = None
-  newest_time = 0
-
-  for subfile in os.listdir(dirpath):
-    ### filter CVS locks? stale NFS handles?
-    if subfile[-2:] != ',v':
-      continue
-    path = os.path.join(dirpath, subfile)
-    info = os.stat(path)
-    if not stat.S_ISREG(info[stat.ST_MODE]):
-      continue
-    if info[stat.ST_MTIME] > newest_time:
-      kind, verboten = _check_path(path)
-      if kind == vclib.FILE and not verboten:
-        newest_file = subfile[:-2]
-        newest_time = info[stat.ST_MTIME]
-
-  return newest_file
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/__init__.py b/src/www/scm/viewvc/lib/vclib/ccvs/__init__.py
deleted file mode 100644
index c9c6f0c..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/__init__.py
+++ /dev/null
@@ -1,351 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""
-This is a Version Control library driver for locally accessible cvs-repositories.
-"""
-
-import os
-import string
-import re
-import cStringIO
-import tempfile
-
-import vclib
-import rcsparse
-import blame
-
-### The functionality shared with bincvs should probably be moved to a
-### separate module
-from vclib.bincvs import CVSRepository, Revision, Tag, \
-                         _file_log, _log_path
-
-class CCVSRepository(CVSRepository):
-  def dirlogs(self, path_parts, rev, entries, options):
-    """see vclib.Repository.dirlogs docstring
-
-    rev can be a tag name or None. if set only information from revisions
-    matching the tag will be retrieved
-
-    Option values recognized by this implementation:
-
-      cvs_subdirs
-        boolean. true to fetch logs of the most recently modified file in each
-        subdirectory
-
-    Option values returned by this implementation:
-
-      cvs_tags, cvs_branches
-        lists of tag and branch names encountered in the directory
-    """
-    subdirs = options.get('cvs_subdirs', 0)
-
-    dirpath = self._getpath(path_parts)
-    alltags = {           # all the tags seen in the files of this dir
-      'MAIN' : '',
-      'HEAD' : '1.1'
-    }
-
-    for entry in entries:
-      entry.rev = entry.date = entry.author = entry.dead = entry.log = None
-      path = _log_path(entry, dirpath, subdirs)
-      if path:
-        entry.path = path
-        try:
-          rcsparse.Parser().parse(open(path, 'rb'), InfoSink(entry, rev, alltags))
-        except IOError, e:
-          entry.errors.append("rcsparse error: %s" % e)
-        except RuntimeError, e:
-          entry.errors.append("rcsparse error: %s" % e)
-        except rcsparse.RCSStopParser:
-          pass
-
-    branches = options['cvs_branches'] = []
-    tags = options['cvs_tags'] = []
-    for name, rev in alltags.items():
-      if Tag(None, rev).is_branch:
-        branches.append(name)
-      else:
-        tags.append(name)
-
-  def itemlog(self, path_parts, rev, options):
-    """see vclib.Repository.itemlog docstring
-
-    rev parameter can be a revision number, a branch number, a tag name,
-    or None. If None, will return information about all revisions, otherwise,
-    will only return information about the specified revision or branch.
-
-    Option values returned by this implementation:
-
-      cvs_tags
-        dictionary of Tag objects for all tags encountered
-    """
-    path = self.rcsfile(path_parts, 1)
-    sink = TreeSink()
-    rcsparse.Parser().parse(open(path, 'rb'), sink)
-    filtered_revs = _file_log(sink.revs.values(), sink.tags,
-                              sink.default_branch, rev)
-    for rev in filtered_revs:
-      if rev.prev and len(rev.number) == 2:
-        rev.changed = rev.prev.next_changed
-    options['cvs_tags'] = sink.tags
-
-    return filtered_revs
-
-  def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
-    temp1 = tempfile.mktemp()
-    open(temp1, 'wb').write(self.openfile(path_parts1, rev1)[0].getvalue())
-    temp2 = tempfile.mktemp()
-    open(temp2, 'wb').write(self.openfile(path_parts2, rev2)[0].getvalue())
-
-    r1 = self.itemlog(path_parts1, rev1, {})[-1]
-    r2 = self.itemlog(path_parts2, rev2, {})[-1]
-
-    info1 = (self.rcsfile(path_parts1, root=1, v=0), r1.date, r1.string)
-    info2 = (self.rcsfile(path_parts2, root=1, v=0), r2.date, r2.string)
-
-    diff_args = vclib._diff_args(type, options)
-
-    return vclib._diff_fp(temp1, temp2, info1, info2, diff_args)
-
-  def annotate(self, path_parts, rev=None):
-    source = blame.BlameSource(self.rcsfile(path_parts, 1), rev)
-    return source, source.revision
-
-  def openfile(self, path_parts, rev=None):
-    path = self.rcsfile(path_parts, 1)
-    sink = COSink(rev)
-    rcsparse.Parser().parse(open(path, 'rb'), sink)
-    revision = sink.last and sink.last.string
-    return cStringIO.StringIO(string.join(sink.sstext.text, "\n")), revision
-
-class MatchingSink(rcsparse.Sink):
-  """Superclass for sinks that search for revisions based on tag or number"""
-
-  def __init__(self, find):
-    """Initialize with tag name or revision number string to match against"""
-    if not find or find == 'MAIN' or find == 'HEAD':
-      self.find = None
-    else:
-      self.find = find
-
-    self.find_tag = None
-
-  def set_principal_branch(self, branch_number):
-    if self.find is None:
-      self.find_tag = Tag(None, branch_number)
-
-  def define_tag(self, name, revision):
-    if name == self.find:
-      self.find_tag = Tag(None, revision)
-
-  def admin_completed(self):
-    if self.find_tag is None:
-      if self.find is None:
-        self.find_tag = Tag(None, '')
-      else:
-        try:
-          self.find_tag = Tag(None, self.find)
-        except ValueError:
-          pass
-
-class InfoSink(MatchingSink):
-  def __init__(self, entry, tag, alltags):
-    MatchingSink.__init__(self, tag)
-    self.entry = entry
-    self.alltags = alltags
-    self.matching_rev = None
-    self.perfect_match = 0
-
-  def define_tag(self, name, revision):
-    MatchingSink.define_tag(self, name, revision)
-    self.alltags[name] = revision
-
-  def admin_completed(self):
-    MatchingSink.admin_completed(self)
-    if self.find_tag is None:
-      # tag we're looking for doesn't exist
-      raise rcsparse.RCSStopParser
-
-  def define_revision(self, revision, date, author, state, branches, next):
-    if self.perfect_match:
-      return
-
-    tag = self.find_tag
-    rev = Revision(revision, date, author, state == "dead")
-
-    # perfect match if revision number matches tag number or if revision is on
-    # trunk and tag points to trunk. imperfect match if tag refers to a branch
-    # and this revision is the highest revision so far found on that branch
-    perfect = ((rev.number == tag.number) or
-               (not tag.number and len(rev.number) == 2))
-    if perfect or (tag.is_branch and tag.number == rev.number[:-1] and
-                   (not self.matching_rev or
-                    rev.number > self.matching_rev.number)):
-      self.matching_rev = rev
-      self.perfect_match = perfect
-
-  def set_revision_info(self, revision, log, text):
-    if self.matching_rev:
-      if revision == self.matching_rev.string:
-        self.entry.rev = self.matching_rev.string
-        self.entry.date = self.matching_rev.date
-        self.entry.author = self.matching_rev.author
-        self.entry.dead = self.matching_rev.dead
-        self.entry.log = log
-        raise rcsparse.RCSStopParser
-    else:
-      raise rcsparse.RCSStopParser
-
-class TreeSink(rcsparse.Sink):
-  d_command = re.compile('^d(\d+)\\s(\\d+)')
-  a_command = re.compile('^a(\d+)\\s(\\d+)')
-
-  def __init__(self):
-    self.revs = { }
-    self.tags = { }
-    self.head = None
-    self.default_branch = None
-
-  def set_head_revision(self, revision):
-    self.head = revision
-
-  def set_principal_branch(self, branch_number):
-    self.default_branch = branch_number
-
-  def define_tag(self, name, revision):
-    # check !tags.has_key(tag_name)
-    self.tags[name] = revision
-
-  def define_revision(self, revision, date, author, state, branches, next):
-    # check !revs.has_key(revision)
-    self.revs[revision] = Revision(revision, date, author, state == "dead")
-
-  def set_revision_info(self, revision, log, text):
-    # check revs.has_key(revision)
-    rev = self.revs[revision]
-    rev.log = log
-
-    changed = None
-    added = 0
-    deled = 0
-    if self.head != revision:
-      changed = 1
-      lines = string.split(text, '\n')
-      idx = 0
-      while idx < len(lines):
-        command = lines[idx]
-        dmatch = self.d_command.match(command)
-        idx = idx + 1
-        if dmatch:
-          deled = deled + string.atoi(dmatch.group(2))
-        else:
-          amatch = self.a_command.match(command)
-          if amatch:
-            count = string.atoi(amatch.group(2))
-            added = added + count
-            idx = idx + count
-          elif command:
-            raise "error while parsing deltatext: %s" % command
-
-    if len(rev.number) == 2:
-      rev.next_changed = changed and "+%i -%i" % (deled, added)
-    else:
-      rev.changed = changed and "+%i -%i" % (added, deled)
-
-class StreamText:
-  d_command = re.compile('^d(\d+)\\s(\\d+)')
-  a_command = re.compile('^a(\d+)\\s(\\d+)')
-
-  def __init__(self, text):
-    self.text = string.split(text, "\n")
-
-  def command(self, cmd):
-    adjust = 0
-    add_lines_remaining = 0
-    diffs = string.split(cmd, "\n")
-    if diffs[-1] == "":
-      del diffs[-1]
-    if len(diffs) == 0:
-      return
-    if diffs[0] == "":
-      del diffs[0]
-    for command in diffs:
-      if add_lines_remaining > 0:
-        # Insertion lines from a prior "a" command
-        self.text.insert(start_line + adjust, command)
-        add_lines_remaining = add_lines_remaining - 1
-        adjust = adjust + 1
-        continue
-      dmatch = self.d_command.match(command)
-      amatch = self.a_command.match(command)
-      if dmatch:
-        # "d" - Delete command
-        start_line = string.atoi(dmatch.group(1))
-        count      = string.atoi(dmatch.group(2))
-        begin = start_line + adjust - 1
-        del self.text[begin:begin + count]
-        adjust = adjust - count
-      elif amatch:
-        # "a" - Add command
-        start_line = string.atoi(amatch.group(1))
-        count      = string.atoi(amatch.group(2))
-        add_lines_remaining = count
-      else:
-        raise RuntimeError, 'Error parsing diff commands'
-
-def secondnextdot(s, start):
-  # find the position the second dot after the start index.
-  return string.find(s, '.', string.find(s, '.', start) + 1)
-
-
-class COSink(MatchingSink):
-  def __init__(self, rev):
-    MatchingSink.__init__(self, rev)
-
-  def set_head_revision(self, revision):
-    self.head = Revision(revision)
-    self.last = None
-    self.sstext = None
-
-  def admin_completed(self):
-    MatchingSink.admin_completed(self)
-    if self.find_tag is None:
-      raise vclib.InvalidRevision(self.find)
-
-  def set_revision_info(self, revision, log, text):
-    tag = self.find_tag
-    rev = Revision(revision)
-
-    if rev.number == tag.number:
-      self.log = log
-
-    depth = len(rev.number)
-
-    if rev.number == self.head.number:
-      assert self.sstext is None
-      self.sstext = StreamText(text)
-    elif (depth == 2 and tag.number and rev.number >= tag.number[:depth]):
-      assert len(self.last.number) == 2
-      assert rev.number < self.last.number
-      self.sstext.command(text)
-    elif (depth > 2 and rev.number[:depth-1] == tag.number[:depth-1] and
-          (rev.number <= tag.number or len(tag.number) == depth-1)):
-      assert len(rev.number) - len(self.last.number) in (0, 2)
-      assert rev.number > self.last.number
-      self.sstext.command(text)
-    else:
-      rev = None
-
-    if rev:
-      #print "tag =", tag.number, "rev =", rev.number, "<br>"
-      self.last = rev
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/blame.py b/src/www/scm/viewvc/lib/vclib/ccvs/blame.py
deleted file mode 100644
index 50abfa1..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/blame.py
+++ /dev/null
@@ -1,464 +0,0 @@
-#!/usr/bin/env python
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-# Copyright (C) 2000 Curt Hagenlocher <curt at hagenlocher.org>
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# blame.py: Annotate each line of a CVS file with its author,
-#           revision #, date, etc.
-#
-# -----------------------------------------------------------------------
-#
-# This file is based on the cvsblame.pl portion of the Bonsai CVS tool,
-# developed by Steve Lamm for Netscape Communications Corporation.  More
-# information about Bonsai can be found at
-#    http://www.mozilla.org/bonsai.html
-#
-# cvsblame.pl, in turn, was based on Scott Furman's cvsblame script
-#
-# -----------------------------------------------------------------------
-
-import string
-import re
-import time
-import math
-import rcsparse
-
-class CVSParser(rcsparse.Sink):
-  # Precompiled regular expressions
-  trunk_rev   = re.compile('^[0-9]+\\.[0-9]+$')
-  last_branch = re.compile('(.*)\\.[0-9]+')
-  is_branch   = re.compile('^(.*)\\.0\\.([0-9]+)$')
-  d_command   = re.compile('^d(\d+)\\s(\\d+)')
-  a_command   = re.compile('^a(\d+)\\s(\\d+)')
-
-  SECONDS_PER_DAY = 86400
-
-  def __init__(self):
-    self.Reset()
-
-  def Reset(self):
-    self.last_revision = {}
-    self.prev_revision = {}
-    self.revision_date = {}
-    self.revision_author = {}
-    self.revision_branches = {}
-    self.next_delta = {}
-    self.prev_delta = {}
-    self.tag_revision = {}
-    self.timestamp = {}
-    self.revision_ctime = {}
-    self.revision_age = {}
-    self.revision_log = {}
-    self.revision_deltatext = {}
-    self.revision_map = []    # map line numbers to revisions
-    self.lines_added  = {}
-    self.lines_removed = {}
-
-  # Map a tag to a numerical revision number.  The tag can be a symbolic
-  # branch tag, a symbolic revision tag, or an ordinary numerical
-  # revision number.
-  def map_tag_to_revision(self, tag_or_revision):
-    try:
-      revision = self.tag_revision[tag_or_revision]
-      match = self.is_branch.match(revision)
-      if match:
-        branch = match.group(1) + '.' + match.group(2)
-        if self.last_revision.get(branch):
-          return self.last_revision[branch]
-        else:
-          return match.group(1)
-      else:
-        return revision
-    except:
-      return ''
-
-  # Construct an ordered list of ancestor revisions to the given
-  # revision, starting with the immediate ancestor and going back
-  # to the primordial revision (1.1).
-  #
-  # Note: The generated path does not traverse the tree the same way
-  #       that the individual revision deltas do.  In particular,
-  #       the path traverses the tree "backwards" on branches.
-  def ancestor_revisions(self, revision):
-    ancestors = []
-    revision = self.prev_revision.get(revision)
-    while revision:
-      ancestors.append(revision)
-      revision = self.prev_revision.get(revision)
-
-    return ancestors
-
-  # Split deltatext specified by rev to each line.
-  def deltatext_split(self, rev):
-    lines = string.split(self.revision_deltatext[rev], '\n')
-    if lines[-1] == '':
-      del lines[-1]
-    return lines
-
-  # Extract the given revision from the digested RCS file.
-  # (Essentially the equivalent of cvs up -rXXX)
-  def extract_revision(self, revision):
-    path = []
-    add_lines_remaining = 0
-    start_line = 0
-    count = 0
-    while revision:
-      path.append(revision)
-      revision = self.prev_delta.get(revision)
-    path.reverse()
-    path = path[1:]  # Get rid of head revision
-
-    text = self.deltatext_split(self.head_revision)
-
-    # Iterate, applying deltas to previous revision
-    for revision in path:
-      adjust = 0
-      diffs = self.deltatext_split(revision)
-      self.lines_added[revision]   = 0
-      self.lines_removed[revision] = 0
-      lines_added_now = 0
-      lines_removed_now = 0
-
-      for command in diffs:
-        dmatch = self.d_command.match(command)
-        amatch = self.a_command.match(command)
-        if add_lines_remaining > 0:
-          # Insertion lines from a prior "a" command
-          text.insert(start_line + adjust, command)
-          add_lines_remaining = add_lines_remaining - 1
-          adjust = adjust + 1
-        elif dmatch:
-          # "d" - Delete command
-          start_line = string.atoi(dmatch.group(1))
-          count      = string.atoi(dmatch.group(2))
-          begin = start_line + adjust - 1
-          del text[begin:begin + count]
-          adjust = adjust - count
-          lines_removed_now = lines_removed_now + count
-        elif amatch:
-          # "a" - Add command
-          start_line = string.atoi(amatch.group(1))
-          count      = string.atoi(amatch.group(2))
-          add_lines_remaining = count
-          lines_added_now = lines_added_now + count
-        else:
-          raise RuntimeError, 'Error parsing diff commands'
-
-      self.lines_added[revision]   = self.lines_added[revision]   + lines_added_now
-      self.lines_removed[revision] = self.lines_removed[revision] + lines_removed_now
-    return text
-
-  def set_head_revision(self, revision):
-    self.head_revision = revision
-
-  def set_principal_branch(self, branch_name):
-    self.principal_branch = branch_name
-
-  def define_tag(self, name, revision):
-    # Create an associate array that maps from tag name to
-    # revision number and vice-versa.
-    self.tag_revision[name] = revision
-
-  def set_comment(self, comment):
-    self.file_description = comment
-
-  def set_description(self, description):
-    self.rcs_file_description = description
-
-  # Construct dicts that represent the topology of the RCS tree
-  # and other arrays that contain info about individual revisions.
-  #
-  # The following dicts are created, keyed by revision number:
-  #   self.revision_date     -- e.g. "96.02.23.00.21.52"
-  #   self.timestamp         -- seconds since 12:00 AM, Jan 1, 1970 GMT
-  #   self.revision_author   -- e.g. "tom"
-  #   self.revision_branches -- descendant branch revisions, separated by spaces,
-  #                             e.g. "1.21.4.1 1.21.2.6.1"
-  #   self.prev_revision     -- revision number of previous *ancestor* in RCS tree.
-  #                             Traversal of this array occurs in the direction
-  #                             of the primordial (1.1) revision.
-  #   self.prev_delta        -- revision number of previous revision which forms
-  #                             the basis for the edit commands in this revision.
-  #                             This causes the tree to be traversed towards the
-  #                             trunk when on a branch, and towards the latest trunk
-  #                             revision when on the trunk.
-  #   self.next_delta        -- revision number of next "delta".  Inverts prev_delta.
-  #
-  # Also creates self.last_revision, keyed by a branch revision number, which
-  # indicates the latest revision on a given branch,
-  #   e.g. self.last_revision{"1.2.8"} == 1.2.8.5
-  def define_revision(self, revision, timestamp, author, state,
-                      branches, next):
-    self.tag_revision[revision] = revision
-    branch = self.last_branch.match(revision).group(1)
-    self.last_revision[branch] = revision
-
-    #self.revision_date[revision] = date
-    self.timestamp[revision] = timestamp
-
-    # Pretty print the date string
-    ltime = time.localtime(self.timestamp[revision])
-    formatted_date = time.strftime("%d %b %Y %H:%M", ltime)
-    self.revision_ctime[revision] = formatted_date
-
-    # Save age
-    self.revision_age[revision] = ((time.time() - self.timestamp[revision])
-                                   / self.SECONDS_PER_DAY)
-
-    # save author
-    self.revision_author[revision] = author
-
-    # ignore the state
-
-    # process the branch information
-    branch_text = ''
-    for branch in branches:
-      self.prev_revision[branch] = revision
-      self.next_delta[revision] = branch
-      self.prev_delta[branch] = revision
-      branch_text = branch_text + branch + ''
-    self.revision_branches[revision] = branch_text
-
-    # process the "next revision" information
-    if next:
-      self.next_delta[revision] = next
-      self.prev_delta[next] = revision
-      is_trunk_revision = self.trunk_rev.match(revision) is not None
-      if is_trunk_revision:
-        self.prev_revision[revision] = next
-      else:
-        self.prev_revision[next] = revision
-
-  # Construct associative arrays containing info about individual revisions.
-  #
-  # The following associative arrays are created, keyed by revision number:
-  #   revision_log        -- log message
-  #   revision_deltatext  -- Either the complete text of the revision,
-  #                          in the case of the head revision, or the
-  #                          encoded delta between this revision and another.
-  #                          The delta is either with respect to the successor
-  #                          revision if this revision is on the trunk or
-  #                          relative to its immediate predecessor if this
-  #                          revision is on a branch.
-  def set_revision_info(self, revision, log, text):
-    self.revision_log[revision] = log
-    self.revision_deltatext[revision] = text
-
-  def parse_cvs_file(self, rcs_pathname, opt_rev = None, opt_m_timestamp = None):
-    # Args in:  opt_rev - requested revision
-    #           opt_m - time since modified
-    # Args out: revision_map
-    #           timestamp
-    #           revision_deltatext
-
-    # CheckHidden(rcs_pathname)
-    try:
-      rcsfile = open(rcs_pathname, 'rb')
-    except:
-      raise RuntimeError, ('error: %s appeared to be under CVS control, ' +
-              'but the RCS file is inaccessible.') % rcs_pathname
-
-    rcsparse.Parser().parse(rcsfile, self)
-    rcsfile.close()
-
-    if opt_rev in [None, '', 'HEAD']:
-      # Explicitly specified topmost revision in tree
-      revision = self.head_revision
-    else:
-      # Symbolic tag or specific revision number specified.
-      revision = self.map_tag_to_revision(opt_rev)
-      if revision == '':
-        raise RuntimeError, 'error: -r: No such revision: ' + opt_rev
-
-    # The primordial revision is not always 1.1!  Go find it.
-    primordial = revision
-    while self.prev_revision.get(primordial):
-      primordial = self.prev_revision[primordial]
-
-    # Don't display file at all, if -m option is specified and no
-    # changes have been made in the specified file.
-    if opt_m_timestamp and self.timestamp[revision] < opt_m_timestamp:
-      return ''
-
-    # Figure out how many lines were in the primordial, i.e. version 1.1,
-    # check-in by moving backward in time from the head revision to the
-    # first revision.
-    line_count = 0
-    if self.revision_deltatext.get(self.head_revision):
-      tmp_array = self.deltatext_split(self.head_revision)
-      line_count = len(tmp_array)
-
-    skip = 0
-
-    rev = self.prev_revision.get(self.head_revision)
-    while rev:
-      diffs = self.deltatext_split(rev)
-      for command in diffs:
-        dmatch = self.d_command.match(command)
-        amatch = self.a_command.match(command)
-        if skip > 0:
-          # Skip insertion lines from a prior "a" command
-          skip = skip - 1
-        elif dmatch:
-          # "d" - Delete command
-          start_line = string.atoi(dmatch.group(1))
-          count      = string.atoi(dmatch.group(2))
-          line_count = line_count - count
-        elif amatch:
-          # "a" - Add command
-          start_line = string.atoi(amatch.group(1))
-          count      = string.atoi(amatch.group(2))
-          skip       = count
-          line_count = line_count + count
-        else:
-          raise RuntimeError, 'error: illegal RCS file'
-
-      rev = self.prev_revision.get(rev)
-
-    # Now, play the delta edit commands *backwards* from the primordial
-    # revision forward, but rather than applying the deltas to the text of
-    # each revision, apply the changes to an array of revision numbers.
-    # This creates a "revision map" -- an array where each element
-    # represents a line of text in the given revision but contains only
-    # the revision number in which the line was introduced rather than
-    # the line text itself.
-    #
-    # Note: These are backward deltas for revisions on the trunk and
-    # forward deltas for branch revisions.
-
-    # Create initial revision map for primordial version.
-    self.revision_map = [primordial] * line_count
-
-    ancestors = [revision, ] + self.ancestor_revisions(revision)
-    ancestors = ancestors[:-1]  # Remove "1.1"
-    last_revision = primordial
-    ancestors.reverse()
-    for revision in ancestors:
-      is_trunk_revision = self.trunk_rev.match(revision) is not None
-
-      if is_trunk_revision:
-	diffs = self.deltatext_split(last_revision)
-
-        # Revisions on the trunk specify deltas that transform a
-        # revision into an earlier revision, so invert the translation
-        # of the 'diff' commands.
-        for command in diffs:
-          if skip > 0:
-            skip = skip - 1
-          else:
-            dmatch = self.d_command.match(command)
-            amatch = self.a_command.match(command)
-            if dmatch:
-              start_line = string.atoi(dmatch.group(1))
-              count      = string.atoi(dmatch.group(2))
-              temp = []
-              while count > 0:
-                temp.append(revision)
-                count = count - 1
-              self.revision_map = (self.revision_map[:start_line - 1] +
-                      temp + self.revision_map[start_line - 1:])
-            elif amatch:
-              start_line = string.atoi(amatch.group(1))
-              count      = string.atoi(amatch.group(2))
-              del self.revision_map[start_line:start_line + count]
-              skip = count
-            else:
-              raise RuntimeError, 'Error parsing diff commands'
-
-      else:
-        # Revisions on a branch are arranged backwards from those on
-        # the trunk.  They specify deltas that transform a revision
-        # into a later revision.
-        adjust = 0
-	diffs = self.deltatext_split(revision)
-        for command in diffs:
-          if skip > 0:
-            skip = skip - 1
-          else:
-            dmatch = self.d_command.match(command)
-            amatch = self.a_command.match(command)
-            if dmatch:
-              start_line = string.atoi(dmatch.group(1))
-              count      = string.atoi(dmatch.group(2))
-              adj_begin  = start_line + adjust - 1
-              adj_end    = start_line + adjust - 1 + count
-              del self.revision_map[adj_begin:adj_end]
-              adjust = adjust - count
-            elif amatch:
-              start_line = string.atoi(amatch.group(1))
-              count      = string.atoi(amatch.group(2))
-              skip = count
-              temp = []
-              while count > 0:
-                temp.append(revision)
-                count = count - 1
-              self.revision_map = (self.revision_map[:start_line + adjust] +
-                      temp + self.revision_map[start_line + adjust:])
-              adjust = adjust + skip
-            else:
-              raise RuntimeError, 'Error parsing diff commands'
-
-      last_revision = revision
-
-    return revision
-
-
-class BlameSource:
-  def __init__(self, rcs_file, opt_rev=None):
-    # Parse the CVS file
-    parser = CVSParser()
-    revision = parser.parse_cvs_file(rcs_file, opt_rev)
-    count = len(parser.revision_map)
-    lines = parser.extract_revision(revision)
-    if len(lines) != count:
-      raise RuntimeError, 'Internal consistency error'
-
-    # set up some state variables
-    self.revision = revision
-    self.lines = lines
-    self.num_lines = count
-    self.parser = parser
-
-    # keep track of where we are during an iteration
-    self.idx = -1
-    self.last = None
-
-  def __getitem__(self, idx):
-    if idx == self.idx:
-      return self.last
-    if idx >= self.num_lines:
-      raise IndexError("No more annotations")
-    if idx != self.idx + 1:
-      raise BlameSequencingError()
-
-    # Get the line and metadata for it.
-    rev = self.parser.revision_map[idx]
-    prev_rev = self.parser.prev_revision.get(rev)
-    line_number = idx + 1
-    author = self.parser.revision_author[rev]
-    thisline = self.lines[idx]
-    ### TODO:  Put a real date in here.
-    item = _item(text=thisline, line_number=line_number, rev=rev,
-                 prev_rev=prev_rev, author=author, date=None)
-    self.last = item
-    self.idx = idx
-    return item
-
-
-class BlameSequencingError(Exception):
-  pass
-
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
-
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/__init__.py b/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/__init__.py
deleted file mode 100644
index 829c117..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""This package provides parsing tools for RCS files."""
-
-from common import *
-
-try:
-  from tparse import parse
-except ImportError:
-  try:
-    from texttools import Parser
-  except ImportError:
-    from default import Parser
-
-  def parse(file, sink):
-    return Parser().parse(file, sink)
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/common.py b/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/common.py
deleted file mode 100644
index f45561c..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/common.py
+++ /dev/null
@@ -1,290 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""common.py: common classes and functions for the RCS parsing tools."""
-
-import time
-import string
-
-### compat isn't in vclib right now. need to work up a solution
-import compat
-
-
-class Sink:
-  def set_head_revision(self, revision):
-    pass
-  def set_principal_branch(self, branch_name):
-    pass
-  def define_tag(self, name, revision):
-    pass
-  def set_access(self, accessors):
-    pass
-  def set_expansion(self, mode):
-    pass
-  def set_locking(self, mode):
-    """Used to signal locking mode.
-
-    Called with mode argument 'strict' if strict locking
-    Not called when no locking used."""
-    pass
-  def set_locker(self, revision, locker):
-    pass
-  def set_comment(self, comment):
-    pass
-  def set_description(self, description):
-    pass
-  def define_revision(self, revision, timestamp, author, state,
-                      branches, next):
-    pass
-  def set_revision_info(self, revision, log, text):
-    pass
-  def admin_completed(self):
-    pass
-  def tree_completed(self):
-    pass
-  def parse_completed(self):
-    pass
-
-
-# --------------------------------------------------------------------------
-#
-# EXCEPTIONS USED BY RCSPARSE
-#
-
-class RCSParseError(Exception):
-  pass
-class RCSIllegalCharacter(RCSParseError):
-  pass
-### need more work on this one
-class RCSExpected(RCSParseError):
-  def __init__(self, got, wanted):
-    RCSParseError.__init__(self, got, wanted)
-
-class RCSStopParser(Exception):
-  pass
-
-# --------------------------------------------------------------------------
-#
-# STANDARD TOKEN STREAM-BASED PARSER
-#
-
-class _Parser:
-  stream_class = None	# subclasses need to define this
-
-  def parse_rcs_admin(self):
-    while 1:
-      # Read initial token at beginning of line
-      token = self.ts.get()
-
-      # We're done once we reach the description of the RCS tree
-      if token[0] in string.digits:
-        self.ts.unget(token)
-        return
-
-      if token == "head":
-        semi, rev = self.ts.mget(2)
-        self.sink.set_head_revision(rev)
-        if semi != ';':
-          raise RCSExpected(semi, ';')
-      elif token == "branch":
-        semi, branch = self.ts.mget(2)
-        if semi == ';':
-          self.sink.set_principal_branch(branch)
-        else:
-          if branch == ';':
-            self.ts.unget(semi);
-          else:
-            raise RCSExpected(semi, ';')
-      elif token == "symbols":
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            break
-          self.ts.match(':')
-          tag_name = tag
-          tag_rev = self.ts.get()
-          self.sink.define_tag(tag_name, tag_rev)
-      elif token == "comment":
-        semi, comment = self.ts.mget(2)
-        self.sink.set_comment(comment)
-        if semi != ';':
-          raise RCSExpected(semi, ';')
-      elif token == "expand":
-        semi, expand_mode = self.ts.mget(2)
-        self.sink.set_expansion(expand_mode)
-        if semi != ';':
-          raise RCSExpected(semi, ';')
-      elif token == "locks":
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            break
-          (locker, rev) = string.split(tag,':')
-          self.sink.set_locker(rev, locker)
-
-        tag = self.ts.get()
-        if tag == "strict":
-          self.sink.set_locking("strict")
-          self.ts.match(';')
-        else:
-          self.ts.unget(tag)
-      elif token == "access":
-        accessors = []
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            if accessors != []:
-              self.sink.set_access(accessors)
-            break
-          accessors = accessors + [ tag ]
-
-      # Chew up "newphrase"
-      else:
-        pass
-        # warn("Unexpected RCS token: $token\n")
-
-    raise RuntimeError, "Unexpected EOF"
-
-  def parse_rcs_tree(self):
-    while 1:
-      revision = self.ts.get()
-
-      # End of RCS tree description ?
-      if revision == 'desc':
-        self.ts.unget(revision)
-        return
-
-      # Parse date
-      semi, date, sym = self.ts.mget(3)
-      if sym != 'date':
-        raise RCSExpected(sym, 'date')
-      if semi != ';':
-        raise RCSExpected(semi, ';')
-
-      # Convert date into timestamp
-      date_fields = string.split(date, '.') + ['0', '0', '0']
-      date_fields = map(string.atoi, date_fields)
-      # need to make the date four digits for timegm
-      EPOCH = 1970
-      if date_fields[0] < EPOCH:
-          if date_fields[0] < 70:
-              date_fields[0] = date_fields[0] + 2000
-          else:
-              date_fields[0] = date_fields[0] + 1900
-          if date_fields[0] < EPOCH:
-              raise ValueError, 'invalid year'
-
-      timestamp = compat.timegm(tuple(date_fields))
-
-      # Parse author
-      ### NOTE: authors containing whitespace are violations of the
-      ### RCS specification.  We are making an allowance here because
-      ### CVSNT is known to produce these sorts of authors.
-      self.ts.match('author')
-      author = ''
-      while 1:
-        token = self.ts.get()
-        if token == ';':
-          break
-        author = author + token + ' '
-      author = author[:-1]	# toss the trailing space
-
-      # Parse state
-      self.ts.match('state')
-      state = ''
-      while 1:
-        token = self.ts.get()
-        if token == ';':
-          break
-        state = state + token + ' '
-      state = state[:-1]	# toss the trailing space
-
-      # Parse branches
-      self.ts.match('branches')
-      branches = [ ]
-      while 1:
-        token = self.ts.get()
-        if token == ';':
-          break
-        branches.append(token)
-
-      # Parse revision of next delta in chain
-      next, sym = self.ts.mget(2)
-      if sym != 'next':
-        raise RCSExpected(sym, 'next')
-      if next == ';':
-        next = None
-      else:
-        self.ts.match(';')
-
-      # there are some files with extra tags in them. for example:
-      #    owner	640;
-      #    group	15;
-      #    permissions	644;
-      #    hardlinks	@configure.in@;
-      # this is "newphrase" in RCSFILE(5). we just want to skip over these.
-      while 1:
-        token = self.ts.get()
-        if token == 'desc' or token[0] in string.digits:
-          self.ts.unget(token)
-          break
-        # consume everything up to the semicolon
-        while self.ts.get() != ';':
-          pass
-
-      self.sink.define_revision(revision, timestamp, author, state, branches,
-                                next)
-
-  def parse_rcs_description(self):
-    self.ts.match('desc')
-    self.sink.set_description(self.ts.get())
-
-  def parse_rcs_deltatext(self):
-    while 1:
-      revision = self.ts.get()
-      if revision is None:
-        # EOF
-        break
-      text, sym2, log, sym1 = self.ts.mget(4)
-      if sym1 != 'log':
-        print `text[:100], sym2[:100], log[:100], sym1[:100]`
-        raise RCSExpected(sym1, 'log')
-      if sym2 != 'text':
-        raise RCSExpected(sym2, 'text')
-      ### need to add code to chew up "newphrase"
-      self.sink.set_revision_info(revision, log, text)
-
-  def parse(self, file, sink):
-    self.ts = self.stream_class(file)
-    self.sink = sink
-
-    self.parse_rcs_admin()
-
-    # let sink know when the admin section has been completed
-    self.sink.admin_completed()
-
-    self.parse_rcs_tree()
-
-    # many sinks want to know when the tree has been completed so they can
-    # do some work to prep for the arrival of the deltatext
-    self.sink.tree_completed()
-
-    self.parse_rcs_description()
-    self.parse_rcs_deltatext()
-
-    # easiest for us to tell the sink it is done, rather than worry about
-    # higher level software doing it.
-    self.sink.parse_completed()
-
-    self.ts = self.sink = None
-
-# --------------------------------------------------------------------------
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/debug.py b/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/debug.py
deleted file mode 100644
index cfeaf2b..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/debug.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"""debug.py: various debugging tools for the rcsparse package."""
-
-import time
-
-from __init__ import parse
-import common
-
-
-class DebugSink(common.Sink):
-  def set_head_revision(self, revision):
-    print 'head:', revision
-
-  def set_principal_branch(self, branch_name):
-    print 'branch:', branch_name
-
-  def define_tag(self, name, revision):
-    print 'tag:', name, '=', revision
-
-  def set_comment(self, comment):
-    print 'comment:', comment
-
-  def set_description(self, description):
-    print 'description:', description
-
-  def define_revision(self, revision, timestamp, author, state,
-                      branches, next):
-    print 'revision:', revision
-    print '    timestamp:', timestamp
-    print '    author:', author
-    print '    state:', state
-    print '    branches:', branches
-    print '    next:', next
-
-  def set_revision_info(self, revision, log, text):
-    print 'revision:', revision
-    print '    log:', log
-    print '    text:', text[:100], '...'
-
-
-class DumpSink(common.Sink):
-  """Dump all the parse information directly to stdout.
-
-  The output is relatively unformatted and untagged. It is intended as a
-  raw dump of the data in the RCS file. A copy can be saved, then changes
-  made to the parsing engine, then a comparison of the new output against
-  the old output.
-  """
-  def __init__(self):
-    global sha
-    import sha
-
-  def set_head_revision(self, revision):
-    print revision
-
-  def set_principal_branch(self, branch_name):
-    print branch_name
-
-  def define_tag(self, name, revision):
-    print name, revision
-
-  def set_comment(self, comment):
-    print comment
-
-  def set_description(self, description):
-    print description
-
-  def define_revision(self, revision, timestamp, author, state,
-                      branches, next):
-    print revision, timestamp, author, state, branches, next
-
-  def set_revision_info(self, revision, log, text):
-    print revision, sha.new(log).hexdigest(), sha.new(text).hexdigest()
-
-  def tree_completed(self):
-    print 'tree_completed'
-
-  def parse_completed(self):
-    print 'parse_completed'
-
-
-def dump_file(fname):
-  parse(open(fname, 'rb'), DumpSink())
-
-def time_file(fname):
-  f = open(fname, 'rb')
-  s = common.Sink()
-  t = time.time()
-  parse(f, s)
-  t = time.time() - t
-  print t
-
-def _usage():
-  print 'This is normally a module for importing, but it has a couple'
-  print 'features for testing as an executable script.'
-  print 'USAGE: %s COMMAND filename,v' % sys.argv[0]
-  print '  where COMMAND is one of:'
-  print '    dump: filename is "dumped" to stdout'
-  print '    time: filename is parsed with the time written to stdout'
-  sys.exit(1)
-
-if __name__ == '__main__':
-  import sys
-  if len(sys.argv) != 3:
-    _usage()
-  if sys.argv[1] == 'dump':
-    dump_file(sys.argv[2])
-  elif sys.argv[1] == 'time':
-    time_file(sys.argv[2])
-  else:
-    _usage()
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/default.py b/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/default.py
deleted file mode 100644
index 7d27dd4..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/default.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# This file was originally based on portions of the blame.py script by
-# Curt Hagenlocher.
-#
-# -----------------------------------------------------------------------
-
-import string
-import common
-
-class _TokenStream:
-  token_term = string.whitespace + ';'
-
-  # the algorithm is about the same speed for any CHUNK_SIZE chosen.
-  # grab a good-sized chunk, but not too large to overwhelm memory.
-  # note: we use a multiple of a standard block size
-  CHUNK_SIZE  = 192 * 512  # about 100k
-
-#  CHUNK_SIZE  = 5	# for debugging, make the function grind...
-
-  def __init__(self, file):
-    self.rcsfile = file
-    self.idx = 0
-    self.buf = self.rcsfile.read(self.CHUNK_SIZE)
-    if self.buf == '':
-      raise RuntimeError, 'EOF'
-
-  def get(self):
-    "Get the next token from the RCS file."
-
-    # Note: we can afford to loop within Python, examining individual
-    # characters. For the whitespace and tokens, the number of iterations
-    # is typically quite small. Thus, a simple iterative loop will beat
-    # out more complex solutions.
-
-    buf = self.buf
-    idx = self.idx
-
-    while 1:
-      if idx == len(buf):
-        buf = self.rcsfile.read(self.CHUNK_SIZE)
-        if buf == '':
-          # signal EOF by returning None as the token
-          del self.buf	# so we fail if get() is called again
-          return None
-        idx = 0
-
-      if buf[idx] not in string.whitespace:
-        break
-
-      idx = idx + 1
-
-    if buf[idx] == ';':
-      self.buf = buf
-      self.idx = idx + 1
-      return ';'
-
-    if buf[idx] != '@':
-      end = idx + 1
-      token = ''
-      while 1:
-        # find token characters in the current buffer
-        while end < len(buf) and buf[end] not in self.token_term:
-          end = end + 1
-        token = token + buf[idx:end]
-
-        if end < len(buf):
-          # we stopped before the end, so we have a full token
-          idx = end
-          break
-
-        # we stopped at the end of the buffer, so we may have a partial token
-        buf = self.rcsfile.read(self.CHUNK_SIZE)
-        idx = end = 0
-
-      self.buf = buf
-      self.idx = idx
-      return token
-
-    # a "string" which starts with the "@" character. we'll skip it when we
-    # search for content.
-    idx = idx + 1
-
-    chunks = [ ]
-
-    while 1:
-      if idx == len(buf):
-        idx = 0
-        buf = self.rcsfile.read(self.CHUNK_SIZE)
-        if buf == '':
-          raise RuntimeError, 'EOF'
-      i = string.find(buf, '@', idx)
-      if i == -1:
-        chunks.append(buf[idx:])
-        idx = len(buf)
-        continue
-      if i == len(buf) - 1:
-        chunks.append(buf[idx:i])
-        idx = 0
-        buf = '@' + self.rcsfile.read(self.CHUNK_SIZE)
-        if buf == '@':
-          raise RuntimeError, 'EOF'
-        continue
-      if buf[i + 1] == '@':
-        chunks.append(buf[idx:i+1])
-        idx = i + 2
-        continue
-
-      chunks.append(buf[idx:i])
-
-      self.buf = buf
-      self.idx = i + 1
-
-      return string.join(chunks, '')
-
-#  _get = get
-#  def get(self):
-    token = self._get()
-    print 'T:', `token`
-    return token
-
-  def match(self, match):
-    "Try to match the next token from the input buffer."
-
-    token = self.get()
-    if token != match:
-      raise RuntimeError, ('Unexpected parsing error in RCS file.\n' +
-                           'Expected token: %s, but saw: %s' % (match, token))
-
-  def unget(self, token):
-    "Put this token back, for the next get() to return."
-
-    # Override the class' .get method with a function which clears the
-    # overridden method then returns the pushed token. Since this function
-    # will not be looked up via the class mechanism, it should be a "normal"
-    # function, meaning it won't have "self" automatically inserted.
-    # Therefore, we need to pass both self and the token thru via defaults.
-
-    # note: we don't put this into the input buffer because it may have been
-    # @-unescaped already.
-
-    def give_it_back(self=self, token=token):
-      del self.get
-      return token
-
-    self.get = give_it_back
-
-  def mget(self, count):
-    "Return multiple tokens. 'next' is at the end."
-    result = [ ]
-    for i in range(count):
-      result.append(self.get())
-    result.reverse()
-    return result
-
-
-class Parser(common._Parser):
-  stream_class = _TokenStream
-
-  def parse_rcs_admin(self):
-    while 1:
-      # Read initial token at beginning of line
-      token = self.ts.get()
-
-      # We're done once we reach the description of the RCS tree
-      if token[0] in string.digits:
-        self.ts.unget(token)
-        return
-
-      if token == "head":
-        semi, rev = self.ts.mget(2)
-        self.sink.set_head_revision(rev)
-        if semi != ';':
-          raise common.RCSExpected(semi, ';')
-      elif token == "branch":
-        semi, branch = self.ts.mget(2)
-        if semi == ';':
-          self.sink.set_principal_branch(branch)
-        else:
-          if branch == ';':
-            self.ts.unget(semi);
-          else:
-            raise common.RCSExpected(semi, ';')
-      elif token == "symbols":
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            break
-          (tag_name, tag_rev) = string.split(tag, ':')
-          self.sink.define_tag(tag_name, tag_rev)
-      elif token == "comment":
-        semi, comment = self.ts.mget(2)
-        self.sink.set_comment(comment)
-        if semi != ';':
-          raise common.RCSExpected(semi, ';')
-      elif token == "expand":
-        semi, expand_mode = self.ts.mget(2)
-        self.sink.set_expansion(expand_mode)
-        if semi != ';':
-          raise RCSExpected(semi, ';')
-      elif token == "locks":
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            break
-          (locker, rev) = string.split(tag,':')
-          self.sink.set_locker(rev, locker)
-
-        tag = self.ts.get()
-        if tag == "strict":
-          self.sink.set_locking("strict")
-          self.ts.match(';')
-        else:
-          self.ts.unget(tag)
-      elif token == "access":
-        accessors = []
-        while 1:
-          tag = self.ts.get()
-          if tag == ';':
-            if accessors != []:
-              self.sink.set_access(accessors)
-            break
-          accessors = accessors + [ tag ]
-
-      # Chew up "newphrase".
-      else:
-        pass
-        # warn("Unexpected RCS token: $token\n")
-
-    raise RuntimeError, "Unexpected EOF"
diff --git a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/texttools.py b/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/texttools.py
deleted file mode 100644
index 5ecda35..0000000
--- a/src/www/scm/viewvc/lib/vclib/ccvs/rcsparse/texttools.py
+++ /dev/null
@@ -1,309 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-import string
-
-# note: this will raise an ImportError if it isn't available. the rcsparse
-# package will recognize this and switch over to the default parser.
-from mx import TextTools
-
-import common
-
-
-# for convenience
-_tt = TextTools
-
-_idchar_list = map(chr, range(33, 127)) + map(chr, range(160, 256))
-_idchar_list.remove('$')
-_idchar_list.remove(',')
-#_idchar_list.remove('.')	leave as part of 'num' symbol
-_idchar_list.remove(':')
-_idchar_list.remove(';')
-_idchar_list.remove('@')
-_idchar = string.join(_idchar_list, '')
-_idchar_set = _tt.set(_idchar)
-
-_onechar_token_set = _tt.set(':;')
-
-_not_at_set = _tt.invset('@')
-
-_T_TOKEN = 30
-_T_STRING_START = 40
-_T_STRING_SPAN = 60
-_T_STRING_END = 70
-
-_E_COMPLETE = 100	# ended on a complete token
-_E_TOKEN = 110	# ended mid-token
-_E_STRING_SPAN = 130	# ended within a string
-_E_STRING_END = 140	# ended with string-end ('@') (could be mid-@@)
-
-_SUCCESS = +100
-
-_EOF = 'EOF'
-_CONTINUE = 'CONTINUE'
-_UNUSED = 'UNUSED'
-
-
-# continuation of a token over a chunk boundary
-_c_token_table = (
-  (_T_TOKEN,      _tt.AllInSet, _idchar_set),
-  )
-
-class _mxTokenStream:
-
-  # the algorithm is about the same speed for any CHUNK_SIZE chosen.
-  # grab a good-sized chunk, but not too large to overwhelm memory.
-  # note: we use a multiple of a standard block size
-  CHUNK_SIZE  = 192 * 512  # about 100k
-
-#  CHUNK_SIZE  = 5	# for debugging, make the function grind...
-
-  def __init__(self, file):
-    self.rcsfile = file
-    self.tokens = [ ]
-    self.partial = None
-
-    self.string_end = None
-
-  def _parse_chunk(self, buf, start=0):
-    "Get the next token from the RCS file."
-
-    buflen = len(buf)
-
-    assert start < buflen
-
-    # construct a tag table which refers to the buffer we need to parse.
-    table = (
-      # ignore whitespace. with or without whitespace, move to the next rule.
-      (None, _tt.AllInSet, _tt.whitespace_set, +1),
-
-      (_E_COMPLETE, _tt.EOF + _tt.AppendTagobj, _tt.Here, +1, _SUCCESS),
-
-      # accumulate token text and exit, or move to the next rule.
-      (_UNUSED,      _tt.AllInSet + _tt.AppendMatch, _idchar_set, +2),
-
-      (_E_TOKEN,  _tt.EOF + _tt.AppendTagobj, _tt.Here, -3, _SUCCESS),
-
-      # single character tokens exit immediately, or move to the next rule
-      (_UNUSED,    _tt.IsInSet + _tt.AppendMatch, _onechar_token_set, +2),
-
-      (_E_COMPLETE, _tt.EOF + _tt.AppendTagobj, _tt.Here, -5, _SUCCESS),
-
-      # if this isn't an '@' symbol, then we have a syntax error (go to a
-      # negative index to indicate that condition). otherwise, suck it up
-      # and move to the next rule.
-      (_T_STRING_START, _tt.Is + _tt.AppendTagobj, '@'),
-
-      (None, _tt.Is, '@', +4, +1),
-      (buf, _tt.Is, '@', +1, -1),
-      (_T_STRING_END, _tt.Skip + _tt.AppendTagobj, 0, 0, +1),
-      (_E_STRING_END, _tt.EOF + _tt.AppendTagobj, _tt.Here, -10, _SUCCESS),
-
-      (_E_STRING_SPAN, _tt.EOF + _tt.AppendTagobj, _tt.Here, +1, _SUCCESS),
-
-      # suck up everything that isn't an AT. go to next rule to look for EOF
-      (buf,  _tt.AllInSet, _not_at_set, 0, +1),
-
-      # go back to look for double AT if we aren't at the end of the string
-      (_E_STRING_SPAN,   _tt.EOF + _tt.AppendTagobj, _tt.Here, -6, _SUCCESS),
-      )
-
-    success, taglist, idx = _tt.tag(buf, table, start)
-
-    if not success:
-      ### need a better way to report this error
-      raise common.RCSIllegalCharacter()
-    assert idx == buflen
-
-    # pop off the last item
-    last_which = taglist.pop()
-
-    i = 0
-    tlen = len(taglist)
-    while i < tlen:
-      if taglist[i] == _T_STRING_START:
-        j = i + 1
-        while j < tlen:
-          if taglist[j] == _T_STRING_END:
-            s = _tt.join(taglist, '', i+1, j)
-            del taglist[i:j]
-            tlen = len(taglist)
-            taglist[i] = s
-            break
-          j = j + 1
-        else:
-          assert last_which == _E_STRING_SPAN
-          s = _tt.join(taglist, '', i+1)
-          del taglist[i:]
-          self.partial = (_T_STRING_SPAN, [ s ])
-          break
-      i = i + 1
-
-    # figure out whether we have a partial last-token
-    if last_which == _E_TOKEN:
-      self.partial = (_T_TOKEN, [ taglist.pop() ])
-    elif last_which == _E_COMPLETE:
-      pass
-    elif last_which == _E_STRING_SPAN:
-      assert self.partial
-    else:
-      assert last_which == _E_STRING_END
-      self.partial = (_T_STRING_END, [ taglist.pop() ])
-
-    taglist.reverse()
-    taglist.extend(self.tokens)
-    self.tokens = taglist
-
-  def _set_end(self, taglist, text, l, r, subtags):
-    self.string_end = l
-
-  def _handle_partial(self, buf):
-    which, chunks = self.partial
-    if which == _T_TOKEN:
-      success, taglist, idx = _tt.tag(buf, _c_token_table)
-      if not success:
-        # The start of this buffer was not a token. So the end of the
-        # prior buffer was a complete token.
-        self.tokens.insert(0, string.join(chunks, ''))
-      else:
-        assert len(taglist) == 1 and taglist[0][0] == _T_TOKEN \
-               and taglist[0][1] == 0 and taglist[0][2] == idx
-        if idx == len(buf):
-          #
-          # The whole buffer was one huge token, so we may have a
-          # partial token again.
-          #
-          # Note: this modifies the list of chunks in self.partial
-          #
-          chunks.append(buf)
-
-          # consumed the whole buffer
-          return len(buf)
-
-        # got the rest of the token.
-        chunks.append(buf[:idx])
-        self.tokens.insert(0, string.join(chunks, ''))
-
-      # no more partial token
-      self.partial = None
-
-      return idx
-
-    if which == _T_STRING_END:
-      if buf[0] != '@':
-        self.tokens.insert(0, string.join(chunks, ''))
-        return 0
-      chunks.append('@')
-      start = 1
-    else:
-      start = 0
-
-    self.string_end = None
-    string_table = (
-      (None,    _tt.Is, '@', +3, +1),
-      (_UNUSED, _tt.Is + _tt.AppendMatch, '@', +1, -1),
-      (self._set_end, _tt.Skip + _tt.CallTag, 0, 0, _SUCCESS),
-
-      (None,    _tt.EOF, _tt.Here, +1, _SUCCESS),
-
-      # suck up everything that isn't an AT. move to next rule to look
-      # for EOF
-      (_UNUSED, _tt.AllInSet + _tt.AppendMatch, _not_at_set, 0, +1),
-
-      # go back to look for double AT if we aren't at the end of the string
-      (None,    _tt.EOF, _tt.Here, -5, _SUCCESS),
-      )
-
-    success, unused, idx = _tt.tag(buf, string_table,
-                                   start, len(buf), chunks)
-
-    # must have matched at least one item
-    assert success
-
-    if self.string_end is None:
-      assert idx == len(buf)
-      self.partial = (_T_STRING_SPAN, chunks)
-    elif self.string_end < len(buf):
-      self.partial = None
-      self.tokens.insert(0, string.join(chunks, ''))
-    else:
-      self.partial = (_T_STRING_END, chunks)
-
-    return idx
-
-  def _parse_more(self):
-    buf = self.rcsfile.read(self.CHUNK_SIZE)
-    if not buf:
-      return _EOF
-
-    if self.partial:
-      idx = self._handle_partial(buf)
-      if idx is None:
-        return _CONTINUE
-      if idx < len(buf):
-        self._parse_chunk(buf, idx)
-    else:
-      self._parse_chunk(buf)
-
-    return _CONTINUE
-
-  def get(self):
-    try:
-      return self.tokens.pop()
-    except IndexError:
-      pass
-
-    while not self.tokens:
-      action = self._parse_more()
-      if action == _EOF:
-        return None
-
-    return self.tokens.pop()
-
-
-#  _get = get
-#  def get(self):
-    token = self._get()
-    print 'T:', `token`
-    return token
-
-  def match(self, match):
-    if self.tokens:
-      token = self.tokens.pop()
-      if token != match:
-        raise RuntimeError, ('Unexpected parsing error in RCS file.\n'
-                             'Expected token: %s, but saw: %s'
-                             % (match, token))
-    else:
-      token = self.get()
-      if token != match:
-        raise RuntimeError, ('Unexpected parsing error in RCS file.\n'
-                             'Expected token: %s, but saw: %s'
-                             % (match, token))
-
-  def unget(self, token):
-    self.tokens.append(token)
-
-  def mget(self, count):
-    "Return multiple tokens. 'next' is at the end."
-    while len(self.tokens) < count:
-      action = self._parse_more()
-      if action == _EOF:
-        ### fix this
-        raise RuntimeError, 'EOF hit while expecting tokens'
-    result = self.tokens[-count:]
-    del self.tokens[-count:]
-    return result
-
-
-class Parser(common._Parser):
-  stream_class = _mxTokenStream
diff --git a/src/www/scm/viewvc/lib/vclib/svn/__init__.py b/src/www/scm/viewvc/lib/vclib/svn/__init__.py
deleted file mode 100644
index 4385168..0000000
--- a/src/www/scm/viewvc/lib/vclib/svn/__init__.py
+++ /dev/null
@@ -1,704 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"Version Control lib driver for locally accessible Subversion repositories"
-
-import vclib
-import os
-import os.path
-import string
-import cStringIO
-import signal
-import time
-import tempfile
-import popen
-import re
-from svn import fs, repos, core, delta
-
-
-### Require Subversion 1.2.0 or better.
-if (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_PATCH) < (1, 2, 0):
-  raise Exception, "Version requirement not met (needs 1.2.0 or better)"
-
-  
-def _allow_all(root, path, pool):
-  """Generic authz_read_func that permits access to all paths"""
-  return 1
-
-
-def _fs_path_join(base, relative):
-  # Subversion filesystem paths are '/'-delimited, regardless of OS.
-  joined_path = base + '/' + relative
-  parts = filter(None, string.split(joined_path, '/'))
-  return string.join(parts, '/')
-
-
-def _cleanup_path(path):
-  """Return a cleaned-up Subversion filesystem path"""
-  return string.join(filter(None, string.split(path, '/')), '/')
-  
-
-def _compare_paths(path1, path2):
-  path1_len = len (path1);
-  path2_len = len (path2);
-  min_len = min(path1_len, path2_len)
-  i = 0
-
-  # Are the paths exactly the same?
-  if path1 == path2:
-    return 0
-  
-  # Skip past common prefix
-  while (i < min_len) and (path1[i] == path2[i]):
-    i = i + 1
-
-  # Children of paths are greater than their parents, but less than
-  # greater siblings of their parents
-  char1 = '\0'
-  char2 = '\0'
-  if (i < path1_len):
-    char1 = path1[i]
-  if (i < path2_len):
-    char2 = path2[i]
-    
-  if (char1 == '/') and (i == path2_len):
-    return 1
-  if (char2 == '/') and (i == path1_len):
-    return -1
-  if (i < path1_len) and (char1 == '/'):
-    return -1
-  if (i < path2_len) and (char2 == '/'):
-    return 1
-
-  # Common prefix was skipped above, next character is compared to
-  # determine order
-  return cmp(char1, char2)
-
-
-def _datestr_to_date(datestr, pool):
-  if datestr is None:
-    return None
-  return core.svn_time_from_cstring(datestr, pool) / 1000000
-
-  
-def _fs_rev_props(fsptr, rev, pool):
-  author = fs.revision_prop(fsptr, rev, core.SVN_PROP_REVISION_AUTHOR, pool)
-  msg = fs.revision_prop(fsptr, rev, core.SVN_PROP_REVISION_LOG, pool)
-  date = fs.revision_prop(fsptr, rev, core.SVN_PROP_REVISION_DATE, pool)
-  return date, author, msg
-
-
-def date_from_rev(svnrepos, rev):
-  if (rev < 0) or (rev > svnrepos.youngest):
-    raise vclib.InvalidRevision(rev)
-  datestr = fs.revision_prop(svnrepos.fs_ptr, rev,
-                             core.SVN_PROP_REVISION_DATE, svnrepos.pool)
-  return _datestr_to_date(datestr, svnrepos.pool)
-
-
-def get_location(svnrepos, path, rev, old_rev):
-  try:
-    results = repos.svn_repos_trace_node_locations(svnrepos.fs_ptr, path,
-                                                   rev, [old_rev],
-                                                   _allow_all, svnrepos.pool)
-  except core.SubversionException, e:
-    if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
-      raise vclib.ItemNotFound(path)
-    raise
-
-  try:
-    old_path = results[old_rev]
-  except KeyError:
-    raise vclib.ItemNotFound(path)
-
-  return _cleanup_path(old_path)
-
-
-def last_rev(svnrepos, path, peg_revision, limit_revision=None):
-  """Given PATH, known to exist in PEG_REVISION, find the youngest
-  revision older than, or equal to, LIMIT_REVISION in which path
-  exists.  Return that revision, and the path at which PATH exists in
-  that revision."""
-  
-  # Here's the plan, man.  In the trivial case (where PEG_REVISION is
-  # the same as LIMIT_REVISION), this is a no-brainer.  If
-  # LIMIT_REVISION is older than PEG_REVISION, we can use Subversion's
-  # history tracing code to find the right location.  If, however,
-  # LIMIT_REVISION is younger than PEG_REVISION, we suffer from
-  # Subversion's lack of forward history searching.  Our workaround,
-  # ugly as it may be, involves a binary search through the revisions
-  # between PEG_REVISION and LIMIT_REVISION to find our last live
-  # revision.
-  peg_revision = svnrepos._getrev(peg_revision)
-  limit_revision = svnrepos._getrev(limit_revision)
-  try:
-    if peg_revision == limit_revision:
-      return peg_revision, path
-    elif peg_revision > limit_revision:
-      fsroot = svnrepos._getroot(peg_revision)
-      history = fs.node_history(fsroot, path, svnrepos.scratch_pool)
-      while history:
-        path, peg_revision = fs.history_location(history,
-                                                 svnrepos.scratch_pool);
-        if peg_revision <= limit_revision:
-          return max(peg_revision, limit_revision), _cleanup_path(path)
-        history = fs.history_prev(history, 1, svnrepos.scratch_pool)
-      return peg_revision, _cleanup_path(path)
-    else:
-      ### Warning: this is *not* an example of good pool usage.
-      orig_id = fs.node_id(svnrepos._getroot(peg_revision), path,
-                           svnrepos.scratch_pool)
-      while peg_revision != limit_revision:
-        mid = (peg_revision + 1 + limit_revision) / 2
-        try:
-          mid_id = fs.node_id(svnrepos._getroot(mid), path,
-                              svnrepos.scratch_pool)
-        except core.SubversionException, e:
-          if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
-            cmp = -1
-          else:
-            raise
-        else:
-          ### Not quite right.  Need a comparison function that only returns
-          ### true when the two nodes are the same copy, not just related.
-          cmp = fs.compare_ids(orig_id, mid_id)
-
-        if cmp in (0, 1):
-          peg_revision = mid
-        else:
-          limit_revision = mid - 1
-
-      return peg_revision, path
-  finally:
-    svnrepos._scratch_clear()
-
-
-def created_rev(svnrepos, full_name, rev):
-  fsroot = svnrepos._getroot(rev)
-  return fs.node_created_rev(fsroot, full_name, svnrepos.pool)
-
-
-class Revision(vclib.Revision):
-  "Hold state for each revision's log entry."
-  def __init__(self, rev, date, author, msg, size,
-               filename, copy_path, copy_rev):
-    vclib.Revision.__init__(self, rev, str(rev), date, author, None, msg, size)
-    self.filename = filename
-    self.copy_path = copy_path
-    self.copy_rev = copy_rev
-
-
-class NodeHistory:
-  def __init__(self, fs_ptr, show_all_logs):
-    self.histories = {}
-    self.fs_ptr = fs_ptr
-    self.show_all_logs = show_all_logs
-    
-  def add_history(self, path, revision, pool):
-    # If filtering, only add the path and revision to the histories
-    # list if they were actually changed in this revision (where
-    # change means the path itself was changed, or one of its parents
-    # was copied).  This is useful for omitting bubble-up directory
-    # changes.
-    if not self.show_all_logs:
-      rev_root = fs.revision_root(self.fs_ptr, revision, pool)
-      changed_paths = fs.paths_changed(rev_root, pool)
-      paths = changed_paths.keys()
-      if path not in paths:
-        # Look for a copied parent
-        test_path = path
-        found = 0
-        subpool = core.svn_pool_create(pool)
-        while 1:
-          core.svn_pool_clear(subpool)
-          off = string.rfind(test_path, '/')
-          if off < 0:
-            break
-          test_path = test_path[0:off]
-          if test_path in paths:
-            copyfrom_rev, copyfrom_path = \
-                          fs.copied_from(rev_root, test_path, subpool)
-            if copyfrom_rev >= 0 and copyfrom_path:
-              found = 1
-              break
-        core.svn_pool_destroy(subpool)
-        if not found:
-          return
-    self.histories[revision] = _cleanup_path(path)
-    
-  
-def _get_history(svnrepos, full_name, rev, options={}):
-  fsroot = svnrepos._getroot(rev)
-  show_all_logs = options.get('svn_show_all_dir_logs', 0)
-  if not show_all_logs:
-    # See if the path is a file or directory.
-    kind = fs.check_path(fsroot, full_name, svnrepos.pool)
-    if kind is core.svn_node_file:
-      show_all_logs = 1
-      
-  # Instantiate a NodeHistory collector object.
-  history = NodeHistory(svnrepos.fs_ptr, show_all_logs)
-
-  # Do we want to cross copy history?
-  cross_copies = options.get('svn_cross_copies', 0)
-
-  # Get the history items for PATH.
-  repos.svn_repos_history(svnrepos.fs_ptr, full_name, history.add_history,
-                          1, rev, cross_copies, svnrepos.pool)
-  return history.histories
-
-
-class ChangedPath:
-  def __init__(self, filename, pathtype, prop_mods, text_mods,
-               base_path, base_rev, action, is_copy):
-    self.filename = filename
-    self.pathtype = pathtype
-    self.prop_mods = prop_mods
-    self.text_mods = text_mods
-    self.base_path = base_path
-    self.base_rev = base_rev
-    self.action = action
-    self.is_copy = is_copy
-
-
-class ChangedPathSet:
-  def __init__(self):
-    self.changes = { }
-
-  def add_change(self, change):
-    if change.path:
-      change.path = _cleanup_path(change.path)
-    if change.base_path:
-      change.base_path = _cleanup_path(change.base_path)
-    path = change.path
-    action = 'modified'
-    is_copy = 0
-    if not change.path:
-      action = 'deleted'
-      path = change.base_path
-    elif change.added:
-      action = 'added'
-      replace_check_path = path
-      if change.base_path and change.base_rev:
-        is_copy = 1
-        replace_check_path = change.base_path
-      if self.changes.has_key(replace_check_path) \
-             and self.changes[replace_check_path].action == 'deleted':
-        action = 'replaced'
-    if change.item_kind == core.svn_node_dir:
-      pathtype = vclib.DIR
-    elif change.item_kind == core.svn_node_file:
-      pathtype = vclib.FILE
-    else:
-      pathtype = None
-    self.changes[path] = ChangedPath(path, pathtype, change.prop_changes,
-                                     change.text_changed, change.base_path,
-                                     change.base_rev, action, is_copy)
-
-  def get_changes(self):
-    changes = self.changes.values()
-    changes.sort(lambda a, b: _compare_paths(a.filename, b.filename))
-    return changes
-    
-  
-def get_revision_info(svnrepos, rev):
-  fsroot = svnrepos._getroot(rev)
-
-  # Get the changes for the revision
-  cps = ChangedPathSet()
-  editor = repos.ChangeCollector(svnrepos.fs_ptr, fsroot,
-                                 svnrepos.pool, cps.add_change)
-  e_ptr, e_baton = delta.make_editor(editor, svnrepos.pool)
-  repos.svn_repos_replay(fsroot, e_ptr, e_baton, svnrepos.pool)
-
-  # Now get the revision property info.  Would use
-  # editor.get_root_props(), but something is broken there...
-  datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, svnrepos.pool)
-  date = _datestr_to_date(datestr, svnrepos.pool)
-
-  return date, author, msg, cps.get_changes()
-
-
-def _log_helper(svnrepos, rev, path, pool):
-  rev_root = fs.revision_root(svnrepos.fs_ptr, rev, pool)
-
-  # Was this path at rev the target of a copy?
-  copyfrom_rev, copyfrom_path = fs.copied_from(rev_root, path, pool)
-
-  # Assemble our LogEntry
-  datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, pool)
-  date = _datestr_to_date(datestr, pool)
-  if fs.is_file(rev_root, path, pool):
-    size = fs.file_length(rev_root, path, pool)
-  else:
-    size = None
-  entry = Revision(rev, date, author, msg, size, path,
-                   copyfrom_path and _cleanup_path(copyfrom_path),
-                   copyfrom_rev)
-  return entry
-  
-
-def _fetch_log(svnrepos, full_name, which_rev, options, pool):
-  revs = []
-
-  if options.get('svn_latest_log', 0):
-    rev = _log_helper(svnrepos, which_rev, full_name, pool)
-    if rev:
-      revs.append(rev)
-  else:
-    history_set = _get_history(svnrepos, full_name, which_rev, options)
-    history_revs = history_set.keys()
-    history_revs.sort()
-    history_revs.reverse()
-    subpool = core.svn_pool_create(pool)
-    for history_rev in history_revs:
-      core.svn_pool_clear(subpool)
-      rev = _log_helper(svnrepos, history_rev, history_set[history_rev],
-                        subpool)
-      if rev:
-        revs.append(rev)
-    core.svn_pool_destroy(subpool)
-  return revs
-
-
-def _get_last_history_rev(fsroot, path, pool):
-  history = fs.node_history(fsroot, path, pool)
-  history = fs.history_prev(history, 0, pool)
-  history_path, history_rev = fs.history_location(history, pool);
-  return history_rev
-  
-  
-def get_logs(svnrepos, full_name, rev, files):
-  fsroot = svnrepos._getroot(rev)
-  subpool = core.svn_pool_create(svnrepos.pool)
-  for file in files:
-    core.svn_pool_clear(subpool)
-    path = _fs_path_join(full_name, file.name)
-    rev = _get_last_history_rev(fsroot, path, subpool)
-    datestr, author, msg = _fs_rev_props(svnrepos.fs_ptr, rev, subpool)
-    date = _datestr_to_date(datestr, subpool)
-    file.rev = str(rev)
-    file.date = date
-    file.author = author
-    file.log = msg
-    if file.kind == vclib.FILE:
-      file.size = fs.file_length(fsroot, path, subpool)
-  core.svn_pool_destroy(subpool)
-
-
-def get_youngest_revision(svnrepos):
-  return svnrepos.youngest
-
-def temp_checkout(svnrepos, path, rev, pool):
-  """Check out file revision to temporary file"""
-  temp = tempfile.mktemp()
-  fp = open(temp, 'wb')
-  try:
-    root = svnrepos._getroot(rev)
-    stream = fs.file_contents(root, path, pool)
-    try:
-      while 1:
-        chunk = core.svn_stream_read(stream, int(core.SVN_STREAM_CHUNK_SIZE))
-        if not chunk:
-          break
-        fp.write(chunk)
-    finally:
-      core.svn_stream_close(stream)
-  finally:
-    fp.close()
-  return temp
-
-class FileContentsPipe:
-  def __init__(self, root, path, pool):
-    self._pool = core.svn_pool_create(pool)
-    self._stream = fs.file_contents(root, path, self._pool)
-    self._eof = 0
-
-  def __del__(self):
-    core.svn_pool_destroy(self._pool)
-    
-  def read(self, len=None):
-    chunk = None
-    if not self._eof:
-      if len is None:
-        buffer = cStringIO.StringIO()
-        try:
-          while 1:
-            hunk = core.svn_stream_read(self._stream, 8192)
-            if not hunk:
-              break
-            buffer.write(hunk)
-          chunk = buffer.getvalue()
-        finally:
-          buffer.close()
-
-      else:
-        chunk = core.svn_stream_read(self._stream, len)   
-    if not chunk:
-      self._eof = 1
-    return chunk
-  
-  def readline(self):
-    chunk = None
-    if not self._eof:
-      chunk, self._eof = core.svn_stream_readline(self._stream, '\n',
-                                                  self._pool)
-      if not self._eof:
-        chunk = chunk + '\n'
-    if not chunk:
-      self._eof = 1
-    return chunk
-
-  def readlines(self):
-    lines = []
-    while True:
-      line = self.readline()
-      if not line:
-        break
-      lines.append(line)
-    return lines
-
-  def close(self):
-    return core.svn_stream_close(self._stream)
-
-  def eof(self):
-    return self._eof
-
-
-_re_blameinfo = re.compile(r"\s*(\d+)\s*(.*)")
-
-class BlameSource:
-  def __init__(self, svn_client_path, rootpath, fs_path, rev, first_rev):
-    self.idx = -1
-    self.line_number = 1
-    self.last = None
-    self.first_rev = first_rev
-    
-    rootpath = os.path.abspath(rootpath)
-    url = 'file://' + string.join([rootpath, fs_path], "/")
-    fp = popen.popen(svn_client_path,
-                     ('blame', "-r%d" % int(rev), "%s@%d" % (url, int(rev))),
-                     'rb', 1)
-    self.fp = fp
-    
-  def __getitem__(self, idx):
-    if idx == self.idx:
-      return self.last
-    if idx != self.idx + 1:
-      raise BlameSequencingError()
-    line = self.fp.readline()
-    if not line:
-      raise IndexError("No more annotations")
-    m = _re_blameinfo.match(line[:17])
-    if not m:
-      raise vclib.Error("Could not parse blame output at line %i\n%s"
-                        % (idx+1, line))
-    rev, author = m.groups()
-    text = line[18:]
-    rev = int(rev)
-    prev_rev = None
-    if rev > self.first_rev:
-      prev_rev = rev - 1
-    item = _item(text=text, line_number=idx+1, rev=rev,
-                 prev_rev=prev_rev, author=author, date=None)
-    self.last = item
-    self.idx = idx
-    return item
-
-
-class BlameSequencingError(Exception):
-  pass
-
-  
-class SubversionRepository(vclib.Repository):
-  def __init__(self, name, rootpath, svn_path):
-    if not os.path.isdir(rootpath):
-      raise vclib.ReposNotFound(name)
-
-    # Initialize some stuff.
-    self.pool = None
-    self.apr_init = 0
-    self.rootpath = rootpath
-    self.name = name
-    self.svn_client_path = os.path.normpath(os.path.join(svn_path, 'svn'))
-
-    # Register a handler for SIGTERM so we can have a chance to
-    # cleanup.  If ViewVC takes too long to start generating CGI
-    # output, Apache will grow impatient and SIGTERM it.  While we
-    # don't mind getting told to bail, we want to gracefully close the
-    # repository before we bail.
-    def _sigterm_handler(signum, frame, self=self):
-      self._close()
-      sys.exit(-1)
-    try:
-      signal.signal(signal.SIGTERM, _sigterm_handler)
-    except ValueError:
-      # This is probably "ValueError: signal only works in main
-      # thread", which will get thrown by the likes of mod_python
-      # when trying to install a signal handler from a thread that
-      # isn't the main one.  We'll just not care.
-      pass
-
-    # Initialize APR and get our top-level pool.
-    core.apr_initialize()
-    self.apr_init = 1
-    self.pool = core.svn_pool_create(None)
-    self.scratch_pool = core.svn_pool_create(self.pool)
-    
-    # Open the repository and init some other variables.
-    self.repos = repos.svn_repos_open(rootpath, self.pool)
-    self.fs_ptr = repos.svn_repos_fs(self.repos)
-    self.youngest = fs.youngest_rev(self.fs_ptr, self.pool)
-    self._fsroots = {}
-
-  def __del__(self):
-    self._close()
-    
-  def _close(self):
-    if self.pool:
-      core.svn_pool_destroy(self.pool)
-      self.pool = None
-    if self.apr_init:
-      core.apr_terminate()
-      self.apr_init = 0
-
-  def _scratch_clear(self):
-    core.svn_pool_clear(self.scratch_pool)
-
-  def itemtype(self, path_parts, rev):
-    rev = self._getrev(rev)
-    basepath = self._getpath(path_parts)
-    kind = fs.check_path(self._getroot(rev), basepath, self.scratch_pool)
-    self._scratch_clear()
-    if kind == core.svn_node_dir:
-      return vclib.DIR
-    if kind == core.svn_node_file:
-      return vclib.FILE
-    raise vclib.ItemNotFound(path_parts)
-
-  def openfile(self, path_parts, rev):
-    path = self._getpath(path_parts)
-    rev = self._getrev(rev)
-    fsroot = self._getroot(rev)
-    revision = str(_get_last_history_rev(fsroot, path, self.scratch_pool))
-    self._scratch_clear()
-    fp = FileContentsPipe(fsroot, path, self.pool)
-    return fp, revision
-
-  def listdir(self, path_parts, rev, options):
-    basepath = self._getpath(path_parts)
-    if self.itemtype(path_parts, rev) != vclib.DIR:
-      raise vclib.Error("Path '%s' is not a directory." % basepath)
-
-    rev = self._getrev(rev)
-    fsroot = self._getroot(rev)
-    dirents = fs.dir_entries(fsroot, basepath, self.scratch_pool)
-    entries = [ ]
-    for entry in dirents.values():
-      if entry.kind == core.svn_node_dir:
-        kind = vclib.DIR
-      elif entry.kind == core.svn_node_file:
-        kind = vclib.FILE              
-      entries.append(vclib.DirEntry(entry.name, kind))
-    self._scratch_clear()
-    return entries
-
-  def dirlogs(self, path_parts, rev, entries, options):
-    get_logs(self, self._getpath(path_parts), self._getrev(rev), entries)
-
-  def itemlog(self, path_parts, rev, options):
-    """see vclib.Repository.itemlog docstring
-
-    Option values recognized by this implementation
-
-      svn_show_all_dir_logs
-        boolean, default false. if set for a directory path, will include
-        revisions where files underneath the directory have changed
-
-      svn_cross_copies
-        boolean, default false. if set for a path created by a copy, will
-        include revisions from before the copy
-
-      svn_latest_log
-        boolean, default false. if set will return only newest single log
-        entry
-    """
-    path = self._getpath(path_parts)
-    rev = self._getrev(rev)
-
-    revs = _fetch_log(self, path, rev, options, self.scratch_pool)
-    self._scratch_clear()
-    
-    revs.sort()
-    prev = None
-    for rev in revs:
-      rev.prev = prev
-      prev = rev
-
-    return revs
-
-  def annotate(self, path_parts, rev):
-    path = self._getpath(path_parts)
-    rev = self._getrev(rev)
-    fsroot = self._getroot(rev)
-
-    history_set = _get_history(self, path, rev, {'svn_cross_copies': 1})
-    history_revs = history_set.keys()
-    history_revs.sort()
-    revision = history_revs[-1]
-    first_rev = history_revs[0]
-    source = BlameSource(self.svn_client_path, self.rootpath,
-                         path, rev, first_rev)
-    return source, revision
-    
-  def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
-    p1 = self._getpath(path_parts1)
-    p2 = self._getpath(path_parts2)
-    r1 = self._getrev(rev1)
-    r2 = self._getrev(rev2)
-    args = vclib._diff_args(type, options)
-
-    try:
-      temp1 = temp_checkout(self, p1, r1, self.pool)
-      temp2 = temp_checkout(self, p2, r2, self.pool)
-      info1 = p1, date_from_rev(self, r1), r1
-      info2 = p2, date_from_rev(self, r2), r2
-      return vclib._diff_fp(temp1, temp2, info1, info2, args)
-    except vclib.svn.core.SubversionException, e:
-      if e.apr_err == vclib.svn.core.SVN_ERR_FS_NOT_FOUND:
-        raise vclib.InvalidRevision
-      raise
-
-  def _getpath(self, path_parts):
-    return string.join(path_parts, '/')
-
-  def _getrev(self, rev):
-    if rev is None or rev == 'HEAD':
-      return self.youngest
-    try:
-      rev = int(rev)
-    except ValueError:
-      raise vclib.InvalidRevision(rev)
-    if (rev < 0) or (rev > self.youngest):
-      raise vclib.InvalidRevision(rev)
-    return rev
-
-  def _getroot(self, rev):
-    try:
-      return self._fsroots[rev]
-    except KeyError:
-      r = self._fsroots[rev] = fs.revision_root(self.fs_ptr, rev, self.pool)
-      return r
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
diff --git a/src/www/scm/viewvc/lib/vclib/svn_ra/__init__.py b/src/www/scm/viewvc/lib/vclib/svn_ra/__init__.py
deleted file mode 100644
index 05de940..0000000
--- a/src/www/scm/viewvc/lib/vclib/svn_ra/__init__.py
+++ /dev/null
@@ -1,444 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-
-"Version Control lib driver for remotely accessible Subversion repositories."
-
-import vclib
-import sys
-import os
-import string
-import re
-import tempfile
-import popen2
-import time
-from vclib.svn import Revision, ChangedPath, _datestr_to_date, _compare_paths, _cleanup_path
-from svn import core, delta, client, wc, ra
-
-
-### Require Subversion 1.3.0 or better. (for svn_ra_get_locations support)
-if (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_PATCH) < (1, 3, 0):
-  raise Exception, "Version requirement not met (needs 1.3.0 or better)"
-
-  
-def _rev2optrev(rev):
-  assert type(rev) is int
-  rt = core.svn_opt_revision_t()
-  rt.kind = core.svn_opt_revision_number
-  rt.value.number = rev
-  return rt
-
-
-def date_from_rev(svnrepos, rev):
-  datestr = ra.svn_ra_rev_prop(svnrepos.ra_session, rev,
-                               'svn:date', svnrepos.pool)
-  return _datestr_to_date(datestr, svnrepos.pool)
-
-
-def get_location(svnrepos, path, rev, old_rev):
-  try:
-    results = ra.get_locations(svnrepos.ra_session, path, rev,
-                               [old_rev], svnrepos.pool)
-  except core.SubversionException, e:
-    if e.apr_err == core.SVN_ERR_FS_NOT_FOUND:
-      raise vclib.ItemNotFound(path)
-    raise
-
-  try:
-    old_path = results[old_rev]
-  except KeyError:
-    raise vclib.ItemNotFound(path)
-
-  return _cleanup_path(old_path)
-
-
-def last_rev(svnrepos, path, peg_revision, limit_revision=None):
-  """Given PATH, known to exist in PEG_REVISION, find the youngest
-  revision older than, or equal to, LIMIT_REVISION in which path
-  exists.  Return that revision, and the path at which PATH exists in
-  that revision."""
-  
-  # Here's the plan, man.  In the trivial case (where PEG_REVISION is
-  # the same as LIMIT_REVISION), this is a no-brainer.  If
-  # LIMIT_REVISION is older than PEG_REVISION, we can use Subversion's
-  # history tracing code to find the right location.  If, however,
-  # LIMIT_REVISION is younger than PEG_REVISION, we suffer from
-  # Subversion's lack of forward history searching.  Our workaround,
-  # ugly as it may be, involves a binary search through the revisions
-  # between PEG_REVISION and LIMIT_REVISION to find our last live
-  # revision.
-  peg_revision = svnrepos._getrev(peg_revision)
-  limit_revision = svnrepos._getrev(limit_revision)
-  if peg_revision == limit_revision:
-    return peg_revision, path
-  elif peg_revision > limit_revision:
-    path = get_location(svnrepos, path, peg_revision, limit_revision)
-    return limit_revision, path
-  else:
-    ### Warning: this is *not* an example of good pool usage.
-    direction = 1
-    while peg_revision != limit_revision:
-      mid = (peg_revision + 1 + limit_revision) / 2
-      try:
-        path = get_location(svnrepos, path, peg_revision, mid)
-      except vclib.ItemNotFound:
-        limit_revision = mid - 1
-      else:
-        peg_revision = mid
-    return peg_revision, path
-
-
-def created_rev(svnrepos, full_name, rev):
-  kind = ra.svn_ra_check_path(svnrepos.ra_session, full_name, rev,
-                              svnrepos.pool)
-  if kind == core.svn_node_dir:
-    props = ra.svn_ra_get_dir(svnrepos.ra_session, full_name,
-                              rev, svnrepos.pool)
-    return int(props[core.SVN_PROP_ENTRY_COMMITTED_REV])
-  return core.SVN_INVALID_REVNUM
-
-
-class LastHistoryCollector:
-  def __init__(self):
-    self.has_history = 0
-
-  def add_history(self, paths, revision, author, date, message, pool):
-    if not self.has_history:
-      self.has_history = 1
-      self.revision = revision
-      self.author = author
-      self.date = date
-      self.message = message
-      self.changes = []
-
-      if not paths:
-        return
-      changed_paths = paths.keys()
-      changed_paths.sort(lambda a, b: _compare_paths(a, b))
-      action_map = { 'D' : 'deleted',
-                     'A' : 'added',
-                     'R' : 'replaced',
-                     'M' : 'modified',
-                     }
-      for changed_path in changed_paths:
-        change = paths[changed_path]
-        action = action_map.get(change.action, 'modified')
-        ### Wrong, diddily wrong wrong wrong.  Can you say,
-        ### "Manufacturing data left and right because it hurts to
-        ### figure out the right stuff?"
-        if change.copyfrom_path and change.copyfrom_rev:
-          self.changes.append(ChangedPath(changed_path[1:], None, 0, 0,
-                                          change.copyfrom_path,
-                                          change.copyfrom_rev, action, 1))
-        else:
-          self.changes.append(ChangedPath(changed_path[1:], None, 0, 0,
-                                          changed_path[1:], 0, action, 0))
-
-  def get_history(self):
-    if not self.has_history:
-      return None, None, None, None, None
-    return self.revision, self.author, self.date, self.message, self.changes
-
-
-def _get_rev_details(svnrepos, rev, pool):
-  lhc = LastHistoryCollector()
-  client.svn_client_log([svnrepos.rootpath],
-                        _rev2optrev(rev), _rev2optrev(rev),
-                        1, 0, lhc.add_history, svnrepos.ctx, pool)
-  return lhc.get_history()
-
-  
-def get_revision_info(svnrepos, rev):
-  rev, author, date, log, changes = \
-       _get_rev_details(svnrepos, rev, svnrepos.pool)
-  return _datestr_to_date(date, svnrepos.pool), author, log, changes
-
-
-class LogCollector:
-  def __init__(self, path, show_all_logs):
-    # This class uses leading slashes for paths internally
-    if not path:
-      self.path = '/'
-    else:
-      self.path = path[0] == '/' and path or '/' + path
-    self.logs = []
-    self.show_all_logs = show_all_logs
-    
-  def add_log(self, paths, revision, author, date, message, pool):
-    # Changed paths have leading slashes
-    changed_paths = paths.keys()
-    changed_paths.sort(lambda a, b: _compare_paths(a, b))
-    this_path = None
-    if self.path in changed_paths:
-      this_path = self.path
-      change = paths[self.path]
-      if change.copyfrom_path:
-        this_path = change.copyfrom_path
-    for changed_path in changed_paths:
-      if changed_path != self.path:
-        # If a parent of our path was copied, our "next previous"
-        # (huh?) path will exist elsewhere (under the copy source).
-        if (string.rfind(self.path, changed_path) == 0) and \
-               self.path[len(changed_path)] == '/':
-          change = paths[changed_path]
-          if change.copyfrom_path:
-            this_path = change.copyfrom_path + self.path[len(changed_path):]
-    if self.show_all_logs or this_path:
-      date = _datestr_to_date(date, pool)
-      entry = Revision(revision, date, author, message, None,
-                       self.path[1:], None, None)
-      self.logs.append(entry)
-    if this_path:
-      self.path = this_path
-    
-
-def get_logs(svnrepos, full_name, rev, files):
-  dirents = svnrepos._get_dirents(full_name, rev)
-  subpool = core.svn_pool_create(svnrepos.pool)
-  rev_info_cache = { }
-  for file in files:
-    core.svn_pool_clear(subpool)
-    entry = dirents[file.name]
-    if rev_info_cache.has_key(entry.created_rev):
-      rev, author, date, log = rev_info_cache[entry.created_rev]
-    else:
-      ### i think this needs some get_last_history action to be accurate
-      rev, author, date, log, changes = \
-           _get_rev_details(svnrepos, entry.created_rev, subpool)
-      rev_info_cache[entry.created_rev] = rev, author, date, log
-    file.rev = rev
-    file.author = author
-    file.date = _datestr_to_date(date, subpool)
-    file.log = log
-    file.size = entry.size
-  core.svn_pool_destroy(subpool)    
-
-def get_youngest_revision(svnrepos):
-  return svnrepos.youngest
-
-def temp_checkout(svnrepos, path, rev, pool):
-  """Check out file revision to temporary file"""
-  temp = tempfile.mktemp()
-  stream = core.svn_stream_from_aprfile(temp, pool)
-  url = svnrepos.rootpath + (path and '/' + path)
-  client.svn_client_cat(core.Stream(stream), url, _rev2optrev(rev),
-                        svnrepos.ctx, pool)
-  core.svn_stream_close(stream)
-  return temp
-
-class SelfCleanFP:
-  def __init__(self, path):
-    self._fp = open(path, 'r')
-    self._path = path
-    self._eof = 0
-    
-  def read(self, len):
-    if len:
-      chunk = self._fp.read(len)
-    else:
-      chunk = self._fp.read()
-    if chunk == '':
-      self._eof = 1
-    return chunk
-  
-  def readline(self):
-    chunk = self._fp.readline()
-    if chunk == '':
-      self._eof = 1
-    return chunk
-
-  def close(self):
-    self._fp.close()
-    os.remove(self._path)
-
-  def __del__(self):
-    self.close()
-    
-  def eof(self):
-    return self._eof
-
-
-class SubversionRepository(vclib.Repository):
-  def __init__(self, name, rootpath):
-    # Init the client app
-    core.apr_initialize()
-    pool = core.svn_pool_create(None)
-    core.svn_config_ensure(None, pool)
-
-    # Start populating our members
-    self.pool = pool
-    self.name = name
-    self.rootpath = rootpath
-
-    # Setup the client context baton, complete with non-prompting authstuffs.
-    ctx = client.svn_client_ctx_t()
-    providers = []
-    providers.append(client.svn_client_get_simple_provider(pool))
-    providers.append(client.svn_client_get_username_provider(pool))
-    providers.append(client.svn_client_get_ssl_server_trust_file_provider(pool))
-    providers.append(client.svn_client_get_ssl_client_cert_file_provider(pool))
-    providers.append(client.svn_client_get_ssl_client_cert_pw_file_provider(pool))
-    ctx.auth_baton = core.svn_auth_open(providers, pool)
-    ctx.config = core.svn_config_get_config(None, pool)
-    self.ctx = ctx
-
-    ra_callbacks = ra.svn_ra_callbacks_t()
-    ra_callbacks.auth_baton = ctx.auth_baton
-    self.ra_session = ra.svn_ra_open(self.rootpath, ra_callbacks, None,
-                                     ctx.config, pool)
-    self.youngest = ra.svn_ra_get_latest_revnum(self.ra_session, pool)
-    self._dirent_cache = { }
-
-  def __del__(self):
-    core.svn_pool_destroy(self.pool)
-    core.apr_terminate()
-    
-  def itemtype(self, path_parts, rev):
-    path = self._getpath(path_parts[:-1])
-    rev = self._getrev(rev)
-    if not len(path_parts):
-      return vclib.DIR
-    dirents = self._get_dirents(path, rev)
-    try:
-      entry = dirents[path_parts[-1]]
-      if entry.kind == core.svn_node_dir:
-        return vclib.DIR
-      if entry.kind == core.svn_node_file:
-        return vclib.FILE
-    except KeyError:
-      raise vclib.ItemNotFound(path_parts)
-
-  def openfile(self, path_parts, rev):
-    rev = self._getrev(rev)
-    url = self.rootpath
-    if len(path_parts):
-      url = self.rootpath + '/' + self._getpath(path_parts)
-    tmp_file = tempfile.mktemp()
-    stream = core.svn_stream_from_aprfile(tmp_file, self.pool)
-    ### rev here should be the last history revision of the URL
-    client.svn_client_cat(core.Stream(stream), url,
-                          _rev2optrev(rev), self.ctx, self.pool)
-    core.svn_stream_close(stream)
-    return SelfCleanFP(tmp_file), rev
-
-  def listdir(self, path_parts, rev, options):
-    path = self._getpath(path_parts)
-    rev = self._getrev(rev)
-    entries = [ ]
-    dirents = self._get_dirents(path, rev)
-    for name in dirents.keys():
-      entry = dirents[name]
-      if entry.kind == core.svn_node_dir:
-        kind = vclib.DIR
-      elif entry.kind == core.svn_node_file:
-        kind = vclib.FILE
-      entries.append(vclib.DirEntry(name, kind))
-    return entries
-
-  def dirlogs(self, path_parts, rev, entries, options):
-    get_logs(self, self._getpath(path_parts), self._getrev(rev), entries)
-
-  def itemlog(self, path_parts, rev, options):
-    full_name = self._getpath(path_parts)
-    rev = self._getrev(rev)
-
-    # It's okay if we're told to not show all logs on a file -- all
-    # the revisions should match correctly anyway.
-    lc = LogCollector(full_name, options.get('svn_show_all_dir_logs', 0))
-    dir_url = self.rootpath
-    if full_name:
-      dir_url = dir_url + '/' + full_name
-
-    cross_copies = options.get('svn_cross_copies', 0)
-    client.svn_client_log([dir_url], _rev2optrev(rev), _rev2optrev(1),
-                          1, not cross_copies, lc.add_log,
-                          self.ctx, self.pool)
-    revs = lc.logs
-    revs.sort()
-    prev = None
-    for rev in revs:
-      rev.prev = prev
-      prev = rev
-
-    return revs
-
-  def annotate(self, path_parts, rev):
-    path = self._getpath(path_parts)
-    rev = self._getrev(rev)
-    url = self.rootpath + (path and '/' + path)
-
-    blame_data = []
-
-    def _blame_cb(line_no, revision, author, date,
-                  line, pool, blame_data=blame_data):
-      prev_rev = None
-      if revision > 1:
-        prev_rev = revision - 1
-      blame_data.append(_item(text=line, line_number=line_no+1,
-                              rev=revision, prev_rev=prev_rev,
-                              author=author, date=None))
-      
-    client.svn_client_blame(url, _rev2optrev(1), _rev2optrev(rev),
-                            _blame_cb, self.ctx, self.pool)
-
-    return blame_data, rev
-    
-  def rawdiff(self, path_parts1, rev1, path_parts2, rev2, type, options={}):
-    p1 = self._getpath(path_parts1)
-    p2 = self._getpath(path_parts2)
-    r1 = self._getrev(rev1)
-    r2 = self._getrev(rev2)
-    args = vclib._diff_args(type, options)
-
-    try:
-      temp1 = temp_checkout(self, p1, r1, self.pool)
-      temp2 = temp_checkout(self, p2, r2, self.pool)
-      info1 = p1, date_from_rev(self, r1), r1
-      info2 = p2, date_from_rev(self, r2), r2
-      return vclib._diff_fp(temp1, temp2, info1, info2, args)
-    except vclib.svn.core.SubversionException, e:
-      if e.apr_err == vclib.svn.core.SVN_ERR_FS_NOT_FOUND:
-        raise vclib.InvalidRevision
-      raise
-
-  def _getpath(self, path_parts):
-    return string.join(path_parts, '/')
-
-  def _getrev(self, rev):
-    if rev is None or rev == 'HEAD':
-      return self.youngest
-    try:
-      rev = int(rev)
-    except ValueError:
-      raise vclib.InvalidRevision(rev)
-    if (rev < 0) or (rev > self.youngest):
-      raise vclib.InvalidRevision(rev)
-    return rev
-
-  def _get_dirents(self, path, rev):
-    if path:
-      key = str(rev) + '/' + path
-      dir_url = self.rootpath + '/' + path
-    else:
-      key = str(rev)
-      dir_url = self.rootpath
-    dirents = self._dirent_cache.get(key)
-    if dirents:
-      return dirents
-    dirents = client.svn_client_ls(dir_url, _rev2optrev(rev), 0,
-                                   self.ctx, self.pool)
-    self._dirent_cache[key] = dirents
-    return dirents
-    
-    
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
diff --git a/src/www/scm/viewvc/lib/viewvc.py b/src/www/scm/viewvc/lib/viewvc.py
deleted file mode 100644
index 46b655a..0000000
--- a/src/www/scm/viewvc/lib/viewvc.py
+++ /dev/null
@@ -1,3626 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# viewvc: View CVS/SVN repositories via a web browser
-#
-# -----------------------------------------------------------------------
-
-__version__ = '1.0.0'
-
-# this comes from our library; measure the startup time
-import debug
-debug.t_start('startup')
-debug.t_start('imports')
-
-# standard modules that we know are in the path or builtin
-import sys
-import os
-import sapi
-import cgi
-import string
-import urllib
-import mimetypes
-import time
-import re
-import rfc822
-import stat
-import struct
-import types
-import tempfile
-
-# these modules come from our library (the stub has set up the path)
-import compat
-import config
-import popen
-import ezt
-import accept
-import vclib
-
-try:
-  import idiff
-except (SyntaxError, ImportError):
-  idiff = None
-
-debug.t_end('imports')
-
-#########################################################################
-
-checkout_magic_path = '*checkout*'
-# According to RFC 1738 the '~' character is unsafe in URLs.
-# But for compatibility with URLs bookmarked with old releases of ViewCVS:
-oldstyle_checkout_magic_path = '~checkout~'
-docroot_magic_path = '*docroot*'
-viewcvs_mime_type = 'text/vnd.viewcvs-markup'
-alt_mime_type = 'text/x-cvsweb-markup'
-view_roots_magic = '*viewroots*'
-
-# Put here the variables we need in order to hold our state - they
-# will be added (with their current value) to (almost) any link/query
-# string you construct.
-_sticky_vars = [
-  'hideattic',
-  'sortby',
-  'sortdir',
-  'logsort',
-  'diff_format',
-  'search',
-  'limit_changes',
-  ]
-
-# for reading/writing between a couple descriptors
-CHUNK_SIZE = 8192
-
-# for rcsdiff processing of header
-_RCSDIFF_IS_BINARY = 'binary-diff'
-_RCSDIFF_ERROR = 'error'
-
-# special characters that don't need to be URL encoded
-_URL_SAFE_CHARS = "/*~"
-
-
-class Request:
-  def __init__(self, server, cfg):
-    self.server = server
-    self.cfg = cfg
-
-    self.script_name = _normalize_path(server.getenv('SCRIPT_NAME', ''))
-    self.browser = server.getenv('HTTP_USER_AGENT', 'unknown')
-
-    # in lynx, it it very annoying to have two links per file, so
-    # disable the link at the icon in this case:
-    self.no_file_links = string.find(self.browser, 'Lynx') != -1
-
-    # newer browsers accept gzip content encoding and state this in a
-    # header (netscape did always but didn't state it) It has been
-    # reported that these braindamaged MS-Internet Explorers claim
-    # that they accept gzip .. but don't in fact and display garbage
-    # then :-/
-    self.may_compress = (
-      ( string.find(server.getenv('HTTP_ACCEPT_ENCODING', ''), 'gzip') != -1
-        or string.find(self.browser, 'Mozilla/3') != -1)
-      and string.find(self.browser, 'MSIE') == -1
-      )
-
-    # process the Accept-Language: header
-    hal = server.getenv('HTTP_ACCEPT_LANGUAGE','')
-    self.lang_selector = accept.language(hal)
-    self.language = self.lang_selector.select_from(cfg.general.languages)
-
-    # load the key/value files, given the selected language
-    self.kv = cfg.load_kv_files(self.language)
-
-  def run_viewvc(self):
-
-    cfg = self.cfg
-
-    # global needed because "import vclib.svn" causes the
-    # interpreter to make vclib a local variable
-    global vclib
-
-    # This function first parses the query string and sets the following
-    # variables. Then it executes the request.
-    self.view_func = None  # function to call to process the request
-    self.repos = None      # object representing current repository
-    self.rootname = None   # name of current root (as used in viewvc.conf)
-    self.roottype = None   # current root type ('svn' or 'cvs')
-    self.rootpath = None   # physical path to current root
-    self.pathtype = None   # type of path, either vclib.FILE or vclib.DIR
-    self.where = None      # path to file or directory in current root
-    self.query_dict = {}   # validated and cleaned up query options
-    self.path_parts = None # for convenience, equals where.split('/')
-    self.pathrev = None    # current path revision or tag
-
-    # redirect if we're loading from a valid but irregular URL
-    # These redirects aren't neccessary to make ViewVC work, it functions
-    # just fine without them, but they make it easier for server admins to
-    # implement access restrictions based on URL
-    needs_redirect = 0
-
-    # Process the query params
-    for name, values in self.server.params().items():
-      # patch up old queries that use 'cvsroot' to look like they used 'root'
-      if name == 'cvsroot':
-        name = 'root'
-        needs_redirect = 1
-
-      # same for 'only_with_tag' and 'pathrev'
-      if name == 'only_with_tag':
-        name = 'pathrev'
-        needs_redirect = 1
-
-      # validate the parameter
-      _validate_param(name, values[0])
-
-      # if we're here, then the parameter is okay
-      self.query_dict[name] = values[0]
-
-    # handle view parameter
-    self.view_func = _views.get(self.query_dict.get('view', None), 
-                                self.view_func)
-
-    # Process PATH_INFO component of query string
-    path_info = self.server.getenv('PATH_INFO', '')
-
-    # clean it up. this removes duplicate '/' characters and any that may
-    # exist at the front or end of the path.
-    ### we might want to redirect to the cleaned up URL
-    path_parts = _path_parts(path_info)
-
-    if path_parts:
-      # handle magic path prefixes
-      if path_parts[0] == docroot_magic_path:
-        # if this is just a simple hunk of doc, then serve it up
-        self.where = _path_join(path_parts[1:])
-        return view_doc(self)
-      elif path_parts[0] in (checkout_magic_path,
-                             oldstyle_checkout_magic_path):
-        path_parts.pop(0)
-        self.view_func = view_checkout
-        if not cfg.options.checkout_magic:
-          needs_redirect = 1
-
-      # handle tarball magic suffixes
-      if self.view_func is download_tarball:
-        if (self.query_dict.get('parent')):
-	  del path_parts[-1]
-        elif path_parts[-1][-7:] == ".tar.gz":
-          path_parts[-1] = path_parts[-1][:-7]
-
-    # Figure out root name
-    self.rootname = self.query_dict.get('root')
-    if self.rootname == view_roots_magic:
-      del self.query_dict['root']
-      self.rootname = ""
-      needs_redirect = 1
-    elif self.rootname is None:
-      if cfg.options.root_as_url_component:
-        if path_parts:
-          self.rootname = path_parts.pop(0)
-        else:
-          self.rootname = ""
-      else:
-        self.rootname = cfg.general.default_root
-    elif cfg.options.root_as_url_component:
-      needs_redirect = 1
-
-    self.where = _path_join(path_parts)
-    self.path_parts = path_parts
-
-    if self.rootname:
-      # Create the repository object
-      if cfg.general.cvs_roots.has_key(self.rootname):
-        self.rootpath = os.path.normpath(cfg.general.cvs_roots[self.rootname])
-        try:
-          if cfg.general.use_rcsparse:
-            import vclib.ccvs
-            self.repos = vclib.ccvs.CCVSRepository(self.rootname,
-                                                   self.rootpath)
-          else:
-            import vclib.bincvs
-            self.repos = vclib.bincvs.BinCVSRepository(self.rootname, 
-                                                       self.rootpath,
-                                                       cfg.general)
-          self.roottype = 'cvs'
-        except vclib.ReposNotFound:
-          raise debug.ViewVCException(
-            '%s not found!\nThe wrong path for this repository was '
-            'configured, or the server on which the CVS tree lives may be '
-            'down. Please try again in a few minutes.'
-            % self.rootname)
-        # required so that spawned rcs programs correctly expand $CVSHeader$
-        os.environ['CVSROOT'] = self.rootpath
-      elif cfg.general.svn_roots.has_key(self.rootname):
-        self.rootpath = cfg.general.svn_roots[self.rootname]
-        try:
-          if re.match(_re_rewrite_url, self.rootpath):
-            # If the rootpath is a URL, we'll use the svn_ra module, but
-            # lie about its name.
-            import vclib.svn_ra
-            vclib.svn = vclib.svn_ra
-            self.repos = vclib.svn.SubversionRepository(self.rootname,
-                                                        self.rootpath)
-          else:
-            self.rootpath = os.path.normpath(self.rootpath)
-            import vclib.svn
-            self.repos = vclib.svn.SubversionRepository(self.rootname,
-                                                        self.rootpath,
-                                                        cfg.general.svn_path)
-          self.roottype = 'svn'
-        except vclib.ReposNotFound:
-          raise debug.ViewVCException(
-            '%s not found!\nThe wrong path for this repository was '
-            'configured, or the server on which the Subversion tree lives may'
-            'be down. Please try again in a few minutes.'
-            % self.rootname)
-        except vclib.InvalidRevision, ex:
-          raise debug.ViewVCException(str(ex))
-      else:
-        raise debug.ViewVCException(
-          'The root "%s" is unknown. If you believe the value is '
-          'correct, then please double-check your configuration.'
-          % self.rootname, "404 Repository not found")
-
-    # If this is using an old-style 'rev' parameter, redirect to new hotness.
-    # Subversion URLs will now use 'pathrev'; CVS ones use 'revision'.
-    if self.repos and self.query_dict.has_key('rev'):
-      if self.roottype == 'svn' \
-             and not self.query_dict.has_key('pathrev') \
-             and not self.view_func == view_revision:
-        self.query_dict['pathrev'] = self.query_dict['rev']
-        del self.query_dict['rev']
-      else: # elif not self.query_dict.has_key('revision'): ?
-        self.query_dict['revision'] = self.query_dict['rev']
-        del self.query_dict['rev']
-      needs_redirect = 1
-
-    if self.repos and self.view_func is not redirect_pathrev:
-      # Make sure path exists
-      self.pathrev = pathrev = self.query_dict.get('pathrev')
-      self.pathtype = _repos_pathtype(self.repos, path_parts, pathrev)
-
-      if self.pathtype is None:
-        # path doesn't exist, see if it could be an old-style ViewVC URL
-	# with a fake suffix
-        result = _strip_suffix('.diff', path_parts, pathrev, vclib.FILE,      \
-                               self.repos, view_diff) or                      \
-                 _strip_suffix('.tar.gz', path_parts, pathrev, vclib.DIR,     \
-                               self.repos, download_tarball) or               \
-                 _strip_suffix('root.tar.gz', path_parts, pathrev, vclib.DIR, \
-                               self.repos, download_tarball) or               \
-                 _strip_suffix(self.rootname + '-root.tar.gz',                \
-                               path_parts, pathrev, vclib.DIR,                \
-                               self.repos, download_tarball) or               \
-                 _strip_suffix('root',                                        \
-                               path_parts, pathrev, vclib.DIR,                \
-                               self.repos, download_tarball) or               \
-                 _strip_suffix(self.rootname + '-root',                       \
-                               path_parts, pathrev, vclib.DIR,                \
-                               self.repos, download_tarball)
-        if result:
-          self.path_parts, self.pathtype, self.view_func = result
-          self.where = _path_join(self.path_parts)
-	  needs_redirect = 1
-        else:
-          raise debug.ViewVCException('%s: unknown location'
-                                       % self.where, '404 Not Found')
-
-      # If we have an old ViewCVS Attic URL which is still valid, then redirect
-      if self.roottype == 'cvs':
-        attic_parts = None
-        if (self.pathtype == vclib.FILE and len(self.path_parts) > 1
-            and self.path_parts[-2] == 'Attic'):
-          attic_parts = self.path_parts[:-2] + self.path_parts[-1:]
-        elif (self.pathtype == vclib.DIR and len(self.path_parts) > 0
-              and self.path_parts[-1] == 'Attic'):
-          attic_parts = self.path_parts[:-1]
-        if attic_parts:
-          self.path_parts = attic_parts
-          self.where = _path_join(attic_parts)
-          needs_redirect = 1
-
-    # If this is a forbidden directory, stop now
-    if self.path_parts and self.pathtype == vclib.DIR \
-           and cfg.is_forbidden(self.path_parts[0]):
-      raise debug.ViewVCException('%s: unknown location' % path_parts[0],
-                                   '404 Not Found')
-
-    if self.view_func is None:
-      # view parameter is not set, try looking at pathtype and the 
-      # other parameters
-      if not self.rootname:
-        self.view_func = view_roots
-      elif self.pathtype == vclib.DIR:
-        # ViewCVS 0.9.2 used to put ?tarball=1 at the end of tarball urls
-	if self.query_dict.has_key('tarball'):
-          self.view_func = download_tarball
-        else:
-          self.view_func = view_directory
-      elif self.pathtype == vclib.FILE:
-        if self.query_dict.has_key('r1') and self.query_dict.has_key('r2'):
-          self.view_func = view_diff
-        elif self.query_dict.has_key('annotate'):
-          self.view_func = view_annotate
-        elif self.query_dict.has_key('graph'):
-          if not self.query_dict.has_key('makeimage'):
-            self.view_func = view_cvsgraph
-          else: 
-            self.view_func = view_cvsgraph_image
-        elif self.query_dict.has_key('revision') \
-                 or cfg.options.default_file_view != "log":
-          if self.query_dict.get('content-type', None) in (viewcvs_mime_type,
-                                                           alt_mime_type):
-            self.view_func = view_markup
-          else:
-            self.view_func = view_checkout
-        else:
-          self.view_func = view_log
-
-    # if we have a directory and the request didn't end in "/", then redirect
-    # so that it does.
-    if (self.pathtype == vclib.DIR and path_info[-1:] != '/'
-        and self.view_func is not view_revision
-        and self.view_func is not view_roots
-        and self.view_func is not download_tarball
-        and self.view_func is not redirect_pathrev):
-      needs_redirect = 1
-
-    # redirect now that we know the URL is valid
-    
-    if needs_redirect:
-      self.server.redirect(self.get_url())
-
-    # Finally done parsing query string, set mime type and call view_func
-    self.mime_type = None
-    if self.pathtype == vclib.FILE:
-      self.mime_type = guess_mime(self.where)
-
-    # startup is done now.
-    debug.t_end('startup')
-    
-    self.view_func(self)
-
-  def get_url(self, escape=0, partial=0, **args):
-    """Constructs a link to another ViewVC page just like the get_link
-    function except that it returns a single URL instead of a URL
-    split into components"""
-
-    url, params = apply(self.get_link, (), args)
-    qs = compat.urlencode(params)
-    if qs:
-      result = urllib.quote(url, _URL_SAFE_CHARS) + '?' + qs
-    else:
-      result = urllib.quote(url, _URL_SAFE_CHARS)
-
-    if partial:
-      result = result + (qs and '&' or '?')
-    if escape:
-       result = self.server.escape(result)
-    return result
-
-  def get_form(self, **args):
-    """Constructs a link to another ViewVC page just like the get_link
-    function except that it returns a base URL suitable for use as an HTML
-    form action and a string of HTML input type=hidden tags with the link
-    parameters."""
-
-    url, params = apply(self.get_link, (), args)
-    action = self.server.escape(urllib.quote(url, _URL_SAFE_CHARS))
-    hidden_values = prepare_hidden_values(params)
-    return action, hidden_values
-
-  def get_link(self, view_func=None, where=None, pathtype=None, params=None):
-    """Constructs a link pointing to another ViewVC page. All arguments
-    correspond to members of the Request object. If they are set to 
-    None they take values from the current page. Return value is a base
-    URL and a dictionary of parameters"""
-
-    cfg = self.cfg
-
-    if view_func is None:
-      view_func = self.view_func
-
-    if params is None:
-      params = self.query_dict.copy()
-    else:
-      params = params.copy()
-      
-    # must specify both where and pathtype or neither
-    assert (where is None) == (pathtype is None)
-
-    # if we are asking for the revision info view, we don't need any
-    # path information
-    if (view_func is view_revision or view_func is view_roots
-        or view_func is redirect_pathrev):
-      where = pathtype = None
-    elif where is None:
-      where = self.where
-      pathtype = self.pathtype
-
-    # no need to add sticky variables for views with no links
-    sticky_vars = not (view_func is view_checkout 
-                       or view_func is download_tarball)
-
-    # The logic used to construct the URL is an inverse of the
-    # logic used to interpret URLs in Request.run_viewvc
-
-    url = self.script_name
-
-    # add checkout magic if neccessary
-    if view_func is view_checkout and cfg.options.checkout_magic:
-      url = url + '/' + checkout_magic_path
-
-    # add root to url
-    rootname = None
-    if view_func is not view_roots:
-      if cfg.options.root_as_url_component:
-        # remove root from parameter list if present
-        try:
-          rootname = params['root']
-        except KeyError:
-          rootname = self.rootname
-        else:
-          del params['root']
-
-        # add root path component
-        if rootname is not None:
-          url = url + '/' + rootname
-
-      else:
-        # add root to parameter list
-        try:
-          rootname = params['root']
-        except KeyError:
-          rootname = params['root'] = self.rootname
-
-        # no need to specify default root
-        if rootname == cfg.general.default_root:
-          del params['root']   
-
-    # add 'pathrev' value to parameter list
-    if (self.pathrev is not None
-        and not params.has_key('pathrev')
-        and view_func is not view_revision
-        and rootname == self.rootname):
-      params['pathrev'] = self.pathrev
-
-    # add path
-    if where:
-      url = url + '/' + where
-
-    # add suffix for tarball
-    if view_func is download_tarball:
-      if not where and not cfg.options.root_as_url_component:
-        url = url + '/' + rootname + '-root'
-	params['parent'] = '1'
-      url = url + '.tar.gz'
-
-    # add trailing slash for a directory
-    elif pathtype == vclib.DIR:
-      url = url + '/'
-
-    # normalize top level URLs for use in Location headers and A tags
-    elif not url:
-      url = '/'
-
-    # no need to explicitly specify directory view for a directory
-    if view_func is view_directory and pathtype == vclib.DIR:
-      view_func = None
-
-    # no need to explicitly specify roots view when in root_as_url
-    # mode or there's no default root
-    if view_func is view_roots and (cfg.options.root_as_url_component
-                                    or not cfg.general.default_root):
-      view_func = None
-
-    # no need to explicitly specify annotate view when
-    # there's an annotate parameter
-    if view_func is view_annotate and params.get('annotate') is not None:
-      view_func = None
-
-    # no need to explicitly specify diff view when
-    # there's r1 and r2 parameters
-    if (view_func is view_diff and params.get('r1') is not None
-        and params.get('r2') is not None):
-      view_func = None
-
-    # no need to explicitly specify checkout view when it's the default
-    # view, when checkout_magic is enabled, or when "revision" is present
-    if view_func is view_checkout:
-      if ((cfg.options.default_file_view != "log" and pathtype == vclib.FILE)
-          or cfg.options.checkout_magic
-          or params.get('revision') is not None):
-        view_func = None
-
-    view_code = _view_codes.get(view_func)
-    if view_code and not (params.has_key('view') and params['view'] is None):
-      params['view'] = view_code
-
-    # add sticky values to parameter list
-    if sticky_vars:
-      for name in _sticky_vars:
-        value = self.query_dict.get(name)
-        if value is not None and not params.has_key(name):
-          params[name] = value
-
-    # remove null values from parameter list
-    for name, value in params.items():
-      if value is None:
-        del params[name]
-
-    return url, params
-
-def _path_parts(path):
-  """Split up a repository path into a list of path components"""
-  # clean it up. this removes duplicate '/' characters and any that may
-  # exist at the front or end of the path.
-  return filter(None, string.split(path, '/'))
-
-def _normalize_path(path):
-  """Collapse leading slashes in the script name
-
-  You only get multiple slashes in the script name when users accidentally
-  type urls like http://abc.com//viewvc.cgi/, but we correct for it
-  because we output the script name in links and web browsers
-  interpret //viewvc.cgi/ as http://viewvc.cgi/
-  """
-  
-  i = 0
-  for c in path:
-    if c != '/':
-      break
-    i = i + 1
-
-  if i:
-    return path[i-1:]
-
-  return path
-
-def _validate_param(name, value):
-  """Validate whether the given value is acceptable for the param name.
-
-  If the value is not allowed, then an error response is generated, and
-  this function throws an exception. Otherwise, it simply returns None.
-  """
-
-  try:
-    validator = _legal_params[name]
-  except KeyError:
-    raise debug.ViewVCException(
-      'An illegal parameter name ("%s") was passed.' % name,
-      '400 Bad Request')
-
-  if validator is None:
-    return
-
-  # is the validator a regex?
-  if hasattr(validator, 'match'):
-    if not validator.match(value):
-      raise debug.ViewVCException(
-        'An illegal value ("%s") was passed as a parameter.' %
-        value, '400 Bad Request')
-    return
-
-  # the validator must be a function
-  validator(value)
-
-def _validate_regex(value):
-  # hmm. there isn't anything that we can do here.
-
-  ### we need to watch the flow of these parameters through the system
-  ### to ensure they don't hit the page unescaped. otherwise, these
-  ### parameters could constitute a CSS attack.
-  pass
-
-# obvious things here. note that we don't need uppercase for alpha.
-_re_validate_alpha = re.compile('^[a-z]+$')
-_re_validate_number = re.compile('^[0-9]+$')
-
-# when comparing two revs, we sometimes construct REV:SYMBOL, so ':' is needed
-_re_validate_revnum = re.compile('^[-_.a-zA-Z0-9:~\\[\\]/]*$')
-
-# it appears that RFC 2045 also says these chars are legal: !#$%&'*+^{|}~`
-# but woah... I'll just leave them out for now
-_re_validate_mimetype = re.compile('^[-_.a-zA-Z0-9/]+$')
-
-# date time values
-_re_validate_datetime = re.compile(r'^(\d\d\d\d-\d\d-\d\d(\s+\d\d:\d\d(:\d\d)?)?)?$')
-
-# the legal query parameters and their validation functions
-_legal_params = {
-  'root'          : None,
-  'view'          : None,
-  'search'        : _validate_regex,
-  'p1'            : None,
-  'p2'            : None,
-  
-  'hideattic'     : _re_validate_number,
-  'limit_changes' : _re_validate_number,
-  'sortby'        : _re_validate_alpha,
-  'sortdir'       : _re_validate_alpha,
-  'logsort'       : _re_validate_alpha,
-  'diff_format'   : _re_validate_alpha,
-  'pathrev'       : _re_validate_revnum,
-  'dir_pagestart' : _re_validate_number,
-  'log_pagestart' : _re_validate_number,
-  'hidecvsroot'   : _re_validate_number,
-  'annotate'      : _re_validate_revnum,
-  'graph'         : _re_validate_revnum,
-  'makeimage'     : _re_validate_number,
-  'tarball'       : _re_validate_number,
-  'parent'        : _re_validate_number,
-  'r1'            : _re_validate_revnum,
-  'tr1'           : _re_validate_revnum,
-  'r2'            : _re_validate_revnum,
-  'tr2'           : _re_validate_revnum,
-  'rev'           : _re_validate_revnum,
-  'revision'      : _re_validate_revnum,
-  'content-type'  : _re_validate_mimetype,
-
-  # for query
-  'branch'        : _validate_regex,
-  'branch_match'  : _re_validate_alpha,
-  'dir'           : None,
-  'file'          : _validate_regex,
-  'file_match'    : _re_validate_alpha,
-  'who'           : _validate_regex,
-  'who_match'     : _re_validate_alpha,
-  'querysort'     : _re_validate_alpha,
-  'date'          : _re_validate_alpha,
-  'hours'         : _re_validate_number,
-  'mindate'       : _re_validate_datetime,
-  'maxdate'       : _re_validate_datetime,
-  'format'        : _re_validate_alpha,
-  'limit'         : _re_validate_number,
-
-  # for redirect_pathrev
-  'orig_path'     : None,
-  'orig_pathtype' : None,
-  'orig_pathrev'  : None,
-  'orig_view'     : None,
-  }
-
-def _path_join(path_parts):
-  return string.join(path_parts, '/')
-
-def _strip_suffix(suffix, path_parts, rev, pathtype, repos, view_func):
-  """strip the suffix from a repository path if the resulting path
-  is of the specified type, otherwise return None"""
-  l = len(suffix)
-  if path_parts[-1][-l:] == suffix:
-    path_parts = path_parts[:]
-    if len(path_parts[-1]) == l:
-      del path_parts[-1]
-    else:
-      path_parts[-1] = path_parts[-1][:-l]
-    t = _repos_pathtype(repos, path_parts, rev)
-    if pathtype == t:
-      return path_parts, t, view_func
-  return None
-
-def _repos_pathtype(repos, path_parts, rev):
-  """return the type of a repository path, or None if the path doesn't exist"""
-  try:
-    return repos.itemtype(path_parts, rev)
-  except vclib.ItemNotFound:
-    return None
-
-def _orig_path(request, rev_param='revision', path_param=None):
-  "Get original path of requested file at old revision before copies or moves"
-
-  # The 'pathrev' variable is interpreted by nearly all ViewVC views to
-  # provide a browsable snapshot of a repository at some point in its history.
-  # 'pathrev' is a tag name for CVS repositories and a revision number for
-  # Subversion repositories. It's automatically propagated between pages by
-  # logic in the Request.get_link() function which adds it to links like a
-  # sticky variable. When 'pathrev' is set, directory listings only include
-  # entries that exist in the specified revision or tag. Similarly, log pages
-  # will only show revisions preceding the point in history specified by
-  # 'pathrev.' Markup, checkout, and annotate pages show the 'pathrev'
-  # revision of files by default when no other revision is specified.
-  #
-  # In Subversion repositories, paths are always considered to refer to the
-  # pathrev revision. For example, if there is a "circle.jpg" in revision 3,
-  # which is renamed and modified as "square.jpg" in revision 4, the original
-  # circle image is visible at the following URLs:
-  #
-  #     *checkout*/circle.jpg?pathrev=3
-  #     *checkout*/square.jpg?revision=3
-  #     *checkout*/square.jpg?revision=3&pathrev=4
-  # 
-  # Note that the following:
-  #
-  #     *checkout*/circle.jpg?rev=3
-  #
-  # now gets redirected to one of the following URLs:
-  #
-  #     *checkout*/circle.jpg?pathrev=3  (for Subversion)
-  #     *checkout*/circle.jpg?revision=3  (for CVS)
-  #
-  rev = request.query_dict.get(rev_param, request.pathrev)
-  path = request.query_dict.get(path_param, request.where)
-  
-  if rev is not None and hasattr(request.repos, '_getrev'):
-    pathrev = request.repos._getrev(request.pathrev)
-    rev = request.repos._getrev(rev)
-    return _path_parts(vclib.svn.get_location(request.repos, path, 
-                                              pathrev, rev)), rev
-  return _path_parts(path), rev
-
-def _install_path(path):
-  """Get usable path for a path relative to ViewVC install directory"""
-  if os.path.isabs(path):
-    return path
-  return os.path.normpath(os.path.join(os.path.dirname(__file__),
-                                       os.pardir,
-                                       path))
-
-def check_freshness(request, mtime=None, etag=None, weak=0):
-  # See if we are supposed to disable etags (for debugging, usually)
-
-  cfg = request.cfg
-
-  if not cfg.options.generate_etags:
-    return 0
-  
-  request_etag = request_mtime = None
-  if etag is not None:
-    if weak:
-      etag = 'W/"%s"' % etag
-    else:
-      etag = '"%s"' % etag
-    request_etag = request.server.getenv('HTTP_IF_NONE_MATCH')
-  if mtime is not None:
-    try:
-      request_mtime = request.server.getenv('HTTP_IF_MODIFIED_SINCE')
-      request_mtime = rfc822.mktime_tz(rfc822.parsedate_tz(request_mtime))
-    except:
-      request_mtime = None
-
-  # if we have an etag, use that for freshness checking.
-  # if not available, then we use the last-modified time.
-  # if not available, then the document isn't fresh.
-  if etag is not None:
-    isfresh = (request_etag == etag)
-  elif mtime is not None:
-    isfresh = (request_mtime >= mtime)
-  else:
-    isfresh = 0
-
-  ## require revalidation after 15 minutes ...
-  if cfg and cfg.options.http_expiration_time >= 0:
-    expiration = compat.formatdate(time.time() +
-                                   cfg.options.http_expiration_time)
-    request.server.addheader('Expires', expiration)
-    request.server.addheader('Cache-Control',
-                             'max-age=%d' % cfg.options.http_expiration_time)
-
-  if isfresh:
-    request.server.header(status='304 Not Modified')
-  else:
-    if etag is not None:
-      request.server.addheader('ETag', etag)
-    if mtime is not None:
-      request.server.addheader('Last-Modified', compat.formatdate(mtime))
-  return isfresh
-
-def get_view_template(cfg, view_name, language="en"):
-  # see if the configuration specifies a template for this view
-  tname = vars(cfg.templates).get(view_name)
-
-  # if there is no specific template definition for this view, look in
-  # the default location (relative to the configured template_dir)
-  if not tname:
-    tname = os.path.join(cfg.options.template_dir, view_name + ".ezt")
-
-  # allow per-language template selection
-  tname = string.replace(tname, '%lang%', language)
-
-  # finally, construct the whole template path.
-  tname = _install_path(tname)
-
-  debug.t_start('ezt-parse')
-  template = ezt.Template(tname)
-  debug.t_end('ezt-parse')
-
-  return template
-
-def generate_page(request, view_name, data):
-  template = get_view_template(request.cfg, view_name, request.language)
-  template.generate(request.server.file(), data)
-
-def nav_path(request):
-  """Return current path as list of items with "name" and "href" members
-
-  The href members are view_directory links for directories and view_log
-  links for files, but are set to None when the link would point to
-  the current view"""
-
-  if not request.repos:
-    return []
-
-  is_dir = request.pathtype == vclib.DIR
-
-  # add root item
-  items = []
-  root_item = _item(name=request.server.escape(request.repos.name), href=None)
-  if request.path_parts or request.view_func is not view_directory:
-    root_item.href = request.get_url(view_func=view_directory,
-                                     where='', pathtype=vclib.DIR,
-                                     params={}, escape=1)
-  items.append(root_item)
-
-  # add path part items
-  path_parts = []
-  for part in request.path_parts:
-    path_parts.append(part)
-    is_last = len(path_parts) == len(request.path_parts)
-
-    item = _item(name=part, href=None)
-
-    if not is_last or (is_dir and request.view_func is not view_directory):
-      item.href = request.get_url(view_func=view_directory,
-                                  where=_path_join(path_parts),
-                                  pathtype=vclib.DIR,
-                                  params={}, escape=1)
-    elif not is_dir and request.view_func is not view_log:
-      item.href = request.get_url(view_func=view_log,
-                                  where=_path_join(path_parts),
-                                  pathtype=vclib.FILE,
-                                  params={}, escape=1)
-    items.append(item)
-
-  return items
-
-def prep_tags(request, tags):
-  url, params = request.get_link(params={'pathrev': None})
-  params = compat.urlencode(params)
-  if params:
-    url = urllib.quote(url, _URL_SAFE_CHARS) + '?' + params + '&pathrev='
-  else:
-    url = urllib.quote(url, _URL_SAFE_CHARS) + '?pathrev='
-  url = request.server.escape(url)
-
-  links = [ ]
-  for tag in tags:
-    links.append(_item(name=tag.name, href=url+tag.name))
-  links.sort(lambda a, b: cmp(a.name, b.name))
-  return links
-
-def guess_mime(filename):
-  return mimetypes.guess_type(filename)[0]
-
-def is_viewable_image(mime_type):
-  return mime_type and mime_type in ('image/gif', 'image/jpeg', 'image/png')
-
-def is_text(mime_type):
-  return not mime_type or mime_type[:5] == 'text/'
-
-def is_plain_text(mime_type):
-  return not mime_type or mime_type == 'text/plain'
-
-def default_view(mime_type, cfg):
-  "Determine whether file should be viewed through markup page or sent raw"
-  # If the mime type is text/anything or a supported image format we view
-  # through the markup page. If the mime type is something else, we send
-  # it directly to the browser. That way users can see things like flash
-  # animations, pdfs, word documents, multimedia, etc, which wouldn't be
-  # very useful marked up. If the mime type is totally unknown (happens when
-  # we encounter an unrecognized file extension) we also view it through
-  # the markup page since that's better than sending it text/plain.
-  if (cfg.options.allow_markup and 
-      (is_viewable_image(mime_type) or is_text(mime_type))):
-    return view_markup
-  return view_checkout
-
-def get_file_view_info(request, where, rev=None, mime_type=None, pathrev=-1):
-  """Return common hrefs and a viewability flag used for various views
-  of FILENAME at revision REV whose MIME type is MIME_TYPE."""
-  rev = rev and str(rev) or None
-  mime_type = mime_type or request.mime_type
-  if pathrev == -1: # cheesy default value, since we need to preserve None
-    pathrev = request.pathrev
-  download_text_href = annotate_href = revision_href = None
-  view_href = request.get_url(view_func=view_markup,
-                              where=where,
-                              pathtype=vclib.FILE,
-                              params={'revision': rev,
-                                      'pathrev': pathrev},
-                              escape=1)
-  download_href = request.get_url(view_func=view_checkout,
-                                  where=where,
-                                  pathtype=vclib.FILE,
-                                  params={'revision': rev,
-                                          'pathrev': pathrev},
-                                  escape=1)
-  if not is_plain_text(mime_type):
-    download_text_href = request.get_url(view_func=view_checkout,
-                                         where=where,
-                                         pathtype=vclib.FILE,
-                                         params={'content-type': 'text/plain',
-                                                 'revision': rev,
-                                                 'pathrev': rev},
-                                         escape=1)
-  if request.cfg.options.allow_annotate:
-    annotate_href = request.get_url(view_func=view_annotate,
-                                    where=where,
-                                    pathtype=vclib.FILE,
-                                    params={'annotate': rev,
-                                            'pathrev': pathrev},
-                                    escape=1)
-  if request.roottype == 'svn':
-    revision_href = request.get_url(view_func=view_revision,
-                                    params={'revision': rev},
-                                    escape=1)
-
-  prefer_markup = default_view(mime_type, request.cfg) == view_markup
-
-  return view_href, download_href, download_text_href, \
-         annotate_href, revision_href, ezt.boolean(prefer_markup)
-
-
-# Regular expressions for location text that looks like URLs and email
-# addresses.  Note that the regexps assume the text is already HTML-encoded.
-_re_rewrite_url = re.compile('((http|https|ftp|file|svn|svn\+ssh)(://[-a-zA-Z0-9%.~:_/]+)((\?|\&)([-a-zA-Z0-9%.~:_]+)=([-a-zA-Z0-9%.~:_])+)*(#([-a-zA-Z0-9%.~:_]+)?)?)')
-_re_rewrite_email = re.compile('([-a-zA-Z0-9_.\+]+)@(([-a-zA-Z0-9]+\.)+[A-Za-z]{2,4})')
-def htmlify(html):
-  html = cgi.escape(html)
-  html = re.sub(_re_rewrite_url, r'<a href="\1">\1</a>', html)
-  html = re.sub(_re_rewrite_email, r'<a href="mailto:\1@\2">\1@\2</a>', html)
-  return html
-
-def format_log(log, cfg):
-  s = htmlify(log[:cfg.options.short_log_len])
-  if len(log) > cfg.options.short_log_len:
-    s = s + '...'
-  return s
-
-_time_desc = {
-         1 : 'second',
-        60 : 'minute',
-      3600 : 'hour',
-     86400 : 'day',
-    604800 : 'week',
-   2628000 : 'month',
-  31536000 : 'year',
-  }
-
-def get_time_text(request, interval, num):
-  "Get some time text, possibly internationalized."
-  ### some languages have even harder pluralization rules. we'll have to
-  ### deal with those on demand
-  if num == 0:
-    return ''
-  text = _time_desc[interval]
-  if num == 1:
-    attr = text + '_singular'
-    fmt = '%d ' + text
-  else:
-    attr = text + '_plural'
-    fmt = '%d ' + text + 's'
-  try:
-    fmt = getattr(request.kv.i18n.time, attr)
-  except AttributeError:
-    pass
-  return fmt % num
-
-def little_time(request):
-  try:
-    return request.kv.i18n.time.little_time
-  except AttributeError:
-    return 'very little time'
-
-def html_time(request, secs, extended=0):
-  secs = long(time.time()) - secs
-  if secs < 2:
-    return little_time(request)
-  breaks = _time_desc.keys()
-  breaks.sort()
-  i = 0
-  while i < len(breaks):
-    if secs < 2 * breaks[i]:
-      break
-    i = i + 1
-  value = breaks[i - 1]
-  s = get_time_text(request, value, secs / value)
-
-  if extended and i > 1:
-    secs = secs % value
-    value = breaks[i - 2]
-    ext = get_time_text(request, value, secs / value)
-    if ext:
-      ### this is not i18n compatible. pass on it for now
-      s = s + ', ' + ext
-  return s
-
-def common_template_data(request):
-  cfg = request.cfg
-  data = {
-    'cfg' : cfg,
-    'vsn' : __version__,
-    'kv'  : request.kv,
-    'docroot' : cfg.options.docroot is None                        \
-                and request.script_name + '/' + docroot_magic_path \
-                or cfg.options.docroot,
-    'where' : request.server.escape(request.where),
-    'roottype' : request.roottype,
-    'rootname' : request.server.escape(request.rootname),
-    'pathtype' : None,
-    'nav_path' : nav_path(request),
-    'up_href'  : None,
-    'log_href' : None,
-    'log_href_rev': None,
-    'graph_href': None,
-    'rss_href' : None,
-    'view'     : _view_codes[request.view_func],
-  }
-
-  if request.pathtype == vclib.DIR:
-    data['pathtype'] = 'dir'
-  elif request.pathtype == vclib.FILE:
-    data['pathtype'] = 'file'
-
-  data['change_root_action'], data['change_root_hidden_values'] = \
-    request.get_form(view_func=view_directory, where='', pathtype=vclib.DIR,
-                     params={'root': None})
-
-  # add in the roots for the selection
-  roots = []
-  allroots = list_roots(cfg)
-  if len(allroots):
-    rootnames = allroots.keys()
-    rootnames.sort(icmp)
-    for rootname in rootnames:
-      href = request.get_url(view_func=view_directory,
-                             where='', pathtype=vclib.DIR,
-                             params={'root': rootname}, escape=1)
-      roots.append(_item(name=request.server.escape(rootname),
-                         type=allroots[rootname][1], href=href))
-  data['roots'] = roots
-
-  if request.path_parts:
-    dir = _path_join(request.path_parts[:-1])
-    data['up_href'] = request.get_url(view_func=view_directory,
-                                      where=dir, pathtype=vclib.DIR,
-                                      params={}, escape=1)
-
-  if request.pathtype == vclib.FILE:
-    if (request.view_func is not view_log):
-      data['log_href'] = request.get_url(view_func=view_log,
-                                         params={}, escape=1)
-      if (request.view_func is view_diff):
-        data['log_href_rev'] = request.query_dict.get('r2')
-      elif (request.view_func is view_annotate):
-        # if user did "view=annotate" there may not be an annotate key
-        if request.query_dict.has_key('annotate'):
-          data['log_href_rev'] = request.query_dict.get('annotate')
-      elif request.query_dict.has_key('revision'):
-        data['log_href_rev'] = request.query_dict.get('revision')
-
-    if (request.roottype == 'cvs' and cfg.options.use_cvsgraph
-        and request.view_func is not view_cvsgraph):
-      data['graph_href'] = request.get_url(view_func=view_cvsgraph,
-                                           params={}, escape=1)
-  elif request.pathtype == vclib.DIR:
-    if request.roottype == 'svn':
-      data['log_href'] = request.get_url(view_func=view_log,
-                                         params={}, escape=1)
-
-  if is_query_supported(request):
-    data['rss_href'] = request.get_url(view_func=view_query,
-                                       params={'date': 'month',
-                                               'format': 'rss'},
-                                       escape=1)
-  return data
-
-def nav_header_data(request, rev, orig_path):
-  view_href, download_href, download_text_href, annotate_href, \
-             revision_href, prefer_markup \
-      = get_file_view_info(request, request.where, rev, request.mime_type)
-  
-  data = common_template_data(request)
-  data.update({
-    'rev' : rev,
-    'view_href' : view_href,
-    'annotate_href' : annotate_href,
-    'download_href' : download_href,
-    'download_text_href' : download_text_href,
-    'revision_href' : revision_href,
-    'prefer_markup' : prefer_markup,
-    'orig_path' : None,
-    'orig_href' : None,
-  })
-
-  if orig_path != request.path_parts:
-    path = _path_join(orig_path)
-    data['orig_path'] = path
-    data['orig_href'] = request.get_url(view_func=view_log,
-                                        where=path,
-                                        pathtype=vclib.FILE,
-                                        params={'pathrev': rev},
-                                        escape=1)
-
-  return data
-
-def retry_read(src, reqlen=CHUNK_SIZE):
-  while 1:
-    chunk = src.read(CHUNK_SIZE)
-    if not chunk:
-      # need to check for eof methods because the cStringIO file objects
-      # returned by ccvs don't provide them
-      if hasattr(src, 'eof') and src.eof() is None:
-        time.sleep(1)
-        continue
-    return chunk
-  
-def copy_stream(src, dst=None, htmlize=0):
-  if dst is None:
-    dst = sys.stdout
-  while 1:
-    chunk = retry_read(src)
-    if not chunk:
-      break
-    if htmlize:
-      chunk = htmlify(chunk)
-    dst.write(chunk)
-
-class MarkupPipeWrapper:
-  """An EZT callback that outputs a filepointer, plus some optional
-  pre- and post- text."""
-
-  def __init__(self, fp, pretext=None, posttext=None, htmlize=1):
-    self.fp = fp
-    self.pretext = pretext
-    self.posttext = posttext
-    self.htmlize = htmlize
-
-  def __call__(self, ctx):
-    if self.pretext:
-      ctx.fp.write(self.pretext)
-    copy_stream(self.fp, ctx.fp, self.htmlize)
-    self.fp.close()
-    if self.posttext:
-      ctx.fp.write(self.posttext)
-
-class MarkupShell:
-  """A EZT callback object slamming file contents through shell tools."""
-
-  def __init__(self, fp, cmds):
-    self.fp = fp
-    self.cmds = cmds
-
-  def __call__(self, ctx):
-    ctx.fp.flush()
-    try:
-      pipe = popen.pipe_cmds(self.cmds, ctx.fp)
-      try:
-        if self.fp:
-          copy_stream(self.fp, pipe)
-          self.fp.close()
-          self.fp = None
-      finally:
-        pipe.close()
-    except IOError:
-      raise debug.ViewVCException \
-        ('Error running external program. Command line was: "%s"'
-         % string.join(map(lambda args: string.join(args, ' '), self.cmds),
-                       ' | '))
-
-  def __del__(self):
-    self.close()
-
-  def close(self):
-    if self.fp:
-      self.fp.close()
-      self.fp = None
-
-class MarkupEnscript(MarkupShell):
-  def __init__(self, cfg, fp, filename):
-    
-    # I've tried to pass option '-C' to enscript to generate line numbers
-    # Unfortunately this option doesn't work with HTML output in enscript
-    # version 1.6.2.
-    enscript_cmd = [os.path.normpath(os.path.join(cfg.options.enscript_path,
-                                                  'enscript')),
-                    '--color', '--language=html', '--pretty-print',
-                    '-o', '-', '-']
-
-    ### I'd like to also strip the <PRE> and </PRE> tags, too, but
-    ### can't come up with a suitable sed expression.  Using
-    ### '1,/^<PRE>$/d;/<\\/PRE>/,$d;p' gets me most of the way, but
-    ### will drop the last line of a non-newline-terminated filed.
-    sed_cmd = ['sed', '-n', '/^<PRE>$/,/<\\/PRE>$/p']
-
-    MarkupShell.__init__(self, fp, [enscript_cmd, sed_cmd])
-    self.filename = filename
-
-  def __call__(self, ctx):
-    # create a temporary file with the same name as the file in
-    # the repository so enscript can detect file type correctly
-    dir = compat.mkdtemp()
-    try:
-      file = os.path.join(dir, self.filename)
-      try:
-        copy_stream(self.fp, open(file, 'wb'))
-        self.fp.close()
-        self.fp = None
-        self.cmds[0][-1] = file
-        MarkupShell.__call__(self, ctx)
-      finally:
-        os.unlink(file)
-    finally:
-       os.rmdir(dir)
-
-class MarkupPHP(MarkupShell):
-  def __init__(self, php_exe_path, fp):
-    php_cmd = [php_exe_path, '-q', '-s', '-n']
-    MarkupShell.__init__(self, fp, [php_cmd])
-
-class MarkupHighlight(MarkupShell):
-  def __init__(self, cfg, fp, filename):
-    try:
-      ext = filename[string.rindex(filename, ".") + 1:]
-    except ValueError:
-      ext = 'txt'
-
-    highlight_cmd = [os.path.normpath(os.path.join(cfg.options.highlight_path,
-                                                   'highlight')),
-                     '--syntax', ext, '--force',
-                     '--anchors', '--fragment', '--xhtml']
-
-    if cfg.options.highlight_line_numbers:
-      highlight_cmd.extend(['--linenumbers'])
-
-    if cfg.options.highlight_convert_tabs:
-      highlight_cmd.extend(['--replace-tabs',
-                            str(cfg.options.highlight_convert_tabs)])
-
-    MarkupShell.__init__(self, fp, [highlight_cmd])
-
-def markup_stream_python(fp, cfg):
-  ### Convert this code to use the recipe at:
-  ###     http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52298
-  ### Note that the cookbook states all the code is licensed according to
-  ### the Python license.
-  try:
-    # See if Marc-Andre Lemburg's py2html stuff is around.
-    # http://www.egenix.com/files/python/SoftwareDescriptions.html#py2html.py
-    ### maybe restrict the import to *only* this directory?
-    sys.path.insert(0, cfg.options.py2html_path)
-    import py2html
-    import PyFontify
-  except ImportError:
-    return None
-
-  ### It doesn't escape stuff quite right, nor does it munge URLs and
-  ### mailtos as well as we do.
-  html = cgi.escape(fp.read())
-  pp = py2html.PrettyPrint(PyFontify.fontify, "rawhtml", "color")
-  pp.set_mode_rawhtml_color()
-  html = pp.fontify(html)
-  html = re.sub(_re_rewrite_url, r'<a href="\1">\1</a>', html)
-  html = re.sub(_re_rewrite_email, r'<a href="mailto:\1">\1</a>', html)
-  return html
-
-def markup_stream_php(fp, cfg):
-  if not cfg.options.use_php:
-    return None
-
-  sys.stdout.flush()
-
-  # clearing the following environment variables prevents a 
-  # "No input file specified" error from the php cgi executable
-  # when ViewVC is running under a cgi environment. when the
-  # php cli executable is used they can be left alone
-  #
-  #os.putenv("GATEWAY_INTERFACE", "")
-  #os.putenv("PATH_TRANSLATED", "")
-  #os.putenv("REQUEST_METHOD", "")
-  #os.putenv("SERVER_NAME", "")
-  #os.putenv("SERVER_SOFTWARE", "")
-
-  return MarkupPHP(cfg.options.php_exe_path, fp)
-
-markup_streamers = {
-# '.py' : markup_stream_python,
-  '.php' : markup_stream_php,
-  '.inc' : markup_stream_php,
-  }
-
-def make_time_string(date, cfg):
-  """Returns formatted date string in either local time or UTC.
-
-  The passed in 'date' variable is seconds since epoch.
-
-  """
-  if date is None:
-    return 'Unknown date'
-  if cfg.options.use_localtime:
-    localtime = time.localtime(date)
-    return time.asctime(localtime) + ' ' + time.tzname[localtime[8]]
-  else:
-    return time.asctime(time.gmtime(date)) + ' UTC'
-
-def make_rss_time_string(date, cfg):
-  """Returns formatted date string in UTC, formatted for RSS.
-
-  The passed in 'date' variable is seconds since epoch.
-
-  """
-  if date is None:
-    return 'Unknown date'
-  return time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime(date)) + ' UTC'
-
-def view_markup(request):
-  cfg = request.cfg
-  path, rev = _orig_path(request)
-  fp, revision = request.repos.openfile(path, rev)
-
-  # Since the templates could be changed by the user, we can't provide
-  # a strong validator for this page, so we mark the etag as weak.
-  if check_freshness(request, None, revision, weak=1):
-    fp.close()
-    return
-
-  data = nav_header_data(request, revision, path)
-  data.update({
-    'mime_type' : request.mime_type,
-    'log' : None,
-    'date' : None,
-    'ago' : None,
-    'author' : None,
-    'branches' : None,
-    'tags' : None,
-    'branch_points' : None,
-    'changed' : None,
-    'size' : None,
-    'state' : None,
-    'vendor_branch' : None,
-    'prev' : None,
-    })
-
-  if cfg.options.show_log_in_markup:
-    options = {'svn_latest_log': 1}
-    revs = request.repos.itemlog(path, revision, options)
-    entry = revs[-1]
-    data.update({
-        'date' : make_time_string(entry.date, cfg),
-        'author' : entry.author,
-        'changed' : entry.changed,
-        'log' : htmlify(entry.log),
-        'size' : entry.size,
-        })
-
-    if entry.date is not None:
-      data['ago'] = html_time(request, entry.date, 1)
-      
-    if request.roottype == 'cvs':
-      branch = entry.branch_number
-      prev = entry.prev or entry.parent
-      data.update({
-        'state' : entry.dead and 'dead',
-        'prev' : prev and prev.string,
-        'vendor_branch' : ezt.boolean(branch and branch[2] % 2 == 1),
-        'branches' : string.join(map(lambda x: x.name, entry.branches), ', '),
-        'tags' : string.join(map(lambda x: x.name, entry.tags), ', '),
-        'branch_points': string.join(map(lambda x: x.name,
-                                         entry.branch_points), ', ')
-        })
-
-  markup_fp = None
-  if is_viewable_image(request.mime_type):
-    fp.close()
-    url = request.get_url(view_func=view_checkout, params={'revision': rev},
-                          escape=1)
-    markup_fp = '<img src="%s" alt="" /><br />' % url
-  else:
-    basename, ext = os.path.splitext(request.path_parts[-1])
-    streamer = markup_streamers.get(ext)
-    if streamer:
-      markup_fp = streamer(fp, cfg)
-    elif cfg.options.use_enscript:
-      markup_fp = MarkupEnscript(cfg, fp, request.path_parts[-1])
-    elif cfg.options.use_highlight:
-      markup_fp = MarkupHighlight(cfg, fp, request.path_parts[-1])
-
-  # If no one has a suitable markup handler, we'll use the default.
-  if not markup_fp:
-    markup_fp = MarkupPipeWrapper(fp)
-    
-  data['markup'] = markup_fp
-  
-  request.server.header()
-  generate_page(request, "markup", data)
-
-def revcmp(rev1, rev2):
-  rev1 = map(int, string.split(rev1, '.'))
-  rev2 = map(int, string.split(rev2, '.'))
-  return cmp(rev1, rev2)
-
-def prepare_hidden_values(params):
-  """returns variables from params encoded as a invisible HTML snippet.
-  """
-  hidden_values = []
-  for name, value in params.items():
-    hidden_values.append('<input type="hidden" name="%s" value="%s" />' %
-                         (name, value))
-  return string.join(hidden_values, '')
-
-def sort_file_data(file_data, roottype, sortdir, sortby, group_dirs):
-  # convert sortdir into a sign bit
-  s = sortdir == "down" and -1 or 1
-
-  # in cvs, revision numbers can't be compared meaningfully between
-  # files, so try to do the right thing and compare dates instead
-  if roottype == "cvs" and sortby == "rev":
-    sortby = "date"
-
-  def file_sort_cmp(file1, file2, sortby=sortby, group_dirs=group_dirs, s=s):
-    # if we're grouping directories together, sorting is pretty
-    # simple.  a directory sorts "higher" than a non-directory, and
-    # two directories are sorted as normal.
-    if group_dirs:
-      if file1.kind == vclib.DIR:
-        if file2.kind == vclib.DIR:
-          # two directories, no special handling.
-          pass
-        else:
-          # file1 is a directory, it sorts first.
-          return -1
-      elif file2.kind == vclib.DIR:
-        # file2 is a directory, it sorts first.
-        return 1
-
-    # we should have data on these. if not, then it is because we requested
-    # a specific tag and that tag is not present on the file.
-    if file1.rev is not None and file2.rev is not None:
-      # sort according to sortby
-      if sortby == 'rev':
-        return s * revcmp(file1.rev, file2.rev)
-      elif sortby == 'date':
-        return s * cmp(file2.date, file1.date)        # latest date is first
-      elif sortby == 'log':
-        return s * cmp(file1.log, file2.log)
-      elif sortby == 'author':
-        return s * cmp(file1.author, file2.author)
-    elif file1.rev is not None:
-      return -1
-    elif file2.rev is not None:
-      return 1
-
-    # sort by file name
-    return s * cmp(file1.name, file2.name)
-
-  file_data.sort(file_sort_cmp)
-
-def icmp(x, y):
-  """case insensitive comparison"""
-  return cmp(string.lower(x), string.lower(y))
-
-def view_roots(request):
-  data = common_template_data(request)
-  request.server.header()
-  generate_page(request, "roots", data)
-
-def view_directory(request):
-  # For Subversion repositories, the revision acts as a weak validator for
-  # the directory listing (to take into account template changes or
-  # revision property changes).
-  if request.roottype == 'svn':
-    rev = request.repos._getrev(request.pathrev)
-    tree_rev = vclib.svn.created_rev(request.repos, request.where, rev)
-    if check_freshness(request, None, str(tree_rev), weak=1):
-      return
-
-  # List current directory
-  cfg = request.cfg
-  options = {}
-  if request.roottype == 'cvs':
-    hideattic = int(request.query_dict.get('hideattic', 
-                                           cfg.options.hide_attic))
-    options["cvs_subdirs"] = (cfg.options.show_subdir_lastmod and
-                              cfg.options.show_logs)
-
-  file_data = request.repos.listdir(request.path_parts, request.pathrev,
-                                    options)
-
-  # Filter file list if a regex is specified
-  search_re = request.query_dict.get('search', '')
-  if cfg.options.use_re_search and search_re:
-    file_data = search_files(request.repos, request.path_parts, request.pathrev,
-                             file_data, search_re)
-
-  # Retrieve log messages, authors, revision numbers, timestamps
-  request.repos.dirlogs(request.path_parts, request.pathrev, file_data, options)
-
-  # sort with directories first, and using the "sortby" criteria
-  sortby = request.query_dict.get('sortby', cfg.options.sort_by) or 'file'
-  sortdir = request.query_dict.get('sortdir', 'up')
-  sort_file_data(file_data, request.roottype, sortdir, sortby,
-                 cfg.options.sort_group_dirs)
-
-  # loop through entries creating rows and changing these values
-  rows = [ ]
-  num_displayed = 0
-  num_dead = 0
-  
-  # set some values to be used inside loop
-  where = request.where
-  where_prefix = where and where + '/'
-
-  for file in file_data:
-    row = _item(graph_href=None, author=None, log=None, log_file=None,
-                log_rev=None, state=None, size=None, mime_type=None,
-                date=None, ago=None, view_href=None, log_href=None,
-                revision_href=None, annotate_href=None, download_href=None,
-                download_text_href=None, prefer_markup=ezt.boolean(0))
-
-    row.rev = file.rev
-    row.author = file.author
-    row.state = (request.roottype == 'cvs' and file.dead) and 'dead' or ''
-    if file.date is not None:
-      row.date = make_time_string(file.date, cfg)
-      row.ago = html_time(request, file.date)
-    if cfg.options.show_logs and file.log is not None:
-      row.log = format_log(file.log, cfg)
-
-    row.anchor = request.server.escape(file.name)
-    row.name = request.server.escape(file.name)
-    row.pathtype = (file.kind == vclib.FILE and 'file') or \
-                   (file.kind == vclib.DIR and 'dir')
-    row.errors = file.errors
-
-    if file.kind == vclib.DIR:
-
-      if (where == '') and (cfg.is_forbidden(file.name)):
-        continue
-
-      if (request.roottype == 'cvs' and cfg.options.hide_cvsroot
-          and where == '' and file.name == 'CVSROOT'):
-        continue
-    
-      row.view_href = request.get_url(view_func=view_directory,
-                                      where=where_prefix+file.name,
-                                      pathtype=vclib.DIR,
-                                      params={},
-                                      escape=1)
-
-      if request.roottype == 'svn':
-        row.revision_href = request.get_url(view_func=view_revision,
-                                            params={'revision': file.rev},
-                                            escape=1)
-
-      if request.roottype == 'cvs' and file.rev is not None:
-        row.rev = None
-        if cfg.options.show_logs:
-          row.log_file = file.newest_file
-          row.log_rev = file.rev
-
-      if request.roottype == 'svn':
-        row.log_href = request.get_url(view_func=view_log,
-                                       where=where_prefix + file.name,
-                                       pathtype=vclib.DIR,
-                                       params={},
-                                       escape=1)
-      
-    elif file.kind == vclib.FILE:
-      if request.roottype == 'cvs' and file.dead:
-        num_dead = num_dead + 1
-        if hideattic:
-          continue
-      num_displayed = num_displayed + 1
-
-      file_where = where_prefix + file.name
-      if request.roottype == 'svn': 
-        row.size = file.size
-
-      ### for Subversion, we should first try to get this from the properties
-      row.mime_type = guess_mime(file.name)
-      row.view_href, row.download_href, row.download_text_href, \
-                     row.annotate_href, row.revision_href, \
-                     row.prefer_markup \
-          = get_file_view_info(request, file_where, file.rev, row.mime_type)
-      row.log_href = request.get_url(view_func=view_log,
-                                     where=file_where,
-                                     pathtype=vclib.FILE,
-                                     params={},
-                                     escape=1)
-      if cfg.options.use_cvsgraph and request.roottype == 'cvs':
-         row.graph_href = request.get_url(view_func=view_cvsgraph,
-                                          where=file_where,
-                                          pathtype=vclib.FILE,
-                                          params={},
-                                          escape=1)
-
-    rows.append(row)
-
-  # prepare the data that will be passed to the template
-  data = common_template_data(request)
-  data.update({
-    'entries' : rows,
-    'sortby' : sortby,
-    'sortdir' : sortdir,
-    'tarball_href' : None,
-    'search_re' : search_re and htmlify(search_re) or None,
-    'dir_pagestart' : None,
-    'sortby_file_href' :   request.get_url(params={'sortby': 'file',
-                                                   'sortdir': None},
-                                           escape=1),
-    'sortby_rev_href' :    request.get_url(params={'sortby': 'rev',
-                                                   'sortdir': None},
-                                           escape=1),
-    'sortby_date_href' :   request.get_url(params={'sortby': 'date',
-                                                   'sortdir': None},
-                                           escape=1),
-    'sortby_author_href' : request.get_url(params={'sortby': 'author',
-                                                   'sortdir': None},
-                                           escape=1),
-    'sortby_log_href' :    request.get_url(params={'sortby': 'log',
-                                                   'sortdir': None},
-                                           escape=1),
-    'files_shown' : num_displayed,
-    'num_dead' : num_dead,
-    'youngest_rev' : None,
-    'youngest_rev_href' : None,
-    'selection_form' : None,
-    'queryform_href' : None,
-    'attic_showing' : None,
-    'show_attic_href' : None,
-    'hide_attic_href' : None,
-    'branch_tags': None,
-    'plain_tags': None,
-  })
-
-  # clicking on sort column reverses sort order
-  if sortdir == 'down':
-    revsortdir = None # 'up'
-  else:
-    revsortdir = 'down'
-  if sortby in ['file', 'rev', 'date', 'log', 'author']:
-    data['sortby_%s_href' % sortby] = request.get_url(params={'sortdir':
-                                                              revsortdir},
-                                                      escape=1)
-
-  # set cvs-specific fields
-  if request.roottype == 'cvs':
-    plain_tags = options['cvs_tags']
-    plain_tags.sort(icmp)
-    plain_tags.reverse()
-
-    branch_tags = options['cvs_branches']
-    branch_tags.sort(icmp)
-    branch_tags.reverse()
-
-    data.update({
-      'attic_showing' : ezt.boolean(not hideattic),
-      'show_attic_href' : request.get_url(params={'hideattic': 0}, escape=1),
-      'hide_attic_href' : request.get_url(params={'hideattic': 1}, escape=1),
-      'branch_tags': branch_tags,
-      'plain_tags': plain_tags,
-    })
-
-  # set svn-specific fields
-  elif request.roottype == 'svn':
-    data['tree_rev'] = tree_rev
-    data['tree_rev_href'] = request.get_url(view_func=view_revision,
-                                            params={'revision': tree_rev},
-                                            escape=1)
-    data['youngest_rev'] = vclib.svn.get_youngest_revision(request.repos)
-    data['youngest_rev_href'] = request.get_url(view_func=view_revision,
-                                                params={},
-                                                escape=1)
-
-  if is_query_supported(request):
-    params = {}
-    if request.roottype == 'cvs' and request.pathrev:
-      params['branch'] = request.pathrev
-    data['queryform_href'] = request.get_url(view_func=view_queryform,
-                                             params=params,
-                                             escape=1)
-
-  if cfg.options.use_pagesize:
-    data['dir_paging_action'], data['dir_paging_hidden_values'] = \
-      request.get_form(params={'dir_pagestart': None})
-
-  if cfg.options.allow_tar:
-    data['tarball_href'] = request.get_url(view_func=download_tarball, 
-                                           params={},
-                                           escape=1)
-
-  pathrev_form(request, data)
-
-  ### one day, if EZT has "or" capability, we can lose this
-  data['search_re_form'] = ezt.boolean(cfg.options.use_re_search
-                                       and (num_displayed > 0 or search_re))
-  if data['search_re_form']:
-    data['search_re_action'], data['search_re_hidden_values'] = \
-      request.get_form(params={'search': None})
-
-  if cfg.options.use_pagesize:
-    data['dir_pagestart'] = int(request.query_dict.get('dir_pagestart',0))
-    data['entries'] = paging(data, 'entries', data['dir_pagestart'], 'name',
-                             cfg.options.use_pagesize)
-
-  request.server.header()
-  generate_page(request, "directory", data)
-
-def paging(data, key, pagestart, local_name, pagesize):
-  # Implement paging
-  # Create the picklist
-  picklist = data['picklist'] = []
-  for i in range(0, len(data[key]), pagesize):
-    pick = _item(start=None, end=None, count=None)
-    pick.start = getattr(data[key][i], local_name)
-    pick.count = i
-    pick.page = (i / pagesize) + 1
-    try:
-      pick.end = getattr(data[key][i+pagesize-1], local_name)
-    except IndexError:
-      pick.end = getattr(data[key][-1], local_name)
-    picklist.append(pick)
-  data['picklist_len'] = len(picklist)
-  # Need to fix
-  # pagestart can be greater than the length of data[key] if you
-  # select a tag or search while on a page other than the first.
-  # Should reset to the first page, this test won't do that every
-  # time that it is needed.
-  # Problem might go away if we don't hide non-matching files when
-  # selecting for tags or searching.
-  if pagestart > len(data[key]):
-    pagestart = 0
-  pageend = pagestart + pagesize
-  # Slice
-  return data[key][pagestart:pageend]
-
-def pathrev_form(request, data):
-  lastrev = None
-
-  if request.roottype == 'svn':
-    data['pathrev_action'], data['pathrev_hidden_values'] = \
-      request.get_form(view_func=redirect_pathrev,
-                       params={'pathrev': None,
-                               'orig_path': request.where,
-                               'orig_pathtype': request.pathtype,
-                               'orig_pathrev': request.pathrev,
-                               'orig_view': _view_codes.get(request.view_func)})
-
-    if request.pathrev:
-      youngest = vclib.svn.get_youngest_revision(request.repos)
-      lastrev = vclib.svn.last_rev(request.repos, request.where,
-                                   request.pathrev, youngest)[0]
-
-      if lastrev == youngest:
-         lastrev = None
-
-  data['pathrev'] = request.pathrev
-  data['lastrev'] = lastrev
-
-  action, hidden_values = request.get_form(params={'pathrev': lastrev})
-  if request.roottype != 'svn':
-    data['pathrev_action'] = action
-    data['pathrev_hidden_values'] = hidden_values
-  data['pathrev_clear_action'] = action
-  data['pathrev_clear_hidden_values'] = hidden_values
-
-  return lastrev
-
-def redirect_pathrev(request):
-  assert request.roottype == 'svn'
-  new_pathrev = request.query_dict.get('pathrev') or None
-  path = request.query_dict.get('orig_path', '')
-  pathtype = request.query_dict.get('orig_pathtype')
-  pathrev = request.query_dict.get('orig_pathrev') 
-  view = _views.get(request.query_dict.get('orig_view'))
-  
-  youngest = vclib.svn.get_youngest_revision(request.repos)
-
-  # go out of the way to allow revision numbers higher than youngest
-  try:
-    new_pathrev = int(new_pathrev)
-  except ValueError:
-    pass
-  except TypeError:
-    pass
-  else:
-    if new_pathrev > youngest:
-      new_pathrev = youngest
-
-  if _repos_pathtype(request.repos, _path_parts(path), new_pathrev):
-    pathrev = new_pathrev
-  else:
-    pathrev, path = vclib.svn.last_rev(request.repos, path, pathrev, 
-                                       new_pathrev)
-    # allow clearing sticky revision by submitting empty string
-    if new_pathrev is None and pathrev == youngest:
-      pathrev = None
-
-  request.server.redirect(request.get_url(view_func=view, 
-                                          where=path,
-                                          pathtype=pathtype,
-                                          params={'pathrev': pathrev}))
-
-def logsort_date_cmp(rev1, rev2):
-  # sort on date; secondary on revision number
-  return -cmp(rev1.date, rev2.date) or -cmp(rev1.number, rev2.number)
-
-def logsort_rev_cmp(rev1, rev2):
-  # sort highest revision first
-  return -cmp(rev1.number, rev2.number)
-
-def view_log(request):
-  cfg = request.cfg
-  diff_format = request.query_dict.get('diff_format', cfg.options.diff_format)
-  logsort = request.query_dict.get('logsort', cfg.options.log_sort)
-  pathtype = request.pathtype
-
-  if pathtype is vclib.DIR and request.roottype == 'cvs':
-    raise debug.ViewVCException('Unsupported feature: log view on CVS '
-                                 'directory', '400 Bad Request')
-
-  options = {}
-  options['svn_show_all_dir_logs'] = 1 ### someday make this optional?
-  options['svn_cross_copies'] = cfg.options.cross_copies
-    
-  show_revs = request.repos.itemlog(request.path_parts, request.pathrev,
-                                    options)
-  if logsort == 'date':
-    show_revs.sort(logsort_date_cmp)
-  elif logsort == 'rev':
-    show_revs.sort(logsort_rev_cmp)
-  else:
-    # no sorting
-    pass
-
-  # selected revision
-  selected_rev = request.query_dict.get('r1')
-
-  entries = [ ]
-  name_printed = { }
-  cvs = request.roottype == 'cvs'
-  for rev in show_revs:
-    entry = _item()
-    entry.rev = rev.string
-    entry.state = (cvs and rev.dead and 'dead')
-    entry.author = rev.author
-    entry.changed = rev.changed
-    entry.date = make_time_string(rev.date, cfg)
-    entry.ago = None
-    if rev.date is not None:
-      entry.ago = html_time(request, rev.date, 1)
-    entry.log = htmlify(rev.log or "")
-    entry.size = rev.size
-    entry.branch_point = None
-    entry.next_main = None
-    entry.orig_path = None
-    entry.copy_path = None
-
-    entry.view_href = None
-    entry.download_href = None
-    entry.download_text_href = None
-    entry.annotate_href = None
-    entry.revision_href = None
-    entry.sel_for_diff_href = None
-    entry.diff_to_sel_href = None
-    entry.diff_to_prev_href = None
-    entry.diff_to_branch_href = None
-    entry.diff_to_main_href = None
-        
-    if request.roottype == 'cvs':
-      prev = rev.prev or rev.parent
-      entry.prev = prev and prev.string
-
-      branch = rev.branch_number
-      entry.vendor_branch = ezt.boolean(branch and branch[2] % 2 == 1)
-
-      entry.branches = prep_tags(request, rev.branches)
-      entry.tags = prep_tags(request, rev.tags)
-      entry.branch_points = prep_tags(request, rev.branch_points)
-
-      entry.tag_names = map(lambda x: x.name, rev.tags)
-      if branch and not name_printed.has_key(branch):
-        entry.branch_names = map(lambda x: x.name, rev.branches)
-        name_printed[branch] = 1
-      else:
-        entry.branch_names = [ ]
-
-      if rev.parent and rev.parent is not prev and not entry.vendor_branch:
-        entry.branch_point = rev.parent.string
-
-      # if it's the last revision on a branch then diff against the
-      # last revision on the higher branch (e.g. change is committed and
-      # brought over to -stable)
-      if not rev.next and rev.parent and rev.parent.next:
-        r = rev.parent.next
-        while r.next:
-          r = r.next
-        entry.next_main = r.string
-
-    elif request.roottype == 'svn':
-      entry.prev = rev.prev and rev.prev.string
-      entry.branches = entry.tags = entry.branch_points = [ ]
-      entry.tag_names = entry.branch_names = [ ]
-      entry.vendor_branch = None
-      if rev.filename != request.where:
-        entry.orig_path = rev.filename
-      entry.copy_path = rev.copy_path
-      entry.copy_rev = rev.copy_rev
-
-      if entry.orig_path:
-        entry.orig_href = request.get_url(view_func=view_log,
-                                          where=entry.orig_path,
-                                          pathtype=vclib.FILE,
-                                          params={'pathrev': rev.string},
-                                          escape=1)
-
-      if rev.copy_path:
-        entry.copy_href = request.get_url(view_func=view_log,
-                                          where=rev.copy_path,
-                                          pathtype=vclib.FILE,
-                                          params={'pathrev': rev.copy_rev},
-                                          escape=1)
-
-
-    # view/download links
-    if pathtype is vclib.FILE:
-      entry.view_href, entry.download_href, entry.download_text_href, \
-        entry.annotate_href, entry.revision_href, entry.prefer_markup \
-        = get_file_view_info(request, request.where, rev.string,
-                             request.mime_type)
-    else:
-      entry.revision_href = request.get_url(view_func=view_revision,
-                                            params={'revision': rev.string},
-                                            escape=1)
-      entry.view_href = request.get_url(view_func=view_directory,
-                                        where=rev.filename,
-                                        pathtype=vclib.DIR,
-                                        params={'pathrev': rev.string},
-                                        escape=1)
-
-    # calculate diff links
-    if selected_rev != entry.rev:
-      entry.sel_for_diff_href = \
-        request.get_url(view_func=view_log, params={'r1': entry.rev}, escape=1)
-    if entry.prev is not None:
-      entry.diff_to_prev_href = \
-        request.get_url(view_func=view_diff,
-                        params={'r1': entry.prev,
-                                'r2': entry.rev,
-                                'diff_format': None},
-                        escape=1)
-    if selected_rev and \
-           selected_rev != str(entry.rev) and \
-           selected_rev != str(entry.prev) and \
-           selected_rev != str(entry.branch_point) and \
-           selected_rev != str(entry.next_main):
-      entry.diff_to_sel_href = \
-        request.get_url(view_func=view_diff,
-                        params={'r1': selected_rev,
-                                'r2': entry.rev,
-                                'diff_format': None},
-                        escape=1)
-
-    if entry.next_main:
-      entry.diff_to_main_href = \
-        request.get_url(view_func=view_diff,
-                        params={'r1': entry.next_main,
-                                'r2': entry.rev,
-                                'diff_format': None},
-                        escape=1)
-    if entry.branch_point:
-      entry.diff_to_branch_href = \
-        request.get_url(view_func=view_diff,
-                        params={'r1': entry.branch_point,
-                                'r2': entry.rev,
-                                'diff_format': None},
-                        escape=1)
-
-    # Save our escaping until the end so stuff above works
-    if entry.orig_path:
-      entry.orig_path = request.server.escape(entry.orig_path)
-    if entry.copy_path:
-      entry.copy_path = request.server.escape(entry.copy_path)
-    entries.append(entry)
-
-  data = common_template_data(request)
-  data.update({
-    'default_branch' : None,
-    'mime_type' : request.mime_type,
-    'rev_selected' : selected_rev,
-    'diff_format' : diff_format,
-    'logsort' : logsort,
-    'human_readable' : ezt.boolean(diff_format in ('h', 'l')),
-    'log_pagestart' : None,
-    'entries': entries,
-    'prefer_markup' : ezt.boolean(0),
-    'view_href' : None,
-    'download_href': None,
-    'download_text_href': None,
-    'annotate_href': None,
-    'tag_prefer_markup' : ezt.boolean(0),
-    'tag_view_href' : None,
-    'tag_download_href': None,
-    'tag_download_text_href': None,
-    'tag_annotate_href': None,
-  })
-
-  lastrev = pathrev_form(request, data)
-
-  if cfg.options.use_pagesize:
-    data['log_paging_action'], data['log_paging_hidden_values'] = \
-      request.get_form(params={'log_pagestart': None})
-  
-  data['diff_select_action'], data['diff_select_hidden_values'] = \
-    request.get_form(view_func=view_diff,
-                     params={'r1': None, 'r2': None, 'tr1': None,
-                             'tr2': None, 'diff_format': None})
-
-  data['logsort_action'], data['logsort_hidden_values'] = \
-    request.get_form(params={'logsort': None})
-
-  if pathtype is vclib.FILE:
-    if not request.pathrev or lastrev is None:
-      view_href, download_href, download_text_href, \
-        annotate_href, revision_href, prefer_markup \
-        = get_file_view_info(request, request.where, None,
-                             request.mime_type, None)
-      data.update({
-        'view_href': view_href,
-        'download_href': download_href,
-        'download_text_href': download_text_href,
-        'annotate_href': annotate_href,
-        'prefer_markup': prefer_markup,
-        })
-
-    if request.pathrev and request.roottype == 'cvs':
-      view_href, download_href, download_text_href, \
-        annotate_href, revision_href, prefer_markup \
-        = get_file_view_info(request, request.where, None, request.mime_type)
-      data.update({
-        'tag_view_href': view_href,
-        'tag_download_href': download_href,
-        'tag_download_text_href': download_text_href,
-        'tag_annotate_href': annotate_href,
-        'tag_prefer_markup': prefer_markup,
-        })
-  else:
-    if not request.pathrev:
-      data['view_href'] = request.get_url(view_func=view_directory, 
-                                          params={}, escape=1)
-
-  taginfo = options.get('cvs_tags', {})
-  tagitems = taginfo.items()
-  tagitems.sort()
-  tagitems.reverse()
-
-  main = taginfo.get('MAIN')
-  if main:
-    # Default branch may have multiple names so we list them
-    branches = []
-    for branch in main.aliases:
-      # Don't list MAIN
-      if branch is not main:
-        branches.append(branch)
-    data['default_branch'] = prep_tags(request, branches)
-
-  data['tags'] = tags = [ ]
-  data['branch_tags'] = branch_tags = []
-  data['plain_tags'] = plain_tags = []
-  for tag, rev in tagitems:
-    if rev.co_rev:
-      tags.append(_item(rev=rev.co_rev.string, name=tag))
-    if rev.is_branch:
-      branch_tags.append(tag)
-    else:
-      plain_tags.append(tag)
-
-  if cfg.options.use_pagesize:
-    data['log_pagestart'] = int(request.query_dict.get('log_pagestart',0))
-    data['entries'] = paging(data, 'entries', data['log_pagestart'],
-                             'revision', cfg.options.use_pagesize)
-
-  request.server.header()
-  generate_page(request, "log", data)
-
-def view_checkout(request):
-  path, rev = _orig_path(request)
-  fp, revision = request.repos.openfile(path, rev)
-
-  # The revision number acts as a strong validator.
-  if not check_freshness(request, None, revision):
-    request.server.header(request.query_dict.get('content-type')
-                          or request.mime_type or 'text/plain')
-    copy_stream(fp)
-  fp.close()
-
-def view_annotate(request):
-  if not request.cfg.options.allow_annotate:
-    raise debug.ViewVCException('Annotation view is disabled',
-                                 '403 Forbidden')
-
-  path, rev = _orig_path(request, 'annotate')
-
-  ### be nice to hook this into the template...
-  import blame
-
-  diff_url = request.get_url(view_func=view_diff,
-                             params={'r1': None, 'r2': None},
-			     escape=1, partial=1)
-
-  include_url = request.get_url(view_func=view_log, where='/WHERE/',
-                                pathtype=vclib.FILE, params={}, escape=1)
-
-  source, revision = blame.blame(request.repos, path,
-                                 diff_url, include_url, rev)
-
-  data = nav_header_data(request, revision, path)
-  data['lines'] = source
-
-  request.server.header()
-  generate_page(request, "annotate", data)
-
-def view_cvsgraph_image(request):
-  "output the image rendered by cvsgraph"
-  # this function is derived from cgi/cvsgraphmkimg.cgi
-
-  cfg = request.cfg
-
-  if not cfg.options.use_cvsgraph:
-    raise debug.ViewVCException('Graph view is disabled', '403 Forbidden')
-  
-  request.server.header('image/png')
-  rcsfile = request.repos.rcsfile(request.path_parts)
-  fp = popen.popen(os.path.normpath(os.path.join(cfg.options.cvsgraph_path,
-                                                 'cvsgraph')),
-                   ("-c", _install_path(cfg.options.cvsgraph_conf),
-                    "-r", request.repos.rootpath,
-                    rcsfile), 'rb', 0)
-  copy_stream(fp)
-  fp.close()
-
-def view_cvsgraph(request):
-  "output a page containing an image rendered by cvsgraph"
-
-  cfg = request.cfg
-
-  if not cfg.options.use_cvsgraph:
-    raise debug.ViewVCException('Graph view is disabled', '403 Forbidden')
-
-  data = common_template_data(request)
-
-  # Required only if cvsgraph needs to find it's supporting libraries.
-  # Uncomment and set accordingly if required.
-  #os.environ['LD_LIBRARY_PATH'] = '/usr/lib:/usr/local/lib'
-
-  imagesrc = request.get_url(view_func=view_cvsgraph_image, escape=1)
-
-  view = default_view(request.mime_type, cfg)
-  up_where = _path_join(request.path_parts[:-1])
-
-  # Create an image map
-  rcsfile = request.repos.rcsfile(request.path_parts)
-  fp = popen.popen(os.path.join(cfg.options.cvsgraph_path, 'cvsgraph'),
-                   ("-i",
-                    "-c", _install_path(cfg.options.cvsgraph_conf),
-                    "-r", request.repos.rootpath,
-                    "-x", "x",
-                    "-3", request.get_url(view_func=view_log, params={},
-                                          escape=1),
-                    "-4", request.get_url(view_func=view, 
-                                          params={'revision': None},
-                                          escape=1, partial=1),
-                    "-5", request.get_url(view_func=view_diff,
-                                          params={'r1': None, 'r2': None},
-                                          escape=1, partial=1),
-                    "-6", request.get_url(view_func=view_directory,
-                                          where=up_where,
-                                          pathtype=vclib.DIR,
-                                          params={'pathrev': None},
-                                          escape=1, partial=1),
-                    rcsfile), 'rb', 0)
-
-  data.update({
-    'imagemap' : fp,
-    'imagesrc' : imagesrc,
-    })
-
-  request.server.header()
-  generate_page(request, "graph", data)
-
-def search_files(repos, path_parts, rev, files, search_re):
-  """ Search files in a directory for a regular expression.
-
-  Does a check-out of each file in the directory.  Only checks for
-  the first match.  
-  """
-
-  # Pass in search regular expression. We check out
-  # each file and look for the regular expression. We then return the data
-  # for all files that match the regex.
-
-  # Compile to make sure we do this as fast as possible.
-  searchstr = re.compile(search_re)
-
-  # Will become list of files that have at least one match.
-  # new_file_list also includes directories.
-  new_file_list = [ ]
-
-  # Loop on every file (and directory)
-  for file in files:
-    # Is this a directory?  If so, append name to new_file_list
-    # and move to next file.
-    if file.kind != vclib.FILE:
-      new_file_list.append(file)
-      continue
-
-    # Only files at this point
-    
-    # Shouldn't search binary files, or should we?
-    # Should allow all text mime types to pass.
-    if not is_text(guess_mime(file.name)):
-      continue
-
-    # Only text files at this point
-
-    # Assign contents of checked out file to fp.
-    fp = repos.openfile(path_parts + [file.name], rev)[0]
-
-    # Read in each line, use re.search to search line.
-    # If successful, add file to new_file_list and break.
-    while 1:
-      line = fp.readline()
-      if not line:
-        break
-      if searchstr.search(line):
-        new_file_list.append(file)
-        # close down the pipe (and wait for the child to terminate)
-        fp.close()
-        break
-
-  return new_file_list
-
-
-def view_doc(request):
-  """Serve ViewVC static content locally.
-
-  Using this avoids the need for modifying the setup of the web server.
-  """
-  document = request.where
-  filename = _install_path(os.path.join(request.cfg.options.template_dir,
-                                        "docroot", document))
-
-  # Stat the file to get content length and last-modified date.
-  try:
-    info = os.stat(filename)
-  except OSError, v:
-    raise debug.ViewVCException('Static file "%s" not available\n(%s)'
-                                 % (document, str(v)), '404 Not Found')
-  content_length = str(info[stat.ST_SIZE])
-  last_modified = info[stat.ST_MTIME]
-
-  # content_length + mtime makes a pretty good etag.
-  if check_freshness(request, last_modified,
-                     "%s-%s" % (content_length, last_modified)):
-    return
-
-  try:
-    fp = open(filename, "rb")
-  except IOError, v:
-    raise debug.ViewVCException('Static file "%s" not available\n(%s)'
-                                 % (document, str(v)), '404 Not Found')
-
-  request.server.addheader('Content-Length', content_length)
-  if document[-3:] == 'png':
-    request.server.header('image/png')
-  elif document[-3:] == 'jpg':
-    request.server.header('image/jpeg')
-  elif document[-3:] == 'gif':
-    request.server.header('image/gif')
-  elif document[-3:] == 'css':
-    request.server.header('text/css')
-  else: # assume HTML:
-    request.server.header()
-  copy_stream(fp)
-  fp.close()
-
-def rcsdiff_date_reformat(date_str, cfg):
-  if date_str is None:
-    return None
-  try:
-    date = compat.cvs_strptime(date_str)
-  except ValueError:
-    return date_str
-  return make_time_string(compat.timegm(date), cfg)
-
-_re_extract_rev = re.compile(r'^[-+*]{3} [^\t]+\t([^\t]+)\t((\d+\.)*\d+)$')
-_re_extract_info = re.compile(r'@@ \-([0-9]+).*\+([0-9]+).*@@(.*)')
-
-def spaced_html_text(text, cfg):
-  text = string.expandtabs(string.rstrip(text))
-  hr_breakable = cfg.options.hr_breakable
-  
-  # in the code below, "\x01" will be our stand-in for "&". We don't want
-  # to insert "&" because it would get escaped by htmlify().  Similarly,
-  # we use "\x02" as a stand-in for "<br>"
-
-  if hr_breakable > 1 and len(text) > hr_breakable:
-    text = re.sub('(' + ('.' * hr_breakable) + ')', '\\1\x02', text)
-  if hr_breakable:
-    # make every other space "breakable"
-    text = string.replace(text, '  ', ' \x01nbsp;')
-  else:
-    text = string.replace(text, ' ', '\x01nbsp;')
-  text = htmlify(text)
-  text = string.replace(text, '\x01', '&')
-  text = string.replace(text, '\x02', '<span style="color:red">\</span><br />')
-  return text
-
-class DiffSource:
-  def __init__(self, fp, cfg):
-    self.fp = fp
-    self.cfg = cfg
-    self.save_line = None
-    self.line_number = None
-    
-    # keep track of where we are during an iteration
-    self.idx = -1
-    self.last = None
-
-    # these will be set once we start reading
-    self.state = 'no-changes'
-    self.left_col = [ ]
-    self.right_col = [ ]
-
-  def __getitem__(self, idx):
-    if idx == self.idx:
-      return self.last
-    if idx != self.idx + 1:
-      raise DiffSequencingError()
-
-    # keep calling _get_row until it gives us something. sometimes, it
-    # doesn't return a row immediately because it is accumulating changes.
-    # when it is out of data, _get_row will raise IndexError.
-    while 1:
-      item = self._get_row()
-      if item:
-        self.idx = idx
-        self.last = item
-        return item
-
-  def _get_row(self):
-    if self.state[:5] == 'flush':
-      item = self._flush_row()
-      if item:
-        return item
-      self.state = 'dump'
-
-    if self.save_line:
-      line = self.save_line
-      self.save_line = None
-    else:
-      line = self.fp.readline()
-
-    if not line:
-      if self.state == 'no-changes':
-        self.state = 'done'
-        return _item(type='no-changes')
-
-      # see if there are lines to flush
-      if self.left_col or self.right_col:
-        # move into the flushing state
-        self.state = 'flush-' + self.state
-        return None
-
-      # nothing more to return
-      raise IndexError
-
-    if line[:2] == '@@':
-      self.state = 'dump'
-      self.left_col = [ ]
-      self.right_col = [ ]
-
-      match = _re_extract_info.match(line)
-      self.line_number = int(match.group(2)) - 1
-      return _item(type='header',
-                   line_info_left=match.group(1),
-                   line_info_right=match.group(2),
-                   line_info_extra=match.group(3))
-    
-    if line[0] == '\\':
-      # \ No newline at end of file
-
-      # move into the flushing state. note: it doesn't matter if we really
-      # have data to flush or not; that will be figured out later
-      self.state = 'flush-' + self.state
-      return None
-
-    diff_code = line[0]
-    output = spaced_html_text(line[1:], self.cfg)
-    
-    if diff_code == '+':
-      if self.state == 'dump':
-        self.line_number = self.line_number + 1
-        return _item(type='add', right=output, line_number=self.line_number)
-
-      self.state = 'pre-change-add'
-      self.right_col.append(output)
-      return None
-
-    if diff_code == '-':
-      self.state = 'pre-change-remove'
-      self.left_col.append(output)
-      return None  # early exit to avoid line in
-
-    if self.left_col or self.right_col:
-      # save the line for processing again later, and move into the
-      # flushing state
-      self.save_line = line
-      self.state = 'flush-' + self.state
-      return None
-
-    self.line_number = self.line_number + 1
-    return _item(type='context', left=output, right=output,
-                 line_number=self.line_number)
-
-  def _flush_row(self):
-    if not self.left_col and not self.right_col:
-      # nothing more to flush
-      return None
-
-    if self.state == 'flush-pre-change-remove':
-      return _item(type='remove', left=self.left_col.pop(0))
-
-    # state == flush-pre-change-add
-    item = _item(type='change',
-                 have_left=ezt.boolean(0),
-                 have_right=ezt.boolean(0))
-    if self.left_col:
-      item.have_left = ezt.boolean(1)
-      item.left = self.left_col.pop(0)
-    if self.right_col:
-      self.line_number = self.line_number + 1
-      item.have_right = ezt.boolean(1)
-      item.right = self.right_col.pop(0)
-      item.line_number = self.line_number
-    return item
-
-class DiffSequencingError(Exception):
-  pass
-
-def diff_parse_headers(fp, diff_type, rev1, rev2, sym1=None, sym2=None):
-  date1 = date2 = log_rev1 = log_rev2 = flag = None
-  header_lines = []
-
-  if diff_type == vclib.UNIFIED:
-    f1 = '--- '
-    f2 = '+++ '
-  elif diff_type == vclib.CONTEXT:
-    f1 = '*** '
-    f2 = '--- '
-  else:
-    f1 = f2 = None
-
-  # If we're parsing headers, then parse and tweak the diff headers,
-  # collecting them in an array until we've read and handled them all.
-  if f1 and f2:
-    parsing = 1
-    len_f1 = len(f1)
-    len_f2 = len(f2)
-    while parsing:
-      line = fp.readline()
-      if not line:
-        break
-
-      if line[:len(f1)] == f1:
-        match = _re_extract_rev.match(line)
-        if match:
-          date1 = match.group(1)
-          log_rev1 = match.group(2)
-        if sym1:
-          line = line[:-1] + ' %s\n' % sym1
-      elif line[:len(f2)] == f2:
-        match = _re_extract_rev.match(line)
-        if match:
-          date2 = match.group(1)
-          log_rev2 = match.group(2)
-        if sym2:
-          line = line[:-1] + ' %s\n' % sym2
-        parsing = 0
-      elif line[:3] == 'Bin':
-        flag = _RCSDIFF_IS_BINARY
-        parsing = 0
-      elif (string.find(line, 'not found') != -1 or 
-            string.find(line, 'illegal option') != -1):
-        flag = _RCSDIFF_ERROR
-        parsing = 0
-      header_lines.append(line)
-
-  if (log_rev1 and log_rev1 != rev1):
-    raise debug.ViewVCException('rcsdiff found revision %s, but expected '
-                                 'revision %s' % (log_rev1, rev1),
-                                 '500 Internal Server Error')
-  if (log_rev2 and log_rev2 != rev2):
-    raise debug.ViewVCException('rcsdiff found revision %s, but expected '
-                                 'revision %s' % (log_rev2, rev2),
-                                 '500 Internal Server Error')
-
-  return date1, date2, flag, string.join(header_lines, '')
-
-
-def _get_diff_path_parts(request, query_key, rev, base_rev):
-  if request.query_dict.has_key(query_key):
-    parts = _path_parts(request.query_dict[query_key])
-  elif request.roottype == 'svn':
-    try:
-      repos = request.repos
-      parts = _path_parts(vclib.svn.get_location(repos, request.where,
-                                                 repos._getrev(base_rev),
-                                                 repos._getrev(rev)))
-    except vclib.InvalidRevision:
-      raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
-                                   'to diff', '400 Bad Request')
-    except vclib.ItemNotFound:
-      raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
-                                   'to diff', '400 Bad Request')
-  else:
-    parts = request.path_parts
-  return parts
-
-
-def setup_diff(request):
-  query_dict = request.query_dict
-
-  rev1 = r1 = query_dict['r1']
-  rev2 = r2 = query_dict['r2']
-  sym1 = sym2 = None
-
-  # hack on the diff revisions
-  if r1 == 'text':
-    rev1 = query_dict.get('tr1', None)
-    if not rev1:
-      raise debug.ViewVCException('Missing revision from the diff '
-                                   'form text field', '400 Bad Request')
-  else:
-    idx = string.find(r1, ':')
-    if idx == -1:
-      rev1 = r1
-    else:
-      rev1 = r1[:idx]
-      sym1 = r1[idx+1:]
-      
-  if r2 == 'text':
-    rev2 = query_dict.get('tr2', None)
-    if not rev2:
-      raise debug.ViewVCException('Missing revision from the diff '
-                                   'form text field', '400 Bad Request')
-    sym2 = ''
-  else:
-    idx = string.find(r2, ':')
-    if idx == -1:
-      rev2 = r2
-    else:
-      rev2 = r2[:idx]
-      sym2 = r2[idx+1:]
-
-  if request.roottype == 'svn':
-    rev1 = str(request.repos._getrev(rev1))
-    rev2 = str(request.repos._getrev(rev2))
-    
-  p1 = _get_diff_path_parts(request, 'p1', rev1, request.pathrev)
-  p2 = _get_diff_path_parts(request, 'p2', rev2, request.pathrev)
-
-  try:
-    if revcmp(rev1, rev2) > 0:
-      rev1, rev2 = rev2, rev1
-      sym1, sym2 = sym2, sym1
-      p1, p2 = p2, p1
-  except ValueError:
-    raise debug.ViewVCException('Invalid revision(s) passed to diff',
-                                 '400 Bad Request')
-  return p1, p2, rev1, rev2, sym1, sym2
-
-
-def view_patch(request):
-  cfg = request.cfg
-  query_dict = request.query_dict
-  p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request)
-
-  # In the absence of a format dictation in the CGI params, we'll let
-  # use the configured diff format, allowing 'c' to mean 'c' and
-  # anything else to mean 'u'.
-  format = query_dict.get('diff_format',
-                          cfg.options.diff_format == 'c' and 'c' or 'u')
-  if format == 'c':
-    diff_type = vclib.CONTEXT
-  elif format == 'u':
-    diff_type = vclib.UNIFIED
-  else:
-    raise debug.ViewVCException('Diff format %s not understood'
-                                 % format, '400 Bad Request')
-  
-  try:
-    fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type)
-  except vclib.InvalidRevision:
-    raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
-                                 'to diff', '400 Bad Request')
-
-  date1, date2, flag, headers = diff_parse_headers(fp, diff_type, rev1, rev2,
-                                                   sym1, sym2)
-
-  request.server.header('text/plain')
-  sys.stdout.write(headers)
-  copy_stream(fp)
-  fp.close()
-
-
-def view_diff(request):
-  cfg = request.cfg
-  query_dict = request.query_dict
-  p1, p2, rev1, rev2, sym1, sym2 = setup_diff(request)
-  
-  # since templates are in use and subversion allows changes to the dates,
-  # we can't provide a strong etag
-  if check_freshness(request, None, '%s-%s' % (rev1, rev2), weak=1):
-    return
-
-  diff_type = None
-  diff_options = {}
-  human_readable = 0
-
-  format = query_dict.get('diff_format', cfg.options.diff_format)
-  if format == 'c':
-    diff_type = vclib.CONTEXT
-  elif format == 's':
-    diff_type = vclib.SIDE_BY_SIDE
-  elif format == 'l':
-    diff_type = vclib.UNIFIED
-    diff_options['context'] = 15
-    human_readable = 1
-  elif format == 'h':
-    diff_type = vclib.UNIFIED
-    human_readable = 1
-  elif format == 'u':
-    diff_type = vclib.UNIFIED
-  else:
-    raise debug.ViewVCException('Diff format %s not understood'
-                                 % format, '400 Bad Request')
-
-  if human_readable:
-    diff_options['funout'] = cfg.options.hr_funout
-    diff_options['ignore_white'] = cfg.options.hr_ignore_white
-    diff_options['ignore_keyword_subst'] = cfg.options.hr_ignore_keyword_subst
-  try:
-    fp = sidebyside = unified = None
-    if (cfg.options.hr_intraline and idiff
-        and ((human_readable and idiff.sidebyside)
-             or (not human_readable and diff_type == vclib.UNIFIED))):
-      f1 = request.repos.openfile(p1, rev1)[0]
-      try:
-        lines_left = f1.readlines()
-      finally:
-        f1.close()
-
-      f2 = request.repos.openfile(p2, rev2)[0]
-      try:
-        lines_right = f2.readlines()
-      finally:
-        f2.close()
-
-      if human_readable:
-        sidebyside = idiff.sidebyside(lines_left, lines_right,
-                                      diff_options.get("context", 5))
-      else:
-        unified = idiff.unified(lines_left, lines_right,
-                                diff_options.get("context", 2))
-    else: 
-      fp = request.repos.rawdiff(p1, rev1, p2, rev2, diff_type, diff_options)
-  except vclib.InvalidRevision:
-    raise debug.ViewVCException('Invalid path(s) or revision(s) passed '
-                                 'to diff', '400 Bad Request')
-  data = common_template_data(request)
-  data.update({
-    'path_left': _path_join(p1),
-    'path_right': _path_join(p2),
-    'rev_left' : rev1,
-    'rev_right' : rev2,
-    'tag_left' : sym1,
-    'tag_right' : sym2,
-    'diff_format' : request.query_dict.get('diff_format',
-                                           cfg.options.diff_format),
-    'annotate_href' : None,
-    })
-
-  orig_params = request.query_dict.copy()
-  orig_params['diff_format'] = None
-    
-  data['diff_format_action'], data['diff_format_hidden_values'] = \
-    request.get_form(params=orig_params)
-  data['patch_href'] = request.get_url(view_func=view_patch,
-                                       params=orig_params,
-                                       escape=1)
-  if request.cfg.options.allow_annotate:
-    data['annotate_href'] = request.get_url(view_func=view_annotate,
-                                            where=_path_join(p2),
-                                            pathtype=vclib.FILE,
-                                            params={'annotate': rev2},
-                                            escape=1)
-  if fp:
-    date1, date2, flag, headers = diff_parse_headers(fp, diff_type, rev1, rev2,
-                                                     sym1, sym2)
-  else:
-    date1 = date2 = flag = headers = None
-
-  raw_diff_fp = changes = None
-  if fp:
-    if human_readable:
-      if flag is not None:
-        changes = [ _item(type=flag) ]
-      else:
-        changes = DiffSource(fp, cfg)
-    else:
-      raw_diff_fp = MarkupPipeWrapper(fp, htmlify(headers), None, 1)
-
-  data.update({
-    'date_left' : rcsdiff_date_reformat(date1, cfg),
-    'date_right' : rcsdiff_date_reformat(date2, cfg),
-    'raw_diff' : raw_diff_fp,
-    'changes' : changes,
-    'sidebyside': sidebyside,
-    'unified': unified,
-    })
-
-  request.server.header()
-  generate_page(request, "diff", data)
-
-
-def generate_tarball_header(out, name, size=0, mode=None, mtime=0,
-                            uid=0, gid=0, typefrag=None, linkname='',
-                            uname='viewvc', gname='viewvc',
-                            devmajor=1, devminor=0, prefix=None,
-                            magic='ustar', version='', chksum=None):
-  if not mode:
-    if name[-1:] == '/':
-      mode = 0755
-    else:
-      mode = 0644
-
-  if not typefrag:
-    if name[-1:] == '/':
-      typefrag = '5' # directory
-    else:
-      typefrag = '0' # regular file
-
-  if not prefix:
-    prefix = ''
-
-  block1 = struct.pack('100s 8s 8s 8s 12s 12s',
-    name,
-    '%07o' % mode,
-    '%07o' % uid,
-    '%07o' % gid,
-    '%011o' % size,
-    '%011o' % mtime)
-
-  block2 = struct.pack('c 100s 6s 2s 32s 32s 8s 8s 155s',
-    typefrag,
-    linkname,
-    magic,
-    version,
-    uname,
-    gname,
-    '%07o' % devmajor,
-    '%07o' % devminor,
-    prefix)
-
-  if not chksum:
-    dummy_chksum = '        '
-    block = block1 + dummy_chksum + block2
-    chksum = 0
-    for i in range(len(block)):
-      chksum = chksum + ord(block[i])
-
-  block = block1 + struct.pack('8s', '%07o' % chksum) + block2
-  block = block + '\0' * (512 - len(block))
-
-  out.write(block)
-
-def generate_tarball(out, request, reldir, stack):
-  # get directory info from repository
-  rep_path = request.path_parts + reldir
-  entries = request.repos.listdir(rep_path, request.pathrev, {})
-  request.repos.dirlogs(rep_path, request.pathrev, entries, {})
-  entries.sort(lambda a, b: cmp(a.name, b.name))
-
-  # figure out corresponding path in tar file. everything gets put underneath
-  # a single top level directory named after the repository directory being
-  # tarred
-  if request.path_parts:
-    tar_dir = request.path_parts[-1] + '/'
-  else:
-    tar_dir = request.rootname + '/'
-  if reldir:
-    tar_dir = tar_dir + _path_join(reldir) + '/'
-
-  # Subdirectory datestamps will be the youngest of the datestamps of
-  # version items (files for CVS, files or dirs for Subversion) in
-  # that subdirectory.
-  latest_date = 0
-  cvs = request.roottype == 'cvs'
-  for file in entries:
-    # Skip dead or busted CVS files, and CVS subdirs.
-    if (cvs and (file.kind != vclib.FILE or (file.rev is None or file.dead))):
-      continue
-    if file.date > latest_date:
-      latest_date = file.date
-
-  # push directory onto stack. it will only be included in the tarball if
-  # files are found underneath it
-  stack.append(tar_dir)
-
-  for file in entries:
-    if (file.kind != vclib.FILE or
-        (cvs and (file.rev is None or file.dead))):
-      continue
-
-    for dir in stack:
-      generate_tarball_header(out, dir, mtime=latest_date)
-    del stack[:]
-
-    if cvs:
-      info = os.stat(file.path)
-      mode = (info[stat.ST_MODE] & 0555) | 0200
-    else:
-      mode = 0644
-
-    ### read the whole file into memory? bad... better to do 2 passes
-    fp = request.repos.openfile(rep_path + [file.name], request.pathrev)[0]
-    contents = fp.read()
-    fp.close()
-
-    generate_tarball_header(out, tar_dir + file.name,
-                            len(contents), mode, file.date)
-    out.write(contents)
-    out.write('\0' * (511 - ((len(contents) + 511) % 512)))
-
-  # recurse into subdirectories
-  for file in entries:
-    if file.errors or file.kind != vclib.DIR:
-      continue
-
-    # skip forbidden/hidden directories (top-level only)
-    if not rep_path:
-      if (request.cfg.is_forbidden(file.name)
-          or (cvs and request.cfg.options.hide_cvsroot
-              and file.name == 'CVSROOT')):
-        continue
-
-    generate_tarball(out, request, reldir + [file.name], stack)
-
-  # pop directory (if it's being pruned. otherwise stack is already empty)
-  del stack[-1:]
-
-def download_tarball(request):
-  if not request.cfg.options.allow_tar:
-    raise debug.ViewVCException('Tarball generation is disabled',
-                                 '403 Forbidden')
-
-  ### look for GZIP binary
-
-  request.server.header('application/octet-stream')
-  sys.stdout.flush()
-  fp = popen.pipe_cmds([('gzip', '-c', '-n')])
-
-  generate_tarball(fp, request, [], [])
-
-  fp.write('\0' * 1024)
-  fp.close()
-
-def view_revision(request):
-  if request.roottype == "cvs":
-    raise ViewVCException("Revision view not supported for CVS repositories "
-                           "at this time.", "400 Bad Request")
-
-  data = common_template_data(request)
-  query_dict = request.query_dict
-  rev = request.repos._getrev(query_dict.get('revision'))
-  date, author, msg, changes = vclib.svn.get_revision_info(request.repos, rev)
-  date_str = make_time_string(date, request.cfg)
-
-  # The revision number acts as a weak validator.
-  if check_freshness(request, None, str(rev), weak=1):
-    return
-
-  # Handle limit_changes parameter
-  cfg_limit_changes = request.cfg.options.limit_changes
-  limit_changes = int(query_dict.get('limit_changes', cfg_limit_changes))
-  more_changes = None
-  more_changes_href = None
-  first_changes = None
-  first_changes_href = None
-  if limit_changes and len(changes) > limit_changes:
-    more_changes = len(changes) - limit_changes
-    params = query_dict.copy()
-    params['limit_changes'] = 0
-    more_changes_href = request.get_url(params=params, escape=1)
-    changes = changes[:limit_changes]
-  elif cfg_limit_changes and len(changes) > cfg_limit_changes:
-    first_changes = cfg_limit_changes
-    params = query_dict.copy()
-    params['limit_changes'] = None
-    first_changes_href = request.get_url(params=params, escape=1)
-
-  # add the hrefs, types, and prev info
-  for change in changes:
-    change.view_href = change.diff_href = change.type = change.log_href = None
-    pathtype = (change.pathtype == vclib.FILE and 'file') \
-               or (change.pathtype == vclib.DIR and 'dir') \
-               or None
-    if (change.action == 'added' or change.action == 'replaced') \
-           and not change.is_copy:
-      change.text_mods = 0
-      change.prop_mods = 0
-
-    view_func = None
-    if change.pathtype is vclib.FILE:
-      view_func = view_markup
-      if change.text_mods:
-        params = {'pathrev' : str(rev),
-                  'r1' : str(rev),
-                  'r2' : str(change.base_rev),
-                  }
-        change.diff_href = request.get_url(view_func=view_diff,
-                                           where=change.filename, 
-                                           pathtype=change.pathtype,
-                                           params=params,
-                                           escape=1)
-    elif change.pathtype is vclib.DIR:
-      view_func=view_directory
-
-    if change.pathtype:
-      if change.action == 'deleted':
-        link_rev = str(change.base_rev)
-        link_where = change.base_path
-      else:
-        link_rev = str(rev)
-        link_where = change.filename
-
-      change.view_href = request.get_url(view_func=view_func,
-                                         where=link_where,
-                                         pathtype=change.pathtype,
-                                         params={'pathrev' : link_rev},
-                                         escape=1)
-      change.log_href = request.get_url(view_func=view_log,
-                                        where=link_where,
-                                        pathtype=change.pathtype,
-                                        params={'pathrev' : link_rev},
-                                        escape=1)
-    
-    change.text_mods = ezt.boolean(change.text_mods)
-    change.prop_mods = ezt.boolean(change.prop_mods)
-    change.is_copy = ezt.boolean(change.is_copy)
-    change.pathtype = pathtype
-
-    # use same variable names as the log template
-    change.path = change.filename
-    change.copy_path = change.base_path
-    change.copy_rev = change.base_rev
-    del change.filename
-    del change.base_path
-    del change.base_rev
-
-  prev_rev_href = next_rev_href = None
-  if rev > 0:
-    prev_rev_href = request.get_url(view_func=view_revision,
-                                    where=None,
-                                    pathtype=None,
-                                    params={'revision': str(rev - 1)},
-                                    escape=1)
-  if rev < request.repos.youngest:
-    next_rev_href = request.get_url(view_func=view_revision,
-                                    where=None,
-                                    pathtype=None,
-                                    params={'revision': str(rev + 1)},
-                                    escape=1)
-  data.update({
-    'rev' : str(rev),
-    'author' : author,
-    'date' : date_str,
-    'log' : msg and htmlify(msg) or None,
-    'ago' : None,
-    'changes' : changes,
-    'prev_href' : prev_rev_href,
-    'next_href' : next_rev_href,
-    'limit_changes': limit_changes,
-    'more_changes': more_changes,
-    'more_changes_href': more_changes_href,
-    'first_changes': first_changes,
-    'first_changes_href': first_changes_href,
-  })
-
-  if date is not None:
-    data['ago'] = html_time(request, date, 1)
-
-  data['jump_rev_action'], data['jump_rev_hidden_values'] = \
-    request.get_form(params={'revision': None})
-
-  request.server.header()
-  generate_page(request, "revision", data)
-
-def is_query_supported(request):
-  """Returns true if querying is supported for the given path."""
-  return request.cfg.cvsdb.enabled \
-         and request.pathtype == vclib.DIR \
-         and request.roottype in ['cvs', 'svn']
-
-def view_queryform(request):
-  if not is_query_supported(request):
-    raise debug.ViewVCException('Can not query project root "%s" at "%s".'
-                                 % (request.rootname, request.where),
-                                 '403 Forbidden')
-
-  data = common_template_data(request)
-
-  data['query_action'], data['query_hidden_values'] = \
-    request.get_form(view_func=view_query, params={'limit_changes': None})
-
-  # default values ...
-  data['branch'] = request.query_dict.get('branch', '')
-  data['branch_match'] = request.query_dict.get('branch_match', 'exact')
-  data['dir'] = request.query_dict.get('dir', '')
-  data['file'] = request.query_dict.get('file', '')
-  data['file_match'] = request.query_dict.get('file_match', 'exact')
-  data['who'] = request.query_dict.get('who', '')
-  data['who_match'] = request.query_dict.get('who_match', 'exact')
-  data['querysort'] = request.query_dict.get('querysort', 'date')
-  data['date'] = request.query_dict.get('date', 'hours')
-  data['hours'] = request.query_dict.get('hours', '2')
-  data['mindate'] = request.query_dict.get('mindate', '')
-  data['maxdate'] = request.query_dict.get('maxdate', '')
-  data['limit_changes'] = int(request.query_dict.get('limit_changes',
-                                           request.cfg.options.limit_changes))
-
-  data['dir_href'] = request.get_url(view_func=view_directory, params={},
-                                     escape=1)
-
-  request.server.header()
-  generate_page(request, "query_form", data)
-
-def parse_date(s):
-  '''Parse a date string from the query form.'''
-  match = re.match(r'^(\d\d\d\d)-(\d\d)-(\d\d)(?:\ +(\d\d):(\d\d)(?::(\d\d))?)?$', s)
-  if match:
-    year = int(match.group(1))
-    month = int(match.group(2))
-    day = int(match.group(3))
-    hour = match.group(4)
-    if hour is not None:
-      hour = int(hour)
-    else:
-      hour = 0
-    minute = match.group(5)
-    if minute is not None:
-      minute = int(minute)
-    else:
-      minute = 0
-    second = match.group(6)
-    if second is not None:
-      second = int(second)
-    else:
-      second = 0
-    # return a "seconds since epoch" value assuming date given in UTC
-    tm = (year, month, day, hour, minute, second, 0, 0, 0)
-    return compat.timegm(tm)
-  else:
-    return None
-
-def english_query(request):
-  '''Generate a sentance describing the query.'''
-  ret = [ 'Checkins ' ]
-  dir = request.query_dict.get('dir', '')
-  if dir:
-    ret.append('to ')
-    if ',' in dir:
-      ret.append('subdirectories')
-    else:
-      ret.append('subdirectory')
-    ret.append(' <em>%s</em> ' % htmlify(dir))
-  file = request.query_dict.get('file', '')
-  if file:
-    if len(ret) != 1: ret.append('and ')
-    ret.append('to file <em>%s</em> ' % htmlify(file))
-  who = request.query_dict.get('who', '')
-  branch = request.query_dict.get('branch', '')
-  if branch:
-    ret.append('on branch <em>%s</em> ' % htmlify(branch))
-  else:
-    ret.append('on all branches ')
-  if who:
-    ret.append('by <em>%s</em> ' % htmlify(who))
-  date = request.query_dict.get('date', 'hours')
-  if date == 'hours':
-    ret.append('in the last %s hours' % htmlify(request.query_dict.get('hours', '2')))
-  elif date == 'day':
-    ret.append('in the last day')
-  elif date == 'week':
-    ret.append('in the last week')
-  elif date == 'month':
-    ret.append('in the last month')
-  elif date == 'all':
-    ret.append('since the beginning of time')
-  elif date == 'explicit':
-    mindate = request.query_dict.get('mindate', '')
-    maxdate = request.query_dict.get('maxdate', '')
-    if mindate and maxdate:
-      w1, w2 = 'between', 'and'
-    else:
-      w1, w2 = 'since', 'before'
-    if mindate:
-      mindate = make_time_string(parse_date(mindate), request.cfg)
-      ret.append('%s <em>%s</em> ' % (w1, mindate))
-    if maxdate:
-      maxdate = make_time_string(parse_date(maxdate), request.cfg)
-      ret.append('%s <em>%s</em> ' % (w2, maxdate))
-  return string.join(ret, '')
-
-def prev_rev(rev):
-  '''Returns a string representing the previous revision of the argument.'''
-  r = string.split(rev, '.')
-  # decrement final revision component
-  r[-1] = str(int(r[-1]) - 1)
-  # prune if we pass the beginning of the branch
-  if len(r) > 2 and r[-1] == '0':
-    r = r[:-2]
-  return string.join(r, '.')
-
-def build_commit(request, files, limited_files, dir_strip):
-  commit = _item(num_files=len(files), files=[])
-  commit.limited_files = ezt.boolean(limited_files)
-  desc = files[0].GetDescription()
-  commit.log = htmlify(desc)
-  commit.short_log = format_log(desc, request.cfg)
-  commit.author = htmlify(files[0].GetAuthor())
-  commit.rss_date = make_rss_time_string(files[0].GetTime(), request.cfg)
-  if request.roottype == 'svn':
-    commit.rev = files[0].GetRevision()
-    commit.rss_url = 'http://%s%s' % \
-      (request.server.getenv("HTTP_HOST"),
-       request.get_url(view_func=view_revision,
-                       params={'revision': commit.rev},
-                       escape=1))
-  else:
-    commit.rev = None
-    commit.rss_url = None
-
-  len_strip = len(dir_strip)
-
-  for f in files:
-    commit_time = f.GetTime()
-    if commit_time:
-      commit_time = make_time_string(commit_time, request.cfg)
-    else:
-      commit_time = ' '
-
-    dirname = f.GetDirectory()
-    filename = f.GetFile()
-    if dir_strip:
-      assert dirname[:len_strip] == dir_strip
-      assert len(dirname) == len_strip or dirname[len(dir_strip)] == '/'
-      dirname = dirname[len_strip+1:]
-    filename = dirname and ("%s/%s" % (dirname, filename)) or filename
-
-    params = { 'revision': f.GetRevision() }
-    if f.GetBranch(): params['pathrev'] = f.GetBranch()
-    dir_href = request.get_url(view_func=view_directory,
-                               where=dirname, pathtype=vclib.DIR,
-                               params=params,
-                               escape=1)
-    log_href = request.get_url(view_func=view_log,
-                               where=filename, pathtype=vclib.FILE,
-                               params=params,
-                               escape=1)
-    view_href = request.get_url(view_func=view_markup,
-                               where=filename, pathtype=vclib.FILE,
-                               params={'revision': f.GetRevision() },
-                               escape=1)
-    download_href = request.get_url(view_func=view_checkout,
-                                    where=filename, pathtype=vclib.FILE,
-                                    params={'revision': f.GetRevision() },
-                                    escape=1)
-    diff_href = request.get_url(view_func=view_diff,
-                                where=filename, pathtype=vclib.FILE,
-                                params={'r1': prev_rev(f.GetRevision()),
-                                        'r2': f.GetRevision(),
-                                        'diff_format': None},
-                                escape=1)
-
-    # skip files in forbidden or hidden modules
-    dir_parts = filter(None, string.split(dirname, '/'))
-    if dir_parts \
-           and ((dir_parts[0] == 'CVSROOT'
-                 and request.cfg.options.hide_cvsroot) \
-                or request.cfg.is_forbidden(dir_parts[0])):
-      continue
-
-    commit.files.append(_item(date=commit_time,
-                              dir=htmlify(dirname),
-                              file=htmlify(f.GetFile()),
-                              author=htmlify(f.GetAuthor()),
-                              rev=f.GetRevision(),
-                              branch=f.GetBranch(),
-                              plus=int(f.GetPlusCount()),
-                              minus=int(f.GetMinusCount()),
-                              type=f.GetTypeString(),
-                              dir_href=dir_href,
-                              log_href=log_href,
-                              view_href=view_href,
-                              download_href=download_href,
-                              prefer_markup=ezt.boolean
-                              (default_view(guess_mime(filename), request.cfg)
-                               == view_markup),
-                              diff_href=diff_href))
-  return commit
-
-def query_backout(request, commits):
-  request.server.header('text/plain')
-  if commits:
-    print '# This page can be saved as a shell script and executed.'
-    print '# It should be run at the top of your work area.  It will update'
-    print '# your working copy to back out the changes selected by the'
-    print '# query.'
-    print
-  else:
-    print '# No changes were selected by the query.'
-    print '# There is nothing to back out.'
-    return
-  for commit in commits:
-    for fileinfo in commit.files:
-      if request.roottype == 'cvs':
-        print 'cvs update -j %s -j %s %s/%s' \
-              % (fileinfo.rev, prev_rev(fileinfo.rev),
-                 fileinfo.dir, fileinfo.file)
-      elif request.roottype == 'svn':
-        print 'svn merge -r %s:%s %s/%s' \
-              % (fileinfo.rev, prev_rev(fileinfo.rev),
-                 fileinfo.dir, fileinfo.file)
-
-def view_query(request):
-  if not is_query_supported(request):
-    raise debug.ViewVCException('Can not query project root "%s" at "%s".'
-                                 % (request.rootname, request.where),
-                                 '403 Forbidden')
-
-  # get form data
-  branch = request.query_dict.get('branch', '')
-  branch_match = request.query_dict.get('branch_match', 'exact')
-  dir = request.query_dict.get('dir', '')
-  file = request.query_dict.get('file', '')
-  file_match = request.query_dict.get('file_match', 'exact')
-  who = request.query_dict.get('who', '')
-  who_match = request.query_dict.get('who_match', 'exact')
-  querysort = request.query_dict.get('querysort', 'date')
-  date = request.query_dict.get('date', 'hours')
-  hours = request.query_dict.get('hours', '2')
-  mindate = request.query_dict.get('mindate', '')
-  maxdate = request.query_dict.get('maxdate', '')
-  format = request.query_dict.get('format')
-  limit = int(request.query_dict.get('limit', 0))
-  limit_changes = int(request.query_dict.get('limit_changes',
-                                           request.cfg.options.limit_changes))
-
-  match_types = { 'exact':1, 'like':1, 'glob':1, 'regex':1, 'notregex':1 }
-  sort_types = { 'date':1, 'author':1, 'file':1 }
-  date_types = { 'hours':1, 'day':1, 'week':1, 'month':1,
-                 'all':1, 'explicit':1 }
-
-  # parse various fields, validating or converting them
-  if not match_types.has_key(branch_match): branch_match = 'exact'
-  if not match_types.has_key(file_match): file_match = 'exact'
-  if not match_types.has_key(who_match): who_match = 'exact'
-  if not sort_types.has_key(querysort): querysort = 'date'
-  if not date_types.has_key(date): date = 'hours'
-  mindate = parse_date(mindate)
-  maxdate = parse_date(maxdate)
-
-  global cvsdb
-  import cvsdb
-
-  db = cvsdb.ConnectDatabaseReadOnly(request.cfg)
-  repos_root, repos_dir = cvsdb.FindRepository(db, request.rootpath)
-  if not repos_root:
-    raise debug.ViewVCException(
-      "The root '%s' was not found in the commit database "
-      % request.rootname)
-
-  # create the database query from the form data
-  query = cvsdb.CreateCheckinQuery()
-  query.SetRepository(repos_root)
-  # treat "HEAD" specially ...
-  if branch_match == 'exact' and branch == 'HEAD':
-    query.SetBranch('')
-  elif branch:
-    query.SetBranch(branch, branch_match)
-  if dir:
-    for subdir in string.split(dir, ','):
-      path = (_path_join(repos_dir + request.path_parts
-                         + [ string.strip(subdir) ]))
-      query.SetDirectory(path, 'exact')
-      query.SetDirectory('%s/%%' % cvsdb.EscapeLike(path), 'like')
-  else:
-    where = _path_join(repos_dir + request.path_parts)
-    if where: # if we are in a subdirectory ...
-      query.SetDirectory(where, 'exact')
-      query.SetDirectory('%s/%%' % cvsdb.EscapeLike(where), 'like')
-  if file:
-    query.SetFile(file, file_match)
-  if who:
-    query.SetAuthor(who, who_match)
-  query.SetSortMethod(querysort)
-  if date == 'hours':
-    query.SetFromDateHoursAgo(int(hours))
-  elif date == 'day':
-    query.SetFromDateDaysAgo(1)
-  elif date == 'week':
-    query.SetFromDateDaysAgo(7)
-  elif date == 'month':
-    query.SetFromDateDaysAgo(31)
-  elif date == 'all':
-    pass
-  elif date == 'explicit':
-    if mindate is not None:
-      query.SetFromDateObject(mindate)
-    if maxdate is not None:
-      query.SetToDateObject(maxdate)
-  if limit:
-    query.SetLimit(limit)
-  elif format == 'rss':
-    query.SetLimit(request.cfg.cvsdb.rss_row_limit)
-
-  # run the query
-  db.RunQuery(query)
-
-  sql = htmlify(db.CreateSQLQueryString(query))
-
-  # gather commits
-  commits = []
-  plus_count = 0
-  minus_count = 0
-  mod_time = -1
-  if query.commit_list:
-    files = []
-    limited_files = 0
-    current_desc = query.commit_list[0].GetDescriptionID()
-    current_rev = query.commit_list[0].GetRevision()
-    dir_strip = _path_join(repos_dir)
-    for commit in query.commit_list:
-      # base modification time on the newest commit ...
-      if commit.GetTime() > mod_time: mod_time = commit.GetTime()
-      # form plus/minus totals
-      plus_count = plus_count + int(commit.GetPlusCount())
-      minus_count = minus_count + int(commit.GetMinusCount())
-      # group commits with the same commit message ...
-      desc = commit.GetDescriptionID()
-      # For CVS, group commits with the same commit message.
-      # For Subversion, group them only if they have the same revision number
-      if request.roottype == 'cvs':
-        if current_desc == desc:
-          if not limit_changes or len(files) < limit_changes:
-            files.append(commit)
-          else:
-            limited_files = 1
-          continue
-      else:
-        if current_rev == commit.GetRevision():
-          if not limit_changes or len(files) < limit_changes:
-            files.append(commit)
-          else:
-            limited_files = 1
-          continue
-
-      # if our current group has any allowed files, append a commit
-      # with those files.
-      if len(files):
-        commits.append(build_commit(request, files, limited_files, dir_strip))
-
-      files = [ commit ]
-      limited_files = 0
-      current_desc = desc
-      current_rev = commit.GetRevision()
-      
-    # we need to tack on our last commit grouping, but, again, only if
-    # it has allowed files.
-    if len(files):
-      commits.append(build_commit(request, files, limited_files, dir_strip))
-
-  # only show the branch column if we are querying all branches
-  # or doing a non-exact branch match on a CVS repository.
-  show_branch = ezt.boolean(request.roottype == 'cvs' and
-                            (branch == '' or branch_match != 'exact'))
-
-  # a link to modify query
-  queryform_href = request.get_url(view_func=view_queryform, escape=1)
-  # backout link
-  params = request.query_dict.copy()
-  params['format'] = 'backout'
-  backout_href = request.get_url(params=params,
-                                 escape=1)
-
-  # link to zero limit_changes value
-  params = request.query_dict.copy()
-  params['limit_changes'] = 0
-  limit_changes_href = request.get_url(params=params, escape=1)
-
-  # if we got any results, use the newest commit as the modification time
-  if mod_time >= 0:
-    if check_freshness(request, mod_time):
-      return
-
-  if format == 'backout':
-    query_backout(request, commits)
-    return
-
-  data = common_template_data(request)
-  data.update({
-    'sql': sql,
-    'english_query': english_query(request),
-    'queryform_href': queryform_href,
-    'backout_href': backout_href,
-    'plus_count': plus_count,
-    'minus_count': minus_count,
-    'show_branch': show_branch,
-    'querysort': querysort,
-    'commits': commits,
-    'limit_changes': limit_changes,
-    'limit_changes_href': limit_changes_href,
-    })
-
-  if format == 'rss':
-    request.server.header("text/xml")
-    generate_page(request, "rss", data)
-  else:
-    request.server.header()
-    generate_page(request, "query_results", data)
-
-_views = {
-  'annotate':  view_annotate,
-  'co':        view_checkout,
-  'diff':      view_diff,
-  'dir':       view_directory,
-  'graph':     view_cvsgraph,
-  'graphimg':  view_cvsgraph_image,
-  'log':       view_log,
-  'markup':    view_markup,
-  'patch':     view_patch,
-  'query':     view_query,
-  'queryform': view_queryform,
-  'rev':       view_revision,
-  'roots':     view_roots,
-  'tar':       download_tarball,
-  'redirect_pathrev': redirect_pathrev,
-}
-
-_view_codes = {}
-for code, view in _views.items():
-  _view_codes[view] = code
-
-def list_roots(cfg):
-  allroots = { }
-  for root in cfg.general.cvs_roots.keys():
-    allroots[root] = [cfg.general.cvs_roots[root], 'cvs']
-  for root in cfg.general.svn_roots.keys():
-    allroots[root] = [cfg.general.svn_roots[root], 'svn']
-  return allroots
-  
-def load_config(pathname=None, server=None):
-  debug.t_start('load-config')
-
-  if pathname is None:
-    pathname = (os.environ.get("VIEWVC_CONF_PATHNAME")
-                or os.environ.get("VIEWCVS_CONF_PATHNAME")
-                or _install_path("viewvc.conf"))
-
-  cfg = config.Config()
-  cfg.set_defaults()
-  cfg.load_config(pathname, server and server.getenv("HTTP_HOST"))
-
-  # load mime types file
-  if cfg.general.mime_types_file:
-    mimetypes.init([cfg.general.mime_types_file])
-
-  # special handling for root_parents.  Each item in root_parents is
-  # a "directory : repo_type" string.  For each item in
-  # root_parents, we get a list of the subdirectories.
-  #
-  # If repo_type is "cvs", and the subdirectory contains a child
-  # "CVSROOT/config", then it is added to cvs_roots. Or, if the
-  # root directory itself contains a child "CVSROOT/config" file,
-  # then all its subdirectories are added to cvs_roots.
-  #
-  # If repo_type is "svn", and the subdirectory contains a child
-  # "format", then it is added to svn_roots.
-  for pp in cfg.general.root_parents:
-    pos = string.rfind(pp, ':')
-    if pos < 0:
-      raise debug.ViewVCException(
-        "The path '%s' in 'root_parents' does not include a "
-        "repository type." % pp)
-
-    repo_type = string.strip(pp[pos+1:])
-    pp = os.path.normpath(string.strip(pp[:pos]))
-
-    try:
-      subpaths = os.listdir(pp)
-    except OSError:
-      raise debug.ViewVCException(
-        "The path '%s' in 'root_parents' does not refer to "
-        "a valid directory." % pp)
-
-    cvsroot = os.path.exists(os.path.join(pp, "CVSROOT", "config"))
-
-    for subpath in subpaths:
-      if os.path.exists(os.path.join(pp, subpath)):
-        if (repo_type == 'cvs'
-            and (os.path.exists(os.path.join(pp, subpath, "CVSROOT", "config"))
-                 or (cvsroot and (subpath != 'CVSROOT'
-                                  or not cfg.options.hide_cvsroot)))):
-          cfg.general.cvs_roots[subpath] = os.path.join(pp, subpath)
-        elif repo_type == 'svn' and \
-             os.path.exists(os.path.join(pp, subpath, "format")):
-          cfg.general.svn_roots[subpath] = os.path.join(pp, subpath)
-
-  debug.t_end('load-config')
-
-  return cfg
-
-
-def view_error(server, cfg):
-  exc_dict = debug.GetExceptionData()
-  status = exc_dict['status']
-  if exc_dict['msg']:
-    exc_dict['msg'] = htmlify(exc_dict['msg'])
-  if exc_dict['stacktrace']:
-    exc_dict['stacktrace'] = htmlify(exc_dict['stacktrace'])
-  handled = 0
-  
-  # use the configured error template if possible
-  try:
-    if cfg and not server.headerSent:
-      server.header(status=status)
-      template = get_view_template(cfg, "error")
-      template.generate(sys.stdout, exc_dict)
-      handled = 1
-  except:
-    pass
-
-  # but fallback to the old exception printer if no configuration is
-  # available, or if something went wrong
-  if not handled:
-    debug.PrintException(server, exc_dict)
-
-def main(server, cfg):
-  try:
-    debug.t_start('main')
-    try:
-      # build a Request object, which contains info about the HTTP request
-      request = Request(server, cfg)
-      request.run_viewvc()
-    except SystemExit, e:
-      return
-    except:
-      view_error(server, cfg)
-
-  finally:
-    debug.t_end('main')
-    debug.dump()
-    debug.DumpChildren(server)
-
-
-class _item:
-  def __init__(self, **kw):
-    vars(self).update(kw)
diff --git a/src/www/scm/viewvc/lib/win32popen.py b/src/www/scm/viewvc/lib/win32popen.py
deleted file mode 100644
index 02121a0..0000000
--- a/src/www/scm/viewvc/lib/win32popen.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# -*-python-*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# Utilities for controlling processes and pipes on win32
-#
-# -----------------------------------------------------------------------
-
-import os, sys, traceback, string, thread
-import win32process, win32pipe, win32con
-import win32event, win32file, win32api, winerror
-import pywintypes, msvcrt
-
-# Buffer size for spooling
-SPOOL_BYTES = 4096
-
-# File object to write error messages
-SPOOL_ERROR = sys.stderr
-#SPOOL_ERROR = open("m:/temp/error.txt", "wt")
-
-def CommandLine(command, args):
-  """Convert an executable path and a sequence of arguments into a command
-  line that can be passed to CreateProcess"""
-
-  cmd = "\"" + string.replace(command, "\"", "\"\"") + "\""
-  for arg in args:
-    cmd = cmd + " \"" + string.replace(arg, "\"", "\"\"") + "\""
-  return cmd
-
-def CreateProcess(cmd, hStdInput, hStdOutput, hStdError):
-  """Creates a new process which uses the specified handles for its standard
-  input, output, and error. The handles must be inheritable. 0 can be passed
-  as a special handle indicating that the process should inherit the current
-  process's input, output, or error streams, and None can be passed to discard
-  the child process's output or to prevent it from reading any input."""
-
-  # initialize new process's startup info
-  si = win32process.STARTUPINFO()
-  si.dwFlags = win32process.STARTF_USESTDHANDLES
-
-  if hStdInput == 0:
-    si.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
-  else:
-    si.hStdInput = hStdInput
-
-  if hStdOutput == 0:
-    si.hStdOutput = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE)
-  else:
-    si.hStdOutput = hStdOutput
-
-  if hStdError == 0:
-    si.hStdError = win32api.GetStdHandle(win32api.STD_ERROR_HANDLE)
-  else:
-    si.hStdError = hStdError
-
-  # create the process
-  phandle, pid, thandle, tid = win32process.CreateProcess \
-  ( None,                            # appName
-    cmd,                             # commandLine
-    None,                            # processAttributes
-    None,                            # threadAttributes
-    1,                               # bInheritHandles
-    win32con.NORMAL_PRIORITY_CLASS,  # dwCreationFlags
-    None,                            # newEnvironment
-    None,                            # currentDirectory
-    si                               # startupinfo
-  )
-
-  if hStdInput and hasattr(hStdInput, 'Close'):
-    hStdInput.Close()
-
-  if hStdOutput and hasattr(hStdOutput, 'Close'):
-    hStdOutput.Close()
-
-  if hStdError and hasattr(hStdError, 'Close'):
-    hStdError.Close()
-
-  return phandle, pid, thandle, tid
-
-def CreatePipe(readInheritable, writeInheritable):
-  """Create a new pipe specifying whether the read and write ends are
-  inheritable and whether they should be created for blocking or nonblocking
-  I/O."""
-
-  r, w = win32pipe.CreatePipe(None, SPOOL_BYTES)
-  if readInheritable:
-    r = MakeInheritedHandle(r)
-  if writeInheritable:
-    w = MakeInheritedHandle(w)
-  return r, w
-
-def File2FileObject(pipe, mode):
-  """Make a C stdio file object out of a win32 file handle"""
-  if string.find(mode, 'r') >= 0:
-    wmode = os.O_RDONLY
-  elif string.find(mode, 'w') >= 0:
-    wmode = os.O_WRONLY
-  if string.find(mode, 'b') >= 0:
-    wmode = wmode | os.O_BINARY
-  if string.find(mode, 't') >= 0:
-    wmode = wmode | os.O_TEXT
-  return os.fdopen(msvcrt.open_osfhandle(pipe.Detach(),wmode),mode)
-
-def FileObject2File(fileObject):
-  """Get the win32 file handle from a C stdio file object"""
-  return win32file._get_osfhandle(fileObject.fileno())
-
-def DuplicateHandle(handle):
-  """Duplicates a win32 handle."""
-  proc = win32api.GetCurrentProcess()
-  return win32api.DuplicateHandle(proc,handle,proc,0,0,win32con.DUPLICATE_SAME_ACCESS)
-
-def MakePrivateHandle(handle, replace = 1):
-  """Turn an inherited handle into a non inherited one. This avoids the
-  handle duplication that occurs on CreateProcess calls which can create
-  uncloseable pipes."""
-
-  ### Could change implementation to use SetHandleInformation()...
-
-  flags = win32con.DUPLICATE_SAME_ACCESS
-  proc = win32api.GetCurrentProcess()
-  if replace: flags = flags | win32con.DUPLICATE_CLOSE_SOURCE
-  newhandle = win32api.DuplicateHandle(proc,handle,proc,0,0,flags)
-  if replace: handle.Detach() # handle was already deleted by the last call
-  return newhandle
-
-def MakeInheritedHandle(handle, replace = 1):
-  """Turn a private handle into an inherited one."""
-
-  ### Could change implementation to use SetHandleInformation()...
-
-  flags = win32con.DUPLICATE_SAME_ACCESS
-  proc = win32api.GetCurrentProcess()
-  if replace: flags = flags | win32con.DUPLICATE_CLOSE_SOURCE
-  newhandle = win32api.DuplicateHandle(proc,handle,proc,0,1,flags)
-  if replace: handle.Detach() # handle was deleted by the last call
-  return newhandle
-
-def MakeSpyPipe(readInheritable, writeInheritable, outFiles = None, doneEvent = None):
-  """Return read and write handles to a pipe that asynchronously writes all of
-  its input to the files in the outFiles sequence. doneEvent can be None, or a
-  a win32 event handle that will be set when the write end of pipe is closed.
-  """
-
-  if outFiles is None:
-    return CreatePipe(readInheritable, writeInheritable)
-
-  r, writeHandle = CreatePipe(0, writeInheritable)
-  if readInheritable is None:
-    readHandle, w = None, None
-  else:
-    readHandle, w = CreatePipe(readInheritable, 0)
-
-  thread.start_new_thread(SpoolWorker, (r, w, outFiles, doneEvent))
-
-  return readHandle, writeHandle
-
-def SpoolWorker(srcHandle, destHandle, outFiles, doneEvent):
-  """Thread entry point for implementation of MakeSpyPipe"""
-  try:
-    buffer = win32file.AllocateReadBuffer(SPOOL_BYTES)
-
-    while 1:
-      try:
-        #print >> SPOOL_ERROR, "Calling ReadFile..."; SPOOL_ERROR.flush()
-        hr, data = win32file.ReadFile(srcHandle, buffer)
-        #print >> SPOOL_ERROR, "ReadFile returned '%s', '%s'" % (str(hr), str(data)); SPOOL_ERROR.flush()
-        if hr != 0:
-          raise "win32file.ReadFile returned %i, '%s'" % (hr, data)
-        elif len(data) == 0:
-          break
-      except pywintypes.error, e:
-        #print >> SPOOL_ERROR, "ReadFile threw '%s'" % str(e); SPOOL_ERROR.flush()
-        if e.args[0] == winerror.ERROR_BROKEN_PIPE:
-          break
-        else:
-          raise e
-
-      #print >> SPOOL_ERROR, "Writing to %i file objects..." % len(outFiles); SPOOL_ERROR.flush()
-      for f in outFiles:
-        f.write(data)
-      #print >> SPOOL_ERROR, "Done writing to file objects."; SPOOL_ERROR.flush()
-
-      #print >> SPOOL_ERROR, "Writing to destination %s" % str(destHandle); SPOOL_ERROR.flush()
-      if destHandle:
-        #print >> SPOOL_ERROR, "Calling WriteFile..."; SPOOL_ERROR.flush()
-        hr, bytes = win32file.WriteFile(destHandle, data)
-        #print >> SPOOL_ERROR, "WriteFile() passed %i bytes and returned %i, %i" % (len(data), hr, bytes); SPOOL_ERROR.flush()
-        if hr != 0 or bytes != len(data):
-          raise "win32file.WriteFile() passed %i bytes and returned %i, %i" % (len(data), hr, bytes)
-
-    srcHandle.Close()
-
-    if doneEvent:
-      win32event.SetEvent(doneEvent)
-
-    if destHandle:
-      destHandle.Close()
-
-  except:
-    info = sys.exc_info()
-    SPOOL_ERROR.writelines(apply(traceback.format_exception, info), '')
-    SPOOL_ERROR.flush()
-    del info
-
-def NullFile(inheritable):
-  """Create a null file handle."""
-  if inheritable:
-    sa = pywintypes.SECURITY_ATTRIBUTES()
-    sa.bInheritHandle = 1
-  else:
-    sa = None
-
-  return win32file.CreateFile("nul",
-    win32file.GENERIC_READ | win32file.GENERIC_WRITE,
-    win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
-    sa, win32file.OPEN_EXISTING, 0, None)
diff --git a/src/www/scm/viewvc/templates/annotate.ezt b/src/www/scm/viewvc/templates/annotate.ezt
deleted file mode 100644
index f9507d6..0000000
--- a/src/www/scm/viewvc/templates/annotate.ezt
+++ /dev/null
@@ -1,43 +0,0 @@
-[# setup page definitions][define page_title]Annotation of /[where][end][define help_href][docroot]/help_rootview.html[end][# end][include "include/header.ezt" "annotate"]
-[include "include/file_header.ezt"]
-
-<hr />
-
-<p>
-Revision [if-any revision_href]<a href="[revision_href]"><strong>[rev]</strong></a>[else]<strong>[rev]</strong>[end] -
-(<a href="[view_href]"><strong>view</strong></a>)
-(<a href="[download_href]"><strong>download</strong></a>)
-[if-any download_text_href](<a href="[download_text_href]"><strong>as text</strong></a>)[end]
-[if-any orig_path]
-  <br />Original Path: <a href="[orig_href]"><em>[orig_path]</em></a>
-[end]
-</p>
-
-
-[define class1]vc_row_even[end]
-[define class2]vc_row_odd[end]
-[define last_rev]0[end]
-[define rowclass][class1][end]
-
-<table cellspacing="0" cellpadding="0">
-[for lines]
-  [is lines.rev last_rev]
-  [else]
-    [is rowclass class1]
-      [define rowclass][class2][end]
-    [else]
-      [define rowclass][class1][end]
-    [end]
-  [end]
-
-  <tr class="[rowclass]" id="l[lines.line_number]">
-    <td class="vc_blame_line">[lines.line_number] :</td>
-    <td class="vc_blame_author">[is lines.rev last_rev] [else][lines.author][end]</td>
-    <td class="vc_blame_rev">[is lines.rev last_rev] [else][if-any lines.diff_url]<a href="[lines.diff_url]">[end][lines.rev][if-any lines.diff_url]</a>[end][end]</td>
-    <td class="vc_blame_text">[lines.text]</td>
-  </tr>
-  [define last_rev][lines.rev][end]
-[end]
-</table>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/diff.ezt b/src/www/scm/viewvc/templates/diff.ezt
deleted file mode 100644
index 4089268..0000000
--- a/src/www/scm/viewvc/templates/diff.ezt
+++ /dev/null
@@ -1,234 +0,0 @@
-[# setup page definitions]
-  [define page_title]Diff of /[where][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "diff"]
-[include "include/file_header.ezt"]
-
-<h3 style="text-align:center;"></h3>
-
-[if-any raw_diff]
-  <pre class="vc_raw_diff">[raw_diff]</pre>
-[end]
-
-[if-any changes]
-<table cellspacing="0" cellpadding="0">
-  <tr class="vc_diff_header">
-    <th style="width:6%;"></th>
-    <th style="width:47%; vertical-align:top;">
-      [is path_left path_right][else][path_left][end]
-      revision [rev_left], [date_left]
-      [if-any tag_left]<br />Tag: [tag_left][end]
-    </th>
-    <th style="width:47%; vertical-align:top;">
-      [is path_left path_right][else][path_right][end]
-      revision [rev_right], [date_right]
-      [if-any tag_right]<br />Tag: [tag_right][end]
-    </th>
-  </tr>
-
-  [for changes]
-    [is changes.type "header"]
-      <tr class="vc_diff_chunk_header" id="h[changes.line_info_right]">
-        <td style="width:6%;"><strong>#</strong></td>
-        <td style="width:47%;">
-          <strong>Line [changes.line_info_left]</strong> 
-          <span class="vc_diff_chunk_extra">[changes.line_info_extra]</span>
-        </td>
-        <td style="width:47%;">
-          <strong>Line [changes.line_info_right]</strong> 
-          <span class="vc_diff_chunk_extra">[changes.line_info_extra]</span>
-        </td>
-      </tr>
-    [else]
-      [is changes.type "add"]
-        <tr>
-          <td id="l[changes.line_number]">[if-any annotate_href]<a href="[annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
-          <td class="vc_diff_empty"> </td>
-          <td class="vc_diff_add"> [changes.right]</td>
-        </tr>
-      [else]
-        [is changes.type "remove"]
-          <tr>
-            <td></td>
-            <td class="vc_diff_remove"> [changes.left]</td>
-            <td class="vc_diff_empty"> </td>
-          </tr>
-        [else]
-          [is changes.type "change"]
-            <tr>
-              [if-any changes.have_right]
-                <td id="l[changes.line_number]">[if-any annotate_href]<a href="[annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
-              [else]
-                <td></td>
-              [end]
-              [if-any changes.have_left]
-                <td class="vc_diff_change"> [changes.left]</td>
-              [else]
-                <td class="vc_diff_change_empty"> </td>
-              [end]
-              [if-any changes.have_right]
-                <td class="vc_diff_change"> [changes.right]</td>
-              [else]
-                <td class="vc_diff_change_empty"> </td>
-              [end]
-            </tr>
-          [else]
-            [is changes.type "no-changes"]
-              <tr>
-                <td colspan="3"> </td>
-              </tr>
-              <tr class="vc_diff_empty">
-                <td colspan="3" style="text-align:center;"><br />
-                <strong>- No changes -</strong><br />  </td>
-              </tr>
-            [else]
-              [is changes.type "binary-diff"]
-                <tr>
-                  <td colspan="3"> </td>
-                </tr>
-                <tr class="vc_diff_empty">
-                  <td colspan="3" style="text-align:center;"><br />
-                  <strong>- Binary file revisions differ -</strong><br />  </td>
-                </tr>
-              [else]
-                [is changes.type "error"]
-                  <tr>
-                    <td colspan="3"> </td>
-                  </tr>
-                  <tr class="vc_diff_empty">
-                    <td colspan="3" style="text-align:center;"> <br />
-                    <strong>- ViewVC depends on rcsdiff and GNU diff to create 
-                    this page.  ViewVC cannot find GNU diff. Even if you 
-                    have GNU diff installed, the rcsdiff program must be 
-                    configured and compiled with the GNU diff location.
-                    -</strong> <br />  </td>
-                  </tr>
-                [else]
-                  <tr>
-                    <td id="l[changes.line_number]">[if-any annotate_href]<a href="[annotate_href]#l[changes.line_number]">[changes.line_number]</a>[else][changes.line_number][end]</td>
-                    <td class="vc_diff_nochange"> [changes.left]</td>
-                    <td class="vc_diff_nochange"> [changes.right]</td>
-                  </tr>
-                [end]
-              [end]
-            [end]
-          [end]
-        [end]
-      [end]
-    [end]
-  [end]
-</table>
-[end]
-
-[if-any sidebyside]
-  <table class="vc_idiff">
-    <colgroup><col /><col class="content" /></colgroup>
-    <colgroup><col /><col class="content" /></colgroup>
-    <thead>
-      <tr>
-        <th colspan="2">    
-          [is path_left path_right][else][path_left][end]
-          Revision [rev_left]
-        </th>
-        <th colspan="2">
-          [is path_left path_right][else][path_right][end]
-          Revision [rev_right]
-        </th>
-      </tr>
-    </thead>
-    <tbody>
-      [for sidebyside]
-        [if-any sidebyside.gap]
-          <tr>
-            <th>…</th><th></th>
-            <th>…</th><th></th>
-          </tr>
-        [end]
-        <tr>
-          [for sidebyside.columns]
-            <th>[sidebyside.columns.line_number]</th><td[if-any sidebyside.columns.line_number][else] class="vc_idiff_empty"[end]>[for sidebyside.columns.segments][if-any sidebyside.columns.segments.type]<span class="vc_idiff_[sidebyside.columns.segments.type]">[sidebyside.columns.segments.text]</span>[else][sidebyside.columns.segments.text][end][end]</td>
-          [end]
-        </tr>
-      [end]
-    </tbody>
-  </table>
-[end]
-
-[if-any unified]
-  <table class="vc_idiff">
-    <thead>
-      <tr>
-        <th>r[rev_left]</th>
-        <th>r[rev_right]</th>
-        <th></th>
-      </tr>
-    </thead>
-    <tbody>
-      [for unified]
-        [if-any unified.gap]
-          <tr>
-            <th>…</th>
-            <th>…</th>
-            <th></th>
-          </tr>
-        [end]
-        <tr>
-          <th>[unified.left_number]</th>
-          <th>[unified.right_number]</th>
-          <td[if-any unified.type] class="vc_idiff_[unified.type]"[end]>[for unified.segments][if-any unified.segments.type]<span class="vc_idiff_[unified.segments.type]">[unified.segments.text]</span>[else][unified.segments.text][end][end]</td>
-        </tr>
-      [end]
-    </tbody>
-  </table>
-[end]
-
-<hr style="margin-top:1em;" />
-
-<table cellpadding="10" class="auto">
-  <tr>
-    <td>
-      <form method="get" action="[diff_format_action]">
-        <div>
-          [diff_format_hidden_values]
-          <select name="diff_format" onchange="submit()">
-            <option value="h" [is diff_format "h"]selected="selected"[end]>Colored Diff</option>
-            <option value="l" [is diff_format "l"]selected="selected"[end]>Long Colored Diff</option>
-            <option value="u" [is diff_format "u"]selected="selected"[end]>Unidiff</option>
-            <option value="c" [is diff_format "c"]selected="selected"[end]>Context Diff</option>
-            <option value="s" [is diff_format "s"]selected="selected"[end]>Side by Side</option>
-          </select>
-          <input type="submit" value="Show" />
-          </div>
-      </form>
-    </td>
-    <td>
-[if-any raw_diff]
-       
-[else]
-      <table style="border:solid gray 1px;" class="auto">
-        <tr>
-          <td>Legend:<br />
-            <table cellspacing="0" cellpadding="1">
-              <tr>
-                <td style="text-align:center;" class="vc_diff_remove">Removed from v.[rev_left]</td>
-                <td class="vc_diff_empty"> </td>
-              </tr>
-              <tr>
-                <td style="text-align:center;" colspan="2" class="vc_diff_change">changed lines</td>
-              </tr>
-              <tr>
-                <td class="vc_diff_empty"> </td>
-                <td style="text-align:center;" class="vc_diff_add">Added in v.[rev_right]</td>
-              </tr>
-            </table>
-          </td>
-        </tr>
-      </table>
-[end]
-    </td>
-  </tr>
-</table>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/dir_new.ezt b/src/www/scm/viewvc/templates/dir_new.ezt
deleted file mode 100644
index 81c046d..0000000
--- a/src/www/scm/viewvc/templates/dir_new.ezt
+++ /dev/null
@@ -1,118 +0,0 @@
-[include "include/dir_header.ezt"]
-
-<table cellspacing="1" cellpadding="2">
-<thead>
-<tr>
-  <th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
-    <a href="[sortby_file_href]#dirlist">File
-    [is sortby "file"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-  <th class="vc_header[is sortby "rev"]_sort[end]">
-    <a href="[sortby_rev_href]#dirlist">Last Change
-    [is sortby "rev"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-</tr>
-</thead>
-
-<tbody>
-[if-any up_href]
-  <tr class="vc_row_odd">
-    <td>
-      <a href="[up_href]">
-      <img src="[docroot]/images/back_small.png" alt="" width="16" height="16"
-      /> Parent Directory</a>
-    </td>
-    <td> </td>
-    <td> </td>
-  </tr>
- [end]
-[for entries]
-  <tr class="vc_row_[if-index entries even]even[else]odd[end]">
-    <td>
-    <a name="[entries.anchor]" href="[is entries.pathtype "dir"][entries.view_href][else][if-any entries.prefer_markup][entries.view_href][else][entries.download_href][end][end]" title="[is entries.pathtype "dir"]View Directory Contents[else][if-any entries.prefer_markup]View[else]Download[end] File Contents[end]">
-       <img src="[docroot]/images/[is entries.pathtype "dir"]dir[else][is entries.state "dead"]broken[else]text[end][end].png" alt="" width="16" height="16" />
-       [entries.name][is entries.pathtype "dir"]/[end]</a>
-       [is entries.state "dead"](dead)[end]
-    </td>
-
-    [if-any entries.errors]
-      <td colspan="2">[for entries.errors]<em>[entries.errors]</em>[end]</td>
-    [else]
-      <td style="width:1%; white-space: nowrap">
-
-        [# Icon column. We might want to add more icons like a tarball
-         # icon for directories or a diff to previous icon for files. ]
-
-        [if-any entries.log_href]
-        <a href="[entries.log_href]"><img
-        src="[docroot]/images/log.png"
-        alt="View Log" width="16" height="16" /></a>
-        [end]
-
-        [is entries.pathtype "dir"]
-          [is roottype "cvs"]
-            [# no point in showing icon when there's only one to choose from]
-          [else]
-            <a href="[entries.view_href]"><img
-            src="[docroot]/images/list.png"
-            alt="View Directory Listing" width="16" height="16" /></a>
-          [end]
-        [end]
-
-        [is entries.pathtype "file"]
-          [if-any entries.graph_href]
-          <a href="[entries.graph_href]"
-          title="View Revision Graph"><img
-          src="[docroot]/images/cvsgraph_16x16.png"
-          alt="View Revision Graph" width="16" height="16" />
-          </a>
-          [end]
-
-          [if-any entries.view_href]
-          <a href="[entries.view_href]"><img
-          src="[docroot]/images/view.png"
-          alt="View File" width="16" height="16" /></a>
-          [end]
-
-          [if-any entries.download_href]
-          <a href="[entries.download_href]"><img
-          src="[docroot]/images/download.png"
-          alt="Download File" width="16" height="16" /></a>
-          [end]
-
-          [if-any entries.annotate_href]
-          <a href="[entries.annotate_href]"><img
-          src="[docroot]/images/annotate.png"
-          alt="Annotate File" width="16" height="16" /></a>
-          [end]
-        [end]
-      </td>
-      <td>
-        [if-any entries.rev]
-          <strong>[if-any entries.revision_href]<a href="[entries.revision_href]">[entries.rev]</a>[else][entries.rev][end]</strong>
-          ([entries.ago] ago)
-          by <em>[entries.author]</em>:
-          [entries.log]
-          [is entries.pathtype "dir"][is roottype "cvs"]
-            <em>(from [entries.log_file]/[entries.log_rev])</em>
-          [end][end]
-        [end]
-      </td>
-    [end]
-  </tr>
-[end]
-</tbody>
-
-</table>
-
-[include "include/dir_footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/directory.ezt b/src/www/scm/viewvc/templates/directory.ezt
deleted file mode 100644
index 6ff6944..0000000
--- a/src/www/scm/viewvc/templates/directory.ezt
+++ /dev/null
@@ -1,118 +0,0 @@
-[include "include/dir_header.ezt"]
-
-<table cellspacing="1" cellpadding="2">
-<thead>
-<tr>
-  <th class="vc_header[is sortby "file"]_sort[end]" colspan="2">
-    <a href="[sortby_file_href]#dirlist">File
-    [is sortby "file"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-  <th class="vc_header[is sortby "rev"]_sort[end]">
-    <a href="[sortby_rev_href]#dirlist">Rev.
-    [is sortby "rev"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-  <th class="vc_header[is sortby "date"]_sort[end]">
-    <a href="[sortby_date_href]#dirlist">Age
-    [is sortby "date"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-  <th class="vc_header[is sortby "author"]_sort[end]">
-    <a href="[sortby_author_href]#dirlist">Author
-    [is sortby "author"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-[is cfg.options.show_logs "1"]
-  <th class="vc_header[is sortby "log"]_sort[end]">
-    <a href="[sortby_log_href]#dirlist">Last log entry
-    [is sortby "log"]
-      <img class="vc_sortarrow" alt="[is sortdir "down"](rev)[end]"
-        width="13" height="13"
-        src="[docroot]/images/[is sortdir "up"]up[else]down[end].png" />
-    [end]
-    </a>
-  </th>
-[end]
-</tr>
-</thead>
-
-<tbody>
-[if-any up_href]
-  <tr class="vc_row_odd">
-    <td colspan="2">
-      <a href="[up_href]">
-      <img src="[docroot]/images/back_small.png" alt="" width="16" height="16"
-      /> Parent Directory</a>
-    </td>
-    <td> </td>
-    <td> </td>
-    <td> </td>
-    [is cfg.options.show_logs "1"]
-      <td> </td>
-    [end]
-  </tr>
- [end]
- [for entries]
-   <tr class="vc_row_[if-index entries even]even[else]odd[end]">
-     <td[if-any entries.graph_href][else] colspan="2"[end]>
-       [is entries.pathtype "dir"]
-       <a name="[entries.anchor]" href="[entries.view_href]" title="View directory contents">
-       [else]
-       <a name="[entries.anchor]" href="[entries.log_href]" title="View file revision log">
-       [end]
-       <img src="[docroot]/images/[is entries.pathtype "dir"]dir[else][is entries.state "dead"]broken[else]text[end][end].png" alt="" width="16" height="16" />
-       [entries.name][is entries.pathtype "dir"]/[end]</a>
-       [is entries.state "dead"](dead)[end]
-     </td>
-     [if-any entries.graph_href]
-       <td style="width:1%"><a href="[entries.graph_href]"
-       title="View Revision Graph"><img
-       src="[docroot]/images/cvsgraph_16x16.png"
-       alt="View Revision Graph" width="16" height="16" />
-       </a></td>
-     [end]
-     [if-any entries.errors]
-       <td colspan=[is cfg.options.show_logs "1"]4[else]3[end]>
-         [for entries.errors]<em>[entries.errors]</em>[end]
-       </td>
-     [else]
-       [is entries.pathtype "dir"]
-       <td> [if-any entries.rev]<a href="[entries.log_href]" title="View directory revision log"><strong>[entries.rev]</strong></a>[end]</td>
-       [else]
-       <td> [if-any entries.rev]<a href="[if-any entries.prefer_markup][entries.view_href][else][entries.download_href][end]" title="[if-any entries.prefer_markup]View[else]Download[end] file contents"><strong>[entries.rev]</strong></a>[end]</td>
-       [end]
-       <td> [entries.ago]</td>
-       <td> [entries.author]</td>
-       [is cfg.options.show_logs "1"]
-         [if-any entries.log]
-           <td> [entries.log][is entries.pathtype "dir"][is roottype "cvs"]
-             <em>(from [entries.log_file]/[entries.log_rev])</em>[end][end]</td>
-         [else]
-           <td> </td>
-         [end]
-      [end]
-    [end]
-  </tr>
-[end]
-</tbody>
-
-</table>
-
-[include "include/dir_footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/docroot/help_log.html b/src/www/scm/viewvc/templates/docroot/help_log.html
deleted file mode 100644
index 8d9a1e8..0000000
--- a/src/www/scm/viewvc/templates/docroot/help_log.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <title>ViewVC Help: Log View</title>
-  <link rel="stylesheet" href="help.css" type="text/css" />
-  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
-</head>
-<body>
-  <table>
-    <col class="menu" />
-    <col />
-    <tr>
-      <td><a href="http://viewvc.org/index.html"><img
-	     src="images/logo.png" alt="ViewVC logotype" /></a>
-      </td>
-      <td>
-	<h1>ViewVC Help: Log View</h1>
-      </td>
-    </tr>
-    <tr><td>
-       <h3>Help</h3>
-       <a href="help_rootview.html">General</a><br />
-       <a href="help_dirview.html">Directory View</a><br />
-       <strong>Log View</strong><br />
-
-       <h3>Internet</h3>
-       <a href="http://viewvc.org/index.html">Home</a><br />
-       <a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
-       <a href="http://viewvc.org/contributing.html">Contributing</a><br />
-       <a href="http://viewvc.org/license-1.html">License</a><br />
-    </td><td colspan="2">
-    <p>
-      The log view displays the revision history of the selected source
-      file or directory. For each revision the following information is
-      displayed:
-    </p>
-    <ul>
-      <li>The revision number. In Subversion repositories, this is a
-          link to the <a href="help_rootview.html#view-rev">revision
-          view</a></li>
-      <li>For files, links to
-      <a href="help_rootview.html#view-markup">view</a>,
-      <a href="help_rootview.html#view-checkout">download</a>, and
-      <a href="help_rootview.html#view-annotate">annotate</a> the
-        revision. For directories, a link to
-      <a href="help_dirview.html">list directory contents</a></li>
-      <li>A link to select the revision for diffs (see below)</li>
-      <li>The date and age of the change</li>
-      <li>The author of the modification</li>
-      <li>The CVS branch (usually <em>MAIN</em>, if not on a branch)</li>
-      <li>Possibly a list of CVS tags bound to the revision (if any)</li>
-      <li>The size of the change measured in added and removed lines of
-          code. (CVS only)</li>
-      <li>The size of the file in bytes at the time of the revision
-          (Subversion only)</li>
-      <li>Links to view diffs to the previous revision or possibly to
-          an arbitrary selected revision (if any, see above)</li>
-      <li>If the revision is the result of a copy, the path and revision
-          copied from</li>
-      <li>If the revision precedes a copy or rename, the path at the
-          time of the revision</li>
-      <li>And last but not least, the commit log message which should tell
-          about the reason for the change.</li>
-    </ul>
-    <p>
-      At the bottom of the page you will find a form which allows
-      to request diffs between arbitrary revisions.
-    </p>
-  </td></tr></table>
-  <hr />
-  <address><a href="mailto:users at viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
-  </body>
-</html>
diff --git a/src/www/scm/viewvc/templates/docroot/help_query.html b/src/www/scm/viewvc/templates/docroot/help_query.html
deleted file mode 100644
index af9657e..0000000
--- a/src/www/scm/viewvc/templates/docroot/help_query.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <title>ViewVC Help: Query The Commit Database</title>
-  <link rel="stylesheet" href="help.css" type="text/css" />
-</head>
-<body>
-<table>
-  <col class="menu" />
-  <col />
-  <tr>
-    <td><a href=".."><img
-        src="images/logo.png" alt="ViewVC logotype" /></a>
-    </td>
-    <td><h1>ViewVC Help: Query The Commit Database</h1></td>
-  </tr>
-  <tr><td>
-     <h3>Other Help:</h3>
-     <a href="help_rootview.html">General</a><br />
-     <a href="help_dirview.html">Directory View</a><br />
-     <a href="help_log.html">Classic Log View</a><br />
-     <a href="help_logtable.html">Alternative Log View</a><br />
-     <strong>Query Database</strong>
-
-     <h3>Internet</h3>
-     <a href="http://viewvc.org/index.html">Home</a><br />
-     <a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
-     <a href="http://viewvc.org/contributing.html">Contributing</a><br />
-     <a href="http://viewvc.org/license-1.html">License</a><br />
-  </td><td colspan="2">
-
-  <p> 
-    Select your parameters for querying the CVS commit database in the
-    form at the top of the page.  You
-    can search for multiple matches by typing a comma-seperated list
-    into the text fields.  Regular expressions, and wildcards are also
-    supported.  Blank text input fields are treated as wildcards.
-  </p>
-  <p>
-    Any of the text entry fields can take a comma-seperated list of
-    search arguments.  For example, to search for all commits from
-    authors <em>jpaint</em> and <em>gstein</em>, just type: <code>jpaint,
-    gstein</code> in the <em>Author</em> input box.  If you are searching
-    for items containing spaces or quotes, you will need to quote your
-    request.  For example, the same search above with quotes is:
-    <code>"jpaint", "gstein"</code>.
-  </p>
-  <p>                           
-    Wildcard and regular expression searches are entered in a similar
-    way to the quoted requests.  You must quote any wildcard or
-    regular expression request, and a command character preceeds the
-    first quote.  The command character <code>l</code>(lowercase L) is for wildcard
-    searches, and the wildcard character is a percent (<code>%</code>).  The
-    command character for regular expressions is <code>r</code>, and is
-    passed directly to MySQL, so you'll need to refer to the MySQL
-    manual for the exact regex syntax.  It is very similar to Perl.  A
-    wildard search for all files with a <em>.py</em> extention is:
-    <code>l"%.py"</code> in the <em>File</em> input box.  The same search done
-    with a regular expression is: <code>r".*\.py"</code>.
-  </p>
-  <p>                  
-    All search types can be mixed, as long as they are seperated by
-    commas.
-  </p>                                                    
-  </td></tr></table>
-</body></html>
diff --git a/src/www/scm/viewvc/templates/docroot/help_rootview.html b/src/www/scm/viewvc/templates/docroot/help_rootview.html
deleted file mode 100644
index 6308d8b..0000000
--- a/src/www/scm/viewvc/templates/docroot/help_rootview.html
+++ /dev/null
@@ -1,169 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
-  <title>ViewVC Help: General</title>
-  <link rel="stylesheet" href="help.css" type="text/css" />
-</head>
-<body>
-  <table>
-    <col class="menu" />
-    <col />
-    <tr>
-      <td><a href=".."><img
-	     src="images/logo.png" alt="ViewVC logotype" /></a>
-      </td>
-      <td>
-	<h1>ViewVC Help: General</h1>
-      </td>
-    </tr>
-    <tr><td>
-       <h3>Help</h3>
-       <strong>General</strong><br />
-       <a href="help_dirview.html">Directory View</a><br />
-       <a href="help_log.html">Log View</a><br />
-
-       <h3>Internet</h3>
-       <a href="http://viewvc.org/index.html">Home</a><br />
-       <a href="http://viewvc.org/upgrading.html">Upgrading</a><br />
-       <a href="http://viewvc.org/contributing.html">Contributing</a><br />
-       <a href="http://viewvc.org/license-1.html">License</a><br />
-    </td><td colspan="2">
-
-  <p><em>ViewVC</em> is a WWW interface for CVS and Subversion
-  repositories. It allows you to browse the files and directories in a
-  repository while showing you metadata from the repository history: log
-  messages, modification dates, author names, revision numbers, copy
-  history, and so on. It provides several different views of repository
-  data to help you find the information you are looking for:</p>
-
-  <ul>
-    <li><a name="view-dir" href="help_dirview.html"><strong>Directory
-    View</strong></a> - Shows a list of files and subdirectories in a
-    directory of the repository, along with metadata like author names and
-    log entries.</li>
-
-    <li><a name="view-log" href="help_log.html"><strong>Log
-    View</strong></a> - Shows a revision by revision list of all the
-    changes that have made to a file or directory in the repository, with
-    metadata and links to views of each revision.</li>
-
-    <li><a name="view-markup"><strong>File Contents View (Markup
-    View)</strong></a> - Shows the contents of a file at a particular
-    revision, with revision information at the top of the page. File
-    revisions which are GIF, PNG, or JPEG images are displayed inline on
-    the page. Other file types are displayed as marked up text. The markup
-    may be limited to turning URLs and email addresses into links, or
-    configured to show colorized source code.</li>
-
-    <li><a name="view-checkout"><strong>File Download (Checkout
-    View)</strong></a> - Retrieves the unaltered contents of a file
-    revision. Browsers may try to display the file, or just save it to
-    disk.</li>
-
-    <li><a name="view-annotate"><strong>File Annotate View</strong></a> -
-    Shows the contents of a file revision and breaks it down line by line,
-    showing the revision number where each one was last modified, along
-    with links and other information. <em>This view is disabled in some
-    ViewVC configurations</em></li>
-
-    <li><a name="view-diff"><strong>File Diff View</strong></a> - Shows
-    the changes made between two revisions of a file</li>
-
-    <li><a name="view-tarball"><strong>Directory Tarball View</strong></a> -
-    Retrieves a gzipped tar archive containing the contents of a
-    directory.<em>This view is disabled in the default ViewVC
-    configuration.</em></li>
-
-    <li><a name="view-query"><strong>Directory Query View</strong></a> -
-    Shows information about changes made to all subdirectories and files
-    under a parent directory, sorted and filtered by criteria you specify.
-    <em>This view is disabled in the default ViewVC configuration.</em>
-    </li>
-
-    <li><a name="view-rev"><strong>Revision View</strong></a> - Shows
-    information about a revision including log message, author, and a list
-    of changed paths. <em>For Subversion repositories only.</em></li>
-
-    <li><a name="view-graph"><strong>Graph View</strong></a> - Shows a
-    graphical representation of a file's revisions and branches complete
-    with tag and author names and links to markup and diff pages.
-    <em>For CVS repositories only, and disabled in the default
-    configuration.</em></li>
-  </ul>
-
-  <h3><a name="multiple-repositories">Multiple Repositories</a></h3>
-
-  <p>A single installation of ViewVC is often used to provide access to
-  more than one repository. In these installations, ViewVC shows a
-  <em>Project Root</em> drop down box in the top right corner of every
-  generated page to allow for quick access to any repository.</p>
-
-  <h3><a name="sticky-revision-tag">Sticky Revision and Tag</a></h3>
-
-  <p>By default, ViewVC will show the files and directories and revisions
-  that currently exist in the repository. But it's also possible to browse
-  the contents of a repository at a point in its past history by choosing
-  a "sticky tag" (in CVS) or a "sticky revision" (in Subversion) from the
-  forms at the top of directory and log pages. They're called sticky
-  because once they're chosen, they stick around when you navigate to
-  other pages, until you reset them. When they're set, directory and log
-  pages only show revisions preceding the specified point in history. In
-  CVS, when a tag refers to a branch or a revision on a branch, only
-  revisions from the branch history are shown, including branch points and
-  their preceding revisions.</p>
-
-  <h3><a name="dead-files">Dead Files</a></h3>
-
-  <p>In CVS directory listings, ViewVC can optionally display dead files.
-  Dead files are files which used to be in a directory but are currently
-  deleted, or files which just don't exist in the currently selected
-  <a href="#sticky-revision-tag">sticky tag</a>. Dead files cannot be
-  shown in Subversion repositories. The only way to see a deleted file in
-  a Subversion directory is to navigate to a sticky revision where the
-  file previously existed.</p>
-
-  <h3><a name="artificial-tags">Artificial Tags</a></h3>
-
-  <p>In CVS Repositories, ViewVC adds artificial tags <em>HEAD</em> and
-  <em>MAIN</em> to tag listings and accepts them in place of revision
-  numbers and real tag names in all URLs. <em>MAIN</em> acts like a branch
-  tag pointing at the default branch, while <em>HEAD</em> acts like a
-  revision tag pointing to the latest revision on the default branch. The
-  default branch is usually just the trunk, but may be set to other
-  branches inside individual repository files. CVS will always check out
-  revisions from a file's default branch when no other branch is specified
-  on the command line.</p>
-
-  <h3><a name="more-information">More Information</a></h3>
-
-  <p>More information about <em>ViewVC</em> is available from
-  <a href="http://viewvc.org/">viewvc.org</a>.
-  See the links below for guides to CVS and Subversion</p>
-
-  <h4>Documentation about CVS</h4>
-  <blockquote>
-    <p>
-      <a href="http://cvsbook.red-bean.com/"><em>Open Source
-      Development with CVS</em></a><br />
-      <a href="http://www.loria.fr/~molli/cvs/doc/cvs_toc.html">CVS
-      User's Guide</a><br />
-      <a href="http://cellworks.washington.edu/pub/docs/cvs/tutorial/cvs_tutorial_1.html">Another CVS tutorial</a><br />
-      <a href="http://www.csc.calpoly.edu/~dbutler/tutorials/winter96/cvs/">Yet another CVS tutorial (a little old, but nice)</a><br />
-      <a href="http://www.cs.utah.edu/dept/old/texinfo/cvs/FAQ.txt">An old but very useful FAQ about CVS</a>
-    </p>
-  </blockquote>
-
-  <h4>Documentation about Subversion</h4>
-  <blockquote>
-    <p>
-      <a href="http://svnbook.red-bean.com/"><em>Version Control with
-      Subversion</em></a>
-    </p>
-  </blockquote>
-
-  </td></tr></table>
-  <hr />
-  <address><a href="mailto:users at viewvc.tigris.org">ViewVC Users Mailinglist</a></address>
-  </body>
-</html>
diff --git a/src/www/scm/viewvc/templates/docroot/images/chalk.jpg b/src/www/scm/viewvc/templates/docroot/images/chalk.jpg
deleted file mode 100644
index 850a1d9..0000000
Binary files a/src/www/scm/viewvc/templates/docroot/images/chalk.jpg and /dev/null differ
diff --git a/src/www/scm/viewvc/templates/docroot/images/feed-icon-16x16.jpg b/src/www/scm/viewvc/templates/docroot/images/feed-icon-16x16.jpg
deleted file mode 100644
index 8110e8c..0000000
Binary files a/src/www/scm/viewvc/templates/docroot/images/feed-icon-16x16.jpg and /dev/null differ
diff --git a/src/www/scm/viewvc/templates/docroot/images/logo.png b/src/www/scm/viewvc/templates/docroot/images/logo.png
deleted file mode 100644
index 7794a38..0000000
Binary files a/src/www/scm/viewvc/templates/docroot/images/logo.png and /dev/null differ
diff --git a/src/www/scm/viewvc/templates/docroot/styles.css b/src/www/scm/viewvc/templates/docroot/styles.css
deleted file mode 100644
index 9848422..0000000
--- a/src/www/scm/viewvc/templates/docroot/styles.css
+++ /dev/null
@@ -1,199 +0,0 @@
-/*******************************/
-/***  ViewVC CSS Stylesheet ***/
-/*******************************/
-
-/*** Standard Tags ***/
-html, body {
-  color: #000000;
-  background-color: #ffffff;
-}
-
-a:link    { color: #0000ff; }
-a:visited { color: #880088; }
-a:active  { color: #0000ff; }
-
-img { border: none; }
-table {
-  width: 100%;
-  margin: 0; 
-  border: none;
-}
-table.auto {
-  width: auto;
-}
-tr, td, th { vertical-align: top; }
-form { margin: 0; }
-
-/** Navigation Headers ***/
-.vc_navheader {
-  background-color: #cccccc;
-}
-
-
-/*** Table Headers ***/
-.vc_header {
-  text-align: left;
-  vertical-align: top;
-  background-color: #cccccc;
-}
-.vc_header_sort {
-  text-align: left;
-  background-color: #88ff88;
-}
-
-
-/*** Table Rows ***/
-.vc_row_even {
-  background-color: #ffffff;
-}
-.vc_row_odd {
-  background-color: #ccccee;
-}
-
-
-/*** Log messages ***/
-.vc_log {
-  /* unfortunately, white-space: pre-wrap isn't widely supported ... */
-  white-space: -moz-pre-wrap; /* Mozilla based browsers */
-  white-space: -pre-wrap;     /* Opera 4 - 6 */
-  white-space: -o-pre-wrap;   /* Opera >= 7 */
-  white-space: pre-wrap;      /* CSS3 */
-  word-wrap: break-word;      /* IE 5.5+ */
-}
-
-
-/*** Markup Summary Header ***/
-.vc_summary {
-  background-color: #eeeeee;
-}
-
-/*** Highlight Markup Styles ***/
-#vc_markup .num  { color: #000000; }
-#vc_markup .esc  { color: #bd8d8b; }
-#vc_markup .str  { color: #bd8d8b; }
-#vc_markup .dstr { color: #bd8d8b; }
-#vc_markup .slc  { color: #ac2020; font-style: italic; }
-#vc_markup .com  { color: #ac2020; font-style: italic; }
-#vc_markup .dir  { color: #000000; }
-#vc_markup .sym  { color: #000000; }
-#vc_markup .line { color: #555555; }
-#vc_markup .kwa  { color: #9c20ee; font-weight: bold; }
-#vc_markup .kwb  { color: #208920; }
-#vc_markup .kwc  { color: #0000ff; }
-#vc_markup .kwd  { color: #404040; }
-
-/*** Py2html Markup Styles  ***/
-#vc_markup .PY_STRING     { color: #bd8d8b; }
-#vc_markup .PY_COMMENT    { color: #ac2020; font-style: italic; }
-#vc_markup .PY_KEYWORD    { color: #9c20ee; font-weight: bold; }
-#vc_markup .PY_IDENTIFIER { color: #404040; }
-
-/*** Line numbers outputted by highlight colorizer ***/
-.line {
-  border-right-width: 1px;
-  border-right-style: solid;
-  border-right-color: #505050;
-  padding: 1px;
-  background-color: #eeeeee;
-  color: #505050;
-  text-decoration: none;
-  font-weight: normal;
-  font-style: normal;
-}
-
-/*** Diff Styles ***/
-.vc_diff_header {
-  background-color: #ffffff;
-}
-.vc_diff_chunk_header {
-  background-color: #99cccc;
-}
-.vc_diff_chunk_extra {
-  font-size: smaller;
-}
-.vc_diff_empty {
-  background-color: #cccccc;
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_diff_add {
-  background-color: #aaffaa;
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_diff_remove {
-  background-color: #ffaaaa;
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_diff_change {
-  background-color: #ffff77;
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_diff_change_empty {
-  background-color: #eeee77;
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_diff_nochange {
-  font-family: sans-serif;
-  font-size: smaller;
-}
-.vc_raw_diff {
-  background-color: #cccccc;
-  font-size: smaller;
-}
-
-/*** Intraline Diff Styles ***/
-
-.vc_idiff_add {
-  background-color: #aaffaa;
-}
-.vc_idiff_change {
-  background-color:#ffff77;
-}
-.vc_idiff_remove {
-  background-color:#ffaaaa;
-}
-.vc_idiff_empty {
-  background-color:#e0e0e0;
-}
-
-table.vc_idiff col.content { 
-  width: 50%;
-}
-table.vc_idiff tbody {
-  font-family: monospace; 
-  /* unfortunately, white-space: pre-wrap isn't widely supported ... */
-  white-space: -moz-pre-wrap; /* Mozilla based browsers */
-  white-space: -pre-wrap;     /* Opera 4 - 6 */
-  white-space: -o-pre-wrap;   /* Opera >= 7 */
-  white-space: pre-wrap;      /* CSS3 */
-  word-wrap: break-word;      /* IE 5.5+ */
-}
-table.vc_idiff tbody th {
-  background-color:#e0e0e0;
-  text-align:right;
-}
-
-/*** Annotate Styles ***/
-.vc_blame_line, .vc_blame_author, .vc_blame_rev {
-  font-family: monospace;
-  font-size: smaller;
-  text-align: right;
-  white-space: nowrap;
-  padding-right: 1em;
-}
-.vc_blame_text {
-  font-family: monospace;
-  font-size: smaller;
-  text-align: left;
-  white-space: pre;
-  width: 100%;
-}
-
-/*** Query Form ***/
-.vc_query_form {
-  background-color: #e6e6e6;
-}
diff --git a/src/www/scm/viewvc/templates/error.ezt b/src/www/scm/viewvc/templates/error.ezt
deleted file mode 100644
index 2ba190c..0000000
--- a/src/www/scm/viewvc/templates/error.ezt
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<!-- ViewVC :: http://www.viewvc.org/ -->
-<head>
-<title>ViewVC Exception</title>
-</head>
-<body>
-<h3>An Exception Has Occurred</h3>
-
-[if-any msg]
-  <p><pre>[msg]</pre></p>
-[end]
-[if-any status]
-  <h4>HTTP Response Status</h4>
-  <p><pre>[status]</pre></p>
-  <hr />
-[end]
-<h4>Python Traceback</h4>
-<p><pre>
-[stacktrace]
-</pre></p>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/templates/graph.ezt b/src/www/scm/viewvc/templates/graph.ezt
deleted file mode 100644
index 5227abc..0000000
--- a/src/www/scm/viewvc/templates/graph.ezt
+++ /dev/null
@@ -1,18 +0,0 @@
-[# setup page definitions]
-  [define page_title]Graph of /[where][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "graph"]
-[include "include/file_header.ezt"]
-
-<hr />
-
-<div style="text-align:center;">
-[imagemap]
-<img usemap="#MyMapName"
-  src="[imagesrc]" 
-  alt="Revisions of [where]" />
-</div>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/include/diff_form.ezt b/src/www/scm/viewvc/templates/include/diff_form.ezt
deleted file mode 100644
index f86f516..0000000
--- a/src/www/scm/viewvc/templates/include/diff_form.ezt
+++ /dev/null
@@ -1,66 +0,0 @@
-  <hr />
-  <p><a name="diff"></a>
-  This form allows you to request diffs between any two revisions of this file.
-  For each of the two "sides" of the diff,
-[if-any tags]
-  select a symbolic revision name using the selection box, or choose
-  'Use Text Field' and enter a numeric revision.
-[else]
-  enter a numeric revision.
-[end]
-  </p>
-  <form method="get" action="[diff_select_action]" name="diff_select">
-
-  <table cellpadding="2" cellspacing="0" class="auto">
-  <tr>
-  <td> </td>
-  <td>
-  [diff_select_hidden_values]
-  Diffs between
-[if-any tags]
-  <select name="r1">
-    <option value="text" selected="selected">Use Text Field</option>
-  [for tags]
-    <option value="[tags.rev]:[tags.name]">[tags.name]</option>
-  [end]
-  </select>
-  <input type="text" size="12" name="tr1" 
-         value="[if-any rev_selected][rev_selected][else][first_revision][end]"
-         onchange="document.diff_select.r1.selectedIndex=0" />
-[else]
-  <input type="text" size="12" name="r1"
-         value="[if-any rev_selected][rev_selected][else][first_revision][end]" />
-[end]
-
-  and
-[if-any tags]
-  <select name="r2">
-    <option value="text" selected="selected">Use Text Field</option>
-  [for tags]
-    <option value="[tags.rev]:[tags.name]">[tags.name]</option>
-  [end]
-  </select>
-  <input type="text" size="12" name="tr2" 
-         value="[last_revision]"
-         onchange="document.diff_select.r1.selectedIndex=0" />
-[else]
-  <input type="text" size="12" name="r2" value="[last_revision]" />
-[end]
-  </td>
-  </tr>
-  <tr>
-  <td> </td>
-  <td>
-  Type of Diff should be a
-  <select name="diff_format" onchange="submit()">
-    <option value="h" [is diff_format "h"]selected="selected"[end]>Colored Diff</option>
-    <option value="l" [is diff_format "l"]selected="selected"[end]>Long Colored Diff</option>
-    <option value="u" [is diff_format "u"]selected="selected"[end]>Unidiff</option>
-    <option value="c" [is diff_format "c"]selected="selected"[end]>Context Diff</option>
-    <option value="s" [is diff_format "s"]selected="selected"[end]>Side by Side</option>
-  </select>
-  <input type="submit" value="  Get Diffs  " />
-  </td>
-  </tr>
-  </table>
-  </form>
diff --git a/src/www/scm/viewvc/templates/include/dir_footer.ezt b/src/www/scm/viewvc/templates/include/dir_footer.ezt
deleted file mode 100644
index af4d122..0000000
--- a/src/www/scm/viewvc/templates/include/dir_footer.ezt
+++ /dev/null
@@ -1,38 +0,0 @@
-[if-any search_re_form]
-  <hr />
-  [# this table holds the selectors on the left, and reset on the right ]
-  <table class="auto">
-        <tr>
-          <td>Show files containing the regular expression:</td>
-          <td>
-            <form method="get" action="[search_re_action]">
-              <div>
-                [search_re_hidden_values]
-                <input type="text" name="search" value="[search_re]" />
-                <input type="submit" value="Show" />
-              </div>
-            </form>
-          </td>
-        </tr>
-      [if-any search_re]
-        <tr>
-          <td> </td>
-          <td>
-            <form method="get" action="[search_tag_action]">
-              <div>
-                [search_tag_hidden_values]
-                <input type="submit" value="Show all files" />
-              </div>
-            </form>
-          </td>
-        </tr>
-    [end]
-  </table>
-[end]
-
-[# if you want to disable tarball generation remove the following: ]
-[if-any tarball_href]
-  <p style="margin:0;"><a href="[tarball_href]">Download tarball</a></p>
-[end]
-
-[include "footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/include/dir_header.ezt b/src/www/scm/viewvc/templates/include/dir_header.ezt
deleted file mode 100644
index ad1f069..0000000
--- a/src/www/scm/viewvc/templates/include/dir_header.ezt
+++ /dev/null
@@ -1,64 +0,0 @@
-[# setup page definitions]
-  [define page_title]Index of /[where][end]
-  [define help_href][docroot]/help_[if-any where]dir[else]root[end]view.html[end]
-[# end]
-
-[include "header.ezt" "directory"]
-
-[if-any where][else]
-  <!-- you may insert repository access instructions here -->
-[end]
-
-<table class="auto">
-<tr><td>Files shown:</td><td><strong>[files_shown]</strong>
-[is num_dead "0"]
-[else]
-  [if-any attic_showing]
-    (<a href="[hide_attic_href]">Hide [num_dead] dead files</a>)
-  [else]
-    (<a href="[show_attic_href]">Show [num_dead] dead files</a>)
-  [end]
-[end]
-</td></tr>
-
-[is roottype "svn"]
-<tr>
-  <td>Directory revision:</td>
-  <td><a href="[tree_rev_href]">[tree_rev]</a>[if-any youngest_rev] (of <a href="[youngest_rev_href]">[youngest_rev]</a>)[end]</td>
-</tr>
-[end]
-<tr>
-  <td>Sticky [is roottype "cvs"]Tag[else]Revision[end]:</td>
-  <td>[include "pathrev_form.ezt"]</td>
-</tr>
-[if-any search_re]
-<tr><td>Current search:</td><td><strong>[search_re]</strong></td></tr>
-[end]
-
-[if-any queryform_href]
-<tr>
-  <td>Query:</td>
-  <td><a href="[queryform_href]">Query revision history</a></td>
-</tr>
-[end]
-</table>
-  [is cfg.options.use_pagesize "0"]
-  [else]
-    [is picklist_len "1"]
-    [else]
-      <form method="get" action="[dir_paging_action]">
-        [dir_paging_hidden_values]
-        <input type="submit" value="Go to:" />
-        <select name="dir_pagestart"  onchange="submit()">
-          [for picklist]
-            <option [is picklist.count dir_pagestart]selected[end] value="[picklist.count]">Page [picklist.page]: [picklist.start] to [picklist.end]</option>
-          [end]
-        </select>
-      </form>
-    [end]
-  [end]
-
-<p><a name="dirlist"></a></p>
-
-<hr />
-
diff --git a/src/www/scm/viewvc/templates/include/file_header.ezt b/src/www/scm/viewvc/templates/include/file_header.ezt
deleted file mode 100644
index adc07ba..0000000
--- a/src/www/scm/viewvc/templates/include/file_header.ezt
+++ /dev/null
@@ -1,16 +0,0 @@
-<p style="margin:0;">
-[is pathtype "file"]
-<a href="[up_href]"><img src="[docroot]/images/back_small.png" width="16" height="16" alt="Parent Directory" /> Parent Directory</a>
-[if-any log_href] 
-  | <a href="[log_href][if-any log_href_rev]#rev[log_href_rev][end]"><img src="[docroot]/images/log.png" width="16" height="16" alt="Revision Log" /> Revision Log</a>
-[end]
-[if-any graph_href]
-  | <a href="[graph_href]"><img src="[docroot]/images/cvsgraph_16x16.png" width="16" height="16" alt="View Revision Graph" /> Revision Graph</a>
-[end]
-[is view "diff"]
-  | <a href="[patch_href]"><img src="[docroot]/images/diff.png" width="16" height="16" alt="View Patch" /> Patch</a>
-[end]
-[else]
-<a href="[view_href]"><img src="[docroot]/images/dir.png" width="16" height="16" alt="View Directory Listing" /> Directory Listing</a>
-[end]
-</p>
diff --git a/src/www/scm/viewvc/templates/include/footer.ezt b/src/www/scm/viewvc/templates/include/footer.ezt
deleted file mode 100644
index 2c76c3b..0000000
--- a/src/www/scm/viewvc/templates/include/footer.ezt
+++ /dev/null
@@ -1,17 +0,0 @@
-[# standard footer used by all ViewVC pages ]
-
-<hr />
-
-<table>
-<tr>
-  <td><address>[cfg.general.address]</address></td>
-  <td style="text-align: right;"><strong><a href="[help_href]">ViewVC Help</strong></td>
-</tr>
-<tr>
-  <td>Powered by <a href="http://viewvc.tigris.org/">ViewVC [vsn]</a></td>
-  <td style="text-align: right;">[if-any rss_href]<a href="[rss_href]" title="RSS 2.0 feed"><img src="[docroot]/images/feed-icon-16x16.jpg"/>[else] [end]</td>
-</tr>
-</table>
-
-</body>
-</html>
diff --git a/src/www/scm/viewvc/templates/include/header.ezt b/src/www/scm/viewvc/templates/include/header.ezt
deleted file mode 100644
index 9fb87c6..0000000
--- a/src/www/scm/viewvc/templates/include/header.ezt
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<!-- ViewVC :: http://www.viewvc.org/ -->
-<head>
-  <title>[if-any rootname][[][rootname]][else]ViewVC[end] [page_title]</title>
-  <meta name="generator" content="ViewVC [vsn]" />
-  <link rel="stylesheet" href="[docroot]/styles.css" type="text/css" />
-  [if-any rss_href]<link rel="alternate" type="application/rss+xml" title="RSS [[][rootname]][where]" HREF="[rss_href]">[end]
-</head>
-<body>
-<div class="vc_navheader">
-<table style="padding:0.1em;">
-<tr>
-  <td>
-  [if-any nav_path]<strong>
-    [for nav_path]
-      [if-any nav_path.href]<a href="[nav_path.href]">[end]
-      [if-index nav_path first]
-        [[][nav_path.name]][else]
-        [nav_path.name][end][if-any nav_path.href]</a>[end]
-      [if-index nav_path last][else]/[end]
-    [end]
-    </strong>
-  [end]
-  </td>
-  <td style="text-align:right;">
-     
-  </td>
-</tr>
-</table>
-</div>
-
-<div style="float: right; padding: 5px;"><a href="http://www.viewvc.org/"><img src="[docroot]/images/logo.png" alt="ViewVC logotype" width="128" height="48" /></a></div>
-<h1>[page_title]</h1>
-
-
diff --git a/src/www/scm/viewvc/templates/include/log_footer.ezt b/src/www/scm/viewvc/templates/include/log_footer.ezt
deleted file mode 100644
index b39c861..0000000
--- a/src/www/scm/viewvc/templates/include/log_footer.ezt
+++ /dev/null
@@ -1,10 +0,0 @@
-[include "paging.ezt"]
-
-[is pathtype "file"]
-  [include "diff_form.ezt"]
-[end]
-
-[include "sort.ezt"]
-
-[include "footer.ezt"]
-
diff --git a/src/www/scm/viewvc/templates/include/log_header.ezt b/src/www/scm/viewvc/templates/include/log_header.ezt
deleted file mode 100644
index f84667b..0000000
--- a/src/www/scm/viewvc/templates/include/log_header.ezt
+++ /dev/null
@@ -1,54 +0,0 @@
-[# setup page definitions]
-  [define page_title]Log of /[where][end]
-  [define help_href][docroot]/help_log.html[end]
-[# end]
-
-[include "header.ezt" "log"]
-[include "file_header.ezt"]
-
-<hr />
-
-<table class="auto">
-
-[if-any default_branch]
-<tr>
-  <td>Default branch:</td>
-  <td>[for default_branch]<a href="[default_branch.href]">[default_branch.name]</a>[if-index default_branch last][else], [end]
-[end]</td>
-</tr>
-[end]
-
-[is pathtype "file"]
-[if-any view_href]
-<tr>
-  <td>Links to HEAD:</td>
-  <td>
-    (<a href="[view_href]">view</a>)
-    [if-any download_href](<a href="[download_href]">download</a>)[end]
-    [if-any download_text_href](<a href="[download_text_href]">as text</a>)[end]
-    [if-any annotate_href](<a href="[annotate_href]">annotate</a>)[end]
-  </td>
-</tr>
-[end]
-
-[if-any tag_view_href]
-<tr>
-  <td>Links to [pathrev]:</td>
-  <td>
-    (<a href="[tag_view_href]">view</a>)
-    [if-any tag_download_href](<a href="[tag_download_href]">download</a>)[end]
-    [if-any tag_download_text_href](<a href="[tag_download_text_href]">as text</a>)[end]
-    [if-any tag_annotate_href](<a href="[tag_annotate_href]">annotate</a>)[end]
-  </td>
-</tr>
-[end]
-[end]
-
-<tr>
-  <td>Sticky [is roottype "cvs"]Tag[else]Revision[end]:</td>
-  <td>[include "pathrev_form.ezt"]</td>
-</tr>
-
-</table>
-
-[include "paging.ezt"]
diff --git a/src/www/scm/viewvc/templates/include/paging.ezt b/src/www/scm/viewvc/templates/include/paging.ezt
deleted file mode 100644
index b88e74a..0000000
--- a/src/www/scm/viewvc/templates/include/paging.ezt
+++ /dev/null
@@ -1,18 +0,0 @@
-  [is cfg.options.use_pagesize "0"]
-  [else]
-    [is picklist_len "1"]
-    [else]
-      <hr />
-      <form method="get" action="[log_paging_action]">
-        [log_paging_hidden_values]
-        <input type="submit" value="Go to:">
-        <select name="log_pagestart"  onchange="submit()">
-          [for picklist]
-            <option [is picklist.count log_pagestart]selected[end] value="[picklist.count]">Page [picklist.page]: [picklist.start] - [picklist.end]</option>
-          [end]
-        </select>
-      </form>
-    [end]
-  [end]
-
-
diff --git a/src/www/scm/viewvc/templates/include/pathrev_form.ezt b/src/www/scm/viewvc/templates/include/pathrev_form.ezt
deleted file mode 100644
index 971288c..0000000
--- a/src/www/scm/viewvc/templates/include/pathrev_form.ezt
+++ /dev/null
@@ -1,49 +0,0 @@
-<form method="get" action="[pathrev_action]" style="display: inline">
-[pathrev_hidden_values]
-[is roottype "cvs"]
-  [define pathrev_selected][pathrev][end]
-  <select name="pathrev" onchange="submit()">
-  <option value=""></option>
-  [if-any branch_tags]
-    <optgroup label="Branches">
-    [for branch_tags]
-      [is branch_tags pathrev]
-        <option selected>[branch_tags]</option>
-        [define pathrev_selected][end]
-      [else]
-        <option>[branch_tags]</option>
-      [end]
-    [end]
-    </optgroup>
-  [end]
-  <optgroup label="Non-branch tags">
-  [for plain_tags]
-    [is plain_tags pathrev]
-      <option selected>[plain_tags]</option>
-      [define pathrev_selected][end]
-    [else]
-      <option>[plain_tags]</option>
-    [end]
-  [end]
-  </optgroup>
-  [if-any pathrev_selected]
-    <option selected>[pathrev_selected]</option>
-  [end]
-  </select>
-[else]
-  <input type="text" name="pathrev" value="[pathrev]" size="6"/>
-[end]
-<input type="submit" value="Set" />
-</form>
-
-[if-any pathrev]
-<form method="get" action="[pathrev_clear_action]" style="display: inline">
-[pathrev_clear_hidden_values]
-[if-any lastrev]
-  [is pathrev lastrev][else]<input type="submit" value="Set to [lastrev]">[end]
-  (<i>Current path doesn't exist after revision <strong>[lastrev]</strong></i>)
-[else]
-  <input type="submit" value="Clear">
-[end]
-</form>
-[end]
diff --git a/src/www/scm/viewvc/templates/include/sort.ezt b/src/www/scm/viewvc/templates/include/sort.ezt
deleted file mode 100644
index 30af0f9..0000000
--- a/src/www/scm/viewvc/templates/include/sort.ezt
+++ /dev/null
@@ -1,14 +0,0 @@
-<form method="get" action="[logsort_action]">
-  <div>
-    <hr />
-    <a name="logsort"></a>
-      [logsort_hidden_values]
-      Sort log by:
-      <select name="logsort" onchange="submit()">
-        <option value="cvs" [is logsort "cvs"]selected="selected"[end]>Not sorted</option>
-        <option value="date" [is logsort "date"]selected="selected"[end]>Commit date</option>
-        <option value="rev" [is logsort "rev"]selected="selected"[end]>Revision</option>
-      </select>
-      <input type="submit" value="  Sort  " />
-  </div>
-</form>
diff --git a/src/www/scm/viewvc/templates/log.ezt b/src/www/scm/viewvc/templates/log.ezt
deleted file mode 100644
index 7dce9a8..0000000
--- a/src/www/scm/viewvc/templates/log.ezt
+++ /dev/null
@@ -1,141 +0,0 @@
-[include "include/log_header.ezt"]
-
-[define first_revision][end]
-[define last_revision][end]
-
-[for entries]
-[if-index entries first][define first_revision][entries.rev][end][end]
-[if-index entries last][define last_revision][entries.rev][end][end]
-<div>
-  <hr />
-
-  [is entries.state "dead"]
-    Revision <strong>[entries.rev]</strong>
-  [else]
-    <a name="rev[entries.rev]"></a>
-    [for entries.tag_names]<a name="[entries.tag_names]"></a>
-    [end]
-    [for entries.branch_names]<a name="[entries.branch_names]"></a>
-    [end]
-
-    Revision [is roottype "svn"]<a href="[entries.revision_href]"><strong>[entries.rev]</strong></a>[else]<strong>[entries.rev]</strong>[end] -
-    [is pathtype "file"]
-      (<a href="[entries.view_href]">view</a>)
-    [else]
-      <a href="[entries.view_href]">Directory Listing</a>
-    [end]
-    [if-any entries.download_href](<a href="[entries.download_href]">download</a>)[end]
-    [if-any entries.download_text_href](<a href="[entries.download_text_href]">as text</a>)[end]
-    [if-any entries.annotate_href](<a href="[entries.annotate_href]">annotate</a>)[end]
-
-    [is pathtype "file"]
-      [# if you don't want to allow select for diffs then remove this section]
-      [is entries.rev rev_selected]
-        - <strong>[[]selected]</strong>
-      [else]
-        - <a href="[entries.sel_for_diff_href]">[[]select for diffs]</a>
-      [end]
-    [end]
-  [end]
-
-  [if-any entries.vendor_branch]
-    <em>(vendor branch)</em>
-  [end]
-
-  <br />
-
-  [is roottype "svn"]
-    [if-index entries last]Added[else]Modified[end]
-  [end]
-
-  <em>[entries.date]</em> ([entries.ago] ago) by <em>[entries.author]</em>
-
-  [if-any entries.orig_path]
-    <br />Original Path: <a href="[entries.orig_href]"><em>[entries.orig_path]</em></a>
-  [end]
-
-  [if-any entries.branches]
-    <br />Branch:
-    [for entries.branches]
-      <a href="[entries.branches.href]"><strong>[entries.branches.name]</strong></a>[if-index entries.branches last][else],[end]
-    [end]
-  [end]
-
-  [if-any entries.tags]
-    <br />CVS Tags:
-    [for entries.tags]
-      <a href="[entries.tags.href]"><strong>[entries.tags.name]</strong></a>[if-index entries.tags last][else],[end]
-    [end]
-  [end]
-
-  [if-any entries.branch_points]
-    <br />Branch point for:
-    [for entries.branch_points]
-      <a href="[entries.branch_points.href]"><strong>[entries.branch_points.name]</strong></a>[if-index entries.branch_points last][else],[end]
-    [end]
-  [end]
-
-  [if-any entries.prev]
-    [if-any entries.changed]
-      [is roottype "cvs"]
-      <br />Changes since <strong>[entries.prev]: [entries.changed] lines</strong>
-      [end]
-    [end]
-  [end]
-
-  [is roottype "svn"]
-    [if-any entries.size]
-    <br />File length: [entries.size] byte(s)
-    [end]
-
-    [if-any entries.copy_path]
-    <br />Copied from: <a href="[entries.copy_href]"><em>[entries.copy_path]</em></a> revision [entries.copy_rev]
-    [end]
-  [end]
-
-  [is entries.state "dead"]
-    <br /><strong><em>FILE REMOVED</em></strong>
-  [else]
-   [is pathtype "file"]
-    [if-any entries.prev]
-      <br />Diff to <a href="[entries.diff_to_prev_href]">previous [entries.prev]</a>
-      [if-any human_readable]
-      [else]
-        (<a href="[entries.diff_to_prev_href]&diff_format=h">colored</a>)
-      [end]
-    [end]
-
-    [is roottype "cvs"]
-      [if-any entries.branch_point]
-        , to <a href="[entries.diff_to_branch_href]">branch point [entries.branch_point]</a>
-        [if-any human_readable]
-        [else]
-           (<a href="[entries.diff_to_branch_href]&diff_format=h">colored</a>)
-        [end]
-      [end]
-  
-      [if-any entries.next_main]
-        , to <a href="[entries.diff_to_main_href]">next main [entries.next_main]</a>
-        [if-any human_readable]
-        [else]
-           (<a href="[entries.diff_to_main_href]&diff_format=h">colored</a>)
-        [end]
-      [end]
-    [end]
-
-    [if-any entries.diff_to_sel_href]
-      [if-any entries.prev], [else]<br />Diff[end]
-        to <a href="[entries.diff_to_sel_href]">selected [rev_selected]</a>
-      [if-any human_readable]
-      [else]
-        (<a href="[entries.diff_to_sel_href]&diff_format=h">colored</a>)
-      [end]
-    [end]
-   [end]
-  [end]
-
-<pre class="vc_log">[entries.log]</pre>
-</div>
-[end]
-
-[include "include/log_footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/log_table.ezt b/src/www/scm/viewvc/templates/log_table.ezt
deleted file mode 100644
index 591df9d..0000000
--- a/src/www/scm/viewvc/templates/log_table.ezt
+++ /dev/null
@@ -1,168 +0,0 @@
-[include "include/log_header.ezt"]
-
-<hr />
-<table cellspacing="1" cellpadding="2">
-<thead>
-<tr>
-  <th class="vc_header[is logsort "rev"]_sort[end]">Revision</th>
-  <th class="vc_header">Tasks</th>
-  [is pathtype "file"]
-  <th class="vc_header">Diffs</th>
-  [end]
-  [is roottype "cvs"]
-  <th class="vc_header">Branches/<br />Tags</th>
-  [end]
-  <th class="vc_header[is logsort "date"]_sort[end]">Age</th>
-  <th class="vc_header">Author</th>
-</tr>
-</thead>
-
-[define first_revision][end]
-[define last_revision][end]
-
-[for entries]
-[if-index entries first][define first_revision][entries.rev][end][end]
-[if-index entries last][define last_revision][entries.rev][end][end]
-  <tbody>
-  <tr style="vertical-align: top;" class="vc_row_[if-index entries even]even[else]odd[end]">
-
-    [# Revision column]
-    <td rowspan="2">
-      [is roottype "svn"]<a href="[entries.revision_href]"><strong>[entries.rev]</strong></a>[else]<strong>[entries.rev]</strong>[end]
-      <a name="rev[entries.rev]"></a>
-    </td>
-
-    [# Tasks column]
-    <td>
-      [is pathtype "file"]
-        <a href="[entries.view_href]"><strong>View</strong></a><br />
-      [else]
-        <a href="[entries.view_href]"><strong>Directory Listing</strong></a><br />
-      [end]
-      [if-any entries.download_href]<a href="[entries.download_href]"><strong>Download</strong></a><br />[end]
-      [if-any entries.download_text_href]<a href="[entries.download_text_href]"><strong>As text</strong></a><br />[end]
-      [if-any entries.annotate_href]<a href="[entries.annotate_href]"><strong>Annotate</strong></a><br />[end]
-    </td>
-
-    [is pathtype "file"]
-      <td>
-      [# Diffs column]
-      [is entries.state "dead"]
-        <strong><em>FILE REMOVED</em></strong>
-      [else]
-      [# if you don't want to allow select for diffs then remove this section]
-      [is entries.rev rev_selected]
-        <strong>[[]selected]</strong><br />
-      [else]
-      <a href="[entries.sel_for_diff_href]"><strong>[[]select for diffs]</strong></a><br />
-      [end]
-        [if-any entries.diff_to_sel_href]
-          <a href="[entries.diff_to_sel_href]"><strong>Diff to selected [rev_selected]</strong></a>
-          [if-any human_readable]
-          [else]
-            (<a href="[entries.diff_to_sel_href]&diff_format=h"><strong>colored</strong></a>)
-          [end]<br />
-        [end]
-        [if-any entries.prev]
-          <a href="[entries.diff_to_prev_href]"><strong>Diff to previous [entries.prev]</strong></a>
-          [if-any human_readable]
-          [else]
-            (<a href="[entries.diff_to_prev_href]&diff_format=h"><strong>colored</strong></a>)
-          [end]<br />
-        [end]
-      [end]  
-      </td>
-    [end]
-    [is roottype "cvs"]
-    <td>
-      [# Branches column]
-      [if-any entries.vendor_branch]
-        <em>vendor branch</em><br />
-      [end]
-      [if-any entries.branches]
-        [for entries.branches]
-          <a href="[entries.branches.href]"><strong>[entries.branches.name]</strong></a><br />
-        [end]
-      [end]
-      [if-any entries.branch_points]
-        Branch point for:
-        [for entries.branch_points]
-          <a href="[entries.branch_points.href]"><strong>[entries.branch_points.name]</strong></a><br />
-        [end]
-      [end]
-      [if-any entries.next_main]
-        <a href="[entries.diff_to_main_href]"><strong>Diff to next MAIN [entries.next_main]</strong></a>
-        [if-any human_readable]
-        [else]
-          (<a href="[entries.diff_to_main_href]&diff_format=h"><strong>colored</strong></a>)
-        [end]<br />
-      [end]
-      [if-any entries.branch_point]
-        <a href="[entries.diff_to_branch_href]"><strong>Diff to branch point [entries.branch_point]</strong></a>
-        [if-any human_readable]
-        [else]
-          (<a href="[entries.diff_to_branch_href]&diff_format=h"><strong>colored</strong></a>)
-        [end]<br />
-      [end]
-
-      [# Tags ]
-      [if-any entries.tags]
-        <form method=get action="[pathrev_action]" >
-          [pathrev_hidden_values]
-          <select name="pathrev" onChange="submit()">
-          <option value="" [is pathrev ""]selected[end]>Show all tags</option>
-          [for entries.tags]
-            <option [is pathrev entries.tags.name]selected[end]>[entries.tags.name]</option>
-          [end]
-          </select>
-        </form>
-      [else] 
-      [end]
-    </td>
-    [end]
-
-    [# Time column]
-    <td>
-      [is roottype "svn"]
-        [if-index entries last]Added[else]Modified[end]
-      [end]
-      [entries.ago] ago<br /><em>[entries.date]</em>
-      [is roottype "cvs"]
-        [if-any entries.prev]
-          [if-any entries.changed]
-            <br />Changes since <strong>[entries.prev]: [entries.changed] lines</strong>
-          [end]
-        [end]
-      [end]
-    </td>
-
-    [# Author column]
-    <td>
-      [entries.author]
-    </td>
-
-  </tr>
-  <tr class="vc_row_[if-index entries even]even[else]odd[end]">
-    <td colspan=5>
-      [is roottype "svn"]
-        [if-any entries.orig_path]
-          Original Path: <a href="[entries.orig_href]"><em>[entries.orig_path]</em></a><br />
-        [end]
-
-        [if-any entries.size]
-          <strong>File length: </strong>[entries.size] byte(s)<br />
-        [end]
-
-        [if-any entries.copy_path]
-           <strong>Copied from: </strong><a href="[entries.copy_href]"><em>[entries.copy_path]</em></a> revision [entries.copy_rev]<br />
-        [end]
-      [end]
-
-      <strong>Log: </strong><pre class="vc_log">[entries.log]</pre>
-    </td>
-  </tr>
-  </tbody>
-[end]
-</table>
-
-[include "include/log_footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/markup.ezt b/src/www/scm/viewvc/templates/markup.ezt
deleted file mode 100644
index a39394c..0000000
--- a/src/www/scm/viewvc/templates/markup.ezt
+++ /dev/null
@@ -1,50 +0,0 @@
-[# setup page definitions]
-  [define page_title]View of /[where][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "markup"]
-[include "include/file_header.ezt"]
-<hr />
-<div class="vc_summary">
-Revision [if-any revision_href]<a href="[revision_href]"><strong>[rev]</strong></a>[else]<strong>[rev]</strong>[end] -
-(<a href="[download_href]"><strong>download</strong></a>)
-[if-any download_text_href](<a href="[download_text_href]"><strong>as text</strong></a>)[end]
-[if-any annotate_href](<a href="[annotate_href]"><strong>annotate</strong></a>)[end]
-
-[if-any vendor_branch] <em>(vendor branch)</em>[end]
-<br />[if-any date]<em>[date]</em>[end] 
-      [if-any ago]([ago] ago)[end]
-      [if-any author]by <em>[author]</em>[end]
-[if-any orig_path]
-  <br />Original Path: <a href="[orig_href]"><em>[orig_path]</em></a>
-[end]
-
-[if-any branches]
-  <br />Branch: <strong>[branches]</strong>
-[end]
-[if-any tags]
-  <br />CVS Tags: <strong>[tags]</strong>
-[end]
-[if-any branch_points]
-  <br />Branch point for: <strong>[branch_points]</strong>
-[end]
-[is roottype "cvs"]
-  [if-any changed]
-    <br />Changes since <strong>[prev]: [changed] lines</strong>
-  [end]
-[end]
-[is roottype "svn"][if-any size]
-  <br />File size: [size] byte(s)
-[end][end]
-[is state "dead"]
-  <br /><strong><em>FILE REMOVED</em></strong>
-[end]
-[if-any log]
-  <pre class="vc_log">[log]</pre>
-[end]
-</div>
-
-<div id="vc_markup"><pre>[markup]</pre></div>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/query.ezt b/src/www/scm/viewvc/templates/query.ezt
deleted file mode 100644
index fa33c00..0000000
--- a/src/www/scm/viewvc/templates/query.ezt
+++ /dev/null
@@ -1,241 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
-    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<!-- ViewVC :: http://www.viewvc.org/ -->
-<head>
-  <title>Checkin Database Query</title>
-  <link rel="stylesheet" href="[docroot]/styles.css" type="text/css" />
-</head>
-
-<body>
-
-[# setup page definitions]
-  [define help_href][docroot]/help_query.html[end]
-[# end]
-
-  <p> 
-    Select your parameters for querying the CVS commit database.  You
-    can search for multiple matches by typing a comma-seperated list
-    into the text fields.  Regular expressions, and wildcards are also
-    supported.  Blank text input fields are treated as wildcards.
-  </p>
-  <p>
-    Any of the text entry fields can take a comma-seperated list of
-    search arguments.  For example, to search for all commits from
-    authors <em>jpaint</em> and <em>gstein</em>, just type: <strong>jpaint,
-    gstein</strong> in the <em>Author</em> input box.  If you are searching
-    for items containing spaces or quotes, you will need to quote your
-    request.  For example, the same search above with quotes is:
-    <strong>"jpaint", "gstein"</strong>.
-  </p>
-  <p>                           
-
-    Wildcard and regular expression searches are entered in a similar
-    way to the quoted requests.  You must quote any wildcard or
-    regular expression request, and a command charactor preceeds the
-    first quote.  The command charactor <strong>l</strong> is for wildcard
-    searches, and the wildcard charactor is a percent (<strong>%</strong>).  The
-    command charactor for regular expressions is <strong>r</strong>, and is
-    passed directly to MySQL, so you'll need to refer to the MySQL
-    manual for the exact regex syntax.  It is very similar to Perl.  A
-    wildard search for all files with a <em>.py</em> extention is:
-    <strong>l"%.py"</strong> in the <em>File</em> input box.  The same search done
-    with a regular expression is: <strong>r".*\.py"</strong>.
-  </p>
-  <p>                  
-    All search types can be mixed, as long as they are seperated by
-    commas.
-  </p>                                                    
-
-<form method="get" action="">
-
-<div class="vc_query_form">
-<table cellspacing="0" cellpadding="2" class="auto">
- <tr>
-  <td>
-   <table>
-    <tr>
-     <td style="vertical-align:top;">
-
-      <table>
-       <tr>
-        <td align="right">CVS Repository:</td>
-        <td>
-         <input type="text" name="repository" size="40" value="[repository]" />
-        </td>
-       </tr>
-       <tr>
-        <td align="right">CVS Branch:</td>
-        <td>
-         <input type="text" name="branch" size="40" value="[branch]" />
-        </td>
-       </tr>
-       <tr>
-        <td align="right">Directory:</td>
-        <td>
-         <input type="text" name="directory" size="40" value="[directory]" />
-        </td>
-       </tr>
-       <tr>
-        <td align="right">File:</td>
-        <td>
-         <input type="text" name="file" size="40" value="[file]" />
-        </td>
-       </tr>
-       <tr>
-        <td align="right">Author:</td>
-        <td>
-         <input type="text" name="who" size="40" value="[who]" />
-        </td>
-       </tr>
-      </table>
-
-     </td>
-     <td style="vertical-align:top;">
-
-      <table>
-       <tr>
-        <td align="left">Sort By:</td>
-        <td>
-         <select name="sortby">
-          <option value="date" [is sortby "date"]selected="selected"[end]>Date</option>
-          <option value="author" [is sortby "author"]selected="selected"[end]>Author</option>
-          <option value="file" [is sortby "file"]selected="selected"[end]>File</option>
-         </select>
-        </td>
-       </tr>
-       <tr>
-        <td colspan="2">
-         <table cellspacing="0" cellpadding="0">
-          <tr>
-           <td>Date:</td>
-          </tr>
-          <tr>
-           <td><input type="radio" name="date" value="hours"
-		  [is date "hours"]checked="checked"[end] /></td>
-           <td>In the last
-             <input type="text" name="hours" value="[hours]" size="4" />hours
-           </td>
-          </tr>
-          <tr>
-           <td><input type="radio" name="date" value="day"
-		  [is date "day"]checked="checked"[end] /></td>
-           <td>In the last day</td>
-          </tr>
-          <tr>
-           <td><input type="radio" name="date" value="week"
-		  [is date "week"]checked="checked"[end] /></td>
-           <td>In the last week</td>
-          </tr>
-          <tr>
-           <td><input type="radio" name="date" value="month"
-		  [is date "month"]checked="checked"[end] /></td>
-           <td>In the last month</td>
-          </tr>
-          <tr>
-           <td><input type="radio" name="date" value="all"
-		  [is date "all"]checked="checked"[end] /></td>
-           <td>Since the beginning of time</td>
-          </tr>
-         </table>
-        </td>
-       </tr>
-      </table>
-
-     </td>
-    </tr>
-   </table>
-  </td>
-  <td>
-   <input type="submit" value="Search" />
-  </td>
- </tr>
-</table>
-</div>
-
-</form>
-
-[is query "skipped"]
-[else]
-<p><strong>[num_commits]</strong> matches found.</p>
-
-[if-any commits]
-<table cellspacing="0" cellpadding="2">
- <thead>
- <tr class="vc_header">
-  <th>Revision</th>
-  <th>File</th>
-  <th>Branch</th>
-  <th>+/-</th>
-  <th>Date</th>
-  <th>Author</th>
-[# uncommment, if you want a separate Description column: (also see below)
-<th>Description</th>
-]
- </tr>
- </thead>
-[for commits]
- <tbody>
-  [for commits.files]
-    <tr class="vc_row_[if-index commits even]even[else]odd[end]">
-      <td style="vertical-align:top;">
-	[if-any commits.files.rev][commits.files.rev][else] [end]
-      </td>
-      <td style="vertical-align:top;">[commits.files.link]</td>
-      <td style="vertical-align:top;">
-	[if-any commits.files.branch][commits.files.branch][else] [end]
-      </td>
-      <td style="vertical-align:top;">
-        [is commits.files.type "Add"]<ins>[end]
-        [is commits.files.type "Change"]<a href="[commits.files.difflink]">[end]
-        [is commits.files.type "Remove"]<del>[end]
-          [commits.files.plus]/[commits.files.minus]
-        [is commits.files.type "Add"]</ins>[end]
-        [is commits.files.type "Change"]</a>[end]
-        [is commits.files.type "Remove"]</del>[end]
-      </td>
-      <td style="vertical-align:top;">
-	[if-any commits.files.date][commits.files.date][else] [end]
-      </td>
-      <td style="vertical-align:top;">
-	[if-any commits.files.author][commits.files.author][else] [end]
-      </td>
-
-[# uncommment, if you want a separate Description column:
-      {if-index commits.files first{
-        <td style="vertical-align:top;" rowspan="{commits.num_files}">
-          {commits.log}
-        </td>
-      {end}
-
-   (substitute brackets for the braces)
-]
-    </tr>
-[# and also take the following out in the "Description column"-case:]
-      [if-index commits.files last]
-	<tr class="vc_row_[if-index commits even]even[else]odd[end]">
-	  <td> </td>
-	  <td colspan="5"><strong>Log:</strong><br />
-	    <pre class="vc_log">[commits.log]</pre></td>
-	</tr>
-      [end]
-[# ---]
-  [end]
- </tbody>
-[end]
-
- <tr class="vc_header">
-  <th style="text-align:left;vertical-align:top;"> </th>
-  <th style="text-align:left;vertical-align:top;"> </th>
-  <th style="text-align:left;vertical-align:top;"> </th>
-  <th style="text-align:left;vertical-align:top;"> </th>
-  <th style="text-align:left;vertical-align:top;"> </th>
-  <th style="text-align:left;vertical-align:top;"> </th>
-[# uncommment, if you want a separate Description column:
-  <th style="text-align:left;vertical-align:top;"> </th>
-]
- </tr>
-</table>
-[end]
-[end]
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/query_form.ezt b/src/www/scm/viewvc/templates/query_form.ezt
deleted file mode 100644
index 5e1f480..0000000
--- a/src/www/scm/viewvc/templates/query_form.ezt
+++ /dev/null
@@ -1,181 +0,0 @@
-[# setup page definitions]
-  [define page_title]Query on /[where][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "query"]
-
-<p><a href="[dir_href]">
-<img src="[docroot]/images/dir.png" width="16" height="16" alt="Directory" />
-Browse Directory</a></p>
-
-<form action="[query_action]" method="get">
-
-<div class="vc_query_form">
-  [query_hidden_values]
-<table cellspacing="0" cellpadding="5" class="auto">
-  [is roottype "cvs"]
-  [# For subversion, the branch field is not used ]
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Branch:</th>
-    <td>
-      <input type="text" name="branch" value="[branch]" /><br />
-      <label for="branch_match_exact">
-        <input type="radio" name="branch_match" id="branch_match_exact"
-           value="exact" [is branch_match "exact"]checked="checked"[end] />
-        Exact match
-      </label>
-      <label for="branch_match_glob">
-        <input type="radio" name="branch_match" id="branch_match_glob"
-           value="glob" [is branch_match "glob"]checked="checked"[end] />
-        Glob pattern match
-      </label>
-      <label for="branch_match_regex">
-        <input type="radio" name="branch_match" id="branch_match_regex"
-           value="regex" [is branch_match "regex"]checked="checked"[end] />
-        Regex match
-      </label>
-      <label for="branch_match_notregex">
-        <input type="radio" name="branch_match" id="branch_match_notregex"
-           value="notregex" [is branch_match "notregex"]checked="checked"[end] />
-        Regex doesn't match
-      </label>
-    </td>
-  </tr>
-  [end]
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Subdirectory:</th>
-    <td>
-      <input type="text" name="dir" value="[dir]" /><br />
-      (you can list multiple directories separated by commas)
-    </td>
-  </tr>
-  <tr>
-    <th style="text-align:right;vertical-align:top;">File:</th>
-    <td>
-      <input type="text" name="file" value="[file]" /><br />
-      <label for="file_match_exact">
-        <input type="radio" name="file_match" id="file_match_exact"
-           value="exact" [is file_match "exact"]checked="checked"[end] />
-        Exact match
-      </label>
-      <label for="file_match_glob">
-        <input type="radio" name="file_match" id="file_match_glob"
-           value="glob" [is file_match "glob"]checked="checked"[end] />
-        Glob pattern match
-      </label>
-      <label for="file_match_regex">
-        <input type="radio" name="file_match" id="file_match_regex"
-           value="regex" [is file_match "regex"]checked="checked"[end] />
-        Regex match
-      </label>
-      <label for="file_match_notregex">
-        <input type="radio" name="file_match" id="file_match_notregex"
-           value="notregex" [is file_match "notregex"]checked="checked"[end] />
-        Regex doesn't match
-      </label>
-    </td>
-  </tr>
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Who:</th>
-    <td>
-      <input type="text" name="who" value="[who]" /><br />
-      <label for="who_match_exact">
-        <input type="radio" name="who_match" id="who_match_exact"
-           value="exact" [is who_match "exact"]checked="checked"[end] />
-        Exact match
-      </label>
-      <label for="who_match_glob">
-        <input type="radio" name="who_match" id="who_match_glob"
-           value="glob" [is who_match "glob"]checked="checked"[end] />
-        Glob pattern match
-      </label>
-      <label for="who_match_regex">
-        <input type="radio" name="who_match" id="who_match_regex"
-           value="regex" [is who_match "regex"]checked="checked"[end] />
-        Regex match
-      </label>
-      <label for="who_match_notregex">
-        <input type="radio" name="who_match" id="who_match_notregex"
-           value="notregex" [is who_match "notregex"]checked="checked"[end] />
-        Regex doesn't match
-      </label>
-    </td>
-  </tr>
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Sort By:</th>
-    <td>
-      <select name="querysort">
-        <option value="date" [is querysort "date"]selected="selected"[end]>Date</option>
-        <option value="author" [is querysort "author"]selected="selected"[end]>Author</option>
-        <option value="file" [is querysort "file"]selected="selected"[end]>File</option>
-      </select>
-    </td>
-  </tr>
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Date:</th>
-    <td>
-      <table cellspacing="0" cellpadding="0">
-        <tr>
-          <td><input type="radio" name="date" id="date_hours"
-                 value="hours" [is date "hours"]checked="checked"[end] /></td>
-          <td>
-            <label for="date_hours">In the last</label>
-            <input type="text" name="hours" value="[hours]" size="4" />
-            hours
-          </td>
-        </tr>
-        <tr>
-          <td><input type="radio" name="date" id="date_day"
-                 value="day" [is date "day"]checked="checked"[end] /></td>
-          <td><label for="date_day">In the last day</label></td>
-        </tr>
-        <tr>
-          <td><input type="radio" name="date" id="date_week"
-                 value="week" [is date "week"]checked="checked"[end] /></td>
-          <td><label for="date_week">In the last week</label></td>
-        </tr>
-        <tr>
-          <td><input type="radio" name="date" id="date_month"
-                 value="month" [is date "month"]checked="checked"[end] /></td>
-          <td><label for="date_month">In the last month</label></td>
-        </tr>
-        <tr>
-          <td><input type="radio" name="date" id="date_all"
-                 value="all" [is date "all"]checked="checked"[end] /></td>
-          <td><label for="date_all">Since the beginning of time</label></td>
-        </tr>
-        <tr>
-          <td><input type="radio" name="date" id="date_explicit"
-                 value="explicit" [is date "explicit"]checked="checked"[end] /></td>
-          <td>
-            <label for="date_explicit">Between</label>
-            <input type="text" name="mindate" value="[mindate]" size="20" />
-            and
-            <input type="text" name="maxdate" value="[maxdate]" size="20" />
-            <br />
-            (use the form <strong>yyyy-mm-dd hh:mm:ss</strong>)
-          </td>
-        </tr>
-      </table>
-    </td>
-  </tr>
-  <tr>
-    <th style="text-align:right;vertical-align:top;">Limit:</th>
-    <td>
-      Show at most
-      <input type="text" name="limit_changes" value="[limit_changes]" size="5" />
-      changed files per commit.<br />
-      (use 0 to show all files)
-    </td>
-  </tr>
-  <tr>
-    <td></td>
-    <td><input type="submit" value="Search" /></td>
-  </tr>
-</table>
-</div>
-
-</form>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/query_results.ezt b/src/www/scm/viewvc/templates/query_results.ezt
deleted file mode 100644
index 441aeb8..0000000
--- a/src/www/scm/viewvc/templates/query_results.ezt
+++ /dev/null
@@ -1,84 +0,0 @@
-[# setup page definitions]
-  [define page_title]Query results on /[where][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt"]
-
-<p><strong>[english_query]</strong></p>
-[# <!-- {sql} --> ]
-<p><a href="[queryform_href]">Modify query</a></p>
-<p><a href="[backout_href]">Show commands which could be used to back out these changes</a></p>
-
-<p><strong>+[plus_count]/-[minus_count]</strong> lines changed.</p>
-
-[if-any commits]
-<table cellspacing="1" cellpadding="2">
- <thead>
-  <tr>
-   <th class="vc_header">Revision</th>
-   <th class="vc_header[is querysort "file"]_sort[end]">File</th>
-[if-any show_branch]
-   <th class="vc_header">Branch</th>
-[end]
-   <th class="vc_header">+/-</th>
-   <th class="vc_header[is querysort "date"]_sort[end]">Date</th>
-   <th class="vc_header[is querysort "author"]_sort[end]">Author</th>
-[# uncommment, if you want a separate Description column: (also see below)
-   <th class="vc_header">Description</th>
-]
-  </tr>
- </thead>
-[for commits]
-  [for commits.files]
-    <tbody>
-    <tr class="vc_row_[if-index commits even]even[else]odd[end]">
-      <td style="vertical-align: top;">
-	[if-any commits.files.rev]<a href="[if-any commits.files.prefer_markup][commits.files.view_href][else][commits.files.download_href][end]">[commits.files.rev]</a>[else] [end]
-      </td>
-      <td style="vertical-align: top;">
-        <a href="[commits.files.dir_href]">[commits.files.dir]/</a>
-        <a href="[commits.files.log_href]">[commits.files.file]</a>
-      </td>
-[if-any show_branch]
-      <td style="vertical-align: top;">
-	[if-any commits.files.branch][commits.files.branch][else] [end]
-      </td>
-[end]
-      <td style="vertical-align: top;">
-        [# only show a diff link for changes ]
-        [is commits.files.type "Add"]<ins>[end]
-        [is commits.files.type "Change"]<a href="[commits.files.diff_href]">[end]
-        [is commits.files.type "Remove"]<del>[end]
-          [commits.files.plus]/[commits.files.minus]
-        [is commits.files.type "Add"]</ins>[end]
-        [is commits.files.type "Change"]</a>[end]
-        [is commits.files.type "Remove"]</del>[end]
-      </td>
-      <td style="vertical-align: top;">
-	[if-any commits.files.date][commits.files.date][else] [end]
-      </td>
-      <td style="vertical-align: top;">
-	[if-any commits.files.author][commits.files.author][else] [end]
-      </td>
-    </tr>
-  [end]
-  [if-any commits.limited_files]
-    <tr class="vc_row_[if-index commits even]even[else]odd[end]">
-      <td> </td>
-      <td colspan="5">
-        <strong><em><small>Only first [commits.num_files] files shown.
-        <a href="[limit_changes_href]">Show all files</a> or
-        <a href="[queryform_href]">adjust limit</a>.</small></em></strong>
-    </tr>
-  [end]
-  <tr class="vc_row_[if-index commits even]even[else]odd[end]">
-    <td> </td>
-    <td colspan="5"><strong>Log:</strong><pre class="vc_log">[commits.log]</pre></td>
-  </tr>
-  </tbody>
-[end]
-</table>
-[end]
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/revision.ezt b/src/www/scm/viewvc/templates/revision.ezt
deleted file mode 100644
index d357180..0000000
--- a/src/www/scm/viewvc/templates/revision.ezt
+++ /dev/null
@@ -1,80 +0,0 @@
-[# setup page definitions]
-  [define page_title]Revision [rev][end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "revision"]
-
-<hr />
-<form method="get" action="[jump_rev_action]">
-<table cellspacing="1" cellpadding="2" style="width: auto;">
-  <tr align="left">
-    <th>Jump to revision:</th>
-    <td>
-      [jump_rev_hidden_values]
-      <input type="text" name="revision" value="[rev]" />
-      <input type="submit" value="Go" />
-      [if-any prev_href]
-        <a href="[prev_href]"><img src="[docroot]/images/back.png" alt="Previous" width="20" height="22" /></a>[end]
-      [if-any next_href] <a href="[next_href]"><img src="[docroot]/images/forward.png" width="20" height="22" alt="Next" /></a>[end]
-    </td>
-  </tr>
-  <tr align="left">
-    <th>Author:</th>
-    <td>[author]</td>
-  </tr>
-  <tr align="left">
-    <th>Date:</th>
-    <td>[date] <em>([ago] ago)</em></td>
-  </tr>
-  <tr align="left">
-    <th>Log Message:</th>
-    <td><pre class="vc_log">[log]</pre></td>
-  </tr>
-</table>
-</form>
-
-<hr />
-
-<p><strong>Changed paths:</strong></p>
-
-[if-any more_changes]
-  <div>
-    Only [limit_changes] changes shown,
-    <a href="[more_changes_href]">display [more_changes] more changes...</a>
-  </div>
-[end]
-
-[if-any first_changes]
-  <div><a href="[first_changes_href]">Show only first [first_changes] changes...</div>
-[end]
-
-<table cellspacing="1" cellpadding="2">
-  <thead>
-  <tr align="left">
-    <th class="vc_header_sort">Path</th>
-    <th class="vc_header">Details</th>
-  </tr>
-  </thead>
-  <tbody>
-  [if-any changes]
-   [for changes]
-    <tr class="vc_row_[if-index changes even]even[else]odd[end]">
-      <td>[if-any changes.view_href]<a href="[changes.view_href]">[end]<img src="[docroot]/images/[is changes.pathtype "dir"]dir[else]text[end].png" width="16" height="16" alt="Directory" />[changes.path][is changes.pathtype "dir"]/[end][if-any changes.view_href]</a>[end]
-      [if-any changes.is_copy]<br /><em>(Copied from [changes.copy_path], r[changes.copy_rev])</em>[end]
-      </td>
-      <td>[if-any changes.log_href]<a href="[changes.log_href]">[end][changes.action][if-any changes.log_href]</a>[end]
-          [if-any changes.text_mods], [if-any changes.diff_href]<a href="[changes.diff_href]">[end]text changed[if-any changes.diff_href]</a>[end][end]
-          [if-any changes.prop_mods], props changed[end]
-      </td>
-    </tr>
-   [end]
-  [else]
-    <tr>
-    <td colspan="5">No changed paths.</td>
-    </tr>
-  [end]
-  </tbody>
-</table>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/roots.ezt b/src/www/scm/viewvc/templates/roots.ezt
deleted file mode 100644
index 6abba65..0000000
--- a/src/www/scm/viewvc/templates/roots.ezt
+++ /dev/null
@@ -1,29 +0,0 @@
-[# setup page definitions]
-  [define page_title]Repository Listing[end]
-  [define help_href][docroot]/help_rootview.html[end]
-[# end]
-
-[include "include/header.ezt" "directory"]
-
-<table cellspacing="1" cellpadding="2">
-<thead>
-<tr>
-  <th class="vc_header_sort">Name</th>
-</tr>
-</thead>
-
-<tbody>
-[for roots]
-  <tr class="vc_row_[if-index roots even]even[else]odd[end]">
-    <td>
-      <a href="[roots.href]">
-      <img src="[docroot]/images/dir.png" alt="" width="16" height="16" />
-      [roots.name]</a>
-    </td>
-  </tr>
-[end]
-</tbody>
-
-</table>
-
-[include "include/footer.ezt"]
diff --git a/src/www/scm/viewvc/templates/rss.ezt b/src/www/scm/viewvc/templates/rss.ezt
deleted file mode 100644
index a1f81d9..0000000
--- a/src/www/scm/viewvc/templates/rss.ezt
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0"?>
-<rss version="2.0">
-<channel>
-    <title>[rootname] checkins[if-any where] (in [where])[end]</title>
-
-    <description>[is roottype "svn"]Subversion[else]CVS[end] commits to the[if-any where] [where] directory of the[end] [rootname] repository</description>
-
-	[for commits]<item>
-        <title>[if-any commits.rev][commits.rev]: [end][[commits.author]] [commits.short_log]</title>
-		[if-any commits.rss_url]<link>[commits.rss_url]</link>[end]
-		<author>[commits.author]</author>
-		<pubDate>[commits.rss_date]</pubDate>
-		<description>[commits.log]</description>
-    </item>[end]
-</channel>	
-</rss>
diff --git a/src/www/scm/viewvc/viewvc-install b/src/www/scm/viewvc/viewvc-install
deleted file mode 100755
index 74b305c..0000000
--- a/src/www/scm/viewvc/viewvc-install
+++ /dev/null
@@ -1,359 +0,0 @@
-#!/usr/bin/env python
-# -*- Mode: python -*-
-#
-# Copyright (C) 1999-2006 The ViewCVS Group. All Rights Reserved.
-#
-# By using this file, you agree to the terms and conditions set forth in
-# the LICENSE.html file which can be found at the top level of the ViewVC
-# distribution or at http://viewvc.org/license-1.html.
-#
-# For more information, visit http://viewvc.org/
-#
-# -----------------------------------------------------------------------
-#
-# install script for viewvc -- temporary?
-#
-# ### this will eventually be replaced by autoconf plus tools. an
-# ### interactive front-end to ./configure may be provided.
-#
-# -----------------------------------------------------------------------
-
-import os
-import sys
-import string
-import re
-import traceback
-import py_compile
-import getopt
-import StringIO
-
-# get access to our library modules
-sys.path.insert(0, os.path.join(os.path.dirname(sys.argv[0]), 'lib'))
-
-import compat
-import viewvc
-import compat_ndiff
-version = viewvc.__version__
-
-
-## installer text
-INFO_TEXT = """
-
-This is the ViewVC %s installer.
-
-It will allow you to choose the install path for ViewVC.  You will
-now be asked some installation questions.
-
-Defaults are given in square brackets.  Just hit [Enter] if a default
-is okay.
-""" % version
-
-## installer defaults
-DESTDIR = None
-ROOT_DIR = None
-
-
-## list of files for installation
-## tuple (source path, destination path, install mode, true/false flag for
-##        search-and-replace, flag or text for prompt before replace, 
-##        compile_it)
-##       
-
-FILE_INFO_LIST = [
-    ("bin/cgi/viewvc.cgi", "bin/cgi/viewvc.cgi", 0755, 1, 0, 0),
-    ("bin/cgi/query.cgi", "bin/cgi/query.cgi", 0755, 1, 0, 0),
-    ("bin/mod_python/viewvc.py", "bin/mod_python/viewvc.py", 0755, 1, 0, 0),
-    ("bin/mod_python/query.py", "bin/mod_python/query.py", 0755, 1, 0, 0),
-    ("bin/mod_python/handler.py", "bin/mod_python/handler.py", 0755, 1, 0, 0),
-    ("bin/mod_python/.htaccess", "bin/mod_python/.htaccess", 0755, 0, 0, 0),
-    ("bin/standalone.py", "bin/standalone.py", 0755, 1, 0, 0),
-    ("viewvc.conf.dist", "viewvc.conf", 0644, 0,
-	     """Note: If you are upgrading from viewcvs-0.7 or earlier: 
-The section [text] has been removed from viewcvs.conf.  The functionality
-went into the new files in subdirectory templates.""", 0),
-    ("cvsgraph.conf.dist", "cvsgraph.conf", 0644, 0, 1, 0),
-
-    ("bin/loginfo-handler", "bin/loginfo-handler", 0755, 1, 0, 0),
-    ("bin/cvsdbadmin", "bin/cvsdbadmin", 0755, 1, 0, 0),
-    ("bin/svndbadmin", "bin/svndbadmin", 0755, 1, 0, 0),
-    ("bin/make-database", "bin/make-database", 0755, 1, 0, 0),
-    ]
-
-if sys.platform == "win32":
-  FILE_INFO_LIST.extend([
-    ("bin/asp/viewvc.asp", "bin/asp/viewvc.asp", 0755, 1, 0, 0),
-    ("bin/asp/query.asp", "bin/asp/query.asp", 0755, 1, 0, 0),
-  ])
-
-TREE_LIST = [
-  ("lib",       "lib",       0),
-  ("templates", "templates", 1),
-  ]
-
-# used to escape substitution strings passed to re.sub(). re.escape() is no
-# good because it blindly puts backslashes in front of anything that is not
-# a number or letter regardless of whether the resulting sequence will be
-# interpreted.
-def ReEscape(str):
-  return string.replace(str, "\\", "\\\\")
-
-def Error(text, etype=None, evalue=None):
-    print
-    print "[ERROR] %s" % text
-    if etype:
-        print '[ERROR] ',
-        traceback.print_exception(etype, evalue, None, file=sys.stdout)
-    sys.exit(1)
-    
-
-def MkDir(path):
-    try:
-        compat.makedirs(path)
-    except os.error, e:
-        if e[0] == 17:
-            # EEXIST: file exists
-            return
-        if e[0] == 13:
-            # EACCES: permission denied
-            Error("You do not have permission to create directory %s" % path)
-        Error("Unknown error creating directory %s" % path, OSError, e)
-
-
-
-def SetOnePath(contents, var, value):
-    pattern = re.compile('^' + var + r'\s*=\s*.*$', re.MULTILINE)
-    repl = '%s = r"%s"' % (var, os.path.join(ROOT_DIR, value))
-    return re.sub(pattern, ReEscape(repl), contents)
-
-
-def SetPythonPaths(contents):
-    if contents[:2] == '#!':
-        shbang = '#!' + sys.executable
-        contents = re.sub('^#![^\n]*', ReEscape(shbang), contents)
-    contents = SetOnePath(contents, 'LIBRARY_DIR', 'lib')
-    contents = SetOnePath(contents, 'CONF_PATHNAME', 'viewvc.conf')
-    return contents
-
-
-def InstallFile(src_path, dest_path, mode, set_python_paths, prompt_replace,
-                compile_it):
-  dest_path = os.path.join(ROOT_DIR, dest_path)
-    
-  if prompt_replace and os.path.exists(DESTDIR + dest_path):
-    # Collect ndiff output from ndiff
-    sys.stdout = StringIO.StringIO()
-    compat_ndiff.main([DESTDIR + dest_path, src_path])
-    ndiff_output = sys.stdout.getvalue()
-
-    # Return everything to normal
-    sys.stdout = sys.__stdout__
-
-    # Collect the '+ ' and '- ' lines
-    # total collects the difference lines to be printed later
-    total = ""
-    # I use flag to throw out match lines.
-    flag = 1
-    for line in string.split(ndiff_output,'\n'):
-      # Print line if it is a difference line
-      if line[:2] == "+ " or line[:2] == "- " or line[:2] == "? ":
-        total = total + line + "\n"
-        flag = 1
-      else:
-        # Compress lines that are the same to print one blank line
-        if flag:
-          total = total + "\n"
-          flag = 0
-
-    if total == "\n":
-      print "    File %s exists,\n    but there is no difference between target and source files.\n" % (DESTDIR + dest_path)
-      return
-
-    if type(prompt_replace) == type(""):
-      print prompt_replace
-    while 1:
-      temp = raw_input("""
-    File %s exists and is different from source file.
-      DO YOU WANT TO,
-        overwrite [o]
-        do not overwrite [d]
-        view differences [v]: """ % (DESTDIR + dest_path))
-      print
-
-      temp = string.lower(temp[0])
-
-      if temp == "d":
-        return
-
-      if temp == "v":
-        if string.lower(src_path[-4:]) in [ '.gif', '.png', '.jpg' ]:
-          print 'Can not print differences between binary files'
-        else:
-          print total
-          print """
-LEGEND
- A leading '- ' indicates line to remove from installed file
- A leading '+ ' indicates line to add to installed file
- A leading '? ' shows intraline differences."""
-
-      if temp == "o": 
-        ReplaceFile(src_path, dest_path, mode, set_python_paths,
-                    prompt_replace, compile_it)
-        return
-  else:
-    ReplaceFile(src_path, dest_path, mode, set_python_paths,
-                prompt_replace, compile_it)
-  return
-
-def ReplaceFile(src_path, dest_path, mode, set_python_paths,
-                prompt_replace, compile_it):
-  try:
-    contents = open(src_path, "rb").read()
-  except IOError, e:
-    Error(str(e))
-
-  if set_python_paths:
-    contents = SetPythonPaths(contents)
-
-  ## write the file to the destination location
-  path, basename = os.path.split(DESTDIR + dest_path)
-  MkDir(path)
-  
-  try:
-    open(DESTDIR + dest_path, "wb").write(contents)
-  except IOError, e:
-    if e[0] == 13:
-      # EACCES: permission denied
-      Error("You do not have permission to write file %s" % dest_path)
-    Error("Unknown error writing file %s" % dest_path, IOError, e)
-    
-  os.chmod(DESTDIR + dest_path, mode)
-  
-  if compile_it:
-    py_compile.compile(DESTDIR + dest_path,
-                       DESTDIR + dest_path + "c" , dest_path)
-  
-  return
-
-
-def install_tree(src_path, dst_path, prompt_replace):
-  files = os.listdir(src_path)
-  files.sort()
-  for fname in files:
-    # eliminate some items which appear in a development area
-    if fname == 'CVS' or fname == '.svn' or fname == '_svn' \
-       or fname[-4:] == '.pyc' or fname[-5:] == '.orig' \
-       or fname[-4:] == '.rej' or fname[0] == '.' \
-       or fname[-1] ==  '~':
-      continue
-
-    src = os.path.join(src_path, fname)
-    dst = os.path.join(dst_path, fname)
-    if os.path.isdir(src):
-      install_tree(src, dst, prompt_replace)
-    else:
-      print " ", src
-      set_paths = 0
-      compile_it = fname[-3:] == '.py'
-      InstallFile(src, dst, 0644, set_paths, prompt_replace, compile_it)
-
-  # prompt to delete all .py and .pyc files that don't belong in installation
-  full_dst_path = os.path.join(DESTDIR + ROOT_DIR, dst_path)
-  for fname in os.listdir(full_dst_path):
-    if not os.path.isfile(os.path.join(full_dst_path, fname)) or \
-       not ((fname[-3:] == '.py' and fname not in files) or
-            (fname[-4:] == '.pyc' and fname[:-1] not in files)):
-      continue
-    
-    while 1:
-      temp = raw_input("""
-    File %s does not belong in ViewVC %s.
-    DO YOU WANT TO,
-        delete [d]
-        leave as is [l]: """ % (os.path.join(dst_path, fname), version))
-      print
-      
-      temp = string.lower(temp[0])
-      
-      if temp == "l":
-        break
-      
-      if temp == "d": 
-        os.unlink(os.path.join(full_dst_path, fname))
-        break
-
-## MAIN
-if __name__ == "__main__":
-    # option parsing
-    try:
-      optlist, args = getopt.getopt(sys.argv[1:], "", ['prefix=', 'destdir='])
-    except getopt.GetoptError, e:
-      Error("Invalid option", getopt.GetoptError, e)
-    for opt, arg in optlist:
-      if opt == '--prefix':
-        ROOT_DIR = arg
-      if opt == '--destdir':
-        DESTDIR = arg
-
-    ## print greeting
-    print INFO_TEXT
-
-    ## prompt for ROOT_DIR if none provided
-    if ROOT_DIR is None:
-      if sys.platform == "win32":
-        pf = os.getenv("ProgramFiles", "C:\\Program Files")
-        default = os.path.join(pf, "viewvc-" + version)  
-      else:
-        default = "/usr/local/viewvc-" + version
-      temp = string.strip(raw_input("Installation path [%s]: " % default))
-      print
-      if len(temp):
-        ROOT_DIR = temp
-      else:
-        ROOT_DIR = default
-        
-    ## prompt for DESTDIR if none provided
-    if DESTDIR is None:
-      default = ''
-      temp = string.strip(raw_input(
-        "DESTDIR path (generally, only package maintainers will need "
-        "to change\nthis) [%s]: " % default))
-      print
-      if len(temp):
-        DESTDIR = temp
-      else:
-        DESTDIR = default
-        
-    ## install the files
-    print "Installing ViewVC to:", ROOT_DIR,
-    if DESTDIR:
-      print "(DESTDIR = %s)" % (DESTDIR)
-    else:
-      print
-
-    for args in FILE_INFO_LIST:
-        print " ", args[0]
-        apply(InstallFile, args)
-
-    for args in TREE_LIST:
-      apply(install_tree, args)
-
-    print """
-
-ViewVC File Installation Complete
-
-Consult INSTALL for detailed information to finish the installation
-and configure ViewVC for your system.
-
-Overview of remaining steps:
-
-1) Edit the %s file.
-
-2) Configure an existing web server to run (or copy to cgi-bin) 
-   %s.
-      OR 
-   Run the web server that comes with ViewVC at 
-   %s.
-""" % (
-    os.path.join(ROOT_DIR, 'viewvc.conf'),
-    os.path.join(ROOT_DIR, 'bin', 'cgi', 'viewvc.cgi'),
-    os.path.join(ROOT_DIR, 'standalone.py'))
diff --git a/src/www/scm/viewvc/viewvc.cgi b/src/www/scm/viewvc/viewvc.cgi
new file mode 100755
index 0000000..2a944b7
--- /dev/null
+++ b/src/www/scm/viewvc/viewvc.cgi
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+# Locate ViewVC and run it
+
+import sys
+import os
+import glob
+
+LIBRARY_GLOBS = (
+  r"/usr/lib/viewvc/lib",  # Debian
+  r"/usr/lib/python2.?/site-packages/viewvc/lib",  # Fedora/CentOS
+  r"/srv/viewvc/lib",  # openSUSE
+)
+CONF_GLOBS = (
+  r"/etc/viewvc/viewvc.conf",  # Debian/Fedora/CentOS
+  r"/srv/viewvc/viewvc.conf",  # openSUSE
+)
+
+for pat in LIBRARY_GLOBS:
+  if glob.glob(pat):
+    LIBRARY_DIR=glob.glob(pat)[0]
+    break
+sys.path.insert(0, LIBRARY_DIR)
+
+for pat in CONF_GLOBS:
+  if glob.glob(pat):
+    CONF_PATHNAME=glob.glob(pat)[0]
+    break
+#CONF_PATHNAME = os.path.dirname(__filename__) + '/viewvc.conf'
+
+
+import sapi
+import viewvc
+
+server = sapi.CgiServer()
+cfg = viewvc.load_config(CONF_PATHNAME, server)
+
+# Read the repository root dir from the environment.
+# This way, we will only have ONE repository configured (the one we're browsing). This 
+# is more secure than having one (CVS|SVN) root configured with all the repositories inside
+
+if os.environ["REPOSITORY_TYPE"] == 'cvs':
+  cfg.general.cvs_roots[os.environ["REPOSITORY_NAME"]] = os.environ["REPOSITORY_ROOT"]
+elif os.environ["REPOSITORY_TYPE"] == 'svn':
+  cfg.general.svn_roots[os.environ["REPOSITORY_NAME"]] = os.environ["REPOSITORY_ROOT"]
+
+cfg.general.address = "<a href='mailto:root@"+os.environ["HTTP_HOST"]+"'>root@" + os.environ["HTTP_HOST"]+ "</a>"
+cfg.options.docroot = os.environ["DOCROOT"]
+cfg.options.allow_compress = False
+cfg.options.generate_etags = False
+
+viewvc.main(server, cfg)
diff --git a/src/www/scm/viewvc/viewvc.conf b/src/www/scm/viewvc/viewvc.conf
deleted file mode 100644
index b522a92..0000000
--- a/src/www/scm/viewvc/viewvc.conf
+++ /dev/null
@@ -1,363 +0,0 @@
-[general]
-
-# SCM roots are handled by GForge -- don't put the configuration here
-# docroot variable is set by the "viewcvs" wrapper, and it points to (url of current theme)/viewvc
-#address = <a href="mailto:cvs-admin at insert.your.domain.here">No admin address has been configured</a>
-
-use_rcsparse = 0
-forbidden =
-kv_files =
-languages = en-us
-
-#---------------------------------------------------------------------------
-[options]
-### DOC
-
-# root_as_url_component: Interpret the first path component in the URL
-# after the script location as the root to use.  This is an
-# alternative to using the "root=" query key. If ViewVC is configured
-# with multiple repositories, this results in more natural looking
-# ViewVC URLs and allows you to browse checked out HTML files with 
-# relative links to other repository files within ViewVC.
-# Note: Enabling this option will break backwards compatibility with
-# any old ViewVC URL which doesn't have an explicit "root" parameter.
-root_as_url_component = 0
-
-# checkout_magic: Generate checkout links with a magic *checkout* prefix.
-# This option is enabled for backwards compatibility with URLs used by old
-# versions of ViewVC. If you disable it, old *checkout* URLs will continue
-# to work, but old log page urls which don't have explicit "view=log" 
-# parameters will load checkout pages instead. It is recommended that you
-# disable this option in a fresh viewvc installation, or if you don't need
-# to support old-style log URLs. 
-checkout_magic = 1
-
-# http_expiration_time: Expiration time (in seconds) for cacheable
-# pages served by ViewVC.  Note that in most cases, a cache aware
-# client will only revalidate the page after it expires (using the
-# If-Modified-Since and/or If-None-Match headers) and that browsers
-# will also revalidate the page when the reload button is pressed.
-# Set to 0 to disable the transmission of these caching headers.
-http_expiration_time = 600
-
-# generate_etags: Generate Etag headers for relevant pages to assist
-# in browser caching.
-#   1      Generate Etags
-#   0      Don't generate Etags
-generate_etags = 0
-
-# sort_by: File sort order
-#   file   Sort by filename
-#   rev    Sort by revision number
-#   date   Sort by commit date
-#   author Sort by author
-#   log    Sort by log message
-sort_by = file
-
-# sort_group_dirs: Group directories when sorting
-#   1      Group directories together
-#   0      No grouping -- sort directories as any other item would be sorted
-sort_group_dirs = 1
-
-# hide_attic: Hide or show the contents of the Attic subdirectory
-#   1      Hide dead files inside Attic subdir
-#   0      Show the files which are inside the Attic subdir
-hide_attic = 1
-
-# log_sort: Sort order for log messages
-#   date   Sort revisions by date
-#   rev    Sort revision by revision number
-#   cvs    Don't sort them. Same order as CVS/RCS shows them.
-log_sort = date
-
-# diff_format: Default diff format
-#   h      Human readable
-#   u      Unified diff
-#   c      Context diff
-#   s      Side by side
-#   l      Long human readable (more context)
-diff_format = h
-
-# hide_cvsroot: Don't show the CVSROOT directory
-#   1      Hide CVSROOT directory
-#   0      Show CVSROOT directory
-hide_cvsroot = 1
-
-# set to 1 to make lines break at spaces,
-# set to 0 to make no-break lines,
-# set to a positive integer to make the lines cut at that length
-hr_breakable = 1
-
-# give out function names in human readable diffs
-# this just makes sense if we have C-files, otherwise
-# diff's heuristic doesn't work well ..
-# ( '-p' option to diff)
-hr_funout = 0
-
-# ignore whitespaces for human readable diffs
-# (indendation and stuff ..)
-# ( '-w' option to diff)
-hr_ignore_white = 1
-
-# ignore diffs which are caused by
-# keyword-substitution like $Id - Stuff
-# ( '-kk' option to rcsdiff)
-hr_ignore_keyword_subst = 1
-
-# allow annotation of files.
-allow_annotate = 1
-
-# allow pretty-printed version of files
-allow_markup = 1
-
-# allow compression with gzip of output if the Browser accepts it
-# (HTTP_ACCEPT_ENCODING=gzip)
-# [make sure to have gzip in the path]
-allow_compress = 1
-
-# The directory which contains the EZT templates used by ViewVC to
-# customize the display of the various output views.  ViewVC looks in
-# this directory for files with names that match the name of the view
-# ("log", "directory", etc.) plus the ".ezt" extension.  If specified
-# as a relative path, it is relative to the ViewVC installation
-# directory; absolute paths may be used as well.
-#
-# If %lang% occurs in the pathname, then the selected language will be
-# substituted.
-#
-template_dir = templates
-
-# Web path to a directory that contains ViewVC static files
-# (stylesheets, images, etc.)  If set, static files will get
-# downloaded directory from this location.  If unset, static files
-# will be served by the ViewVC script (at a likely performance
-# penalty, and from the "docroot" subdirectory of the directory
-# specified by the "template_dir" option).
-#docroot = /scm/viewvc/templates/docroot
-
-# Show last changelog message for sub directories
-# The current implementation makes many assumptions and may show the
-# incorrect file at some times. The main assumption is that the last
-# modified file has the newest filedate. But some CVS operations
-# touches the file without even when a new version is not checked in,
-# and TAG based browsing essentially puts this out of order, unless
-# the last checkin was on the same tag as you are viewing.
-# Enable this if you like the feature, but don't rely on correct results.
-show_subdir_lastmod = 0
-
-# show a portion of the most recent log entry in directory listings
-show_logs = 1
-
-# Show log when viewing file contents
-show_log_in_markup = 1
-
-# Cross filesystem copies when traversing Subversion file revision histories.
-cross_copies = 1
-
-# Display dates as UTC or in local time zone
-use_localtime = 0
-#use_localtime = 1
-
-# == Configuration defaults ==
-# Defaults for configuration variables that shouldn't need
-# to be configured..
-
-#
-# If you want to use Marc-Andrew Lemburg's py2html (and Just van Rossum's
-# PyFontify) to colorize Python files, then you may need to change this
-# variable to point to their directory location.
-#
-# This directory AND the standard Python path will be searched.
-#
-py2html_path = .
-#py2html_path = /usr/local/lib/python1.5/site-python
-
-# the length to which the most recent log entry should be truncated when
-# shown in the directory view
-short_log_len = 80
-
-# should we use 'enscript' for syntax coloring?
-use_enscript = 0
-
-#
-# if the enscript program is not on the path, set this value
-#
-enscript_path =
-# enscript_path = /usr/bin/
-
-# should we use 'highlight' for syntax coloring?
-# NOTE: use_enscript has to be 0 or escript will be used instead
-use_highlight = 0
-
-#
-# if the highlight program is not on the path, set this value
-#
-# highlight_path = /usr/bin
-
-# what coloring style should highlight use?
-highlight_style = emacs
-
-# should we add line numbers?
-highlight_line_numbers = 1
-
-# convert tabs to ## spaces (use 0 for no conversion)
-highlight_convert_tabs = 2
-
-# use php to colorize .php and .inc files?
-use_php = 0
-
-# path to php executable
-php_exe_path = php
-# php_exe_path = /usr/local/bin/php
-# php_exe_path = C:\Program Files\php\cli\php.exe
-
-#
-# ViewVC can generate tarball from a repository on the fly.
-#
-allow_tar = 0
-# allow_tar = 1
-
-#
-# Use CvsGraph. See http://www.akhphd.au.dk/~bertho/cvsgraph/ for
-# documentation and download. 
-#
-use_cvsgraph = 0
-# use_cvsgraph = 1
-
-#
-# if the cvsgraph program is not on the path, set this value
-#
-cvsgraph_path =
-# cvsgraph_path = /usr/local/bin/
-
-#
-# Location of the customized cvsgraph configuration file.  
-# You will need an absolute pathname here:
-#
-cvsgraph_conf = cvsgraph.conf
-
-#
-# Set to enable regular expression search of all files in a directory
-#
-# WARNING:
-#
-#   Enabling this option can consume HUGE amounts of server time. A
-#   "checkout" must be performed on *each* file in a directory, and
-#   the result needs to be searched for a match against the regular
-#   expression.
-#
-#
-# SECURITY WARNING:  Denial Of Service
-#
-#   Since a user can enter the regular expression, it is possible for
-#   them to enter an expression with many alternatives and a lot of
-#   backtracking. Executing that search over thousands of lines over
-#   dozens of files can easily tie up a server for a long period of
-#   time.
-#
-# This option should only be used on sites with trusted users. It is
-# highly inadvisable to use this on a public site.
-#
-use_re_search = 0
-# use_re_search = 1
-
-#
-# Split directories and logs into pages.
-# Allows ViewVC to present discrete pages to the users instead of the
-# entire log or directory.
-# Set use_pagesize to the number of entries you want displayed on a page.
-#
-use_pagesize = 0
-# use_pagesize = 20
-
-# Limit number of changed paths shown per commit in the Subversion revision
-# view and in query results. This is not a hard limit (the UI provides
-# options to show all changed paths), but it prevents ViewVC from generating
-# enormous and hard to read pages by default when they happen to contain
-# import or merge commits affecting hundreds or thousands of files.
-# Set to 0 to disable the limit.
-limit_changes = 100
-
-#---------------------------------------------------------------------------
-[templates]
-
-# You can override the templates used by various ViewVC views in this
-# section.  By default, ViewVC will look for templates in the
-# directory specified by the "template_dir" configuration option (see
-# the documentation for that option for details).  But if you want to
-# use a different template for a particular view, simply uncomment the
-# appropriate option below and specify the currect location of the EZT
-# template file you wish to use for that view.
-# 
-# Templates are specified relative to the installation directory, but
-# absolute paths may also be used as well.
-#
-# If %lang% occurs in the pathname, then the selected language will be
-# substituted.
-#
-# Note: the selected language is defined by the "languages" item in the
-#       [general] section, and based on the request's Accept-Language
-#       header.
-#
-#directory = templates/directory.ezt
-### an alternative directory view
-#directory = templates/dir_new.ezt   
-#log = templates/log.ezt
-### a table-based alternative log view
-#log = templates/log_table.ezt  
-#query = templates/query.ezt
-#diff = templates/diff.ezt
-#graph = templates/graph.ezt
-#annotate = templates/annotate.ezt
-#markup = templates/markup.ezt
-#revision = templates/revision.ezt
-#query_form = templates/query_form.ezt
-#query_results = templates/query_results.ezt
-#error = templates/error.ezt
-#roots = templates/roots.ezt
-
-#---------------------------------------------------------------------------
-[cvsdb]
-
-enabled = 0
-#host = localhost
-#port = 3306
-#database_name = ViewCVS
-#user = 
-#passwd = 
-#readonly_user = 
-#readonly_passwd = 
-#row_limit = 1000
-
-#---------------------------------------------------------------------------
-[vhosts]
-### DOC
-
-# vhost1 = glob1, glob2
-# vhost2 = glob3, glob4
-
-# [vhost1-section]
-# option = value
-# [vhost1-othersection]
-# option = value
-# [vhost2-section]
-# option = value
-
-#
-# Here is an example:
-#
-# [vhosts]
-# lyra = *lyra.org
-#
-# [lyra-general]
-# forbidden = hideme
-#
-# [lyra-options]
-# show_logs = 0
-#
-# Note that "lyra" is the "canonical" name for all hosts in the lyra.org
-# domain. This canonical name is then used within the additional, vhost-
-# specific sections to override specific values in the common sections.
-#
-
-#---------------------------------------------------------------------------
diff --git a/src/www/scm/viewvc/viewvc.conf.dist b/src/www/scm/viewvc/viewvc.conf.dist
deleted file mode 100644
index 2e4d6ff..0000000
--- a/src/www/scm/viewvc/viewvc.conf.dist
+++ /dev/null
@@ -1,615 +0,0 @@
-#---------------------------------------------------------------------------
-#
-# Configuration file for ViewVC
-#
-# Information on ViewVC is located at the following web site:
-#     http://viewvc.org/
-#
-#---------------------------------------------------------------------------
-
-#
-# BASIC CONFIGURATION
-#
-# For correct operation, you will probably need to change the following
-# configuration variables:
-#
-#    cvs_roots (for CVS)
-#    svn_roots (for Subversion)
-#    root_parents (for CVS or Subversion)
-#    default_root
-#    rcs_path or cvsnt_exe_path
-#    mime_types_file 
-#
-# It is usually desirable to change the following variables:
-#
-#    address
-#    forbidden
-#
-#    use_enscript
-#    use_cvsgraph
-#
-# For Python source colorization:
-#
-#    py2html_path
-#
-# To optimize delivery of ViewVC static files:
-#
-#    docroot
-#
-# To customize the display of ViewVC for your site:
-#
-#    template_dir
-#    the [templates] override section
-#
-
-#
-# FORMAT INFORMATION
-#
-# This file is delineated by sections, specified in [brackets]. Within each
-# section, are a number of configuration settings. These settings take the
-# form of: name = value. Values may be continued on the following line by
-# indenting the continued line.
-#
-# WARNING: indentation *always* means continuation. name=value lines should
-#          always start in column zero.
-#
-# Comments should always start in column zero, and are identified with "#".
-#
-# Certain configuration settings may have multiple values. These should be
-# separated by a comma. The settings where this is allowed are noted below.
-#
-# Any other setting that requires special syntax is noted at that setting.
-# 
-
-#---------------------------------------------------------------------------
-[general]
-
-#
-# This setting specifies each of the CVS roots on your system and assigns
-# names to them. Each root should be given by a "name: path" value. Multiple
-# roots should be separated by commas and can be placed on separate lines.
-#
-cvs_roots = cvs: /home/cvsroot
-
-#
-# This setting specifies each of the Subversion roots (repositories)
-# on your system and assigns names to them. Each root should be given
-# by a "name: path" value. Multiple roots should be separated by
-# commas and can be placed on separate lines.
-#
-#svn_roots = svn: /home/svnrepos
-
-# The 'root_parents' setting specifies a list of directories in which
-# any number of repositories may reside.  Rather than force you to add
-# a new entry to 'cvs_roots' or 'svn_roots' each time you create a new
-# repository, ViewVC rewards you for organising all your repositories
-# under a few parent directories by allowing you to simply specifiy
-# just those parent directories.  ViewVC will then notice each
-# repository in that directory as a new root whose name is the
-# subdirectory of the parent path in which that repository lives.
-#
-# You can specify multiple parent paths separated by commas or new lines.
-#
-# Caution: these names can, of course, clash with names you have
-# defined in your cvs_roots or svn_roots configuration items.  If this
-# occurs, you can either rename the offending repository on disk, or
-# grant new names to the clashing item in cvs_roots or svn_roots.
-# Each parent path is processed sequentially, so repositories under
-# later parent paths may override earlier ones.
-#
-#root_parents = /home/svn-repositories : svn,
-#               /home/cvs-repositories : cvs
-
-# this is the name of the default root
-# (ignored when root_as_url_component is turned on)
-default_root = cvs
-
-# uncomment if the RCS binaries are not on the standard path
-#rcs_path = /usr/bin/
-
-# ViewVC can use CVSNT (www.cvsnt.org) instead of the RCS 
-# utilities to retrieve information from CVS repositories.
-# To enable use of CVSNT, set the "cvsnt_exe_path" value
-# to the path of the CVSNT executable. (If CVSNT is on the
-# standard path, you can also set it to the name of the
-# CVSNT executable). By default "cvsnt_exe_path" is set to
-# "cvs" on Windows and is not set on other platforms.
-#
-#cvsnt_exe_path =
-#cvsnt_exe_path = cvs
-#cvsnt_exe_path = K:\Program Files\cvsnt\cvs.exe
-#cvsnt_exe_path = /usr/bin/cvs
-
-# use rcsparse python module to retrieve cvs repository information instead
-# of invoking rcs utilities. this feature is experimental
-use_rcsparse = 0
-
-# uncomment if the svn command-line utilities are not on the standard path
-#svn_path = /usr/bin/
-
-#
-# This is a pathname to a MIME types file to help viewvc to guess the
-# correct MIME type on checkout.
-#
-# If you are having problems with the default guess on the MIME type, then
-# uncomment this option and point it at a MIME type file.
-#
-# For example, you can use the mime.types from apache here:
-#mime_types_file = /usr/local/apache/conf/mime.types
-
-# This address is shown in the footer of the generated pages. 
-# It must be replaced with the address of the local repository maintainer.
-address = <a href="mailto:cvs-admin at insert.your.domain.here">No admin address has been configured</a>
-
-#
-# This should contain a list of modules in the repository that should not be
-# displayed (by default or by explicit path specification).
-#
-# This configuration can be a simple list of modules, or it can get quite
-# complex:
-#
-#   *) The "!" can be used before a module to explicitly state that it
-#      is NOT forbidden. Whenever this form is seen, then all modules will
-#      be forbidden unless one of the "!" modules match.
-#
-#   *) Shell-style "glob" expressions may be used. "*" will match any
-#      sequence of zero or more characters, "?" will match any single
-#      character, "[seq]" will match any character in seq, and "[!seq]"
-#      will match any character not in seq.
-#
-#   *) Tests are performed in sequence. The first match will terminate the
-#      testing. This allows for more complex allow/deny patterns.
-#
-# Tests are case-sensitive.
-#
-forbidden =
-
-# Some examples:
-#
-# Disallow "example" but allow all others:
-#   forbidden = example
-#
-# Disallow "example1" and "example2" but allow all others:
-#   forbidden = example1, example2
-#
-# Allow *only* "example1" and "example2":
-#   forbidden = !example1, !example2
-#
-# Forbid modules starting with "x":
-#   forbidden = x*
-#
-# Allow modules starting with "x" but no others:
-#   forbidden = !x*
-#
-# Allow "xml", forbid other modules starting with "x", and allow the rest:
-#   forbidden = !xml, x*, !*
-#
-
-#
-# This option provides a mechanism for custom key/value pairs to be
-# available to templates. These are stored in key/value files (KV files).
-#
-# Pathnames to the KV files are listed here, specified as absolute paths
-# or relative to this configuration file. The kV files follow the same
-# format as this configuration file. It may have multiple, user-defined
-# sections, and user-defined options in those sections. These are all
-# placed into a structure available to the templates as:
-#
-#    kv.SECTION.OPTION
-#
-# Note that an option name can be dotted. For example:
-#
-#    [my_images]
-#    logos.small = /images/small-logo.png
-#    logos.big = /images/big-logo.png
-#
-# Templates can use these with a directive like: [kv.my_images.logos.small]
-#
-# Note that sections across multiple files will be merged. If two files
-# have a [my_images] section, then the options will be merged together.
-# If two files have the same option name in a section, then one will
-# overwrite the other (it is unspecified regarding which "wins").
-#
-# To further categorize the KV files, and how the values are provided to
-# the templates, a KV file name may be annotated with an additional level
-# of dotted naming. For example:
-#
-#    kv_files = [asf]kv/images.conf
-#
-# Assuming the same section as above, the template would refer to an image
-# using [kv.asf.my_images.logos.small]
-#
-# Lastly, it is possible to use %lang% in the filenames to specify a
-# substitution of the selected language-tag.
-#
-kv_files =
-
-# example:
-# kv_files = kv/file1.conf, kv/file2.conf, [i18n]kv/%lang%_data.conf
-#
-
-#
-# The languages available to ViewVC. There are several i18n mechanisms
-# available:
-#
-#   1) using key/value extension system and reading KV files based on
-#      the selected language
-#   2) GNU gettext to substitute text in the templates
-#   3) using different templates, based on the selected language
-#
-# ### NOTE: at the moment, the GNU gettext style is not implemented
-#
-# This option is a comma-separated list of language-tag values. The first
-# language-tag listed is the default language, and will be used if an
-# Accept-Language header is not present in the request, or none of the
-# user's requested languages are available. If there are ties on the
-# selection of a language, then the first to appear in the list is chosen.
-#
-languages = en-us
-
-# other examples:
-#
-# languages = en-us, de
-# languages = en-us, en-gb, de
-# languages = de, fr, en-us
-#
-
-#---------------------------------------------------------------------------
-[options]
-
-# root_as_url_component: Interpret the first path component in the URL
-# after the script location as the root to use.  This is an
-# alternative to using the "root=" query key. If ViewVC is configured
-# with multiple repositories, this results in more natural looking
-# ViewVC URLs.
-# Note: Enabling this option will break backwards compatibility with
-# any old ViewCVS URL which doesn't have an explicit "root" parameter.
-root_as_url_component = 0
-
-# default_file_view: "log" or "co"
-# Controls whether the default view for file URLs is a checkout view or
-# a log view. "log" is the default for backwards compatibility with old
-# ViewCVS URLs, but "co" has the advantage that it allows ViewVC to serve
-# static HTML pages directly from a repository with working links
-# to other repository files
-# Note: Changing this option may cause old ViewCVS URLs that referred
-# to log pages to load checkout pages instead.
-default_file_view = log
-
-# checkout_magic: Use checkout links with magic /*checkout*/ prefixes so
-# checked out HTML pages can have working links to other repository files
-# Note: This option is DEPRECATED and should not be used in new ViewVC
-# installations. Setting "default_file_view = co" achieves the same effect
-checkout_magic = 0
-
-# http_expiration_time: Expiration time (in seconds) for cacheable
-# pages served by ViewVC.  Note that in most cases, a cache aware
-# client will only revalidate the page after it expires (using the
-# If-Modified-Since and/or If-None-Match headers) and that browsers
-# will also revalidate the page when the reload button is pressed.
-# Set to 0 to disable the transmission of these caching headers.
-http_expiration_time = 600
-
-# generate_etags: Generate Etag headers for relevant pages to assist
-# in browser caching.
-#   1      Generate Etags
-#   0      Don't generate Etags
-generate_etags = 1
-
-# sort_by: File sort order
-#   file   Sort by filename
-#   rev    Sort by revision number
-#   date   Sort by commit date
-#   author Sort by author
-#   log    Sort by log message
-sort_by = file
-
-# sort_group_dirs: Group directories when sorting
-#   1      Group directories together
-#   0      No grouping -- sort directories as any other item would be sorted
-sort_group_dirs = 1
-
-# hide_attic: Hide or show the contents of the Attic subdirectory
-#   1      Hide dead files inside Attic subdir
-#   0      Show the files which are inside the Attic subdir
-hide_attic = 1
-
-# log_sort: Sort order for log messages
-#   date   Sort revisions by date
-#   rev    Sort revision by revision number
-#   cvs    Don't sort them. Same order as CVS/RCS shows them.
-log_sort = date
-
-# diff_format: Default diff format
-#   h      Human readable
-#   u      Unified diff
-#   c      Context diff
-#   s      Side by side
-#   l      Long human readable (more context)
-diff_format = h
-
-# hide_cvsroot: Don't show the CVSROOT directory
-#   1      Hide CVSROOT directory
-#   0      Show CVSROOT directory
-hide_cvsroot = 1
-
-# set to 1 to make lines break at spaces,
-# set to 0 to make no-break lines,
-# set to a positive integer to make the lines cut at that length
-hr_breakable = 1
-
-# give out function names in human readable diffs
-# this just makes sense if we have C-files, otherwise
-# diff's heuristic doesn't work well ..
-# ( '-p' option to diff)
-hr_funout = 0
-
-# ignore whitespaces for human readable diffs
-# (indendation and stuff ..)
-# ( '-w' option to diff)
-hr_ignore_white = 1
-
-# ignore diffs which are caused by
-# keyword-substitution like $Id - Stuff
-# ( '-kk' option to rcsdiff)
-hr_ignore_keyword_subst = 1
-
-# Enable highlighting of intraline changes in human readable diffs
-# this feature is experimental and currently requires python 2.4
-# 
-hr_intraline = 0
-
-# allow annotation of files.
-allow_annotate = 1
-
-# allow pretty-printed version of files
-allow_markup = 1
-
-# allow compression with gzip of output if the Browser accepts it
-# (HTTP_ACCEPT_ENCODING=gzip)
-# [make sure to have gzip in the path]
-allow_compress = 1
-
-# The directory which contains the EZT templates used by ViewVC to
-# customize the display of the various output views.  ViewVC looks in
-# this directory for files with names that match the name of the view
-# ("log", "directory", etc.) plus the ".ezt" extension.  If specified
-# as a relative path, it is relative to the ViewVC installation
-# directory; absolute paths may be used as well.
-#
-# If %lang% occurs in the pathname, then the selected language will be
-# substituted.
-#
-template_dir = templates
-
-# Web path to a directory that contains ViewVC static files
-# (stylesheets, images, etc.)  If set, static files will get
-# downloaded directory from this location.  If unset, static files
-# will be served by the ViewVC script (at a likely performance
-# penalty, and from the "docroot" subdirectory of the directory
-# specified by the "template_dir" option).
-#docroot = /docroot
-
-# Show last changelog message for sub directories
-# The current implementation makes many assumptions and may show the
-# incorrect file at some times. The main assumption is that the last
-# modified file has the newest filedate. But some CVS operations
-# touches the file without even when a new version is not checked in,
-# and TAG based browsing essentially puts this out of order, unless
-# the last checkin was on the same tag as you are viewing.
-# Enable this if you like the feature, but don't rely on correct results.
-show_subdir_lastmod = 0
-
-# show a portion of the most recent log entry in directory listings
-show_logs = 1
-
-# Show log when viewing file contents
-show_log_in_markup = 1
-
-# Cross filesystem copies when traversing Subversion file revision histories.
-cross_copies = 1
-
-# Display dates as UTC or in local time zone
-use_localtime = 0
-#use_localtime = 1
-
-# == Configuration defaults ==
-# Defaults for configuration variables that shouldn't need
-# to be configured..
-
-#
-# If you want to use Marc-Andrew Lemburg's py2html (and Just van Rossum's
-# PyFontify) to colorize Python files, then you may need to change this
-# variable to point to their directory location.
-#
-# This directory AND the standard Python path will be searched.
-#
-py2html_path = .
-#py2html_path = /usr/local/lib/python1.5/site-python
-
-# the length to which the most recent log entry should be truncated when
-# shown in the directory view
-short_log_len = 80
-
-# should we use 'enscript' for syntax coloring?
-use_enscript = 0
-
-#
-# if the enscript program is not on the path, set this value
-#
-enscript_path =
-# enscript_path = /usr/bin/
-
-# should we use 'highlight' for syntax coloring?
-# NOTE: use_enscript has to be 0 or enscript will be used instead
-use_highlight = 0
-
-#
-# if the highlight program is not on the path, set this value
-#
-# highlight_path = /usr/bin
-
-# should we add line numbers?
-highlight_line_numbers = 1
-
-# convert tabs to ## spaces (use 0 for no conversion)
-highlight_convert_tabs = 2
-
-# use php to colorize .php and .inc files?
-use_php = 0
-
-# path to php executable
-php_exe_path = php
-# php_exe_path = /usr/local/bin/php
-# php_exe_path = C:\Program Files\php\cli\php.exe
-
-#
-# ViewVC can generate tarball from a repository on the fly.
-#
-allow_tar = 0
-# allow_tar = 1
-
-#
-# Use CvsGraph. See http://www.akhphd.au.dk/~bertho/cvsgraph/ for
-# documentation and download. 
-#
-use_cvsgraph = 0
-# use_cvsgraph = 1
-
-#
-# if the cvsgraph program is not on the path, set this value
-#
-cvsgraph_path =
-# cvsgraph_path = /usr/local/bin/
-
-#
-# Location of the customized cvsgraph configuration file.  
-# You will need an absolute pathname here:
-#
-cvsgraph_conf = cvsgraph.conf
-
-#
-# Set to enable regular expression search of all files in a directory
-#
-# WARNING:
-#
-#   Enabling this option can consume HUGE amounts of server time. A
-#   "checkout" must be performed on *each* file in a directory, and
-#   the result needs to be searched for a match against the regular
-#   expression.
-#
-#
-# SECURITY WARNING:  Denial Of Service
-#
-#   Since a user can enter the regular expression, it is possible for
-#   them to enter an expression with many alternatives and a lot of
-#   backtracking. Executing that search over thousands of lines over
-#   dozens of files can easily tie up a server for a long period of
-#   time.
-#
-# This option should only be used on sites with trusted users. It is
-# highly inadvisable to use this on a public site.
-#
-use_re_search = 0
-# use_re_search = 1
-
-#
-# Split directories and logs into pages.
-# Allows ViewVC to present discrete pages to the users instead of the
-# entire log or directory.
-# Set use_pagesize to the number of entries you want displayed on a page.
-#
-use_pagesize = 0
-# use_pagesize = 20
-
-# Limit number of changed paths shown per commit in the Subversion revision
-# view and in query results. This is not a hard limit (the UI provides
-# options to show all changed paths), but it prevents ViewVC from generating
-# enormous and hard to read pages by default when they happen to contain
-# import or merge commits affecting hundreds or thousands of files.
-# Set to 0 to disable the limit.
-limit_changes = 100
-
-#---------------------------------------------------------------------------
-[templates]
-
-# You can override the templates used by various ViewVC views in this
-# section.  By default, ViewVC will look for templates in the
-# directory specified by the "template_dir" configuration option (see
-# the documentation for that option for details).  But if you want to
-# use a different template for a particular view, simply uncomment the
-# appropriate option below and specify the currect location of the EZT
-# template file you wish to use for that view.
-# 
-# Templates are specified relative to the installation directory, but
-# absolute paths may also be used as well.
-#
-# If %lang% occurs in the pathname, then the selected language will be
-# substituted.
-#
-# Note: the selected language is defined by the "languages" item in the
-#       [general] section, and based on the request's Accept-Language
-#       header.
-#
-#directory = templates/directory.ezt
-### an alternative directory view
-#directory = templates/dir_new.ezt   
-#log = templates/log.ezt
-### a table-based alternative log view
-#log = templates/log_table.ezt  
-#query = templates/query.ezt
-#diff = templates/diff.ezt
-#graph = templates/graph.ezt
-#annotate = templates/annotate.ezt
-#markup = templates/markup.ezt
-#revision = templates/revision.ezt
-#query_form = templates/query_form.ezt
-#query_results = templates/query_results.ezt
-#error = templates/error.ezt
-#roots = templates/roots.ezt
-
-#---------------------------------------------------------------------------
-[cvsdb]
-
-enabled = 0
-#host = localhost
-#port = 3306
-#database_name = ViewVC
-#user = 
-#passwd = 
-#readonly_user = 
-#readonly_passwd = 
-#row_limit = 1000
-
-#---------------------------------------------------------------------------
-[vhosts]
-### DOC
-
-# vhost1 = glob1, glob2
-# vhost2 = glob3, glob4
-
-# [vhost1-section]
-# option = value
-# [vhost1-othersection]
-# option = value
-# [vhost2-section]
-# option = value
-
-#
-# Here is an example:
-#
-# [vhosts]
-# lyra = *lyra.org
-#
-# [lyra-general]
-# forbidden = hideme
-#
-# [lyra-options]
-# show_logs = 0
-#
-# Note that "lyra" is the "canonical" name for all hosts in the lyra.org
-# domain. This canonical name is then used within the additional, vhost-
-# specific sections to override specific values in the common sections.
-#
-
-#---------------------------------------------------------------------------
diff --git a/src/www/scm/viewvc/viewvc.org/contact.html b/src/www/scm/viewvc/viewvc.org/contact.html
deleted file mode 100644
index 564c693..0000000
--- a/src/www/scm/viewvc/viewvc.org/contact.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: Contact</title>
-<link rel="stylesheet" type="text/css" href="./styles.css"/>
-</head>
-
-<body>
-
-<div id="title">
-<a href="http://www.viewvc.org/"><img 
-   src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
-</div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> |
-   <a href="http://viewvc.tigris.org/">Project Page</a> |
-   <a href="./download.html">Download</a> |
-   <a href="./upgrading.html">Upgrading</a> |
-   <a href="./contributing.html">Contributing</a> |
-   <a href="./license-1.html">License</a> |
-   <a href="./contact.html">Contact</a> |
-   <a href="./who.html">About</a>
-</p>
-</div>
-
-<table id="pagetable">
-<tr>
-<td id="pagecolumn1">
-
-<h4>On this page:</h4>
-
-<ul id="bookmarks">
-  <li><a href="#sec-contacting-us">Contacting Us</a></li>
-</ul>
-
-<hr/>
-
-<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
-
-</td>
-<td id="pagecolumn2">
-
-<div class="section">
-
-<h2 id="sec-contacting-us">Contacting Us</h2>
-
-<p>Please send any comments, questions, or suggestions to the <a
-   href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC users mailing
-   list</a>.  There is also a <a
-   href="mailto:&#100&#101&#118&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">mailing list specifically for
-   ViewVC developers</a>.  You can subscribe to these lists, as well
-   view the list archives, (and other
-   project lists) <a
-   href="http://viewvc.tigris.org/servlets/ProjectMailingListList"
-   >here</a>.</p>
-
-<p>ViewVC is an <a href="http://www.opensource.org/">Open
-   Source</a> project, and all <a href="./contributing.html">contributions</a> 
-   are welcome.</p>
-
-</div>
-
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/contributing.html b/src/www/scm/viewvc/viewvc.org/contributing.html
deleted file mode 100644
index 24d2701..0000000
--- a/src/www/scm/viewvc/viewvc.org/contributing.html
+++ /dev/null
@@ -1,258 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: Contributing</title>
-<link rel="stylesheet" type="text/css" href="./styles.css" />
-</head>
-
-<body>
-
-<div id="title"><a href="http://www.viewvc.org/"><img
-	src="./images/title.jpg" alt="ViewVC: Repository Browsing" /></a></div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> | <a
-	href="http://viewvc.tigris.org/">Project Page</a> | <a
-	href="./download.html">Download</a> | <a href="./upgrading.html">Upgrading</a>
-| <a href="./contributing.html">Contributing</a> | <a
-	href="./license-1.html">License</a> | <a href="./contact.html">Contact</a>
-| <a href="./who.html">About</a></p>
-</div>
-
-<table id="pagetable">
-	<tr>
-		<td id="pagecolumn1">
-
-		<h4>On this page:</h4>
-
-		<ul id="bookmarks">
-			<li><a href="#sec-getting-started">Getting Started</a></li>
-			<li><a href="#sec-testing">Testing and Reporting</a></li>
-			<li><a href="#sec-coding-style">Coding Style</a></li>
-			<li><a href="#sec-patches">Submitting Patches</a></li>
-			<li><a href="#sec-security">Security</a></li>
-			<li><a href="#sec-adding-features">Adding Features</a></li>
-			<li><a href="#sec-templates">Hacking on Templates</a></li>
-			<li><a href="#sec-releasing">Release Management</a></li>
-		</ul>
-
-		<hr />
-
-		<address><a
-			href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC
-		Users Group</a></address>
-
-		</td>
-		<td id="pagecolumn2">
-
-		<div class="section">
-
-		<h2 id="sec-getting-started">Getting Started</h2>
-
-		<p>Some basic knowledge about <a href="http://www.python.org">Python</a>
-		and development tools like <code>diff</code> is required. Your best
-		bet is to start with a fresh source code snapshot, which you may
-		obtain from our Subversion repository (see instructions <a
-			href="./download.html#sec-subversion">here</a>).</p>
-
-		<p>Version control history can be obtained using Subversion
-		clients, but is also browsable using <a
-			href="http://viewvc.tigris.org/source/browse/viewvc/trunk/">tigris.org's
-		integrated ViewVC tool</a>.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-testing">Testing and Reporting</h2>
-
-		<p>Testing usability and the installation process on different
-		platforms is also a valuable contribution. Please report your results
-		back to us developers. Bandwidth is getting cheaper daily, so don't be
-		afraid — in fact, feel encouraged — to dump as much detail
-		about the problems you are seeing as possible into your bug reports.
-		Here are some things you definitely should try to include:</p>
-
-		<ul>
-
-			<li>What version of ViewVC you are using (if you are using a
-			source snapshot, tell us the date of that snapshot).</li>
-
-			<li>What operating system your ViewVC is running on.</li>
-
-			<li>What version of Python you are using.</li>
-
-			<li>Whether you are running ViewVC standalone, or as a CGI
-			program under a web server (and if so, what web server).</li>
-
-			<li>The URL of your ViewVC instantiation, if it is public.
-			Sometimes, letting developers see the problem for themselves can save
-			everyone alot of time.</li>
-
-		</ul>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-coding-style">Coding Style</h2>
-
-		<p>Unlike its predecessor, CvsWeb, ViewVC is written in Python, so
-		it doesn't suffer from the "unmaintainable code effect" that hits most
-		Perl projects sooner or later:</p>
-
-		<blockquote><em>"[Perl] combines all the worst
-		aspects of C and Lisp: a billion different sublanguages in one
-		monolithic executable. It combines the power of C with the readability
-		of PostScript."</em> — Jamie Zawinski</blockquote>
-
-		<p>Of course, a symphony of insanity can be composed in any
-		language, so we do try to stick to some basic guiding principles.
-		Maintain whatever style is present in the code being modified. New
-		code can use anything sane (which generally means <a
-			href="http://python.sourceforge.net/peps/pep-0008.html">PEP 8</a>).
-		Our only real peeve is if someone writes a function call as: <code>some_func (args)</code>
-		— that space between the function name and opening parenthesis
-		is Huge Badness. Oh, and we do <strong>not</strong> use Subversion
-		keywords (such as <code>$</code><code>Id$</code>) within the source.</p>
-
-		<p>Otherwise… <em>shrug</em>.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-patches">Submitting Patches</h2>
-
-		<p>Nothing speaks more loudly when bugs or features are the topic
-		than a patch. And quite frankly, sometimes if you want something done,
-		you gotta do it yourself. So, patches are always welcome. If you
-		aren't sure what exactly a "patch" is, or don't know how to
-		generate one, but you've got code contributions to make, please don't
-		hesitate to ask questions on the mailing lists. Patch generation and
-		application are pretty easy thing to get the hang of, and drastically
-		simplify code submission and review.</p>
-
-		<p>Please use the <a
-			href="http://viewvc.tigris.org/servlets/ProjectIssues">Issue
-		Tracker</a> to submit your patches. Unified contextual diffs against the
-		latest development snapshot are preferred.</p>
-
-		<p>If you have commit access, then you should know what you're
-		doing. Just make changes directly. Subscribing to the <a
-			href="http://viewvc.tigris.org/servlets/ProjectMailingListList"><tt>dev@</tt>
-		developer mailing list</a> is recommended in any case.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-security">Security</h2>
-
-		<p>Since ViewVC is used on the Internet, security is a major
-		concern. If you need to pass data from the request into an external
-		program, please don't use <code>os.system()</code> or <code>os.popen()</code>.
-		Please use the module <code>lib/popen.py</code> that is included in
-		the ViewVC distribution instead.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-adding-features">Adding Features</h2>
-
-		<p>If you need a new configuration option think carefully, into
-		which section it belongs. Try to keep the content of <code>cgi/viewvc.conf.dist</code>
-		file and the library module <code>lib/config.py</code> in sync.</p>
-
-		<p>Because ViewVC is a Web-based application, people will have
-		ViewVC URLs hyperlinked from other sites, embedded in emails,
-		bookmarked in their browsers, etc. It is very important to ensure that
-		those URLs continue to retrieve the information they were intended to
-		retrieve even if ViewVC is upgraded on the hosting server. In other
-		words, as new features require modifications to the <a
-			href="./url-reference.html">ViewVC URL schema</a>, make sure those
-		modifications preserve the existing functionality of all ViewVC URLs.</p>
-
-		<p>The library subdirectory contains a module <code>debug.py</code>,
-		which you may find useful for performance testing.</p>
-
-		<p>If a new file or module is added, a new line in the installer
-		program <code>viewvc-install</code> is required.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-templates">Hacking on Templates</h2>
-
-		<p>The library module <code>ezt.py</code> contains a module
-		docstring which describes the directives used in the HTML templates
-		used by ViewVC. The templates themselves can be found in the <code>templates</code>
-		subdirectory. We're currently developing a how-to guide for <a
-			href="./template-authoring-guide.html">ViewVC template
-		customization</a>.</p>
-
-		</div>
-		<div class="section">
-
-		<h2 id="sec-releasing">Release Management</h2>
-
-		<p>There is a script, <code>tools/make-release</code>, which
-		creates a release directory and the various archive files that we
-		distribute. All other steps required to get a ViewVC release out of
-		the door require manual execution (currently by C. Michael Pilato).
-		Those steps are as follows:</p>
-
-		<ol>
-
-			<li>Add a new subsection to the file <code>website/upgrading.html</code>
-			describing all user visible changes for users of previous releases of
-			ViewVC.</li>
-
-			<li>Update the <code>CHANGES</code> file</li>
-
-			<li>Update the <code>website/index.html</code> file to refer to
-			the new X.Y files. (there are three links to update)</li>
-
-			<li>Edit the file <code>lib/viewvc.py</code> and remove the <tt>"-dev"</tt>
-			suffix from <code>__version__</code>. The remainder should be of the
-			form X.Y.Z, where X, Y, and Z are positive integers.</li>
-
-			<li>Ensure all of the above changes have been committed.</li>
-
-			<li>Test, Test, Test! At the time of this writing (1.0-dev)
-			there is no automatic testsuite available. So just run with permuting
-			different <code>viewvc.conf</code> settings… and pray.</li>
-
-			<li>Review any open <a
-				href="http://viewvc.tigris.org/servlets/ProjectIssues">bug
-			reports.</a></li>
-
-			<li>Use <code>svn cp</code> to tag the release to <code>/tags/<i>X</i>.<i>Y</i>.<i>Z</i></code>,
-			where <i>X</i>, <i>Y</i>, and <i>Z</i> should be replaced by the
-			release number from above. If a developer is willing to volunteer as
-			a bug fix patch release manager, it is now possible to start here at
-			this point with a feature-frozen branch using <code>svn cp</code> to
-			copy the tag to <code>/branches/<i>X</i>.<i>Y</i>.x</code>.</li>
-
-			<li>Go into an empty directory and run <code>tools/make-release
-			viewvc-<i>X.Y.Z</i> <i>X.Y.Z</i></code>. This step requires read access to
-			the Subversion source code repository.</li>
-
-			<li>Upload the created archive files (tar.gz and zip) into the
-			Files and Documents section of the Tigris.org project.</li>
-
-			<li>Edit the file <code>lib/viewvc.py</code> again and this time
-			increment the <code>__version__</code> for the next release cycle,
-			again append the <code>-dev</code> to the version and again <code>svn
-			commit -m "Begin a new release cycle." lib/viewvc.py</code>.</li>
-
-			<li>Write an announcement explaining all the cool new features
-			and post it <a
-				href="mailto:&#97&#110&#110&#111&#117&#110&#99&#101&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">&#97&#110&#110&#111&#117&#110&#99&#101&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103</a>,
-			to the project's News area, and to other places interested in this
-			sort of stuff (such as <a href="http://www.freshmeat.net">Freshmeat</a>).
-		</ol>
-
-		</div>
-
-		</td>
-	</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/download.html b/src/www/scm/viewvc/viewvc.org/download.html
deleted file mode 100644
index c38f6d7..0000000
--- a/src/www/scm/viewvc/viewvc.org/download.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: Download</title>
-<link rel="stylesheet" type="text/css" href="./styles.css"/>
-</head>
-
-<body>
-
-<div id="title">
-<a href="http://www.viewvc.org/"><img 
-   src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
-</div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> |
-   <a href="http://viewvc.tigris.org/">Project Page</a> |
-   <a href="./download.html">Download</a> |
-   <a href="./upgrading.html">Upgrading</a> |
-   <a href="./contributing.html">Contributing</a> |
-   <a href="./license-1.html">License</a> |
-   <a href="./contact.html">Contact</a> |
-   <a href="./who.html">About</a>
-</p>
-</div>
-
-<table id="pagetable">
-<tr>
-<td id="pagecolumn1">
-
-<h4>On this page:</h4>
-
-<ul id="bookmarks">
-  <li><a href="#sec-download">Downloading</a></li>
-  <li><a href="#sec-subversion">Subversion</a></li>
-</ul>
-
-<hr/>
-
-<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
-
-</td>
-<td id="pagecolumn2">
-
-<div class="section">
-
-<h2 id="sec-download">Downloading</h2>
-
-<p>You can download the ViewVC (and the older ViewCVS releases, too)
-   from our <a
-   href="http://viewvc.tigris.org/servlets/ProjectDocumentList?folderID=6004"
-   >File and Documents</a> area.  For information about what has
-   changed in each release, see the <a
-   href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
-   >CHANGES</a> file.</p>
-
-<p>We are also making <a href="./nightly/">nightly snapshots</a>
-   available in tar.gz and zip formats.</p>
-
-</div>
-<div class="section">
-
-<h2 id="sec-subversion">Subversion</h2>
-
-<p>The source code for ViewVC is maintained in a Subversion repository
-   at Tigris.org.  You can checkout the trunk of our development tree
-   from <a href="http://viewvc.tigris.org/svn/viewvc/trunk/"
-   ><tt>http://viewvc.tigris.org/svn/viewvc/trunk/</tt></a>.  You'll
-   need to provide your Tigris.org username and password when so
-   prompted, or, if you don't have a Tigris.org account, use "guest"
-   as both the username and password.</p>
-  
-</div>
-
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/images/bg-grad.jpg b/src/www/scm/viewvc/viewvc.org/images/bg-grad.jpg
deleted file mode 100644
index 70d7042..0000000
Binary files a/src/www/scm/viewvc/viewvc.org/images/bg-grad.jpg and /dev/null differ
diff --git a/src/www/scm/viewvc/viewvc.org/images/title.jpg b/src/www/scm/viewvc/viewvc.org/images/title.jpg
deleted file mode 100644
index d33ed19..0000000
Binary files a/src/www/scm/viewvc/viewvc.org/images/title.jpg and /dev/null differ
diff --git a/src/www/scm/viewvc/viewvc.org/images/title.xcf b/src/www/scm/viewvc/viewvc.org/images/title.xcf
deleted file mode 100644
index 6895777..0000000
Binary files a/src/www/scm/viewvc/viewvc.org/images/title.xcf and /dev/null differ
diff --git a/src/www/scm/viewvc/viewvc.org/index.html b/src/www/scm/viewvc/viewvc.org/index.html
deleted file mode 100644
index bb24d3d..0000000
--- a/src/www/scm/viewvc/viewvc.org/index.html
+++ /dev/null
@@ -1,192 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: Repository Browsing</title>
-<link rel="stylesheet" type="text/css" href="./styles.css"/>
-</head>
-
-<body>
-
-<div id="title">
-<a href="http://www.viewvc.org/"><img 
-   src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
-</div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> |
-   <a href="http://viewvc.tigris.org/">Project Page</a> |
-   <a href="./download.html">Download</a> |
-   <a href="./upgrading.html">Upgrading</a> |
-   <a href="./contributing.html">Contributing</a> |
-   <a href="./license-1.html">License</a> |
-   <a href="./contact.html">Contact</a> |
-   <a href="./who.html">About</a>
-</p>
-</div>
-
-<table id="pagetable">
-<tr>
-<td id="pagecolumn1">
-
-<h4>On this page:</h4>
-
-<ul id="bookmarks">
-  <li><a href="#sec-what-is-viewvc">What Is ViewVC?</a></li>
-  <li><a href="#sec-requirements">Requirements</a></li>
-  <li><a href="#sec-future">Future Plans</a></li>
-</ul>
-
-<hr/>
-
-<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
-
-</td>
-<td id="pagecolumn2">
-
-<div class="section">
-
-<h2 id="sec-what-is-viewvc">What Is ViewVC?</h2>
-
-<p>ViewVC is a browser interface for CVS and Subversion version
-   control repositories.  It generates templatized HTML to present
-   navigable directory, revision, and change log listings.  It can
-   display specific versions of files as well as diffs between those
-   versions.  Basically, ViewVC provides the bulk of the report-like
-   functionality you expect out of your version control tool, but much
-   more prettily than the average textual command-line program
-   output.</p>
-
-<p>Here are some of the additional features of ViewVC:</p>
-
-<ul>
-
-  <li>Support for filesystem-accessible CVS and Subversion repositories.</li>
-
-  <li>Individually configurable virtual host support.</li>
-
-  <li>Line-based annotation/blame display.</li>
-
-  <li>Revision graph capabilities (via integration with <a
-      href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>)
-      (<em>CVS only</em>).</li>
-
-  <li>Syntax highlighting support (via integration with <a
-      href="http://www.codento.com/people/mtr/genscript/">GNU
-      enscript</a> or
-      <a href="http://www.andre-simon.de/">Highlight</a>).</li>
-
-  <li><a href="http://www.mozilla.org/projects/bonsai/">Bonsai</a>-like
-      repository query facilities.</li>
-
-  <li>Template-driven output generation.</li>
-
-  <li>Colorized, side-by-side differences.</li>
-
-  <li>Tarball generation (by tag/branch for CVS, by revision for
-      Subversion).</li>
-
-  <li>I18N support based on the Accept-Language request header.</li>
-
-  <li>Ability to run either as CGI script or as a standalone
-      server.</li>
-  
-  <li>Regexp-based file searching.</li>
-
-  <li>INI-like configuration file (as opposed to requiring actual code
-      tweaks).</li>
-
-</ul>
-
-<p>For a complete list of changes present in each release, see
-   ViewVC's <a
-   href="http://viewvc.tigris.org/source/browse/viewvc/trunk/CHANGES?rev=HEAD"
-   >CHANGES</a> file.</p>
-
-</div>
-<div class="section">
-
-<h2 id="sec-requirements">Requirements</h2>
-
-<p>The only hard software requirement for running ViewVC is <a
-   href="http://www.python.org/">Python 1.5.2</a> or later.  All other
-   requirements depend on what you want to do with the tool.</p>
-
-<p>If you plan to use ViewVC with CVS repositories, you need the
-   following things:</p>
-
-<ul>
-
-  <li><a href="http://www.cs.purdue.edu/homes/trinkle/RCS/">RCS</a>
-      (Revision Control System)</li>
-
-  <li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU 
-      diff</a></li>
- 
-  <li>Read-only, physical access to a CVS repository.</li>
-
-</ul>
-
-<p>For use with Subversion repositories, you need these things:</p>
-
-<ul>
-
-  <li><a href="http://subversion.tigris.org/">Subversion</a> 1.2 or
-      later and its SWIG Python bindings.</li>
-
-  <li><a href="http://www.gnu.org/software/diffutils/diffutils.html">GNU 
-      diff</a></li>
-
-  <li>Physical access to a Subversion repository (though there is
-      limited, use-at-your-risk support for remote access, too).</li>
-
-</ul>
-
-<p>ViewVC integrates with additional pieces of software to provide
-   certain bits of optional functionality:</p>
-
-<ul>
-
-  <li><a href="http://www.mysql.com/">MySQL</a> — Needed to use
-      the commit database query functionality.</li>
-
-  <li><a href="http://www.codento.com/people/mtr/genscript/">GNU
-      enscript</a> — Needed for syntax highlighting in versioned
-      file contents displays</li>
-
-  <li><a href="http://www.akhphd.au.dk/~bertho/cvsgraph/">CvsGraph</a>
-      — Needed for version graph displays.</li>
-
-  <li><a href="http://httpd.apache.org/">Apache HTTP Server</a>, or
-      another server capable of running CGI programs — unless
-      you just want ViewVC to run in standalone server mode.</li>
-
-</ul>
-
-</div>
-<div class="section">
-
-<h2 id="sec-future">Future Plans</h2>
-
-<p>ViewVC is an Open Source project.  So any future development
-   depends on the <a href="./contributing.html">contributions</a> that
-   will be made by its user community.  Certainly working patches have
-   a greater chance to become realized quickly than feature requests,
-   but please don't hesitate to submit your suggestions to our <a
-   href="http://viewvc.tigris.org/servlets/ProjectIssues">issue
-   tracker</a>.</p>
-
-<p>Some things we're thinking about include:</p>
-
-<ul>
-  <li>UI streamlining/simplification.</li>
-  <li>Integration with CVS and Subversion commit mail scripts.</li>
-  <li>Integration with an indexer such as LXR.</li>
-</ul>
-
-</div>
-
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/license-1.html b/src/www/scm/viewvc/viewvc.org/license-1.html
deleted file mode 100644
index 931e973..0000000
--- a/src/www/scm/viewvc/viewvc.org/license-1.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: License v1</title>
-<link rel="stylesheet" type="text/css" href="./styles.css"/>
-</head>
-
-<body>
-
-<div id="title">
-<a href="http://www.viewvc.org/"><img 
-   src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
-</div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> |
-   <a href="http://viewvc.tigris.org/">Project Page</a> |
-   <a href="./download.html">Download</a> |
-   <a href="./upgrading.html">Upgrading</a> |
-   <a href="./contributing.html">Contributing</a> |
-   <a href="./license-1.html">License</a> |
-   <a href="./contact.html">Contact</a> |
-   <a href="./who.html">About</a>
-</p>
-</div>
-
-<table id="pagetable">
-<tr>
-<td id="pagecolumn1">
-
-<h4>On this page:</h4>
-
-<ul id="bookmarks">
-  <li><a href="#sec-license">License</a></li>
-</ul>
-
-<hr/>
-
-<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
-
-</td>
-<td id="pagecolumn2">
-
-<div class="section">
-
-<h2 id="sec-license">License</h2>
-
-<p>The following text constitutes the license agreement for the <a
-   href="./index.html">ViewVC</a> software (formerly known as
-   ViewCVS). It is an agreement between <a
-   href="./who.html#sec-viewcvs-group">The ViewCVS Group</a> and the
-   users of ViewVC.</p>
-
-<p style="font-size: 80%;"><em>Note: the copyright years were updated
-   on May 12, 2001 and September 5, 2002. No other changes were made
-   to the license.</em></p>
-
-<hr/>
-
-<p><strong>Copyright © 1999-2002 The ViewCVS Group.  All rights
-   reserved.</strong></p>
-
-<p>By using ViewVC, you agree to the terms and conditions set forth
-   below:</p>
-
-<p>Redistribution and use in source and binary forms, with or without
-   modification, are permitted provided that the following conditions
-   are met:</p>
-
-<ol>
-  <li>Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following
-      disclaimer.</li>
-  <li>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.</li>
-</ol>
-
-<p>THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
-   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-   TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR 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.</p>
-
-</div>
-
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/styles.css b/src/www/scm/viewvc/viewvc.org/styles.css
deleted file mode 100644
index 988ce26..0000000
--- a/src/www/scm/viewvc/viewvc.org/styles.css
+++ /dev/null
@@ -1,151 +0,0 @@
-body {
-    background-color: rgb(180,193,205);
-    background-image: url('./images/bg-grad.jpg');
-    background-repeat: repeat-x;
-    color: black;
-    font-family: arial, sans-serif;
-    font-size: 90%;
-    margin: 0;
-}
-
-#title {
-    background-color: rgb(100,128,150);
-    height: 60px;
-}
-
-img {
-    border: none;
-}
-
-hr {
-    width: 95%;
-    height: 1px;
-}
-
-address {
-    text-align: center;
-    font-size: 60%;
-    font-style: normal;
-}
-
-h2 {
-    background-color: rgb(204,213,221);
-    padding: 2px 0.5em 2px 0.5em;
-    margin: 0;
-    border-bottom: dotted 1px rgb(180,193,205);
-    font-size: 110%;
-}
-
-h3 {
-    padding: 2px 0.5em 2px 0.5em;
-    margin: 0;
-    font-size: 100%;
-    font-weight: bold;
-}
-
-h4 {
-    padding: 2px 0.5em 2px 0.5em;
-    margin: 0;
-    font-size: 90%;
-    font-weight: bold;
-}
-
-p, dl, ul, ol {
-    padding: 0.5em;
-    margin: 0;
-    font-size: 90%;
-}
-
-ul, ol {
-    padding: 0.5em;
-    margin: 0 0 0 0.25in;
-}
-
-li {
-    font-size: 90%;
-}
-
-code {
-    font-size: 105%;
-    font-style: italic;
-    font-family: monospace;
-}
-
-blockquote {
-    padding: 0.5em;
-    margin: 0 0.25in 0 0.25in;
-    font-size: 80%;
-}
-
-.section {
-    background: white;
-    border-color: rgb(24,24,24);
-    border-width: 1px 2px 2px 1px;
-    border-style: solid;
-    padding: 0;
-    margin-bottom: 0.5em;
-}
-
-#menu {
-    background: black;
-    color: white;
-}
-
-#menu a, #menu a:visited {
-    background: black;
-    color: white;
-    text-decoration: none;
-}
-
-#menu a:hover {
-    background: black;
-    color: white;
-    text-decoration: underline;
-}
-
-#submenu {
-    background: rgb(90%,97%,99%);
-    font-size: 80%;
-}
-
-#pagetable tr {
-    vertical-align: top;
-}
-
-#pagetable {
-    width: 100%;
-}
-
-#pagecolumn1 {
-    width: 175px;
-    padding: 0;
-}
-
-#pagecolumn1 a, #pagecolumn1 a:visited {
-    color: rgb(0,0,164);
-    text-decoration: none;
-}
-
-#pagecolumn1 a:hover {
-    text-decoration: underline;
-}
-
-#pagecolumn2 {
-    padding: 0;
-}
-
-#pagecolumn2 a, #pagecolumn2 a:visited {
-    color: rgb(0,0,164);
-    text-decoration: underline;
-}
-
-#pagecolumn2 a:hover {
-    background-color: rgb(180,193,205);
-    text-decoration: underline;
-}
-
-#bookmarks {
-    padding-left: 0.25in;
-    font-size: 80%;
-    white-space: nowrap;
-}
diff --git a/src/www/scm/viewvc/viewvc.org/template-authoring-guide.html b/src/www/scm/viewvc/viewvc.org/template-authoring-guide.html
deleted file mode 100644
index 39b8dc1..0000000
--- a/src/www/scm/viewvc/viewvc.org/template-authoring-guide.html
+++ /dev/null
@@ -1,2013 +0,0 @@
-<html>
-<head>
-<title>ViewVC 1.0 Template Authoring Guide</title>
-<style>
-body {
-	background-color: rgb(180, 193, 205);
-	color: black;
-	font-family: sans-serif;
-}
-
-table {
-	margin-left: 1em;
-}
-
-td,th {
-	padding: 0 0.5em;
-}
-
-th {
-	vertical-align: bottom;
-	background: rgb(60%, 70%, 90%);
-}
-
-td {
-	vertical-align: top;
-}
-
-.h2,.h3 {
-	padding: 0.5em 1em;
-	border-color: black;
-	border-style: solid;
-	margin-bottom: 1em;
-	background: white;
-}
-
-.h2 {
-	border-width: 1px 2px 2px 1px;
-}
-
-.h3 {
-	border-width: 1px 0 0 0;
-}
-
-.include {
-	background: rgb(55%, 80%, 55%);
-	font-style: italic;
-}
-
-.varlevel1 {
-	background: rgb(65%, 85%, 65%);
-}
-
-.varlevel2 {
-	background: rgb(70%, 90%, 70%);
-}
-
-.varlevel3 {
-	background: rgb(75%, 95%, 75%);
-}
-
-.varname {
-	font-family: monospace;
-}
-
-.varlevel1 .varname {
-	padding-left: 0;
-}
-
-.varlevel2 .varname {
-	padding-left: 2em;
-}
-
-.varlevel3 .varname {
-	padding-left: 4em;
-}
-
-.toc-list {
-	font-size: 90%;
-}
-</style>
-</head>
-<body>
-
-<h1>ViewVC 1.0 Template Authoring Guide</h1>
-
-<div class="h2">
-<h2 id="introduction">Introduction</h2>
-
-<p>This document represents an (unfinished) attempt at providing
-documentation for how to customize ViewVC 1.0-dev's HTML output via
-modification of its templates.</p>
-
-</div>
-
-<div class="h2">
-<h2 id="toc">Table of Contents</h2>
-<ul class="toc-list">
-	<li><a href="#introduction">Introduction</a></li>
-	<li><a href="#ezt">Using EZT</a></li>
-	<li><a href="#variables">Variables Available to ViewVC
-	Templates</a>
-	<ul class="toc-list">
-		<li><a href="#variables-common">Common Template Variable Set
-		(COMMON)</a></li>
-		<li><a href="#variables-navdata">File Navigation Variable Set
-		(NAVDATA)</a></li>
-		<li><a href="#variables-pathrev">Path Revision Form Variable
-		Set (PATHREV)</a></li>
-		<li><a href="#variables-paging">Paging Form Variable Set
-		(PAGING)</a></li>
-		<li><a href="#variables-annotate">Annotation View
-		(annotate.ezt)</a></li>
-		<li><a href="#variables-graph">Revision Graph View
-		(graph.ezt)</a></li>
-		<li><a href="#variables-diff">File Difference View (diff.ezt)</a></li>
-		<li><a href="#variables-directory">Directory Listing View
-		(directory.ezt)</a></li>
-		<li><a href="#variables-error">Error View (error.ezt)</a></li>
-		<li><a href="#variables-log">Revision Log View (log.ezt)</a></li>
-		<li><a href="#variables-markup">File Contents View
-		(markup.ezt)</a></li>
-		<li><a href="#variables-query_results">Revision History Query
-		Results View (query_results.ezt)</a></li>
-		<li><a href="#variables-query_form">Revision History Query
-		Form View (query_form.ezt)</a></li>
-		<li><a href="#variables-revision">Revision/ChangeSet View
-		(revision.ezt)</a></li>
-		<li><a href="#variables-roots">Root Listing View (roots.ezt)</a></li>
-	</ul>
-	</li>
-</ul>
-</div>
-
-<div class="h2">
-<h2 id="ezt">Using EZT</h2>
-
-<p>### TODO ###</p>
-
-</div>
-
-<div class="h2">
-<h2 id="variables">Variables Available to ViewVC Templates</h2>
-
-<div class="h3">
-<h3 id="variables-common">Common Template Variable Set (COMMON)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="varlevel1">
-			<td class="varname">cfg</td>
-			<td>Object</td>
-			<td>Representation of the object used by ViewVC for runtime
-			configuration parameters such as those parsed from <tt>viewvc.conf</tt>.
-			Dot-qualified children of this object map to configuration sections
-			and option keys. For example, <var>cfg.options.show_logs</var>
-			contains the value of the <var>show_logs</var> variable in the <var>options</var>
-			section of the configuration file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">change_root_action</td>
-			<td>String</td>
-			<td>Form action URL for the root selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">change_root_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the root selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">docroot</td>
-			<td>String</td>
-			<td>URL of the static documents directory, generally used for
-			referencing stylesheets and images stored in and under that directory
-			(which is typically relative to the template location).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">graph_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC revision graph view for the current
-			resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">kv</td>
-			<td>Object</td>
-			<td>Representation of the object used by ViewVC for user-defined
-			key/value mappings. Dot-qualified children of this object map to
-			named key/value files and the sections and keys within them. For
-			example, <var>kv.l10n.labels.directory</var> maps to the value of the
-			<var>directory</var> key under the <var>labels</var> section of the
-			key/value file whose configured abstract name is <var>l10n</var>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC revision log view for the current
-			resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log_rev_href</td>
-			<td>String</td>
-			<td>Revision number of the file-revision currently being viewed,
-			or None.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">nav_path</td>
-			<td>List</td>
-			<td>Ordered list of path components from the repository root to
-			the current resource.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">nav_path.href</td>
-			<td>String</td>
-			<td>URL of the default ViewVC view for the path component.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">nav_path.name</td>
-			<td>String</td>
-			<td>Name of the path component.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathtype</td>
-			<td>String</td>
-			<td>Path kind of the current resource. Valid values: <tt>file</tt>
-			(file), <tt>dir</tt> (directory); may be empty.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rootname</td>
-			<td>String</td>
-			<td>Name of the current repository (root).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">roots</td>
-			<td>List</td>
-			<td>Set of configured viewable repositories.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">roots.name</td>
-			<td>String</td>
-			<td>Name of a configured repository.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">roots.type</td>
-			<td>String</td>
-			<td>Version control type of a configured repository. Valid
-			values: <tt>cvs</tt>, <tt>svn</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">roots.href</td>
-			<td>String</td>
-			<td>URL of root directory view for a configured repository.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">roottype</td>
-			<td>String</td>
-			<td>Version control type of the current repository (root). Valid
-			values: <tt>cvs</tt> (CVS), <tt>svn</tt> (Subversion).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">up_href</td>
-			<td>String</td>
-			<td>Link to the current object's parent directory view.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">view</td>
-			<td>String</td>
-			<td>Name of the current view. Valid values: <tt>annotate</tt>
-			(annotation view), <tt>diff</tt> (file difference view), <tt>roots</tt>
-			(root listing view), <tt>dir</tt> (directory listing view), <tt>graph</tt>
-			(revision graph view), <tt>log</tt> (revision log view), <tt>markup</tt>
-			(file contents view), <tt>query</tt> (revision history query results
-			view), <tt>queryform</tt> (revision history query form view), <tt>rev</tt>
-			(revision/changeset view).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">vsn</td>
-			<td>String</td>
-			<td>ViewVC version identifier.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">where</td>
-			<td>String</td>
-			<td>Path (relative to the current repository root) of the
-			current resource.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-navdata">File Navigation Variable Set (NAVDATA)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">annotate_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC annotation view for the current resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">download_href</td>
-			<td>String</td>
-			<td>ViewVC file contents download URL for the current resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">download_text_href</td>
-			<td>String</td>
-			<td>ViewVC file contents as-text download URL for the current
-			resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">orig_path</td>
-			<td>String</td>
-			<td>When viewing an old file revision through a copy of the
-			file, this is the old file revision's original path.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">orig_href</td>
-			<td>String</td>
-			<td>URL of a ViewVC log view for <code>orig_path</code>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">prefer_markup</td>
-			<td>Boolean</td>
-			<td>Indicates whether to make the default file link a link to
-			the markup page instead of the checkout page.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rev</td>
-			<td>String</td>
-			<td>Revision of the current resource.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">revision_href</td>
-			<td>String</td>
-			<td>URL of the Subversion revision view for the current
-			revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rss_href</td>
-			<td>String</td>
-			<td>URL of RSS feed for current location.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">view_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC file contents view for the current
-			resource.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-pathrev">Path Revision Form Variable Set
-(PATHREV)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="varlevel1">
-			<td class="varname">lastrev</td>
-			<td>String</td>
-			<td>If the current path is deleted in a future revision, last
-			revision where the path is available. (Subversion only)</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathrev</td>
-			<td>String</td>
-			<td>Current sticky revision (Subversion) or sticky tag (CVS)</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathrev_action</td>
-			<td>String</td>
-			<td>Form action URL for the sticky revision/tag selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathrev_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the revision/tag selection
-			form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathrev_clear_action</td>
-			<td>String</td>
-			<td>Form action URL for the path revision clear button.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">pathrev_clear_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the path revision clear button.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-paging">Paging Form Variable Set (PAGING)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="varlevel1">
-			<td class="varname">picklist</td>
-			<td>List</td>
-			<td>List of pages that make up the current directory or log
-			view.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">picklist.start</td>
-			<td>String</td>
-			<td>Name of first item on the page</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">picklist.end</td>
-			<td>String</td>
-			<td>Name of last item on the page</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">picklist.page</td>
-			<td>String</td>
-			<td>Page number (indexed from 1)</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">picklist.count</td>
-			<td>String</td>
-			<td>Number of the first item on the page (indexed from 0)</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">picklist_len</td>
-			<td>String</td>
-			<td>Number of pages in <var>picklist</var></td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-annotate">Annotation View (annotate.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-navdata">NAVDATA</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">lines</td>
-			<td>List</td>
-			<td>Set of objects containing information about the most recent
-			modification of a single line of file content in the current
-			resource, naturally ordered by the line numbers they represent. Every
-			line in the resource is represented in the set.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.author</td>
-			<td>String</td>
-			<td>Username of the most recent modifier of the line.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.date</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) of the
-			modification of the line.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.diff_url</td>
-			<td>String</td>
-			<td>URL of the ViewVC file difference view which displays the
-			modification of the line.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.line_number</td>
-			<td>String</td>
-			<td>Line number (1-based) of the line.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.prev_rev</td>
-			<td>String</td>
-			<td>Youngest revision of the resource prior to the line's
-			modification.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.rev</td>
-			<td>String</td>
-			<td>Revision in which the modification of the line occured.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">lines.text</td>
-			<td>String</td>
-			<td>Textual contents of the line.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-graph">Revision Graph View (graph.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">imagemap</td>
-			<td>String</td>
-			<td>HTML markup containing the image map associated with the
-			revision graph.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">imagesrc</td>
-			<td>String</td>
-			<td>URL of the ViewVC revision graph image for the current
-			resource.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-diff">File Difference View (diff.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">annotate_href</td>
-			<td>String</td>
-			<td>URL for the annotate view of the right-side file revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">changes</td>
-			<td>List</td>
-			<td>Set of objects which contain information about a single line
-			of file difference data. Valid only when <var>diff_format</var> is <tt>h</tt>
-			or <tt>l</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.have_left</td>
-			<td>Boolean</td>
-			<td>Specifies whether the left file has a line of content
-			relevant to the difference data line. Valid only when <var>changes.type</var>
-			is <tt>change</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.have_right</td>
-			<td>Boolean</td>
-			<td>Specifies whether the right file has a line of content
-			relevant to the difference data line. Valid only when <var>changes.type</var>
-			is <tt>change</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.left</td>
-			<td>String</td>
-			<td>Textual contents of the relevant line in the left file.
-			Valid only when <var>changes.type</var> is <tt>change</tt>, <tt>context</tt>,
-			or <tt>remove</tt>. When <var>changes.type</var> is <tt>change</tt>,
-			valid only when <var>changes.have_left</var> is set (in order to
-			delineate between missing lines and empty lines, which EZT does not
-			support).</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.right</td>
-			<td>String</td>
-			<td>Textual contents of the relevant line in the right file.
-			Valid only when <var>changes.type</var> is <tt>add</tt>, <tt>change</tt>,
-			or <tt>context</tt>. When <var>changes.type</var> is <tt>change</tt>,
-			valid only when <var>changes.have_left</var> is set (in order to
-			delineate between missing lines and empty lines, which EZT does not
-			support).</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.line_info_extra</td>
-			<td>String</td>
-			<td>Additional line information for the current difference hunk.
-			Valid only when <var>changes.type</var> is <tt>header</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.line_info_left</td>
-			<td>String</td>
-			<td>First line number represented by the current hunk in the
-			left file. Valid only when <var>changes.type</var> is <tt>header</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.line_info_right</td>
-			<td>String</td>
-			<td>First line number represented by the current hunk in the
-			right file. Valid only when <var>changes.type</var> is <tt>header</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.line_number</td>
-			<td>String</td>
-			<td>Line number (1-based) of the line.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.type</td>
-			<td>String</td>
-			<td>The type of change. Value values: <tt>add</tt>, <tt>change</tt>,
-			<tt>context</tt>, <tt>header</tt>, <tt>no-changes</tt>, <tt>remove</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">date_left</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) in which the left
-			file revision was created.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">date_right</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) in which the right
-			file revision was created.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_format</td>
-			<td>String</td>
-			<td>Difference dislay format: Valid values are <tt>c</tt>
-			(context), <tt>h</tt> (human-readable, or colored), <tt>l</tt> (long
-			human-readable), <tt>s</tt> (side-by-side), <tt>u</tt> (unified).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_format_action</td>
-			<td>String</td>
-			<td>Form action URL for the diff format selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_format_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the diff format selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">raw_diff</td>
-			<td>String</td>
-			<td>Raw difference text. Valid only when <var>diff_format</var>
-			is <tt>c</tt>, <tt>s</tt>, or <tt>u</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rev_left</td>
-			<td>String</td>
-			<td>Revision of the left file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rev_right</td>
-			<td>String</td>
-			<td>Revision of the right file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_left</td>
-			<td>String</td>
-			<td>Tag of the left file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_right</td>
-			<td>String</td>
-			<td>Tag of the right file.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-directory">Directory Listing View (directory.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a>, <a href="#variables-pathrev">PATHREV</a>,
-			and <a href="#variables-paging">PAGING</a> variable sets</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">attic_showing</td>
-			<td>Boolean</td>
-			<td>Indicates whether or not the directory list include "dead"
-			files (files not available in, perhaps deleted from, the current
-			tag). CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branch_tags</td>
-			<td>List</td>
-			<td>Set of branch tag names in use by files in the current
-			directory. CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">dir_pagestart</td>
-			<td>String</td>
-			<td>Item number (zero-based) of the first directory entry
-			requested to be shown on the page. Corresponds to the <var>dir_pagestart</var>
-			CGI parameter.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">dir_paging_action</td>
-			<td>String</td>
-			<td>Form action URL for the page selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">dir_paging_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the page selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">entries</td>
-			<td>List</td>
-			<td>Set of objects which represent the entries of this
-			directory.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.ago</td>
-			<td>String</td>
-			<td>Textual description of the time since <var>entries.date</var>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.annotate_href</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.author</td>
-			<td>String</td>
-			<td>Username of the last modifier of the directory entry.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.date</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) of the last
-			modification of the directory entry.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.download_href</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.download_text_href</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.errors</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.graph_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC revision graph view for the directory
-			entry.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.log</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.log_file</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.log_href</td>
-			<td>String</td>
-			<td>URL of the ViewVC revision log view for the directory entry.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.log_rev</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.mime_type</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.name</td>
-			<td>String</td>
-			<td>Name of the directory entry.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.rev</td>
-			<td>String</td>
-			<td>Revision of the directory entry. For CVS repositories, this
-			is a revision at the tip of the selected tag or branch; for
-			Subversion, this is the youngest revision as of the revision of the
-			directory being viewed.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.revision_href</td>
-			<td>String</td>
-			<td>URL of the Subversion revision view for the directory
-			entries current revision. Valid only when <var>roottype</var> is <tt>svn</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.size</td>
-			<td>String</td>
-			<td>Size (in bytes) of the directory entry. Valid only when <var>roottype</var>
-			is <tt>svn</tt> and <var>entries.pathtype</var> is <tt>file</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.state</td>
-			<td></td>
-			<td></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.pathtype</td>
-			<td>String</td>
-			<td>Path kind of the directory entry. Valid values: <tt>file</tt>
-			(file), <tt>dir</tt> (directory); may be empty.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.prefer_markup</td>
-			<td>Boolean</td>
-			<td>Indicates whether to make the default file link a link to
-			the markup page instead of the checkout page. Valid only when <var>entries.pathtype</var>
-			is <tt>file</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.view_href</td>
-			<td></td>
-			<td>This is a URL for the markup view if the entry is a file,
-			and a URL for a directory listing if the entry is a directory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">files_shown</td>
-			<td>String</td>
-			<td>Number of files displayed.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">hide_attic_href</td>
-			<td>String</td>
-			<td>URL for the current view, but with "dead" files hidden. CVS
-			only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">num_dead</td>
-			<td>String</td>
-			<td>Number of dead files in the current directory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">plain_tags</td>
-			<td>List</td>
-			<td>List of tag names in use by files in the current directory.
-			CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">queryform_href</td>
-			<td>String</td>
-			<td>URL for a query form returning results from this directory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">search_re</td>
-			<td>String</td>
-			<td>Current search expression, if any.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">search_re_form</td>
-			<td>Boolean</td>
-			<td>Indicates whether or not to display the regular expression
-			search form. Value depends on the whether searching is enabled in the
-			configuration and whether or not the current directory is empty.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">search_re_action</td>
-			<td>String</td>
-			<td>Form action URL for the regular expression search form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">search_re_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the regular expression search
-			form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">show_attic_href</td>
-			<td>String</td>
-			<td>URL for the current view, but with "dead" files shown. CVS
-			only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby</td>
-			<td>String</td>
-			<td>Current sorting mode. Valid values: <tt>file</tt>, <tt>rev</tt>,
-			<tt>date</tt>, <tt>author</tt>, and <tt>log</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby_author_href</td>
-			<td>String</td>
-			<td>URL for the current view, but sorted by author.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby_date_href</td>
-			<td>String</td>
-			<td>URL for the current view, but sorted by date.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby_file_href</td>
-			<td>String</td>
-			<td>URL for the current view, but sorted by filename.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby_log_href</td>
-			<td>String</td>
-			<td>URL for the current view, but sorted by log message.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortby_rev_href</td>
-			<td>String</td>
-			<td>URL for the current view, but sorted by revision number.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sortdir</td>
-			<td>String</td>
-			<td>Current sorting mode. Valid values: <tt>up</tt> (ascending)
-			and <tt>down</tt> (descending)</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tarball_href</td>
-			<td>String</td>
-			<td>URL to download tarball of the current directory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tree_rev</td>
-			<td>String</td>
-			<td>Last revision number where the current directory (or any
-			path underneath it) was modified. Subversion only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tree_rev_href</td>
-			<td>String</td>
-			<td>URL for revision view showing information about the <var>tree_rev</var>
-			revision. Subversion only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">youngest_rev</td>
-			<td>String</td>
-			<td>Last revision number in the repository. Subversion only</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">youngest_rev_href</td>
-			<td>String</td>
-			<td>URL for revision view showing information about the <var>youngest_rev</var>
-			revision. Subversion only.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-error">Error View (error.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="varlevel1">
-			<td class="varname">msg</td>
-			<td>String</td>
-			<td>Message describing the current error.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">stacktrace</td>
-			<td>String</td>
-			<td>Python stack trace showing where the error occurred.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">status</td>
-			<td>String</td>
-			<td>HTTP status code like "404 Not Found" that was sent to the
-			browser with this error message.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-log">Revision Log View (log.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a>, <a href="#variables-pathrev">PATHREV</a>,
-			and <a href="#variables-paging">PAGING</a> variable sets</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">annotate_href</td>
-			<td>String</td>
-			<td>URL for annotate view of the HEAD revision of the file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branch_tags</td>
-			<td>List</td>
-			<td>Names of branch tags in the file. CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">default_branch</td>
-			<td>List</td>
-			<td>Default branch names (CVS only)</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_format</td>
-			<td>String</td>
-			<td>Currently selected diff format in the diff selection form.
-			Valid values are <tt>c</tt> (context), <tt>h</tt> (human-readable, or
-			colored), <tt>l</tt> (long human-readable), <tt>s</tt>
-			(side-by-side), <tt>u</tt> (unified).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_select_action</td>
-			<td>String</td>
-			<td>Form action URL for the diff selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">diff_select_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the diff selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">download_href</td>
-			<td>String</td>
-			<td>URL to download the HEAD revision of the file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">download_text_href</td>
-			<td>String</td>
-			<td>URL to download the HEAD revision of the file as <tt>text/plain</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">entries</td>
-			<td>List</td>
-			<td>List of revisions where the file or directory was modified.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.ago</td>
-			<td>String</td>
-			<td>Text description of the time elapsed since <var>entries.date</var>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.annotate_href</td>
-			<td>String</td>
-			<td>URL for the annotate view of the file revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.author</td>
-			<td>String</td>
-			<td>Author of the revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.branch_names</td>
-			<td>List</td>
-			<td>If this last revision on a branch, a list of names for that
-			branch.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.branch_point</td>
-			<td>String</td>
-			<td>If the revision is on a branch, this is the revision number
-			the branch branched off from. CVS only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.branch_points</td>
-			<td>String</td>
-			<td>List of branch tags which branch off of this revision. CVS
-			only.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.branch_points.name</td>
-			<td>String</td>
-			<td>Name of the branch tag.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.branch_points.href</td>
-			<td>String</td>
-			<td>URL for the current view, but with this tag set as the
-			sticky tag.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.branches</td>
-			<td>String</td>
-			<td>List of branch tags that include this file revision. CVS
-			only.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.branches.name</td>
-			<td>String</td>
-			<td>Name of the branch tag.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.branches.href</td>
-			<td>String</td>
-			<td>URL for the current view, but with this tag set as the
-			sticky tag.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.changed</td>
-			<td>String</td>
-			<td>Numbers of lines added and removed since the previous
-			revision. CVS only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.copy_href</td>
-			<td>String</td>
-			<td>URL for log view of <var>entries.copy_path</var>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.copy_path</td>
-			<td>String</td>
-			<td>If the file revision was copied from somewhere, this is the
-			path it was copied from. Subversion only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.copy_rev</td>
-			<td>String</td>
-			<td>If the file revision was copied from somewhere, this is the
-			revision number of the path it was copied from. Subversion only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.date</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) of the revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.diff_to_branch_href</td>
-			<td>String</td>
-			<td>URL for a diff view of this file revision showing the
-			changes since the branch was created at (<var>entries.branch_point</var>).
-			CVS only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.diff_to_main_href</td>
-			<td>String</td>
-			<td>If this revision is at the tip of a branch, URL for a diff
-			view of this file revision showing the differences between it and the
-			latest revision on the parent branch (<var>entries.next_main</var>).
-			CVS only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.diff_to_prev_href</td>
-			<td>String</td>
-			<td>URL for a diff view of this file revision showing the
-			changes since the previous revision (<var>entries.prev</var>).</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.diff_to_sel_href</td>
-			<td>String</td>
-			<td>URL for a diff view of this file revision and the currently
-			selected revision (<var>rev_selected</var>).</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.download_href</td>
-			<td>String</td>
-			<td>URL to download the file revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.download_text_href</td>
-			<td>String</td>
-			<td>URL to download the file revision as <tt>text/plain</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.log</td>
-			<td>String</td>
-			<td>Revision log message.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.next_main</td>
-			<td>String</td>
-			<td>If this revision is on the tip of the branch, this is the
-			latest revision of the parent branch, a likely merge candidate.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.orig_href</td>
-			<td>String</td>
-			<td>URL for log view of <var>entries.orig_path</var></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.orig_path</td>
-			<td>String</td>
-			<td>If this file revision is located at a different path than
-			the newest file revision (because it precedes a copy or move), this
-			is the path it was originally located at. Subversion only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.prefer_markup</td>
-			<td>Boolean</td>
-			<td>Indicates whether to make the default file link a link to
-			the markup page instead of the checkout page.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.prev</td>
-			<td>String</td>
-			<td>Previous revision number.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.rev</td>
-			<td>String</td>
-			<td>Revision number.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.revision_href</td>
-			<td>String</td>
-			<td>URL for revision view showing more information about the
-			revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.sel_for_diff_href</td>
-			<td>String</td>
-			<td>URL for current view, but with this revision selected for
-			diffs.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.size</td>
-			<td>String</td>
-			<td>Size of the file revision, in bytes. Subversion only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.state</td>
-			<td>String</td>
-			<td>State of the file revision. Possible values: <tt>dead</tt>,
-			and the empty string.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.tag_names</td>
-			<td>List</td>
-			<td>List of tag names which refer to the revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.tags</td>
-			<td>List</td>
-			<td>List of tags which refer to the revision</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.tags.name</td>
-			<td>String</td>
-			<td>Name of the tag.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">entries.tags.href</td>
-			<td>String</td>
-			<td>URL for the current page, but with this tag set as the
-			sticky tag.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.vendor_branch</td>
-			<td>Boolean</td>
-			<td>Indicates if this revision is on a vendor branch.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">entries.view_href</td>
-			<td>String</td>
-			<td>URL for markup view for a file revision, or directory
-			listing view for a directory revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">human_readable</td>
-			<td>Boolean</td>
-			<td>Indicates whether or not currently selected diff format (<var>diff_format</var>)
-			is human readable (colored).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log_pagestart</td>
-			<td>String</td>
-			<td>Item number (zero based) of the first directory entry
-			requested to be shown on the page. Corresponds to the <var>log_pagestart</var>
-			query parameter.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log_paging_action</td>
-			<td>String</td>
-			<td>Form action URL for the page selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log_paging_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the page selection form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">logsort</td>
-			<td>String</td>
-			<td>Current sorting mode. Possible values: <tt>date</tt> and <tt>rev</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">logsort_action</td>
-			<td>String</td>
-			<td>Form action URL for log sort drop down box.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">logsort_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for the log sort drop down box</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">mime_type</td>
-			<td>String</td>
-			<td>MIME type of current file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">plain_tags</td>
-			<td>List</td>
-			<td>Names of non-branch in the file. CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">prefer_markup</td>
-			<td>Boolean</td>
-			<td>Indicates whether to make the default file link a link to
-			the markup page instead of the checkout page.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rev_selected</td>
-			<td>String</td>
-			<td>Revision number currently selected for diffs.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_annotate_href</td>
-			<td>String</td>
-			<td>URL for annotate view of the file at currently selected
-			sticky tag.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_download_href</td>
-			<td>String</td>
-			<td>URL to download the file at currently selected sticky tag.
-			CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_download_text_href</td>
-			<td>String</td>
-			<td>URL to download the file as <tt>text/plain</tt> at the
-			currently selected sticky tag. CVS only</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">tag_prefer_markup</td>
-			<td>Boolean</td>
-			<td>Indicates whether to make the default file link a link to
-			the markup page instead of the checkout page.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tag_view_href</td>
-			<td>String</td>
-			<td>URL for markup view of the file at the currently selected
-			sticky tag. CVS only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tags</td>
-			<td>String</td>
-			<td>List of tags that in the current file. CVS only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">tags.rev</td>
-			<td>String</td>
-			<td>Revision number for a non-branch tag, or the latest revision
-			number on the branch for a branch tag.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">tags.name</td>
-			<td>String</td>
-			<td>Tag name</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">view_href</td>
-			<td>String</td>
-			<td>URL for markup view of the HEAD revision of the file.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-markup">File Contents View (markup.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-navdata">NAVDATA</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">ago</td>
-			<td>String</td>
-			<td>Text description of the time elapsed since <var>date</var>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">author</td>
-			<td>String</td>
-			<td>Author of the revision being viewed.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branch_points</td>
-			<td>String</td>
-			<td>List of branch tag names which branch off of the revision
-			being viewed (CVS only).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branches</td>
-			<td>List</td>
-			<td>If revision currently being viewed is on a branch, list of
-			names for the branch.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">changed</td>
-			<td>String</td>
-			<td>Numbers of lines added and removed since the previous
-			revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">date</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) of the revision
-			currently being viewed.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log</td>
-			<td>String</td>
-			<td>Log message of the revision currently being viewed.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">markup</td>
-			<td>File</td>
-			<td>Marked up contents of the current file revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">mime_type</td>
-			<td>String</td>
-			<td>MIME type of the current file.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">prev</td>
-			<td>String</td>
-			<td>Previous revision number.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">size</td>
-			<td>String</td>
-			<td>Size of the file revision, in bytes. Subversion only.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">state</td>
-			<td>String</td>
-			<td>State of the file revision. Possible values: <tt>dead</tt>,
-			and the empty string.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">tags</td>
-			<td>List</td>
-			<td>Names of tags that have been applied to the current file
-			revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">vendor_branch</td>
-			<td>Boolean</td>
-			<td>Indicates whether or not the current file revision is on a
-			vendor branch.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-query_results">Revision History Query Results
-View (query_results.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">backout_href</td>
-			<td>String</td>
-			<td>URL for a page that shows a list of commands that can be
-			applied to a working copy to revert all the changes returned by the
-			query.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">commits</td>
-			<td>List</td>
-			<td>List of commits to files under the current directory that
-			meet the query criteria.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.author</td>
-			<td>String</td>
-			<td>Author of the commit.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.files</td>
-			<td>List</td>
-			<td>List of files under the current directory affected by the
-			commit.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.author</td>
-			<td>String</td>
-			<td>Author of the commit.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.date</td>
-			<td>String</td>
-			<td>Date (in UTC if not otherwise configured) the change to the
-			file was committed.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.dir</td>
-			<td>String</td>
-			<td>Path of the directory containing the file.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.dir_href</td>
-			<td>String</td>
-			<td>URL for directory listing of <var>commits.files.dir</var>.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.file</td>
-			<td>String</td>
-			<td>File name.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.rev</td>
-			<td>String</td>
-			<td>Revision number of the file.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.branch</td>
-			<td>File</td>
-			<td>Branch the commit occurred on.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.diff_href</td>
-			<td>String</td>
-			<td>URL to diff page showing changes since previous file
-			revision.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.log_href</td>
-			<td>String</td>
-			<td>URL for file's log page.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.minus</td>
-			<td>String</td>
-			<td>Number of lines removed from the file by the commit.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.plus</td>
-			<td>String</td>
-			<td>Number of lines added to the file by the commit.</td>
-		</tr>
-		<tr class="varlevel3">
-			<td class="varname">commits.files.type</td>
-			<td>String</td>
-			<td>Type of change made to the file by the commit. Possible
-			values: <tt>Change</tt>, <tt>Add</tt>, <tt>Remove</tt></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.log</td>
-			<td>String</td>
-			<td>Commit log message.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.limited_files</td>
-			<td>Boolean</td>
-			<td>True if files list was cut short due to <tt>limit_changes</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.num_files</td>
-			<td>String</td>
-			<td>Number of files in the <var>commits.files</var> list.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.rev</td>
-			<td>String</td>
-			<td>Commit revision number. Subversion only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.rss_date</td>
-			<td>String</td>
-			<td>Date of the commit formatted for RSS.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.rss_url</td>
-			<td>String</td>
-			<td>Absolute URL of the revision page for the commit. Subversion
-			only.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">commits.short_log</td>
-			<td>String</td>
-			<td>Truncated commit log message.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">english_query</td>
-			<td>String</td>
-			<td>Text description of the current query criteria.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">limit_changes</td>
-			<td>String</td>
-			<td>Current <tt>limit_changes</tt> value, maximum number of
-			changed files to show per commit.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">limit_changes_href</td>
-			<td>String</td>
-			<td>URL for the current view but with <tt>limit_changes</tt>
-			disabled.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">minus_count</td>
-			<td>String</td>
-			<td>Total number of lines removed in the commit (over all
-			files).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">plus_count</td>
-			<td>String</td>
-			<td>Total number of lines added in the commit (over all files).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">queryform_href</td>
-			<td>String</td>
-			<td>URL for form to edit query criteria.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">querysort</td>
-			<td>String</td>
-			<td>Indicates how query results are being sorted. Possible
-			values: <tt>date</tt>, <tt>author</tt>, and <tt>file</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">show_branch</td>
-			<td>Boolean</td>
-			<td>Indicates whether or not to list branch names in the
-			results. True when query results can include more than a single
-			branch.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">sql</td>
-			<td>String</td>
-			<td>SQL string used to query database. Included for debugging
-			purposes.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-query_form">Revision History Query Form View
-(query_form.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branch</td>
-			<td>String</td>
-			<td>Query string for filtering results by branch.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">branch_match</td>
-			<td>String</td>
-			<td>Type of match to perform with <var>branch</var> query
-			string. Valid values: <tt>exact</tt>, <tt>like</tt>, <tt>glob</tt>, <tt>regex</tt>,
-			<tt>notregex</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">date</td>
-			<td>String</td>
-			<td>Option for filtering results by date. Possible values: <tt>hours</tt>,
-			<tt>day</tt>, <tt>week</tt>, <tt>month</tt>, <tt>all</tt>, <tt>explicit</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">dir</td>
-			<td>String</td>
-			<td>Query string for filtering results by subdirectory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">dir_href</td>
-			<td>String</td>
-			<td>URL for directory list of current directory.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">file</td>
-			<td>String</td>
-			<td>Query string for filtering results by file name.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">file_match</td>
-			<td>String</td>
-			<td>Type of match to perform with <var>file</var> query string.
-			Valid values: <tt>exact</tt>, <tt>like</tt>, <tt>glob</tt>, <tt>regex</tt>,
-			<tt>notregex</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">hours</td>
-			<td>String</td>
-			<td>If <var>date</var> is <tt>hours</tt>, number of hours back
-			to include results from.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">limit_changes</td>
-			<td>String</td>
-			<td>Current <tt>limit_changes</tt> value, maximum number of
-			changed files to show per commit.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">maxdate</td>
-			<td>String</td>
-			<td>If <var>date</var> is <tt>explicit</tt>, latest date to
-			include results from.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">mindate</td>
-			<td>String</td>
-			<td>If <var>date</var> is <tt>explicit</tt>, earliest date to
-			include results from.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">query_action</td>
-			<td>String</td>
-			<td>Form action URL for query form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">query_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for query form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">querysort</td>
-			<td>String</td>
-			<td>Option for sorting query results. Possible values: <tt>date</tt>,
-			<tt>author</tt>, and <tt>file</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">who</td>
-			<td>String</td>
-			<td>Query string for filtering results by author.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">who_match</td>
-			<td>String</td>
-			<td>Type of match to perform with <var>who</var> query string.
-			Possible values: <tt>exact</tt>, <tt>like</tt>, <tt>glob</tt>, <tt>regex</tt>,
-			<tt>notregex</tt>.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-revision">Revision/ChangeSet View (revision.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">ago</td>
-			<td>String</td>
-			<td>Text description of the time elapsed since <var>date</var>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">author</td>
-			<td>String</td>
-			<td>Author of the revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">changes</td>
-			<td>List</td>
-			<td>List of paths changed in this revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.action</td>
-			<td>String</td>
-			<td>Indicates what happened to the path in this revision. Valid
-			values are: <tt>added</tt>, <tt>modified</tt>, <tt>replaced</tt>, and
-			<tt>deleted</tt>.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.copy_path</td>
-			<td>String</td>
-			<td>Original path if path was copied from somewhere in this
-			revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.copy_rev</td>
-			<td>String</td>
-			<td>Revision number of original path if path was copied from
-			somewhere in this revision</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.diff_href</td>
-			<td>String</td>
-			<td>URL for diff of changed path against previous revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.is_copy</td>
-			<td>Boolean</td>
-			<td>Indicates whether path was copied from another path in this
-			revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.log_href</td>
-			<td>String</td>
-			<td>URL for log view of changed path.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.path</td>
-			<td>String</td>
-			<td>Changed path.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.pathtype</td>
-			<td>String</td>
-			<td>Type of changed path. Valid values: <tt>file</tt> or <tt>dir</tt></td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.prop_mods</td>
-			<td>Boolean</td>
-			<td>Indicates whether the path's properties changed in this
-			revision</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.text_mods</td>
-			<td>Boolean</td>
-			<td>Indicates whether the path's file contents changed in this
-			revision.</td>
-		</tr>
-		<tr class="varlevel2">
-			<td class="varname">changes.view_href</td>
-			<td>String</td>
-			<td>URL for markup view of changed path.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">date</td>
-			<td>String</td>
-			<td>Revision date (in UTC if not otherwise configured).</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">first_changes</td>
-			<td>String</td>
-			<td>Configured value for <tt>limit_changes</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">first_changes_href</td>
-			<td>String</td>
-			<td>URL for the current view but with <tt>limit_changes</tt> set
-			to the configured value.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">jump_rev_action</td>
-			<td>String</td>
-			<td>Form action URL for revision jump form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">jump_rev_hidden_values</td>
-			<td>String</td>
-			<td>Hidden value HTML markup for revision jump form.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">limit_changes</td>
-			<td>String</td>
-			<td>Current <tt>limit_changes</tt> value, maximum number of
-			changed files to show per commit.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">log</td>
-			<td>String</td>
-			<td>Revision log message.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">more_changes</td>
-			<td>String</td>
-			<td>Number of changes not being shown due to <tt>limit_changes</tt>.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">more_changes_href</td>
-			<td>String</td>
-			<td>URL for the current view but with <tt>limit_changes</tt>
-			disabled.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">next_href</td>
-			<td>String</td>
-			<td>URL for revision page of the next revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">prev_href</td>
-			<td>String</td>
-			<td>URL for revision page of the previous revision.</td>
-		</tr>
-		<tr class="varlevel1">
-			<td class="varname">rev</td>
-			<td>String</td>
-			<td>Revision number.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h3">
-<h3 id="variables-roots">Root Listing View (roots.ezt)</h3>
-<table>
-	<thead>
-		<tr>
-			<th>Variable</th>
-			<th>Type</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr class="include">
-			<td colspan="3">Includes all variables from the <a
-				href="#variables-common">COMMON</a> variable set</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-</div>
-</body>
-
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/upgrading.html b/src/www/scm/viewvc/viewvc.org/upgrading.html
deleted file mode 100644
index 5d93c5f..0000000
--- a/src/www/scm/viewvc/viewvc.org/upgrading.html
+++ /dev/null
@@ -1,1154 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<title>ViewVC: Upgrading</title>
-<link rel="stylesheet" type="text/css" href="./styles.css"/>
-<style>
-.varname { font-family: monospace; }
-.unchanged { background: rgb(50%,75%,50%); }
-.renamed { background: rgb(75%,100%,75%); }
-.changed { background: rgb(100%,100%,25%); }
-.replaced { background: rgb(100%,75%,0%); }
-.removed { background: rgb(100%,25%,25%); }
-</style>
-</head>
-
-<body>
-
-<div id="title">
-<a href="http://www.viewvc.org/"><img 
-   src="./images/title.jpg" alt="ViewVC: Repository Browsing"/></a>
-</div>
-
-<div id="menu">
-<p><a href="./index.html">Home</a> |
-   <a href="http://viewvc.tigris.org/">Project Page</a> |
-   <a href="./download.html">Download</a> |
-   <a href="./upgrading.html">Upgrading</a> |
-   <a href="./contributing.html">Contributing</a> |
-   <a href="./license-1.html">License</a> |
-   <a href="./contact.html">Contact</a> |
-   <a href="./who.html">About</a>
-</p>
-</div>
-
-<table id="pagetable">
-<tr>
-<td id="pagecolumn1">
-
-<h4>On this page:</h4>
-
-<ul id="bookmarks">
-  <li><a href="#sec-upgrading">Upgrading Basics</a></li>
-  <li><a href="#sec-from-0-9">Upgrading from 0.9</a></li>
-  <li><a href="#sec-from-0-8">Upgrading from 0.8</a></li>
-</ul>
-
-<hr/>
-
-<address><a href="mailto:&#117&#115&#101&#114&#115&#64&#118&#105&#101&#119&#118&#99&#46&#116&#105&#103&#114&#105&#115&#46&#111&#114&#103">ViewVC Users Group</a></address>
-
-</td>
-<td id="pagecolumn2">
-
-<div class="section">
-
-<h2 id="sec-upgrading">Upgrading Basics</h2>
-
-<p>This document describes some of the things that you will need to 
-   consider, change, or handle when upgrading an existing ViewVC
-   or ViewCVS installation to a newer version.</p>
-
-<p>Upgrading from an ancient version to the latest version
-   isn't necessarily a multi step process.  The instructions are only
-   organized that way.  You can certainly upgrade in a single step.</p>
-
-<p>It is always recommended to install the new version in a fresh
-   directory and to carefully compare the configuration files.  A
-   possible approach is to name the directories
-   <code>/usr/local/viewvc-1.0</code>,
-   <code>/usr/local/viewcvs-1.1</code> and so on and than create a
-   symbolic link <code>viewvc</code> pointing to the production
-   version.  This way you can easily test several versions and switch
-   back if your users start to complain.</p>
-
-</div>
-<div class="section">
-
-<h2 id="sec-from-0-9">Upgrading From ViewCVS 0.9</h2>
-
-<p>This section discusses how to upgrade ViewCVS 0.9 to ViewVC 1.0.</p>
-
-<h3>CGI Stubs</h3>
-    
-<p>The CGI stub scripts haved been moved from
-   <code><VIEWVC_INSTALLATION_DIRECTORY>/cgi/</code> to
-   <code><VIEWVC_INSTALLATION_DIRECTORY>/bin/cgi/</code>, so
-   you will need update any ScriptAlias directives pointing to them in
-   your apache configuration. Also, the contents of these scripts have
-   changed, so you may need to replace copies of the old scripts you
-   put in other directories.</p>
-
-<h3>Checkin Database</h3>
-    
-<p>ViewVC 1.0 reads and writes commit times in the MySQL database in
-   UTC time rather than local time. This can cause times displayed on
-   the query page to be a few hours off if an old database is being
-   used with a new version of ViewVC.  The best way to fix this is to
-   rebuild the database with the new version of cvsdbadmin, but it
-   is also possible to enable a backwards compatibility mode by
-   setting <code>utc_time = 0</code> at the top of lib/dbi.py</p>
-
-<h3>"checkout_magic" Option</h3>
-
-<p>In ViewVC 1.0, the <code>checkout_magic</code> option has been
-   disabled by default to provide a simpler URL scheme that works
-   safely with URL authorization. Most users will not notice any
-   difference in behavior, but users who had been using ViewCVS to
-   browse the contents of static HTML pages stored in a repository
-   may notice that links and images in those pages targetted at other
-   files in the repository no longer display correctly. The new
-   <code>default_file_view</code> option can be used to solve this
-   problem and, if neccessary, <code>checkout_magic</code> can also
-   be re-enabled. The <code>viewcvs.conf</code> file describes these
-   options in detail.</p>
-
-<h3>Configuration Options</h3>
-
-<p>The following options have been added:</p>
-
-<ul>
-  <li>general/svn_roots</li>
-  <li>general/root_parents</li>
-  <li>general/use_rcsparse</li>
-  <li>general/cvsnt_exe_path</li>
-  <li>options/template_dir</li>
-  <li>options/docroot</li>
-  <li>options/http_expiration_time</li>
-  <li>options/generate_etags</li>
-  <li>options/root_as_url_component</li>
-  <li>options/default_file_view</li>
-  <li>options/sort_group_dirs</li>
-  <li>options/use_pagesize</li>
-  <li>options/limit_changes</li>
-  <li>options/use_localtime</li>
-  <li>options/cross_copies</li>
-  <li>options/use_highlight</li>
-  <li>options/highlight_path</li>
-  <li>options/highlight_line_numbers</li>
-  <li>options/highlight_convert_tabs</li>
-  <li>options/use_php</li>
-  <li>options/php_path</li>
-  <li>options/svn_path</li>
-  <li>templates/error</li>
-  <li>templates/query_form</li>
-  <li>templates/query_results</li>
-  <li>cvsdb/port</li>
-  <li>cvsdb/rss_row_limit</li>
-</ul>
-
-<p>The following options have been removed:</p>
-
-<ul>
-  <li>general/main_title</li>
-  <li>options/diff_font_face</li> 
-  <li>options/diff_font_size</li>
-  <li>options/disable_enscript_lang</li>
-  <li>templates/footer</li>
-</ul>
-
-<h3>Templates</h3>
-    
-<p>The templates have changed drastically in this version of ViewVC.
-   If you are using customized templates from 0.9 or earlier, you will want
-   to port your old customizations to the new template files instead of
-   trying to get the old template files to work with the new ViewVC.</p>
-
-<p>There is a new <a href="template-authoring-guide.html">Template
-   Authoring Guide</a> for ViewVC 1.0 templates that can help you
-   with your customizations. And the chart below lists all 0.9 
-   template variables and shows what's become of them in 1.0.</p>
-
-<table>
-<thead>
-<tr>
-  <th>Variable</th>
-  <th>Location</th>
-  <th>Changes</th>
-</tr>
-</thead>
-<tbody>
-<tr class="unchanged">
-  <td class="varname">ago</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">author</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">back_url</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>replaced by <code>up_href</code>, which doesn't include the current #file anchor</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">branch</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>replaced by <code>default_branch</code>, which is a list instead of a string</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">branch</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">branch_names</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>branch_tags</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">branch_points</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">branch_tags</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">branches</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">cfg.general.address</td>
-  <td>footer.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="removed">
-  <td class="varname">cfg.general.main_title</td>
-  <td>dir_alternate.ezt, directory.ezt, query.ezt</td>
-  <td>removed, used to be a string from the configuration file that was shown in the title of the root directory page.</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">cfg.options.use_cvsgraph</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">cfg.options.use_re_search</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">changed</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="changed">
-  <td class="varname">changes</td>
-  <td>diff.ezt</td>
-  <td>attributes changed, see below</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">changes.extra</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>changes.line_info_extra</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">changes.have_left</td>
-  <td>diff.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">changes.have_right</td>
-  <td>diff.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">changes.left</td>
-  <td>diff.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">changes.line1</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>changes.line_info_left</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">changes.line2</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>changes.line_info_right</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">changes.right</td>
-  <td>diff.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="changed">
-  <td class="varname">changes.type</td>
-  <td>diff.ezt</td>
-  <td>new values <code>binary_diff</code> and <code>error</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.desc</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.author</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.branch</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.date</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.link</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.minus</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.plus</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">commits.files.rev</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">current_root</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>rootname</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">date</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">date1</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>date_left</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">date2</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>date_right</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">diff_format</td>
-  <td>diff.ezt, log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">directory</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="changed">
-  <td class="varname">entries</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>attributes changed, see below</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.ago</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.author</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branch_names</td>
-  <td>log.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branch_point</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branch_points</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branch_points.href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branch_points.name</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branches</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branches.href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.branches.name</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.changed</td>
-  <td>log.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">entries.href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>entries.download_href</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">entries.html_log</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>entries.log</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.next_main</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.prev</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.rev</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.state</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.tag_names</td>
-  <td>log.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.tags</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.tags.href</td>
-  <td>log.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.tags.name</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">entries.text_href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>entries.download_text_href</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">entries.to_selected</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>combined into <code>diff_to_sel_href</code> variable</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">entries.utc_date</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>entries.date</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.vendor_branch</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">entries.view_href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">file</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">file_url</td>
-  <td>header.ezt</td>
-  <td>renamed to <code>log_href</code></td>
-</tr>
-<tr class="removed">
-  <td class="varname">filename</td>
-  <td>header.ezt</td>
-  <td>removed, used to be set to the name of the file being shown</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">files_shown</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">graph_href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="removed">
-  <td class="varname">has_tags</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>removed, used to be a boolean that was true when either tag information was available from the current directory or a tag was set. Determined whether or not to show a tag selector box on the bottom of the directory page.</td>
-</tr>
-<tr class="removed">
-  <td class="varname">have_logs</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>removed, used to be a boolean that was true whenever any logs were being shown in a directory listing. When it was false the template code would omit the log column from the directory table.</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">head_abs_href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>download_href</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">head_href</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>replaced by <code>view_href</code> and <code>download_href</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">hidden_values</td>
-  <td>diff.ezt, log.ezt, log_table.ezt</td>
-  <td>combined into <code>*_hidden_values</code> variables</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">hide_attic_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">hours</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">href</td>
-  <td>log.ezt, log_table.ezt</td>
-    <td>combined into <code>*_href</code> variables</td>
-  </tr>
-  <tr class="renamed">
-    <td class="varname">href</td>
-    <td>markup.ezt</td>
-    <td>renamed to <code>download_href</code></td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">human_readable</td>
-    <td>log.ezt, log_table.ezt</td>
-    <td>unchanged</td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">imagemap</td>
-    <td>graph.ezt</td>
-    <td>unchanged</td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">log</td>
-    <td>markup.ezt</td>
-    <td>unchanged</td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">logsort</td>
-    <td>log.ezt, log_table.ezt</td>
-    <td>unchanged</td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">mime_type</td>
-    <td>log.ezt, log_table.ezt, markup.ezt</td>
-    <td>unchanged</td>
-  </tr>
-  <tr class="replaced">
-    <td class="varname">nav_file</td>
-    <td>markup.ezt</td>
-    <td>replaced with <code>nav_path</code></td>
-  </tr>
-  <tr class="changed">
-    <td class="varname">nav_path</td>
-    <td>dir_alternate.ezt, directory.ezt, header.ezt, log.ezt, log_table.ezt</td>
-    <td>changed from a block of HTML to a list of path components</td>
-  </tr>
-  <tr class="removed">
-    <td class="varname">no_match</td>
-    <td>dir_alternate.ezt, directory.ezt</td>
-    <td>removed, used to be a boolean that was true when a directory contained files, but none of them could be displayed due to regular expression or view tag filtering. Would trigger an error message.</td>
-  </tr>
-  <tr class="unchanged">
-    <td class="varname">num_commits</td>
-    <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="removed">
-  <td class="varname">num_files</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>removed, used to be a count of files in a directory, including dead and filtered files. This number was only shown in the <code>no_match</code> error message.</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">params</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>replaced by <code>search_re_hidden_values</code></td>
-</tr>
-<tr class="removed">
-  <td class="varname">path</td>
-  <td>header.ezt</td>
-  <td>removed, used to be set to the directory path of the file being shown</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">plain_tags</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">prev</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">qquery</td>
-  <td>header.ezt</td>
-  <td>combined into <code>log_href</code> variable</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">qquery</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>replaced by <code>diff_select_hidden_values</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">query</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>combined into <code>*_href</code> variables</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">query</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">repository</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">request.amp_query</td>
-  <td>graph.ezt</td>
-  <td>combined into <code>imagesrc</code> variable</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">request.script_name</td>
-  <td>dir_alternate.ezt, directory.ezt, log.ezt, log_table.ezt</td>
-  <td>combined into <code>*_href</code> variables</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">request.url</td>
-  <td>diff.ezt</td>
-  <td>combined into <code>diff_format_action</code> variable</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">request.url</td>
-  <td>graph.ezt</td>
-  <td>combined into <code>imagesrc</code> variable</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">request.where</td>
-  <td>graph.ezt</td>
-  <td>renamed to just <code>where</code></td>
-</tr>
-<tr class="removed">
-  <td class="varname">rev</td>
-  <td>graph.ezt</td>
-  <td>removed, used to be set to the value of the "graph" parameter in CvsGraph page urls. The value was passed on through the <code>rev</code> parameter to CvsGraph image URLs, where, oddly enough, it was ignored. It'd be set to a file revision number in directory page graph links, and just "1" in log page graph links.</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">rev</td>
-  <td>graph.ezt, header.ezt, markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rev1</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>rev_left</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rev2</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>rev_right</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">rev_selected</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="changed">
-  <td class="varname">roots</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>changed to a list of objects instead of a list of strings</td>
-</tr>
-<tr class="replaced">
-  <td class="varname">rows</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>replaced by <code>entries</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.anchor</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.anchor</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.author</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.author</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">rows.cvs</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>replaced by <code>entries.errors</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.graph_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.graph_href</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.log_href</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.log</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.log</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.log_file</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.log_file</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.log_rev</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.log_rev</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.name</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.name</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.rev</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.rev</code></td>
-</tr>
-<tr class="replaced">
-  <td class="varname">rows.rev_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>replaced by <code>entries.view_href</code> and <code>entries.download_href</code></td>
-</tr>
-<tr class="removed">
-  <td class="varname">rows.show_log</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>removed, used to be a boolean that was true whenever a log message was present for the directory entry.</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.state</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.state</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.time</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.ago</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">rows.type</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>entries.pathtype</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">search_re</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">selection_form</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>renamed to <code>search_re_form</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">show_attic_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby</td>
-  <td>dir_alternate.ezt, directory.ezt, query.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby_author_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby_date_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby_file_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby_log_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">sortby_rev_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">state</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">tag</td>
-  <td>markup.ezt</td>
-  <td>renamed to <code>pathrev</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">tag1</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>tag_left</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">tag2</td>
-  <td>diff.ezt</td>
-  <td>renamed to <code>tag_right</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tags</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tags</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tags.name</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tags.rev</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tags</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">tarball_href</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">text_href</td>
-  <td>markup.ezt</td>
-  <td>renamed to <code>download_text_href</code></td>
-</tr>
-<tr class="removed">
-  <td class="varname">tr1</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>removed, used to be a default value for the first text field in the diff selector form. In 1.0, the default value is computed in the templates.</td>
-</tr>
-<tr class="removed">
-  <td class="varname">tr2</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>removed, used to be a default value for the second text field in the diff selector form. In 1.0, the default value is computed in the templates.</td>
-</tr>
-<tr class="removed">
-  <td class="varname">unreadable</td>
-  <td>dir_alternate.ezt, directory.ezt</td>
-  <td>removed, used to be a boolean that was true whenever any of the files in the directory listing were 'unreadable.' It would trigger a generic error message at the bottom of the page.</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">utc_date</td>
-  <td>markup.ezt</td>
-  <td>renamed to <code>date</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">vendor_branch</td>
-  <td>markup.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="renamed">
-  <td class="varname">view_tag</td>
-  <td>dir_alternate.ezt, directory.ezt, log.ezt, log_table.ezt</td>
-  <td>renamed to <code>pathrev</code></td>
-</tr>
-<tr class="renamed">
-  <td class="varname">viewable</td>
-  <td>log.ezt, log_table.ezt</td>
-  <td>renamed to <code>prefer_markup</code></td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">vsn</td>
-  <td>footer.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">where</td>
-  <td>diff.ezt, dir_alternate.ezt, directory.ezt, log.ezt, log_table.ezt</td>
-  <td>unchanged</td>
-</tr>
-<tr class="unchanged">
-  <td class="varname">who</td>
-  <td>query.ezt</td>
-  <td>unchanged</td>
-</tr>
-</tbody>
-</table>
-
-<h4>Template Arrangement</h4>
-    
-<p>The default templates have been rearranged a bit in ViewVC 1.0.
-   Specifically, "header.ezt" and "footer.ezt" have moved into the
-   "templates/include/" subdirectory.  Also, "directory.ezt" and
-   "dir_alternate.ezt" now reference new template files
-   "dir_header.ezt" and "dir_footer.ezt", also found in the
-   "templates/include/" subdirectory.</p>
-
-<p>Notably, the "markup.ezt" and "annotate.ezt" templates are now
-   fully self-contained.  That is, the markup and annotation data
-   generated by ViewVC is now accessible in those templates just like
-   other template variables.  As a result, ViewVC now has no more
-   internal need for the <var>templates.footer</var> configuration
-   variable, so that variable has been removed from the default
-   configuration file.</p>
-
-</div>
-<div class="section">
-
-<h2 id="sec-from-0-8">Upgrading From ViewCVS 0.8</h2>
-
-    <p>
-      This section discusses how to upgrade ViewCVS 0.8 to version
-      0.9 or a later version of the software.
-    </p>
-    
-    <p>
-      <strong>NOTE:</strong> these changes will bring you up to the
-      requirements of version 0.9. You must also follow the directions
-      for <a href="#from9">upgrading from 0.9</a>.
-    </p>
-
-    <h3>Configuration Options</h3>
-    <p>
-      More templates were introduced in version 0.8 of the software,
-      which made many of the configuration options obsolete. This
-      section covers which options were removed. If you made any
-      changes to these options, then you will need to make
-      corresponding changes in the templates.
-    </p>
-
-      <dl>
-	<dt>
-	  Colors:
-	  <strong>diff_heading</strong>,
-	  <strong>diff_empty</strong>,
-	  <strong>diff_remove</strong>,
-	  <strong>diff_change</strong>,
-	  <strong>diff_add</strong>,
-	  and <strong>diff_dark_change</strong>
-	</dt>
-	<dd>
-	  These options have been incorporated into the
-	  <code>diff.ezt</code> template.
-
-	  <p></p>
-	</dd>
-
-	<dt><strong>markup_log</strong></dt>
-	<dd>
-	  This option has been incorporated into the
-	  <code>markup.ezt</code> template.
-
-	  <p></p>
-	</dd>
-
-        <dt>Colors: <strong>nav_header</strong>
-          and <strong>alt_background</strong></dt>
-	<dd>
-	  These options have been incorporated into the
-	  <code>header.ezt</code> template.
-
-	  <p></p>
-	</dd>
-
-        <dt>
-	  Images:
-          <strong>back_icon</strong>,
-          <strong>dir_icon</strong>,
-          and <strong>file_icon</strong>
-        </dt>
-	<dd>
-	  These options have been incorporated into the
-	  <code>directory.ezt</code>, <code>header.ezt</code>,
-	  <code>log.ezt</code>, <code>log_table.ezt</code>, and
-	  <code>query.ezt</code> templates.
-
-	  <p></p>
-	</dd>
-
-	<dt><strong>use_java_script</strong>
-          and <strong>open_extern_window</strong></dt>
-	<dd>
-	  The templates now use JavaScript in all applicable places,
-	  and open external windows for most downloading and viewing
-	  of files. If you wish to not use JavaScript and/or external
-	  windows, then remove the feature(s) from the templates.
-
-	  <p></p>
-	</dd>
-
-	<dt><strong>show_author</strong></dt>
-	<dd>
-          Changing this option would be quite strange and rare. If you
-          do not want to show the author for the revisions, then you
-          should remove it from the various templates.
-
-	  <p></p>
-	</dd>
-
-	<dt><strong>hide_non_readable</strong></dt>
-	<dd>
-          This option was never used, so it has been removed.
-
-	  <p></p>
-	</dd>
-
-	<dt><strong>flip_links_in_dirview</strong></dt>
-	<dd>
-          This option is no longer available. If you want the links in
-          your directory view flipped, then you may use the
-          <code>dir_alternate.ezt</code> template.
-
-	  <p></p>
-	</dd>
-
-      </dl>
-
-    <h3>Template Variables</h3>
-    <p>
-      Some template variables that were available in 0.8 have been
-      removed in 0.9. If you have custom templates that refer to these
-      variables, then you will need to modify your templates.
-    </p>
-
-	    <dl>
-	      <dt><code>directory.ezt</code>: <var>headers</var></dt>
-	      <dd>
-		The headers are now listed explicitly in the template,
-		rather than made available through a list.
-		<p></p>
-	      </dd>
-
-	      <dt>
-		<code>directory.ezt</code>:
-		<var>rows.cols</var>,
-		and <var>rows.span</var>
-	      </dt>
-	      <dd>
-		These variables were used in conjunction with the
-		<var>headers</var> variable to control the column
-		displays. This is now controlled explicitly within the
-		templates.
-		<p></p>
-	      </dd>
-
-	      <dt><code>directory.ezt</code>:
-		<var>rev_in_front</var></dt>
-	      <dd>
-		This was used to indicate that revision links should
-		be used in the first column, rather than in their
-		standard place in the second column. Changing the
-		links should now be done in the template, rather than
-		according to this variable. You may want to look at
-		the <code>dir_alternate.ezt</code> template, which has
-		the revision in front.
-		<p></p>
-	      </dd>
-
-	      <dt><code>directory.ezt</code>:
-		<var>rows.attic</var>
-		and <var>rows.hide_attic_href</var></dt>
-	      <dd>
-		These variable were used to manage the hide and
-		showing of the contents of the <code>Attic/</code>
-		subdirectory. Several new variables were introduced
-		which can be used to replace this functionality:
-		<var>show_attic_href</var>,
-		<var>hide_attic_href</var>, and <var>rows.state</var>.
-		<p></p>
-	      </dd>
-	    </dl>
-
-</div>
-
-</td>
-</tr>
-</table>
-</body>
-</html>
diff --git a/src/www/scm/viewvc/viewvc.org/url-reference.html b/src/www/scm/viewvc/viewvc.org/url-reference.html
deleted file mode 100644
index de626af..0000000
--- a/src/www/scm/viewvc/viewvc.org/url-reference.html
+++ /dev/null
@@ -1,1430 +0,0 @@
-<html>
-<head>
-<title>ViewVC 1.0 URL Reference</title>
-<style>
-body {
-	background-color: rgb(180, 193, 205);
-	color: black;
-	font-family: sans-serif;
-}
-
-table {
-	margin-left: 1em;
-}
-
-td,th {
-	padding: 0 0.5em;
-}
-
-th {
-	vertical-align: bottom;
-	background: rgb(60%, 70%, 90%);
-}
-
-td {
-	vertical-align: top;
-	background: rgb(65%, 85%, 65%);
-}
-
-.h2 {
-	padding: 0.5em 1em;
-	border-color: black;
-	border-style: solid;
-	margin-bottom: 1em;
-	background: white;
-	border-width: 1px 2px 2px 1px;
-}
-
-.toc-list {
-	font-size: 90%;
-}
-
-th.caption {
-	background: rgb(180, 193, 205);
-	font-weight: normal;
-	font-style: italic;
-}
-</style>
-</head>
-<body>
-
-<h1>ViewVC 1.0 URL Reference</h1>
-
-<div class="h2">
-<h2 id="introduction">Introduction</h2>
-
-<p>This document describes the format of URLs accepted by ViewVC 1.0
-and is intended to be useful to users and outside software developers
-who want to create links to ViewVC pages. It should also be useful to
-ViewVC developers as a way of tracking and documenting the many quirks
-of ViewVC's URL handling logic.</p>
-
-<p>Future releases of ViewVC will support the URL formats described
-in this document. Certain URLs currently accepted by ViewVC, such as
-redirecting URLs that result from the submission of form elements on
-ViewVC pages, are not documented here and therefore may not be supported
-by future releases of ViewVC.</p>
-
-</div>
-
-<div class="h2">
-<h2 id="toc">Table of Contents</h2>
-<ul class="toc-list">
-	<li><a href="#introduction">Introduction</a></li>
-	<li><a href="#components">URL Components</a>
-	<ul class="toc-list">
-		<li><a href="#script-component">ViewVC Script Location</a></li>
-		<li><a href="#path-component">Repository Path</a></li>
-		<li><a href="#query-component">Query Parameters</a></li>
-	</ul></li>
-	<li><a href="#syntax">URL Syntax</a>
-	<ul class="toc-list">
-		<li><a href="#annotate-view">Annotate View</a></li>
-		<li><a href="#checkout-view">Checkout View</a></li>
-		<li><a href="#diff-view">Diff View</a></li>
-		<li><a href="#docroot-view">Docroot View</a></li>
-		<li><a href="#directory-view">Directory Listing View</a></li>
-		<li><a href="#graph-view">Graph View</a></li>
-		<li><a href="#graphimg-view">Graph Image View</a></li>
-		<li><a href="#log-view">Log View</a></li>
-		<li><a href="#markup-view">Markup View</a></li>
-		<li><a href="#patch-view">Patch View</a></li>
-		<li><a href="#queryform-view">Query Form View</a></li>
-		<li><a href="#query-view">Query View</a></li>
-		<li><a href="#revision-view">Revision View</a></li>
-		<li><a href="#roots-view">Repository Listing</a></li>
-		<li><a href="#tarball-view">Tarball Download</a></li>
-	</ul></li>
-	<li><a href="#compat">Backwards Compatibility</a>
-	<ul>
-		<li><a href="#compat-cvsroot">'<code>cvsroot</code>'
-		Parameter ⇒ '<code>root</code>'</a></li>
-		<li><a href="#compat-only_with_tag">'<code>only_with_tag</code>'
-		Parameter ⇒ '<code>pathrev</code>'</a></li>
-		<li><a href="#compat-oldcheckout">'<code>~checkout~</code>'
-		Magic Path Prefix ⇒ '<code>*checkout*</code>'</a></li>
-		<li><a href="#compat-checkout">'<code>*checkout*</code>'
-		Magic Path Prefix ⇒ '<code>view=co</code>'</a></li>
-		<li><a href="#compat-root">'<code>root</code>' Parameter
-		⇒ Root Path Component</a></li>
-		<li><a href="#compat-rev">'<code>rev</code>' Parameter ⇒
-		'<code>revision</code>' and '<code>pathrev</code>'</a></li>
-		<li><a href="#compat-diff">'<code>.diff</code>' Suffix ⇒
-		Diff View</a></li>
-		<li><a href="#compat-tgz">'<code>.tar.gz</code>' Suffix
-		⇒ '<code>view=tar</code>'</a></li>
-		<li><a href="#compat-tarball">'<code>tarball=1</code>'
-		Parameter ⇒ '<code>view=tar</code>'</a></li>
-		<li><a href="#compat-graph">'<code>graph=1</code>' Parameter
-		⇒ '<code>view=graph</code>'</a></li>
-		<li><a href="#compat-makeimage">'<code>graph=1&makeimage=1</code>'
-		Parameters ⇒ '<code>view=graphimg</code>'</a></li>
-		<li><a href="#compat-content_type">'<code>content_type=text/vnd.viewcvs-markup</code>'
-		and '<code>content_type=text/x-cvsweb-markup</code>' Parameters
-		⇒ '<code>view=markup</code>'</a></li>
-		<li><a href="#compat-attic">'<code>Attic/FILE</code>' Paths ⇒
-		'<code>FILE</code>'</a></li>
-	</ul></li>
-</ul>
-</div>
-
-<div class="h2">
-<h2 id="components">URL Components</h2>
-<p>A ViewVC URL consists of 3 components: a <a
-	href="#script-component">Script Location</a>, a <a
-	href="#path-component">Repository Path</a>, and some optional <a
-	href="#query-component">Query Parameters</a>. Some examples:</p>
-
-<table>
-	<tr>
-		<th>ViewVC Script Location</th>
-		<th>Repository Path</th>
-		<th>Query Parameters</th>
-	</tr>
-	<tr>
-		<td><code>http://example.org/viewvc.cgi</code></td>
-		<td><code>/some/file</code></td>
-		<td><code>?view=log&revision=1.34</code></td>
-	</tr>
-	<tr>
-		<td><code>http://example.org/viewvc.cgi</code></td>
-		<td><code>/*checkout*/some/other/file</code></td>
-		<td><code>?revision=1.10.2.5</code></td>
-	</tr>
-	<tr>
-		<td><code>http://example.org/viewvc.cgi</code></td>
-		<td><code>/some/dir/</code></td>
-		<td><code>?pathrev=BRANCH_2_3</code></td>
-	</tr>
-	<tr>
-		<td><code>http://example.org/viewvc.cgi</code></td>
-		<td><code>/some/dir.tar.gz</code></td>
-		<td><code>?view=tar&pathrev=BRANCH_2_3</code></td>
-	</tr>
-	<tr>
-		<td><code>http://example.org/viewvc.cgi</code></td>
-		<td><code>/yet/another/file</code></td>
-		<td><code>?view=diff?r1=1.12&r2=1.14</code></td>
-	</tr>
-</table>
-
-<h3 id="script-component">ViewVC Script Location</h3>
-<p>The script location is a common base for all ViewVC URL's
-pertaining to a particular installation. It's whatever location the web
-server is configured to serve ViewVC pages from.</p>
-
-<h3 id="path-component">Repository Path</h3>
-<p>Since ViewVC is essentially a file system browser for
-repositories, repository paths referring to the files and directories
-being browsed get their own section in ViewVC URLs immediately following
-the script location. Repository paths are always case sensitive and
-separated by forward slashes, regardless of the underlying filesystem.</p>
-
-<p>Repository paths can be given certain "magic" prefixes and
-suffixes. For example, a "/*checkout*" prefix can be added to file views
-to force a checkout even without an explicit "view=co" query parameter.
-And a ".tar.gz" suffix is added to download tarball URLs so downloaded
-tarballs will be saved with sensible default names.</p>
-
-<p>If the <code>root_as_url_component</code> configuration option is
-enabled, the first directory name in a repository path (after any magic
-prefix) is taken to be the name (from the ViewVC configuration) of the
-repository to browse rather than the name of an actual directory. The
-repository name can also be specified in a "root=" query parameter
-instead (see <a href="#root-param"><code>root</code> parameter</a>
-below).</p>
-
-<p>Paths beginning with "/*docroot*/" are an exception the rules
-above. These paths are used to provide access to files in the ViewVC
-template directory: image files, static HTML pages, and the ViewVC
-stylesheet. For more information, see the <a href="#docroot-view">Docroot
-View</a> syntax below.</p>
-
-<h3 id="query-component">Query Parameters</h3>
-
-<p>Following the ViewVC and repository locations in URLs is an
-optional query string, a list of parameter/value pairs written like
-"?param1=value1&param2=value2..." Some parameters, like "revision",
-"pathrev", and "root", augment repository path information, specifying
-revisions and repositories. Other parameters like "logsort" and
-"diff_format" control ViewVC display options. Some parameters are also
-"sticky" and get embedded into links inside the generated pages,
-sticking around for future page views.</p>
-
-<p>ViewVC provides a number of different views of repository data
-including a directory listing view, a log view, a file diff view, and
-others. (The views are listed and described in the <code>help_rootview.html</code>
-ViewVC help page). URLs for each of these views accept specific
-parameters described in the <a href="#syntax">URL Syntax</a> section,
-but some parameters are used by multiple views and they are described
-below:</p>
-
-<table>
-	<thead>
-		<tr>
-			<th>Parameter</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td id="view-param"><code>view</code></td>
-			<td>The name of the view to display, does not need to be
-			explicitly specified in many URLs. Possible values are shown in the <a
-				href="#url-syntax">URL Syntax</a> section below.</td>
-		</tr>
-		<tr>
-			<td id="revision-param"><code>revision</code></td>
-			<td>The revision or tag to display information about, used by
-			several different views.</td>
-		</tr>
-		<tr>
-			<td id="pathrev-param"><code>pathrev</code></td>
-			<td>The current sticky revision (Subversion) or sticky tag
-			(CVS), as described in the <code>help_rootview.html</code> ViewVC
-			help page. In Subversion, because path information is revision
-			controlled, this value is also used to look up paths in the
-			repository, providing a means of accessing paths that no longer exist
-			in HEAD.</td>
-		</tr>
-		<tr>
-			<td id="root-param"><code>root</code></td>
-			<td>The name of the repository to browse. When the <code>default_root</code>
-			configuration option is set or the <code>root_as_url_component</code>
-			option is enabled, it is not neccessary to to specify this parameter.
-			When the <code>root_as_url_component</code> option is enabled, ViewVC
-			URLs with <code>root</code> parameters redirect to locations with the
-			root values embedded in the repository paths.</td>
-		</tr>
-	</tbody>
-</table>
-</div>
-
-<div class="h2">
-<h2 id="syntax">URL Syntax</h2>
-<p>This section lists URL syntax for each ViewVC view. Parts of URLs
-which may vary shown as variables in <var>UPPERCASE</var>.</p>
-
-<h3 id="annotate-view">Annotate View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to annotate</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=annotate</code></td>
-			<td>depends</td>
-			<td><a href="#view-param"><code>view</code> parameter</a>. Not
-			required when an <code>annotate</code> parameter is present</td>
-		</tr>
-		<tr>
-			<td><code>annotate=<var>REVISION</var></code></td>
-			<td>optional</td>
-			<td>revision or tag to annotate</td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-
-<h3 id="checkout-view">Checkout View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>/*checkout*</code></td>
-			<td>optional</td>
-			<td>magic prefix. If specified when the <code>checkout_magic</code>
-			configuration option is disabled, ViewVC will redirect to a URL
-			without the prefix.</td>
-		</tr>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to check out</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=co</code></td>
-			<td>depends</td>
-			<td><a href="#view-param"><code>view</code> parameter</a>, not
-			needed if the <code>default_file_view</code> configuration variable
-			is set to <code>co</code>, since that makes the checkout view the
-			default view for file paths. Also not needed if the <code>/*checkout*</code>
-			magic prefix or the <code>revision</code> parameter is present.
-		</tr>
-		<tr>
-			<td><code>content-type=<var>TYPE</var></code></td>
-			<td>optional</td>
-			<td>MIME type to send with checked out file, default is a guess
-			based on file extension</td>
-		</tr>
-		<tr>
-			<td><code>revision=<var>REVISION</var></code></td>
-			<td>optional</td>
-			<td><a href="#revision-param"><code>revision</code>
-			parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="diff-view">Diff View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to display diff of</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=diff</code></td>
-			<td>optional</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		<tr>
-			<td><code>r1=<var>R1</var></code></td>
-			<td>required</td>
-			<td>starting revision or tag or the string "text" to indicate
-			that <code><var>TR1</var></code> value (below) should override this
-			one</td>
-		</tr>
-		<tr>
-			<td><code>r2=<var>R2</var></code></td>
-			<td>required</td>
-			<td>ending revision or tag or the string "text" to indicate that
-			<code><var>TR2</var></code> value (below) should override this one</td>
-		</tr>
-		<tr>
-			<td><code>tr1=<var>TR1</var></code></td>
-			<td>depends</td>
-			<td>starting revision or tag, used if <var>r1</var> parameter is
-			present and set to "text"</td>
-		</tr>
-		<tr>
-			<td><code>tr2=<var>TR2</var></code></td>
-			<td>depends</td>
-			<td>ending revision or tag, used if <var>r2</var> parameter is
-			present and set to "text"</td>
-		</tr>
-		<tr>
-			<td><code>p1=<var>P1</var></code></td>
-			<td>optional</td>
-			<td>starting file path that can override the <code><var>PATH</var></code>
-			value to allow files at two different paths to be compared</td>
-		</tr>
-		<tr>
-			<td><code>p2=<var>P2</var></code></td>
-			<td>optional</td>
-			<td>ending file path that can override the <code><var>PATH</var></code>
-			value to allow files at two different paths to be compared</td>
-		</tr>
-		<tr>
-			<td><code>diff_format=<var>DIFF_FORMAT</var></code></td>
-			<td>optional</td>
-			<td>value specifying the type of diff to display. Can be "u" for
-			unified diff, "c" for context diff, "s" for side by side diff, "h"
-			for human readable diff, "l" for long human readable diff. If no
-			value is specified the default depends on the <code>diff_format</code>
-			configuration option.</td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="directory-view">Directory Listing View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH/</var></code></td>
-			<td>required</td>
-			<td>directory path to view. If the trailing slash is omitted,
-			ViewVC will redirect to a URL that has a trailing slash.</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=dir</code></td>
-			<td>optional</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>hideattic=<var>HIDEATTIC</var></code></td>
-			<td>optional</td>
-			<td>"0" to show dead files in CVS directory listings or "1" to
-			hide dead files. Default depends on the <code>hide_attic</code>
-			configuration value.</td>
-		</tr>
-		<tr>
-			<td><code>search=<var>SEARCH</var></code></td>
-			<td>optional</td>
-			<td>regular expression to search files in the directory with if
-			<code>use_re_search</code> configuration option is enabled</td>
-		</tr>
-		<tr>
-			<td><code>sortby=<var>SORTBY</var></code></td>
-			<td>optional</td>
-			<td>"file" "rev" "date" "author" or "log" to indicate how the
-			directory listing should be sorted. Default depends on <code>sortby</code>
-			configuration option.</td>
-		</tr>
-		<tr>
-			<td><code>sortdir=<var>SORTBY</var></code></td>
-			<td>optional</td>
-			<td>"up" to sort directory in ascending order or "down" for
-			descending order. Default is "up".</td>
-		</tr>
-		<tr>
-			<td><code>dir_pagestart=<var>PAGE</var></code></td>
-			<td>optional</td>
-			<td>item number to start listing at if paging is enabled</td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="docroot-view">Docroot View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>/*docroot*</code></td>
-			<td>required</td>
-			<td>magic prefix</td>
-		</tr>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to retrieve. ViewVC will return the contents of
-			the file located at <code>PATH</code>, relative to the <code>docroot</code>
-			subdirectory of the directory specified in the <code>template_dir</code>
-			configuration option.</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-</table>
-
-<h3 id="graph-view">Graph View</h3>
-<table>
-	<tr>
-		<th colspan="3" class="caption">Path Components (in order of
-		appearance in the URL)</th>
-	</tr>
-	<tr>
-		<th>Component</th>
-		<th>Opt/Req</th>
-		<th>Description</th>
-	</tr>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to generate CvsGraph page for</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=graph</code></td>
-			<td>required</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="graphimg-view">Graph Image View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to generate CvsGraph image for</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=graphimg</code></td>
-			<td>required</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="log-view">Log View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file or directory path to generate log for</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=log</code></td>
-			<td>depends</td>
-			<td><a href="#view-param"><code>view</code> parameter</a>, does
-			not need to be specified for file paths when the <code>default_file_view</code>
-			configuration option is set to <code>log</code>. However it is
-			recommended that the parameter be passed anyway for consistency with
-			directory log URLs and compatibility with ViewVC installations that
-			set <code>default_file_view</code> to <code>co</code>.</td>
-		</tr>
-		<tr>
-			<td><code>logsort=<var>SORT</var></code></td>
-			<td>optional</td>
-			<td>"rev" to sort log entries by revision number or "date" to
-			sort by date. Default depends on the <code>log_sort</code>
-			configuration value.</td>
-		</tr>
-		<tr>
-			<td><code>log_pagestart=<var>PAGE</var></code></td>
-			<td>optional</td>
-			<td>item number to start listing at if paging is enabled</td>
-		</tr>
-		<tr>
-			<td><code>r1=<var>R1</var></code></td>
-			<td>optional</td>
-			<td>current revision selected for diffs</td>
-		</tr>
-		<tr>
-			<td><code>diff_format=<var>DIFF_FORMAT</var></code></td>
-			<td>optional</td>
-			<td>currently selected diff format</td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="markup-view">Markup View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to mark up</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=markup</code></td>
-			<td>required</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		<tr>
-			<td><code>revision=<var>REVISION</var></code></td>
-			<td>optional</td>
-			<td><a href="#revision-param"><code>revision</code>
-			parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="patch-view">Patch View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to display patch of</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=patch</code></td>
-			<td>required</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		<tr>
-			<td><code>r1=<var>R1</var></code></td>
-			<td>required</td>
-			<td>starting revision or tag or the string "text" to indicate
-			that <code><var>TR1</var></code> value (below) should override this
-			one</td>
-		</tr>
-		<tr>
-			<td><code>r2=<var>R2</var></code></td>
-			<td>required</td>
-			<td>ending revision or tag or the string "text" to indicate that
-			<code><var>TR2</var></code> value (below) should override this one</td>
-		</tr>
-		<tr>
-			<td><code>tr1=<var>TR1</var></code></td>
-			<td>depends</td>
-			<td>starting revision or tag, only used if <var>r1</var>
-			parameter is present and set to "text"</td>
-		</tr>
-		<tr>
-			<td><code>tr2=<var>TR2</var></code></td>
-			<td>depends</td>
-			<td>ending revision or tag, only used if <var>r2</var> parameter
-			is present and set to "text"</td>
-		</tr>
-		<tr>
-			<td><code>p1=<var>P1</var></code></td>
-			<td>optional</td>
-			<td>starting file path that can override the <code><var>PATH</var></code>
-			value to allow files at two different paths to be compared</td>
-		</tr>
-		<tr>
-			<td><code>p2=<var>P2</var></code></td>
-			<td>optional</td>
-			<td>ending file path that can override the <code><var>PATH</var></code>
-			value to allow files at two different paths to be compared</td>
-		</tr>
-		<tr>
-			<td><code>diff_format=<var>DIFF_FORMAT</var></code></td>
-			<td>optional</td>
-			<td>value specifying the type of patch to display. Can be "u"
-			for unified diff or "c" for context diff. If no value is specified
-			the default depends on the <code>diff_format</code> configuration
-			option.</td>
-		</tr>
-		<tr>
-			<td><code>pathrev=<var>PATHREV</var></code></td>
-			<td>optional</td>
-			<td><a href="#pathrev-param"><code>pathrev</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>root=<var>ROOT</var></code></td>
-			<td>depends</td>
-			<td><a href="#root-param"><code>root</code> parameter</a></td>
-		</tr>
-</table>
-
-<h3 id="queryform-view">Query Form View</h3>
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Path Components (in order of
-			appearance in the URL)</th>
-		</tr>
-		<tr>
-			<th>Component</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code><var>/PATH</var></code></td>
-			<td>required</td>
-			<td>file path to display query results from</td>
-		</tr>
-</table>
-<br />
-<table>
-	<thead>
-		<tr>
-			<th colspan="3" class="caption">Query Parameters</th>
-		</tr>
-		<tr>
-			<th>Parameter</th>
-			<th>Opt/Req</th>
-			<th>Description</th>
-		</tr>
-	</thead>
-	<tbody>
-		<tr>
-			<td><code>view=queryform</code></td>
-			<td>required</td>
-			<td><a href="#view-param"><code>view</code> parameter</a></td>
-		</tr>
-		<tr>
-			<td><code>branch=<var>BRANCH</var></code></td>
-			<td>optional</td>
-			<td>branch query string</td>
-		</tr>
-		<tr>
-			<td><code>branch_match=BRANCH_MATCH</code></td>
-			<td>optional</td>
-			<td>"exact" "like" "glob" "regex" or "notregex" determining type
-			of branch match</td>
-		</tr>
-		<tr>
-			<td><code>dir=<var>DIR</var></code></td>
-			<td>optional</td>
-			<td>directory query string</td>
-		</tr>
-		<tr>
-			<td><code>file=<var>FILE</var></code></td>
-			<td>optional</td>
-			<td>file query string</td>
-		</tr>
-		<tr>
-			<td><code>file_match=FILE_MATCH</code></td>
-			<td>optional</td>
-			<td>"exact" "like" "glob" "regex" or "notregex" determining type
-			of file match</td>
-		</tr>
-		<tr>
-			<td><code>who=<var>WHO</var></code></td>
-			<td>optional</td>
-			<td>author query string</td>
-		</tr>
-		<tr>
-			<td><code>who_match=WHO_MATCH</code></td>
-			<td>optional</td>
-			<td>"exact" "like" "glob" "regex" or "notregex" determining type
-			of author match</td>
-		</tr>
-		<tr>
-			<td><code>querysort=SORT</code></td>
-			<td>optional</td>
-			<td>"date" "author" or "file" determining order of query results</td>
-		</tr>
-		<tr>
-			<td><code>date=DATE</code></td>
-			<td>o