[med-svn] [exonerate] 01/05: Imported Upstream version 2.4.0

Andreas Tille tille at debian.org
Sun Mar 20 11:46:07 UTC 2016


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

tille pushed a commit to branch master
in repository exonerate.

commit d0bf5439883c1095dcee5cc74ef19786457dcc7c
Author: Andreas Tille <tille at debian.org>
Date:   Sun Mar 20 12:18:53 2016 +0100

    Imported Upstream version 2.4.0
---
 ChangeLog                                          |  27 +-
 Makefile.in                                        |   1 +
 configure                                          |  25 +-
 configure.in                                       |  21 +-
 doc/Makefile.in                                    |   1 +
 doc/man/Makefile.in                                |   1 +
 doc/man/man1/Makefile.in                           |   1 +
 doc/man/man1/exonerate.1                           |  63 +++-
 src/Makefile.in                                    |   1 +
 src/bsdp/Makefile.am                               |   3 +-
 src/bsdp/Makefile.in                               |  16 +-
 src/bsdp/bsdp.c                                    |   2 +-
 src/bsdp/bsdp.h                                    |   2 +-
 src/bsdp/bsdp.test.c                               |   2 +-
 src/bsdp/heuristic.c                               |   2 +-
 src/bsdp/heuristic.h                               |   2 +-
 src/bsdp/heuristic.test.c                          |   2 +-
 src/bsdp/hpair.c                                   |   2 +-
 src/bsdp/hpair.h                                   |   2 +-
 src/bsdp/hpair.test.c                              |   2 +-
 src/bsdp/sar.c                                     |   2 +-
 src/bsdp/sar.h                                     |   2 +-
 src/bsdp/sar.test.c                                |   2 +-
 src/c4/Makefile.am                                 |   9 +-
 src/c4/Makefile.in                                 |  17 +-
 src/c4/alignment.c                                 | 222 ++++++++++-
 src/c4/alignment.h                                 |   8 +-
 src/c4/alignment.test.c                            |   2 +-
 src/c4/c4.c                                        |   8 +-
 src/c4/c4.h                                        |   5 +-
 src/c4/c4.test.c                                   |   2 +-
 src/c4/cgutil.c                                    |   2 +-
 src/c4/cgutil.h                                    |   2 +-
 src/c4/cgutil.test.c                               |   2 +-
 src/c4/codegen.c                                   |   2 +-
 src/c4/codegen.h                                   |   2 +-
 src/c4/codegen.test.c                              |   2 +-
 src/c4/layout.c                                    |   2 +-
 src/c4/layout.h                                    |   2 +-
 src/c4/layout.test.c                               |   2 +-
 src/c4/opair.c                                     |   2 +-
 src/c4/opair.h                                     |   2 +-
 src/c4/opair.test.c                                |   2 +-
 src/c4/optimal.c                                   |   2 +-
 src/c4/optimal.h                                   |   2 +-
 src/c4/optimal.test.c                              |   2 +-
 src/c4/region.c                                    |   2 +-
 src/c4/region.h                                    |   2 +-
 src/c4/region.test.c                               |   2 +-
 src/c4/subopt.c                                    |   2 +-
 src/c4/subopt.h                                    |   2 +-
 src/c4/subopt.test.c                               |   2 +-
 src/c4/viterbi.c                                   |   2 +-
 src/c4/viterbi.h                                   |   2 +-
 src/c4/viterbi.test.c                              |   2 +-
 src/comparison/Makefile.am                         |   3 +
 src/comparison/Makefile.in                         |  10 +-
 src/comparison/comparison.c                        |  30 +-
 src/comparison/comparison.h                        |  10 +-
 src/comparison/comparison.test.c                   |   2 +-
 src/comparison/hspset.c                            | 159 +++++---
 src/comparison/hspset.h                            |  27 +-
 src/comparison/hspset.test.c                       |   2 +-
 src/comparison/match.c                             |  11 +-
 src/comparison/match.h                             |   2 +-
 src/comparison/match.test.c                        |   2 +-
 src/comparison/pcr.c                               |   2 +-
 src/comparison/pcr.h                               |   2 +-
 src/comparison/pcr.test.c                          |   2 +-
 src/comparison/seeder.c                            | 174 ++++++++-
 src/comparison/seeder.h                            |   3 +-
 src/comparison/seeder.test.c                       |   2 +-
 src/comparison/wordhood.c                          |   2 +-
 src/comparison/wordhood.h                          |   2 +-
 src/comparison/wordhood.test.c                     |   2 +-
 src/database/Makefile.am                           |  16 +-
 src/database/Makefile.in                           |  18 +-
 src/database/dataset.c                             |  27 +-
 src/database/dataset.h                             |   3 +-
 src/database/dataset.test.c                        |   2 +-
 src/database/fastadb.c                             |  39 +-
 src/database/fastadb.h                             |   6 +-
 src/database/fastadb.test.c                        |   2 +-
 src/database/fastapipe.c                           |  22 +-
 src/database/fastapipe.h                           |   5 +-
 src/database/fastapipe.test.c                      |   4 +-
 src/database/index.c                               | 148 ++++++--
 src/database/index.h                               |  10 +-
 src/database/index.test.c                          |   2 +-
 src/general/Makefile.am                            |  15 +-
 src/general/Makefile.in                            |  34 +-
 src/general/argument.c                             |  11 +-
 src/general/argument.h                             |   2 +-
 src/general/argument.test.c                        |   2 +-
 src/general/compoundfile.c                         |  50 ++-
 src/general/compoundfile.h                         |  23 +-
 src/general/compoundfile.test.c                    |   2 +-
 src/general/jobqueue.c                             | 137 +++++++
 src/general/jobqueue.h                             |  67 ++++
 .../bitarray.test.c => general/jobqueue.test.c}    |  33 +-
 src/general/lineparse.c                            |   2 +-
 src/general/lineparse.h                            |   2 +-
 src/general/lineparse.test.c                       |   2 +-
 src/general/socket.c                               |  52 ++-
 src/general/socket.h                               |   5 +-
 src/general/socket.test.c                          |   2 +-
 src/general/threadref.c                            |  69 ++++
 src/{hub/bsam.h => general/threadref.h}            |  38 +-
 src/{c4/c4.test.c => general/threadref.test.c}     |  20 +-
 src/hub/Makefile.am                                |   4 +
 src/hub/Makefile.in                                |  18 +-
 src/hub/analysis.c                                 | 416 ++++++++++++++++++---
 src/hub/analysis.h                                 |  28 +-
 src/hub/analysis.test.c                            |   2 +-
 src/hub/bsam.c                                     |   2 +-
 src/hub/bsam.h                                     |   2 +-
 src/hub/bsam.test.c                                |   2 +-
 src/hub/gam.c                                      | 104 ++++--
 src/hub/gam.h                                      |  16 +-
 src/hub/gam.test.c                                 |   2 +-
 src/model/Makefile.am                              |   1 +
 src/model/Makefile.in                              |  51 ++-
 src/model/affine.c                                 |   2 +-
 src/model/affine.h                                 |   2 +-
 src/model/affine.test.c                            |   2 +-
 src/model/bootstrapper.c                           |   2 +-
 src/model/cdna2genome.c                            |   2 +-
 src/model/cdna2genome.h                            |   2 +-
 src/model/cdna2genome.test.c                       |   4 +-
 src/model/coding2coding.c                          |   2 +-
 src/model/coding2coding.h                          |   2 +-
 src/model/coding2coding.test.c                     |   2 +-
 src/model/coding2genome.c                          |   2 +-
 src/model/coding2genome.h                          |   2 +-
 src/model/coding2genome.test.c                     |   2 +-
 src/model/edit_distance.c                          |   2 +-
 src/model/edit_distance.h                          |   2 +-
 src/model/edit_distance.test.c                     |   2 +-
 src/model/est2genome.c                             |   2 +-
 src/model/est2genome.h                             |   2 +-
 src/model/est2genome.test.c                        |   4 +-
 src/model/frameshift.c                             |   2 +-
 src/model/frameshift.h                             |   2 +-
 src/model/frameshift.test.c                        |   2 +-
 src/model/genome2genome.c                          |   2 +-
 src/model/genome2genome.h                          |   2 +-
 src/model/genome2genome.test.c                     |   2 +-
 src/model/intron.c                                 |   2 +-
 src/model/intron.h                                 |   2 +-
 src/model/intron.test.c                            |   2 +-
 src/model/modeltype.c                              |   2 +-
 src/model/modeltype.h                              |   2 +-
 src/model/modeltype.test.c                         |   2 +-
 src/model/ner.c                                    |   2 +-
 src/model/ner.h                                    |   2 +-
 src/model/ner.test.c                               |   2 +-
 src/model/phase.c                                  |   2 +-
 src/model/phase.h                                  |   2 +-
 src/model/phase.test.c                             |   2 +-
 src/model/protein2dna.c                            |   2 +-
 src/model/protein2dna.h                            |   2 +-
 src/model/protein2dna.test.c                       |   2 +-
 src/model/protein2genome.c                         |   2 +-
 src/model/protein2genome.h                         |   2 +-
 src/model/protein2genome.test.c                    |   6 +-
 src/model/ungapped.c                               |   2 +-
 src/model/ungapped.h                               |   2 +-
 src/model/ungapped.test.c                          |   2 +-
 src/program/Makefile.am                            |   6 +-
 src/program/Makefile.in                            |  12 +-
 src/program/exonerate-server.c                     |  77 +++-
 src/program/exonerate.c                            |   8 +-
 src/program/ipcress.c                              |   2 +-
 src/sdp/Makefile.am                                |   1 +
 src/sdp/Makefile.in                                |  12 +-
 src/sdp/boundary.c                                 |   2 +-
 src/sdp/boundary.h                                 |   2 +-
 src/sdp/boundary.test.c                            |   2 +-
 src/sdp/lookahead.c                                |   2 +-
 src/sdp/lookahead.h                                |   2 +-
 src/sdp/lookahead.test.c                           |   2 +-
 src/sdp/scheduler.c                                |   2 +-
 src/sdp/scheduler.h                                |   2 +-
 src/sdp/scheduler.test.c                           |   2 +-
 src/sdp/sdp.c                                      |   8 +-
 src/sdp/sdp.h                                      |   5 +-
 src/sdp/sdp.test.c                                 |   2 +-
 src/sdp/straceback.c                               |   2 +-
 src/sdp/straceback.h                               |   2 +-
 src/sdp/straceback.test.c                          |   2 +-
 src/sequence/Makefile.in                           |   1 +
 src/sequence/alphabet.c                            |  44 ++-
 src/sequence/alphabet.h                            |   9 +-
 src/sequence/alphabet.test.c                       |   2 +-
 src/sequence/codonsubmat.c                         |   2 +-
 src/sequence/codonsubmat.h                         |   2 +-
 src/sequence/codonsubmat.test.c                    |   2 +-
 src/sequence/sequence.c                            | 105 +++++-
 src/sequence/sequence.h                            |  11 +-
 src/sequence/sequence.test.c                       |   2 +-
 src/sequence/splice.c                              |   4 +-
 src/sequence/splice.h                              |   2 +-
 src/sequence/splice.test.c                         |   2 +-
 src/sequence/submat.c                              |   4 +-
 src/sequence/submat.h                              |   2 +-
 src/sequence/submat.test.c                         |   2 +-
 src/sequence/translate.c                           |   6 +-
 src/sequence/translate.h                           |   2 +-
 src/sequence/translate.test.c                      |  10 +-
 src/struct/Makefile.am                             |  13 +-
 src/struct/Makefile.in                             |  14 +-
 src/struct/bitarray.c                              |   2 +-
 src/struct/bitarray.h                              |   4 +-
 src/struct/bitarray.test.c                         |   2 +-
 src/struct/dejavu.c                                |   5 +-
 src/struct/dejavu.h                                |   2 +-
 src/struct/dejavu.test.c                           |   2 +-
 src/struct/fsm.c                                   |   4 +-
 src/struct/fsm.h                                   |   2 +-
 src/struct/fsm.test.c                              |   2 +-
 src/struct/matrix.c                                |   2 +-
 src/struct/matrix.h                                |   2 +-
 src/struct/matrix.test.c                           |   2 +-
 src/struct/noitree.c                               |   2 +-
 src/struct/noitree.h                               |   2 +-
 src/struct/noitree.test.c                          |   2 +-
 src/struct/pqueue.c                                |   2 +-
 src/struct/pqueue.h                                |   2 +-
 src/struct/pqueue.test.c                           |   2 +-
 src/struct/rangetree.c                             |   2 +-
 src/struct/rangetree.h                             |   2 +-
 src/struct/rangetree.test.c                        |   2 +-
 src/struct/recyclebin.c                            |  16 +-
 src/struct/recyclebin.h                            |   2 +-
 src/struct/recyclebin.test.c                       |   2 +-
 src/struct/slist.c                                 |   2 +-
 src/struct/slist.h                                 |   2 +-
 src/struct/slist.test.c                            |   2 +-
 src/struct/sparsecache.c                           |   2 +-
 src/struct/sparsecache.h                           |   2 +-
 src/struct/sparsecache.test.c                      |   2 +-
 src/struct/splaytree.c                             |   2 +-
 src/struct/splaytree.h                             |   2 +-
 src/struct/splaytree.test.c                        |   2 +-
 src/struct/vfsm.c                                  |   2 +-
 src/struct/vfsm.h                                  |   6 +-
 src/struct/vfsm.test.c                             |   2 +-
 src/util/Makefile.am                               |   1 +
 src/util/Makefile.in                               |  10 +-
 src/util/esd2esi.c                                 |  16 +-
 src/util/fasta2esd.c                               |   2 +-
 src/util/fastaannotatecdna.c                       |   2 +-
 src/util/fastachecksum.c                           |   2 +-
 src/util/fastaclean.c                              |   2 +-
 src/util/fastaclip.c                               |   2 +-
 src/util/fastacomposition.c                        |   2 +-
 src/util/fastadiff.c                               |   2 +-
 src/util/fastaexplode.c                            |   2 +-
 src/util/fastafetch.c                              |   6 +-
 src/util/fastahardmask.c                           |   2 +-
 src/util/fastaindex.c                              |   2 +-
 src/util/fastalength.c                             |   2 +-
 src/util/fastanrdb.c                               |   2 +-
 src/util/fastaoverlap.c                            |   2 +-
 src/util/fastareformat.c                           |   2 +-
 src/util/fastaremove.c                             |   2 +-
 src/util/fastarevcomp.c                            |   2 +-
 src/util/fastasoftmask.c                           |   2 +-
 src/util/fastasort.c                               |   2 +-
 src/util/fastasplit.c                              |   2 +-
 src/util/fastasubseq.c                             |   2 +-
 src/util/fastatranslate.c                          |   8 +-
 src/util/fastavalidcds.c                           |   2 +-
 test/Makefile.in                                   |   1 +
 test/data/Makefile.in                              |   1 +
 test/data/cdna/Makefile.in                         |   1 +
 test/data/protein/Makefile.in                      |   1 +
 test/exonerate/Makefile.in                         |   1 +
 test/ipcress/Makefile.in                           |   1 +
 test/util/Makefile.in                              |   1 +
 280 files changed, 2503 insertions(+), 656 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 1731e2e..5751c1e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,29 @@
+
+2.3.0 -> 2.4.0
+    o Fixed many thread safety bugs
+    o Fixed bugs with large files over 4GB
+    o Modified client to work with multiple servers
+    o Fixed server to handle SIGPIPE
+    o Added support for FOSN input (can be files, directories or servers)
+    o Fixed bug with --wordambiguity and --wordjump (with normal FSM)
+    o Added %pS to --ryo (percent self score over equivalenced regions)
+
+2.2.0 -> 2.3.0
+    o Fixed several bugs with thread safety for exonerate-server
+    o Fixed bug with custom genetic codes not working
+    o Fixed bug with overflow of seedrepeat horizon in hspset
+    o Added passing of wordlimit params to server
+    o Implemented --cores option for multi-threaded alignment
+    o Added identity and similarity score for GFF genes and exons
+    o Increased default FSM memory limit to 256Mb
+    o Added --revcomp option to disable searching of reverse complement
+    o Fixed bug with compact-FSM (VFSM) based database searching
+    o Added --wordambiguity option for searching ambiguous reference seqs
+    o Fixed bug with esd2esi and .esd files >2Gb
+
 2.1.0 -> 2.2.0
     o Fixed bug with esd2esi when softmasking is off
-    o Replaced GMemChunk due to caching problems with glib-2
+    o Removed all GMemChunk usage due to caching problems with glib-2
     o Fixed various minor memory leaks
 
 2.0.0 -> 2.1.0
@@ -337,4 +360,6 @@
     o Converted est2genome model to use PSSM splice site prediction
     o Fixed C4_Model_select() to avoid copying redundant calcs
 
+
+
 --
diff --git a/Makefile.in b/Makefile.in
index bcbafbc..a2706f4 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/configure b/configure
index e147300..aa62161 100755
--- a/configure
+++ b/configure
@@ -679,6 +679,7 @@ host
 host_cpu
 host_vendor
 host_os
+custom_guint64_format
 source_root_dir
 PKG_CONFIG
 GLIB_CONFIG
@@ -1940,7 +1941,7 @@ fi
 
 PACKAGE=exonerate
 
-VERSION=2.2.0
+VERSION=2.4.0
 
 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
@@ -4121,6 +4122,8 @@ echo "Set host to $host"
 # AVOID autoconf WARNINGS ABOUT --datarootdir
 
 
+custom_guint64_format="llu"
+
 # TRY TO GET TO BUILD ON ALL PLATFORMS BY DEFAULT
 echo ""$host
 case $host in
@@ -4138,8 +4141,6 @@ case $host in
    CC="cc"
    GCC= # No longer true (prevents GCC specific CFLAGS being set)
    CFLAGS="-O3 -arch ev6 -fast"
-   C4_CC="$CC"
-   C4_CFLAGS="$CFLAGS"
    ;;
    *-irix*)
    echo "Customising build for IRIX"
@@ -4151,8 +4152,17 @@ case $host in
    C4_AR_INIT="cq"
    C4_AR_APPEND="q"
    ;;
+   x86_64-*)
+   echo "Customising build for X86_64"
+   custom_guint64_format="lu"
+   ;;
+   *)
+   echo "*** Unknown build platform: $host ***"
+   ;;
 esac
 
+
+
 # SET SOURCE_ROOT_DIR (REQUIRED FOR viterbi.h)
 source_root_dir=`pwd`
 
@@ -4521,7 +4531,7 @@ elif test "$enable_compiledmodels" = no; then
 # model_extra_programs="bootstrapper"
     codegen_extra_sources=""
     codegen_extra_ldadd="`pwd`/src/c4/viterbi.o  \
-                         `pwd`/src/c4/scheduler.o"
+                         `pwd`/src/sdp/scheduler.o"
 else
     echo "error: must be yes or no:"
     echo "    --enable-compiledmodels:$enable_compiledmodels"
@@ -4569,7 +4579,9 @@ fi
 if test "$enable_pthreads" = yes; then
     echo "Using PTHREADS"
     CFLAGS="$CFLAGS -DUSE_PTHREADS"
-    LDFLAGS="$LDFLAGS -lpthread"
+    # for g_thread_init()
+    g_thread_init_ldflags=`pkg-config --libs gthread-2.0`
+    LDFLAGS="$LDFLAGS $g_thread_init_ldflags -lpthread"
 elif test "$enable_pthreads" = no; then
     echo "Not using pthreads"
 else
@@ -5301,6 +5313,7 @@ host!$host$ac_delim
 host_cpu!$host_cpu$ac_delim
 host_vendor!$host_vendor$ac_delim
 host_os!$host_os$ac_delim
+custom_guint64_format!$custom_guint64_format$ac_delim
 source_root_dir!$source_root_dir$ac_delim
 PKG_CONFIG!$PKG_CONFIG$ac_delim
 GLIB_CONFIG!$GLIB_CONFIG$ac_delim
@@ -5314,7 +5327,7 @@ LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 77; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 78; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.in b/configure.in
index 3dde3ac..a6a019c 100644
--- a/configure.in
+++ b/configure.in
@@ -5,7 +5,7 @@
 # ( Borrowed some config tricks from gtk+, gnet, xscreensaver, mutt )
 
 AC_INIT(src/sequence/sequence.c)
-AM_INIT_AUTOMAKE(exonerate,2.2.0)
+AM_INIT_AUTOMAKE(exonerate,2.4.0)
 AC_PROG_CC
 AC_PROG_INSTALL
 AC_PROG_MAKE_SET
@@ -27,6 +27,8 @@ echo "Set host to $host"
 # AVOID autoconf WARNINGS ABOUT --datarootdir
 AC_SUBST(datarootdir)
 
+custom_guint64_format="llu"
+
 # TRY TO GET TO BUILD ON ALL PLATFORMS BY DEFAULT
 echo ""$host
 case $host in
@@ -44,8 +46,6 @@ case $host in
    CC="cc"
    GCC= # No longer true (prevents GCC specific CFLAGS being set)
    CFLAGS="-O3 -arch ev6 -fast"
-   C4_CC="$CC"
-   C4_CFLAGS="$CFLAGS"
    ;;
    *-irix*)
    echo "Customising build for IRIX"
@@ -57,8 +57,17 @@ case $host in
    C4_AR_INIT="cq"
    C4_AR_APPEND="q"
    ;;
+   x86_64-*)
+   echo "Customising build for X86_64"
+   custom_guint64_format="lu"
+   ;;
+   *)
+   echo "*** Unknown build platform: $host ***"
+   ;;
 esac
 
+AC_SUBST(custom_guint64_format)
+
 # SET SOURCE_ROOT_DIR (REQUIRED FOR viterbi.h)
 source_root_dir=`pwd`
 AC_SUBST(source_root_dir)
@@ -245,7 +254,7 @@ elif test "$enable_compiledmodels" = no; then
 # model_extra_programs="bootstrapper"
     codegen_extra_sources=""
     codegen_extra_ldadd="`pwd`/src/c4/viterbi.o  \
-                         `pwd`/src/c4/scheduler.o"
+                         `pwd`/src/sdp/scheduler.o"
 else
     echo "error: must be yes or no:"
     echo "    --enable-compiledmodels:[$enable_compiledmodels]"
@@ -289,7 +298,9 @@ AC_ARG_ENABLE(pthreads,
 if test "$enable_pthreads" = yes; then
     echo "Using PTHREADS"
     CFLAGS="$CFLAGS -DUSE_PTHREADS"
-    LDFLAGS="$LDFLAGS -lpthread"
+    # for g_thread_init()
+    g_thread_init_ldflags=`pkg-config --libs gthread-2.0`
+    LDFLAGS="$LDFLAGS $g_thread_init_ldflags -lpthread"
 elif test "$enable_pthreads" = no; then
     echo "Not using pthreads"
 else
diff --git a/doc/Makefile.in b/doc/Makefile.in
index b419c62..fa0a7a7 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/doc/man/Makefile.in b/doc/man/Makefile.in
index ae1d7dc..f74e183 100644
--- a/doc/man/Makefile.in
+++ b/doc/man/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/doc/man/man1/Makefile.in b/doc/man/man1/Makefile.in
index 94889fa..5f1bf28 100644
--- a/doc/man/man1/Makefile.in
+++ b/doc/man/man1/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/doc/man/man1/exonerate.1 b/doc/man/man1/exonerate.1
index 162b867..1a5669f 100644
--- a/doc/man/man1/exonerate.1
+++ b/doc/man/man1/exonerate.1
@@ -136,8 +136,7 @@ following a --query flag, or by using with multiple --query flags.
 Specify the target sequences required.  Also, must be in a FASTA
 format file.  As with the query sequences, single or multiple target
 sequences and files may be supplied.
-.B NEW:
-the target filename may by replace by a server name and port number
+The target filename may by replace by a server name and port number
 in the form of
 .B hostname:port
 when using
@@ -145,7 +144,15 @@ when using
 See the man page for
 .B exonerate-server
 for more information on running exonerate in client:server mode.
-
+.B NEW(v2.4.0):
+multiple servers may now be used.  These will be queried in parallel
+if you have set the
+.B --cores
+option.
+.B NEW(v2.4.0):
+If an input file is not a FASTA format file,
+it is assumed to contain a list of other fasta files,
+directories or servers (one per line).
 .\"
 .TP
 .B "-Q | \--querytype" <dna | protein>
@@ -224,6 +231,14 @@ are chromosome-sized, but currently does not currently permit the use
 of a word neighbourhood (ie. exactly matching seeds only).
 .\"
 .TP
+.B "\--revcomp" <boolean>
+Include comparison of the reverse complement of the query and target
+where possible.  By default, this option is enabled,
+but when you know the gene is definitely on the forward strand
+of the query and target,
+this option can halve the time taken to compute alignments.
+.\"
+.TP
 .B "\--forcescan" <none | query | target>
 Force the FSM to scan the query sequence rather than the target.
 This option is useful, for example, if you have a single piece
@@ -246,7 +261,6 @@ for the current pairwise comparison.
 .\"
 .TP
 .B "\--customserver" <command>
-.B NEW:
 When using exonerate in client:server mode with a non-standard
 server, this command allows you to send a custom command to the
 server.  This command is sent by the client (exonerate)
@@ -255,8 +269,16 @@ parameters or other commands specific to the custom server.  See the
 .B exonerate-server
 man page for more information on running exonerate in client:server mode.
 .\"
+.TP
+.B "\--cores" <number>
+The number of cores/CPUs/threads that should be used.
+On a multi-core or multi-CPU machine, increasing this ammount
+allows alignment computations to run in parallel on separate CPUs/cores.
+NB.  Generally, it is better to parallelise the analysis
+by splitting it up into separate jobs, but this option may prove
+useful for problems such as interactive single-gene queries.
+.\"
 
-.RE
 .SH FASTA DATABASE OPTIONS
 .TP
 .B "\--fastasuffix" <extension>
@@ -348,7 +370,6 @@ incorporating all the appropriate gaps and frameshifts.
 .\"
 .TP
 .B protein2dna:bestfit
-.B NEW:
 This is a bestfit version of the protein2dna model,
 with which the entire protein is included in the alignment.
 It is currently only available when using exhaustive alignment.
@@ -362,7 +383,6 @@ This model is simliar to those used by genewise.
 .\"
 .TP
 .B protein2genome:bestfit
-.B NEW:
 This is a bestfit version of the protein2genome model,
 with which the entire protein is included in the alignment.
 It is currently only available when using exhaustive alignment.
@@ -600,10 +620,13 @@ Model name
 Equivalenced {total,id,similarity,mismatches}
 (ie. %em == (%et - %ei))
 .TP
-.B %p[is]
-Percent {id,similarity}
+.B %p[isS]
+Percent {id,similarity,Self}
 over the equivalenced portions of the alignment.
-(ie. %pi == 100*(%ei / %et))
+(ie. %pi == 100*(%ei / %et)).
+Percent Self is the score over the equivalenced portions
+of the alignment as a percentage of the self comparison score
+of the query sequence.
 .TP
 .B %g
 Gene orientation ('+' = forward, '-' = reverse, '.' = unknown)
@@ -917,6 +940,22 @@ This option reduces the memory requirements when using very large
 query sequences, and makes the search run faster, but it also
 damages search sensitivity when high values are set.
 .\"
+.TP
+.B "\--wordambiguity" <limit>
+This option may be used to allow alignment seeds containing
+IUPAC ambiguity symbols.
+The limit is the maximum number of ambiguous words
+allowed at a single position.  If this limit is reached
+then the position is not used for alignment seeding.
+Using this option may slow down a search.
+For large datasets,
+it is recommended to use
+.B  esd2esi --wordambiguity
+instead, as then the speed overhead is only incurred
+during indexing, rather than during the database searching itself.
+NB. This option only works for IUPAC symbols in the target sequence.
+Query words containing IUPAC symbols are (currently) excluded from seeding.
+.\"
 .SH AFFINE MODEL OPTIONS
 .TP
 .B "\-o | \--gapopen" <penalty>
@@ -981,7 +1020,6 @@ ie. when displaying alignment "Met" is used instead of " M "
 .SH TRANSLATION OPTIONS
 .TP
 .B "\--geneticcode" <code>
-.B NEW:
 Specify an alternative genetic code.  The default code (1) is the standard
 genetic code.  Other genetic codes may be specified by in shorthand or
 longhand form.
@@ -1081,7 +1119,6 @@ to be an absolute value.
 .\"
 .TP
 .B "\--seedrepeat" <count>
-.B NEW:
 The seedrepeat parameter sets the number of seeds which must be found
 on the same diagonal or reading frame before HSP extension will occur.
 Increasing the value for
@@ -1151,7 +1188,6 @@ eg. try --geneseed 250
 .\"
 .TP
 .B "\--geneseedrepeat" <count>
-.B NEW:
 The geneseedrepeat parameter is like the seedrepeat parameter,
 but is only applied when looking for the geneseed hsps.
 Using a larger value for
@@ -1184,7 +1220,6 @@ outside of the SARs fall below this quality threshold.
 .B "\--splice3" <path>
 .TP
 .B "\--splice5" <path>
-.B NEW:
 Provide a file containing a custom PSSM (position specific score matrix)
 for prediction of the intron splice sites.
 
diff --git a/src/Makefile.in b/src/Makefile.in
index eeaa16f..635d322 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/src/bsdp/Makefile.am b/src/bsdp/Makefile.am
index 68934bd..73951d8 100644
--- a/src/bsdp/Makefile.am
+++ b/src/bsdp/Makefile.am
@@ -22,6 +22,7 @@ SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
                $(top_srcdir)/src/sequence/translate.o  \
                $(top_srcdir)/src/general/argument.o    \
                $(top_srcdir)/src/general/lineparse.o   \
+               $(top_srcdir)/src/general/threadref.o   \
                -lm
 
 C4_OBJ = $(top_srcdir)/src/c4/c4.o        \
@@ -54,9 +55,9 @@ hpair_test_SOURCES = hpair.test.c hpair.c heuristic.c bsdp.c sar.c
 hpair_test_LDADD = $(top_srcdir)/src/struct/slist.o         \
                    $(top_srcdir)/src/struct/pqueue.o        \
                    $(top_srcdir)/src/struct/recyclebin.o    \
+                   $(top_srcdir)/src/struct/rangetree.o     \
                    $(top_srcdir)/src/comparison/hspset.o    \
                    $(top_srcdir)/src/comparison/wordhood.o  \
-                   $(top_srcdir)/src/struct/rangetree.o     \
                    $(ALIGNMENT_OBJ)
 
 sar_test_SOURCES = sar.test.c sar.c heuristic.c
diff --git a/src/bsdp/Makefile.in b/src/bsdp/Makefile.in
index 41d96fc..610e323 100644
--- a/src/bsdp/Makefile.in
+++ b/src/bsdp/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -87,7 +88,7 @@ INCLUDES = -I$(top_srcdir)/src/struct                           -I$(top_srcdir)/
 
 noinst_HEADERS = heuristic.h bsdp.h hpair.h sar.h
 
-SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  -lm
+SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  $(top_srcdir)/src/general/threadref.o [...]
 
 
 C4_OBJ = $(top_srcdir)/src/c4/c4.o                 $(top_srcdir)/src/c4/alignment.o          $(top_srcdir)/src/c4/optimal.o            $(top_srcdir)/src/c4/codegen.o            $(top_srcdir)/src/c4/region.o             $(top_srcdir)/src/c4/layout.o             $(top_srcdir)/src/c4/viterbi.o            $(top_srcdir)/src/c4/subopt.o             $(top_srcdir)/src/c4/cgutil.o
@@ -105,7 +106,7 @@ bsdp_test_LDADD = $(top_srcdir)/src/general/argument.o                    $(top_
 
 
 hpair_test_SOURCES = hpair.test.c hpair.c heuristic.c bsdp.c sar.c
-hpair_test_LDADD = $(top_srcdir)/src/struct/slist.o                            $(top_srcdir)/src/struct/pqueue.o                           $(top_srcdir)/src/struct/recyclebin.o                       $(top_srcdir)/src/comparison/hspset.o                       $(top_srcdir)/src/comparison/wordhood.o                     $(top_srcdir)/src/struct/rangetree.o                        $(ALIGNMENT_OBJ)
+hpair_test_LDADD = $(top_srcdir)/src/struct/slist.o                            $(top_srcdir)/src/struct/pqueue.o                           $(top_srcdir)/src/struct/recyclebin.o                       $(top_srcdir)/src/struct/rangetree.o                        $(top_srcdir)/src/comparison/hspset.o                       $(top_srcdir)/src/comparison/wordhood.o                     $(ALIGNMENT_OBJ)
 
 
 sar_test_SOURCES = sar.test.c sar.c heuristic.c
@@ -141,7 +142,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 heuristic_test_LDFLAGS = 
 bsdp_test_OBJECTS =  bsdp.test.o bsdp.o
 bsdp_test_DEPENDENCIES =  $(top_srcdir)/src/general/argument.o \
@@ -150,9 +152,9 @@ bsdp_test_LDFLAGS =
 hpair_test_OBJECTS =  hpair.test.o hpair.o heuristic.o bsdp.o sar.o
 hpair_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
 $(top_srcdir)/src/struct/pqueue.o $(top_srcdir)/src/struct/recyclebin.o \
+$(top_srcdir)/src/struct/rangetree.o \
 $(top_srcdir)/src/comparison/hspset.o \
 $(top_srcdir)/src/comparison/wordhood.o \
-$(top_srcdir)/src/struct/rangetree.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/sequence/submat.o $(top_srcdir)/src/c4/c4.o \
@@ -166,7 +168,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 hpair_test_LDFLAGS = 
 sar_test_OBJECTS =  sar.test.o sar.o heuristic.o
 sar_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -185,7 +188,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 sar_test_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/src/bsdp/bsdp.c b/src/bsdp/bsdp.c
index 43f3289..1e574af 100644
--- a/src/bsdp/bsdp.c
+++ b/src/bsdp/bsdp.c
@@ -3,7 +3,7 @@
 *  BSDP : Bounded Sparse Dynamic Programming                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/bsdp.h b/src/bsdp/bsdp.h
index 8402c71..4d83385 100644
--- a/src/bsdp/bsdp.h
+++ b/src/bsdp/bsdp.h
@@ -3,7 +3,7 @@
 *  BSDP: Bounded Sparse Dynamic Programming                      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/bsdp.test.c b/src/bsdp/bsdp.test.c
index 4ecba1b..aa653c7 100644
--- a/src/bsdp/bsdp.test.c
+++ b/src/bsdp/bsdp.test.c
@@ -3,7 +3,7 @@
 *  BSDP : Bounded Sparse Dynamic Programming                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/heuristic.c b/src/bsdp/heuristic.c
index f10e433..5c62ab3 100644
--- a/src/bsdp/heuristic.c
+++ b/src/bsdp/heuristic.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristics          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/heuristic.h b/src/bsdp/heuristic.h
index 5628f7a..70c95f8 100644
--- a/src/bsdp/heuristic.h
+++ b/src/bsdp/heuristic.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristics          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/heuristic.test.c b/src/bsdp/heuristic.test.c
index 536b003..1466a5a 100644
--- a/src/bsdp/heuristic.test.c
+++ b/src/bsdp/heuristic.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristics          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/hpair.c b/src/bsdp/hpair.c
index a2d621b..b20ab3e 100644
--- a/src/bsdp/hpair.c
+++ b/src/bsdp/hpair.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristic pairs     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/hpair.h b/src/bsdp/hpair.h
index f034d72..f073702 100644
--- a/src/bsdp/hpair.h
+++ b/src/bsdp/hpair.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristic pairs     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/hpair.test.c b/src/bsdp/hpair.test.c
index 845b33c..d329bf7 100644
--- a/src/bsdp/hpair.test.c
+++ b/src/bsdp/hpair.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for heuristic pairs     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/sar.c b/src/bsdp/sar.c
index 0a088af..a7aebbd 100644
--- a/src/bsdp/sar.c
+++ b/src/bsdp/sar.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - sub-alignment regions        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/sar.h b/src/bsdp/sar.h
index 80fe474..43f33cd 100644
--- a/src/bsdp/sar.h
+++ b/src/bsdp/sar.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - sub-alignment regions        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/bsdp/sar.test.c b/src/bsdp/sar.test.c
index 56a5d40..d848f52 100644
--- a/src/bsdp/sar.test.c
+++ b/src/bsdp/sar.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - sub-alignment regions        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/Makefile.am b/src/c4/Makefile.am
index d3cea24..a90d8c1 100644
--- a/src/c4/Makefile.am
+++ b/src/c4/Makefile.am
@@ -19,7 +19,8 @@ noinst_HEADERS = region.h c4.h alignment.h codegen.h optimal.h  \
 region_test_SOURCES = region.test.c region.c
 
 c4_test_SOURCES = c4.test.c c4.c region.c
-c4_test_LDADD = $(top_srcdir)/src/struct/matrix.o
+c4_test_LDADD = $(top_srcdir)/src/struct/matrix.o      \
+                $(top_srcdir)/src/general/threadref.o
 
 SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
                $(top_srcdir)/src/struct/matrix.o       \
@@ -34,6 +35,7 @@ SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
 ALIGNMENT_OBJ = $(top_srcdir)/src/comparison/match.o     \
                 $(top_srcdir)/src/sequence/codonsubmat.o \
                 $(top_srcdir)/src/sequence/submat.o      \
+                $(top_srcdir)/src/general/threadref.o    \
                 $(SEQUENCE_OBJ)
 alignment_test_SOURCES = alignment.test.c alignment.c c4.c region.c
 alignment_test_LDADD = $(ALIGNMENT_OBJ)
@@ -42,8 +44,9 @@ codegen_test_SOURCES = codegen.test.c codegen.c
 codegen_test_LDADD = $(top_srcdir)/src/general/argument.o
 
 cgutil_test_SOURCES = cgutil.test.c cgutil.c codegen.c c4.c region.c
-cgutil_test_LDADD = $(top_srcdir)/src/general/argument.o \
-                    $(top_srcdir)/src/struct/matrix.o
+cgutil_test_LDADD = $(top_srcdir)/src/general/argument.o  \
+                    $(top_srcdir)/src/struct/matrix.o     \
+                    $(top_srcdir)/src/general/threadref.o
 
 viterbi_test_SOURCES = viterbi.test.c viterbi.c c4.c region.c \
                        alignment.c codegen.c layout.c subopt.c \
diff --git a/src/c4/Makefile.in b/src/c4/Makefile.in
index 46737d2..ad47bd3 100644
--- a/src/c4/Makefile.in
+++ b/src/c4/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -92,12 +93,13 @@ noinst_HEADERS = region.h c4.h alignment.h codegen.h optimal.h
 region_test_SOURCES = region.test.c region.c
 
 c4_test_SOURCES = c4.test.c c4.c region.c
-c4_test_LDADD = $(top_srcdir)/src/struct/matrix.o
+c4_test_LDADD = $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/general/threadref.o
+
 
 SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  -lm
 
 
-ALIGNMENT_OBJ = $(top_srcdir)/src/comparison/match.o                     $(top_srcdir)/src/sequence/codonsubmat.o                 $(top_srcdir)/src/sequence/submat.o                      $(SEQUENCE_OBJ)
+ALIGNMENT_OBJ = $(top_srcdir)/src/comparison/match.o                     $(top_srcdir)/src/sequence/codonsubmat.o                 $(top_srcdir)/src/sequence/submat.o                      $(top_srcdir)/src/general/threadref.o                    $(SEQUENCE_OBJ)
 
 alignment_test_SOURCES = alignment.test.c alignment.c c4.c region.c
 alignment_test_LDADD = $(ALIGNMENT_OBJ)
@@ -106,7 +108,7 @@ codegen_test_SOURCES = codegen.test.c codegen.c
 codegen_test_LDADD = $(top_srcdir)/src/general/argument.o
 
 cgutil_test_SOURCES = cgutil.test.c cgutil.c codegen.c c4.c region.c
-cgutil_test_LDADD = $(top_srcdir)/src/general/argument.o                     $(top_srcdir)/src/struct/matrix.o
+cgutil_test_LDADD = $(top_srcdir)/src/general/argument.o                      $(top_srcdir)/src/struct/matrix.o                         $(top_srcdir)/src/general/threadref.o
 
 
 viterbi_test_SOURCES = viterbi.test.c viterbi.c c4.c region.c                        alignment.c codegen.c layout.c subopt.c                        cgutil.c
@@ -148,12 +150,14 @@ region_test_LDADD = $(LDADD)
 region_test_DEPENDENCIES = 
 region_test_LDFLAGS = 
 c4_test_OBJECTS =  c4.test.o c4.o region.o
-c4_test_DEPENDENCIES =  $(top_srcdir)/src/struct/matrix.o
+c4_test_DEPENDENCIES =  $(top_srcdir)/src/struct/matrix.o \
+$(top_srcdir)/src/general/threadref.o
 c4_test_LDFLAGS = 
 alignment_test_OBJECTS =  alignment.test.o alignment.o c4.o region.o
 alignment_test_DEPENDENCIES =  $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/sequence/submat.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -173,6 +177,7 @@ $(top_srcdir)/src/struct/rangetree.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/sequence/submat.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -192,6 +197,7 @@ $(top_srcdir)/src/struct/rangetree.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/sequence/submat.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -208,6 +214,7 @@ $(top_srcdir)/src/struct/rangetree.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/sequence/submat.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -222,7 +229,7 @@ $(top_srcdir)/src/struct/recyclebin.o
 subopt_test_LDFLAGS = 
 cgutil_test_OBJECTS =  cgutil.test.o cgutil.o codegen.o c4.o region.o
 cgutil_test_DEPENDENCIES =  $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/struct/matrix.o
+$(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/general/threadref.o
 cgutil_test_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/src/c4/alignment.c b/src/c4/alignment.c
index 04c4cdc..772d1d8 100644
--- a/src/c4/alignment.c
+++ b/src/c4/alignment.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - alignment code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -538,7 +538,9 @@ static void AlignmentView_add_GAP(AlignmentView *av,
     register gint i, j;
     register gint curr_query_pos = query_pos,
                   curr_target_pos = target_pos;
-    static gchar seq_string[4], match_string[4], gap_string[4];
+    register gchar *seq_string = g_new(gchar, 4),
+                   *match_string = g_new(gchar, 4),
+                   *gap_string = g_new(gchar, 4);
     register Alphabet_Type emitted_alphabet_type;
     register gchar tr_codon, *tr_codon_name;
     register gboolean is_translating
@@ -598,6 +600,9 @@ static void AlignmentView_add_GAP(AlignmentView *av,
         curr_query_pos += advance_query;
         curr_target_pos += advance_target;
         }
+    g_free(seq_string);
+    g_free(match_string);
+    g_free(gap_string);
     return;
     }
 /* Display gap:[- N] codon[<->   NNN] frameshift [-*N]
@@ -1416,6 +1421,53 @@ static gint Alignment_get_equivalenced_matching(Alignment *alignment,
 /* Reports the %id over the equivalenced regions of the alignment
  */
 
+static gint Alignment_get_equivalenced_matching_region(Alignment *alignment,
+              Sequence *query, Sequence *target,
+              Translate *translate, gboolean report_id,
+              gpointer user_data, gint exon_query_start, gint exon_query_end){
+    register gint i, j, match = 0;
+    register AlignmentOperation *ao;
+    register gint query_pos = alignment->region->query_start,
+                  target_pos = alignment->region->target_start;
+    register gchar qy_symbol, tg_symbol;
+    for(i = 0; i < alignment->operation_list->len; i++){
+        ao = alignment->operation_list->pdata[i];
+        if(ao->transition->label == C4_Label_MATCH){
+            for(j = 0; j < ao->length; j++){
+                if(query_pos > exon_query_end)
+                    return match;
+                if(query_pos >= exon_query_start){
+                    qy_symbol = Alignment_match_get_symbol(query, query_pos,
+                                           ao->transition->advance_query,
+                                           translate);
+                    tg_symbol = Alignment_match_get_symbol(target,
+                                           target_pos,
+                                           ao->transition->advance_target,
+                                           translate);
+                    if(report_id){
+                        if(toupper(qy_symbol) == toupper(tg_symbol))
+                            match++;
+                    } else { /* report similarity */
+                        if(C4_Calc_score(ao->transition->calc, query_pos,
+                                      target_pos, user_data) > 0)
+                            match++;
+                        }
+                    }
+                query_pos += ao->transition->advance_query;
+                target_pos += ao->transition->advance_target;
+                }
+        } else {
+            query_pos += (ao->transition->advance_query
+                          * ao->length);
+            target_pos += (ao->transition->advance_target
+                          * ao->length);
+            }
+        }
+    return match;
+    }
+/* Reports the %id over the equivalenced regions of the alignment
+ */
+
 static gint Alignment_get_equivalenced_total(Alignment *alignment){
     register gint i, total = 0;
     register AlignmentOperation *ao;
@@ -1427,6 +1479,47 @@ static gint Alignment_get_equivalenced_total(Alignment *alignment){
     return total;
     }
 
+static gint Alignment_get_equivalenced_total_region(Alignment *alignment,
+                          gint exon_query_start, gint exon_query_end){
+    register gint i, j, total = 0;
+    register gint query_pos = alignment->region->query_start,
+                  target_pos = alignment->region->target_start;
+    register AlignmentOperation *ao;
+    for(i = 0; i < alignment->operation_list->len; i++){
+        ao = alignment->operation_list->pdata[i];
+        if(ao->transition->label == C4_Label_MATCH){
+            for(j = 0; j < ao->length; j++){
+                if(query_pos > exon_query_end)
+                    return total;
+                if(query_pos >= exon_query_start)
+                    total++;
+                query_pos += ao->transition->advance_query;
+                target_pos += ao->transition->advance_target;
+                }
+        } else {
+            query_pos += (ao->transition->advance_query
+                          * ao->length);
+            target_pos += (ao->transition->advance_target
+                          * ao->length);
+            }
+        }
+    return total;
+    }
+/* FIXME: optimisation: should use gene object to avoid full alignment pass
+ */
+
+static gfloat Alignment_get_percent_score_region(Alignment *alignment,
+              Sequence *query, Sequence *target,
+              Translate *translate, gboolean report_id, gpointer user_data,
+              gint exon_query_start, gint exon_query_end){
+    return (((gfloat)Alignment_get_equivalenced_matching_region(alignment,
+                     query, target, translate, report_id, user_data,
+                     exon_query_start, exon_query_end))
+          / ((gfloat)Alignment_get_equivalenced_total_region(alignment,
+                         exon_query_start, exon_query_end)))*100;
+    }
+/* FIXME: should also count split codons */
+
 static gfloat Alignment_get_percent_score(Alignment *alignment,
               Sequence *query, Sequence *target,
               Translate *translate, gboolean report_id,
@@ -1435,6 +1528,64 @@ static gfloat Alignment_get_percent_score(Alignment *alignment,
                      query, target, translate, report_id, user_data))
           / ((gfloat)Alignment_get_equivalenced_total(alignment)))*100;
     }
+/* FIXME: should also count split codons */
+
+static gint Alignment_get_match_score(Alignment *alignment,
+                                      Sequence *query, Sequence *target,
+                                      gpointer user_data){
+    register gint i, j;
+    register AlignmentOperation *ao;
+    register C4_Score score = 0;
+    register gint query_pos = alignment->region->query_start,
+                  target_pos = alignment->region->target_start;
+    for(i = 0;  i < alignment->operation_list->len; i++){
+        ao = alignment->operation_list->pdata[i];
+        for(j = 0; j < ao->length; j++){
+            if(ao->transition->label == C4_Label_MATCH){
+                score += C4_Calc_score(ao->transition->calc, query_pos,
+                                       target_pos, user_data);
+                }
+            query_pos += ao->transition->advance_query;
+            target_pos += ao->transition->advance_target;
+            }
+        }
+    g_message("MATCH SCORE [%d]", score);
+    return score;
+    }
+
+static gint Alignment_get_self_match_score(Alignment *alignment,
+                                     Sequence *query, Sequence *target,
+                                     gpointer self_data){
+    register gint i, j;
+    register AlignmentOperation *ao;
+    register C4_Score score = 0;
+    register gint query_pos = alignment->region->query_start;
+    for(i = 0; i < alignment->operation_list->len; i++){
+        ao = alignment->operation_list->pdata[i];
+        for(j = 0; j < ao->length; j++){
+            if(ao->transition->label == C4_Label_MATCH){
+                /* Use self_data to find self-comparison scores */
+                score += C4_Calc_score(ao->transition->calc, query_pos,
+                                       query_pos, self_data);
+                }
+            query_pos += ao->transition->advance_query;
+            }
+        }
+    g_message("SELF MATCH SCORE [%d]", score);
+    return score;
+    }
+
+static gfloat Alignment_get_percent_self(Alignment *alignment,
+              Sequence *query, Sequence *target,
+              Translate *translate, gpointer user_data, gpointer self_data){
+    return (((gfloat)Alignment_get_match_score(alignment,
+                     query, target, user_data))
+          / ((gfloat)Alignment_get_self_match_score(alignment, query, target,
+                                                    self_data)))*100;
+    }
+/* Returns score as a percentage of maximum possible
+ * over the equivalenced transitions
+ */
 
 /**/
 
@@ -1612,6 +1763,7 @@ typedef enum {
     Alignment_RYO_TOKEN_RANK,
     Alignment_RYO_TOKEN_PERCENT_ID,
     Alignment_RYO_TOKEN_PERCENT_SIMILARITY,
+    Alignment_RYO_TOKEN_PERCENT_SELF,
     Alignment_RYO_TOKEN_GENE_ORIENTATION,
     Alignment_RYO_TOKEN_EQUIVALENCED_TOTAL,
     Alignment_RYO_TOKEN_EQUIVALENCED_IDENTCAL,
@@ -1905,6 +2057,11 @@ static GPtrArray *Alignment_RYO_tokenise(gchar *format){
                                  Alignment_RYO_TOKEN_PERCENT_SIMILARITY,
                                  FALSE);
                                 break;
+                            case 'S':
+                                Alignment_RYO_add_token(token_list,
+                                 Alignment_RYO_TOKEN_PERCENT_SELF,
+                                 FALSE);
+                                break;
                             default:
                                 g_error(
                                    "Unknown [%%%c%c] in format string",
@@ -1991,7 +2148,7 @@ static GPtrArray *Alignment_RYO_tokenise(gchar *format){
  *  %s score
  *  %m model_name
  *  %r rank
- *  %p[is] percent {id,similarity}
+ *  %p[isS] percent {id,similarity,self}
  *  %e[tid] equivalenced {total,identical,similar}
  *  %g gene_orientation
  *  %S sugar block
@@ -2204,7 +2361,8 @@ static void Alignment_Coding_destroy(Alignment_Coding *ac){
 
 static void Alignment_RYO_token_list_print(GPtrArray *token_list,
             Alignment *alignment, Sequence *query, Sequence *target,
-            Translate *translate, gint rank, gpointer user_data, FILE *fp){
+            Translate *translate, gint rank,
+            gpointer user_data, gpointer self_data, FILE *fp){
     register gint i, j, pto_start = -1;
     register Alignment_RYO_ComplexToken *rct;
     register Sequence *seq, *subseq;
@@ -2324,6 +2482,11 @@ static void Alignment_RYO_token_list_print(GPtrArray *token_list,
                                  alignment, query, target,
                                  translate, FALSE, user_data));
                 break;
+            case Alignment_RYO_TOKEN_PERCENT_SELF:
+                fprintf(fp, "%2.2f", Alignment_get_percent_self(
+                                 alignment, query, target,
+                                 translate, user_data, self_data));
+                break;
             case Alignment_RYO_TOKEN_GENE_ORIENTATION:
                 fprintf(fp, "%c",
                      Alignment_get_gene_orientation(alignment));
@@ -2446,11 +2609,12 @@ static void Alignment_RYO_token_list_print(GPtrArray *token_list,
 
 void Alignment_display_ryo(Alignment *alignment,
         Sequence *query, Sequence *target, gchar *format,
-        Translate *translate, gint rank, gpointer user_data, FILE *fp){
+        Translate *translate, gint rank,
+        gpointer user_data, gpointer self_data, FILE *fp){
     register GPtrArray *token_list = Alignment_RYO_tokenise(format);
     Alignment_RYO_token_list_print(token_list, alignment,
                                    query, target, translate, rank,
-                                   user_data, fp);
+                                   user_data, self_data, fp);
     Alignment_RYO_token_list_destroy(token_list);
     return;
     }
@@ -2591,6 +2755,7 @@ static void Alignment_free_attribute_list(GPtrArray *attribute_list){
 static void Alignment_display_gff_exon(Alignment *alignment,
                                        Sequence *query,
                                        Sequence *target,
+                                       Translate *translate,
                                        gboolean report_on_query,
                                        gint query_pos,
                                        gint target_pos,
@@ -2599,7 +2764,8 @@ static void Alignment_display_gff_exon(Alignment *alignment,
                                        gint exon_query_gap,
                                        gint exon_target_gap,
                                        gint exon_query_frameshift,
-                                       gint exon_target_frameshift, FILE *fp){
+                                       gint exon_target_frameshift,
+                                       gpointer user_data, FILE *fp){
     register GPtrArray *attribute_list = g_ptr_array_new();
     g_ptr_array_add(attribute_list,
                     g_strdup_printf("insertions %d",
@@ -2609,6 +2775,16 @@ static void Alignment_display_gff_exon(Alignment *alignment,
                     g_strdup_printf("deletions %d",
                                     report_on_query?exon_target_gap
                                                    :exon_query_gap));
+    g_ptr_array_add(attribute_list,
+                    g_strdup_printf("identity %2.2f",
+                                 Alignment_get_percent_score_region(alignment,
+                                 query, target, translate, TRUE, user_data,
+                                 exon_query_start, query_pos)));
+    g_ptr_array_add(attribute_list,
+                    g_strdup_printf("similarity %2.2f",
+                                 Alignment_get_percent_score_region(alignment,
+                                 query, target, translate, FALSE, user_data,
+                                 exon_query_start, query_pos)));
     if(report_on_query){
         if(exon_query_frameshift)
             g_ptr_array_add(attribute_list,
@@ -2667,8 +2843,9 @@ static void Alignment_display_gff_utr(Alignment *alignment,
     }
 
 static void Alignment_display_gff_gene(Alignment *alignment,
-        Sequence *query, Sequence *target, gboolean report_on_query,
-        gint result_id, FILE *fp){
+        Sequence *query, Sequence *target, Translate *translate,
+        gboolean report_on_query,
+        gint result_id, gpointer user_data, FILE *fp){
     register gint i;
     register gint query_pos = alignment->region->query_start,
                   target_pos = alignment->region->target_start;
@@ -2692,6 +2869,14 @@ static void Alignment_display_gff_gene(Alignment *alignment,
                         report_on_query?target->id:query->id));
     g_ptr_array_add(attribute_list,
                     g_strdup_printf("gene_orientation %c", gene_orientation));
+    g_ptr_array_add(attribute_list,
+                    g_strdup_printf("identity %2.2f",
+                                 Alignment_get_percent_score(alignment,
+                                 query, target, translate, TRUE, user_data)));
+    g_ptr_array_add(attribute_list,
+                    g_strdup_printf("similarity %2.2f",
+                                 Alignment_get_percent_score(alignment,
+                                 query, target, translate, FALSE, user_data)));
     Alignment_display_gff_line(alignment, query, target, report_on_query,
                                "gene",
                                alignment->region->query_start,
@@ -2770,12 +2955,12 @@ static void Alignment_display_gff_gene(Alignment *alignment,
                             exon_query_start, exon_target_start,
                             query_pos, target_pos, fp);
                     Alignment_display_gff_exon(alignment,
-                          query, target, report_on_query,
+                          query, target, translate, report_on_query,
                           query_pos, target_pos,
                           exon_query_start, exon_target_start,
                           exon_query_gap, exon_target_gap,
                           exon_query_frameshift,
-                          exon_target_frameshift, fp);
+                          exon_target_frameshift, user_data, fp);
                     in_exon = FALSE;
                     }
                 attribute_list = g_ptr_array_new();
@@ -2811,12 +2996,12 @@ static void Alignment_display_gff_gene(Alignment *alignment,
                             exon_query_start, exon_target_start,
                             query_pos, target_pos, fp);
                     Alignment_display_gff_exon(alignment,
-                          query, target, report_on_query,
+                          query, target, translate, report_on_query,
                           query_pos, target_pos,
                           exon_query_start, exon_target_start,
                           exon_query_gap, exon_target_gap,
                           exon_query_frameshift,
-                          exon_target_frameshift, fp);
+                          exon_target_frameshift, user_data, fp);
                     in_exon = FALSE;
                     }
                 if(gene_orientation == '+'){
@@ -2895,11 +3080,11 @@ static void Alignment_display_gff_gene(Alignment *alignment,
                 }
             }
         Alignment_display_gff_exon(alignment,
-              query, target, report_on_query,
+              query, target, translate, report_on_query,
               query_pos, target_pos,
               exon_query_start, exon_target_start,
               exon_query_gap, exon_target_gap,
-              exon_query_frameshift, exon_target_frameshift, fp);
+              exon_query_frameshift, exon_target_frameshift, user_data, fp);
         }
     return;
     }
@@ -2974,15 +3159,16 @@ static void Alignment_display_gff_similarity(Alignment *alignment,
 
 void Alignment_display_gff(Alignment *alignment,
                            Sequence *query, Sequence *target,
+                           Translate *translate,
                            gboolean report_on_query,
                            gboolean report_on_genomic,
-                           gint result_id, FILE *fp){
+                           gint result_id, gpointer user_data, FILE *fp){
     fprintf(fp, "# --- START OF GFF DUMP ---\n#\n");
     Alignment_display_gff_header(alignment, query, target,
                                  report_on_query, fp);
     if(report_on_genomic){
-        Alignment_display_gff_gene(alignment, query, target,
-                                   report_on_query, result_id, fp);
+        Alignment_display_gff_gene(alignment, query, target, translate,
+                                   report_on_query, result_id, user_data, fp);
         }
     Alignment_display_gff_similarity(alignment, query, target,
                                      report_on_query, result_id, fp);
diff --git a/src/c4/alignment.h b/src/c4/alignment.h
index ad470e0..00094b6 100644
--- a/src/c4/alignment.h
+++ b/src/c4/alignment.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - alignment code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -76,13 +76,15 @@ void Alignment_display_vulgar(Alignment *alignment,
 
 void Alignment_display_gff(Alignment *alignment,
                            Sequence *query, Sequence *target,
+                           Translate *translate,
                            gboolean report_on_query,
                            gboolean report_on_genomic,
-                           gint result_id, FILE *fp);
+                           gint result_id, gpointer user_data, FILE *fp);
 
 void Alignment_display_ryo(Alignment *alignment,
         Sequence *query, Sequence *target, gchar *format,
-        Translate *translate, gint rank, gpointer user_data, FILE *fp);
+        Translate *translate, gint rank,
+        gpointer user_data, gpointer self_data, FILE *fp);
 
 /**/
 
diff --git a/src/c4/alignment.test.c b/src/c4/alignment.test.c
index c860e10..9d0f09f 100644
--- a/src/c4/alignment.test.c
+++ b/src/c4/alignment.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - alignment code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/c4.c b/src/c4/c4.c
index c0568e7..8360b8c 100644
--- a/src/c4/c4.c
+++ b/src/c4/c4.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for models              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -520,7 +520,7 @@ C4_Model *C4_Model_create(gchar *name){
     model->exit_func = NULL;
     model->exit_macro = NULL;
     /**/
-    model->ref_count = 1;
+    model->thread_ref = ThreadRef_create();
     model->is_open = TRUE;
     /**/
     model->state_list      = g_ptr_array_new();
@@ -560,7 +560,7 @@ static void C4_Model_destroy_string_list(GPtrArray *string_list){
 void C4_Model_destroy(C4_Model *model){
     register gint i;
     g_assert(model);
-    if(--model->ref_count)
+    if(ThreadRef_destroy(model->thread_ref))
         return;
     g_free(model->name);
     C4_Model_destroy_string_list(model->global_code_list);
@@ -597,7 +597,7 @@ void C4_Model_destroy(C4_Model *model){
 C4_Model *C4_Model_share(C4_Model *model){
     g_assert(model);
     g_assert(!model->is_open);
-    model->ref_count++;
+    ThreadRef_share(model->thread_ref);
     return model;
     }
 
diff --git a/src/c4/c4.h b/src/c4/c4.h
index 28387fe..d781523 100644
--- a/src/c4/c4.h
+++ b/src/c4/c4.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for models              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -23,6 +23,7 @@ extern "C" {
 #include <glib.h>
 
 #include "region.h"
+#include "threadref.h"
 
 typedef gint C4_Score;
 #define C4_IMPOSSIBLY_LOW_SCORE -987654321
@@ -177,7 +178,7 @@ typedef struct {
             gchar *init_macro; /* If NULL, use init_func     */
       C4_PrepFunc  exit_func;  /* If NULL, no initialisation */
             gchar *exit_macro; /* If NULL, use exit_func     */
-             gint   ref_count;
+        ThreadRef *thread_ref;
          gboolean   is_open;
         GPtrArray  *state_list;
         GPtrArray  *transition_list;
diff --git a/src/c4/c4.test.c b/src/c4/c4.test.c
index 6f543a8..37a56b0 100644
--- a/src/c4/c4.test.c
+++ b/src/c4/c4.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for models              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/cgutil.c b/src/c4/cgutil.c
index 283c7da..4c9350f 100644
--- a/src/c4/cgutil.c
+++ b/src/c4/cgutil.c
@@ -3,7 +3,7 @@
 *  Utilities to facilitate code generation DP implementations    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/cgutil.h b/src/c4/cgutil.h
index b491383..d01f7fe 100644
--- a/src/c4/cgutil.h
+++ b/src/c4/cgutil.h
@@ -3,7 +3,7 @@
 *  Utilities to facilitate code generation DP implementations    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/cgutil.test.c b/src/c4/cgutil.test.c
index 568e423..8e251d9 100644
--- a/src/c4/cgutil.test.c
+++ b/src/c4/cgutil.test.c
@@ -3,7 +3,7 @@
 *  Utilities to facilitate code generation DP implementations    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/codegen.c b/src/c4/codegen.c
index f111381..971d761 100644
--- a/src/c4/codegen.c
+++ b/src/c4/codegen.c
@@ -3,7 +3,7 @@
 *  Code generation module for C4                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/codegen.h b/src/c4/codegen.h
index 8873373..71844d2 100644
--- a/src/c4/codegen.h
+++ b/src/c4/codegen.h
@@ -3,7 +3,7 @@
 *  Code generation module for C4                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/codegen.test.c b/src/c4/codegen.test.c
index 60d7cb6..56a73cc 100644
--- a/src/c4/codegen.test.c
+++ b/src/c4/codegen.test.c
@@ -3,7 +3,7 @@
 *  Code generation module for C4                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/layout.c b/src/c4/layout.c
index 1fb26da..92243cc 100644
--- a/src/c4/layout.c
+++ b/src/c4/layout.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP layout code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/layout.h b/src/c4/layout.h
index 6312dd8..b366015 100644
--- a/src/c4/layout.h
+++ b/src/c4/layout.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP layout code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/layout.test.c b/src/c4/layout.test.c
index c898b68..6d9548d 100644
--- a/src/c4/layout.test.c
+++ b/src/c4/layout.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - optimal alignment code       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/opair.c b/src/c4/opair.c
index 1fdde79..ae6a696 100644
--- a/src/c4/opair.c
+++ b/src/c4/opair.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for optimal pairs       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/opair.h b/src/c4/opair.h
index c6b4a41..25b242c 100644
--- a/src/c4/opair.h
+++ b/src/c4/opair.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for optimal pairs       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/opair.test.c b/src/c4/opair.test.c
index b6d9c93..dcd783c 100644
--- a/src/c4/opair.test.c
+++ b/src/c4/opair.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for optimal pairs       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/optimal.c b/src/c4/optimal.c
index a31bd2f..e07e42c 100644
--- a/src/c4/optimal.c
+++ b/src/c4/optimal.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - optimal alignment code       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/optimal.h b/src/c4/optimal.h
index 74384f0..fdd2038 100644
--- a/src/c4/optimal.h
+++ b/src/c4/optimal.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - optimal alignment code       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/optimal.test.c b/src/c4/optimal.test.c
index 0b3e450..6a1cf75 100644
--- a/src/c4/optimal.test.c
+++ b/src/c4/optimal.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP layout code               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/region.c b/src/c4/region.c
index f5c17c1..594831f 100644
--- a/src/c4/region.c
+++ b/src/c4/region.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for regions             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/region.h b/src/c4/region.h
index b5fb895..0a8fd76 100644
--- a/src/c4/region.h
+++ b/src/c4/region.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for regions             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/region.test.c b/src/c4/region.test.c
index 52e689b..597c9cd 100644
--- a/src/c4/region.test.c
+++ b/src/c4/region.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - code for regions             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/subopt.c b/src/c4/subopt.c
index 885912c..3aca1cb 100644
--- a/src/c4/subopt.c
+++ b/src/c4/subopt.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - suboptimal alignments        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/subopt.h b/src/c4/subopt.h
index 07dd53b..f32f0fa 100644
--- a/src/c4/subopt.h
+++ b/src/c4/subopt.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - suboptimal alignments        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/subopt.test.c b/src/c4/subopt.test.c
index cd6a1de..8295fd0 100644
--- a/src/c4/subopt.test.c
+++ b/src/c4/subopt.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - suboptimal alignments        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/viterbi.c b/src/c4/viterbi.c
index 5178d51..2453760 100644
--- a/src/c4/viterbi.c
+++ b/src/c4/viterbi.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - the Viterbi implementation   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/viterbi.h b/src/c4/viterbi.h
index c9009de..9bc6de6 100644
--- a/src/c4/viterbi.h
+++ b/src/c4/viterbi.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - the Viterbi implementation   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/c4/viterbi.test.c b/src/c4/viterbi.test.c
index ebd60ea..9a7f69f 100644
--- a/src/c4/viterbi.test.c
+++ b/src/c4/viterbi.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - the Viterbi implementation   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/Makefile.am b/src/comparison/Makefile.am
index d37e08f..0ea5867 100644
--- a/src/comparison/Makefile.am
+++ b/src/comparison/Makefile.am
@@ -29,6 +29,7 @@ hspset_test_LDADD = $(top_srcdir)/src/sequence/submat.o      \
                     $(top_srcdir)/src/sequence/codonsubmat.o \
                     $(top_srcdir)/src/struct/pqueue.o        \
                     $(top_srcdir)/src/struct/recyclebin.o    \
+                    $(top_srcdir)/src/general/threadref.o    \
                     $(SEQUENCE_OBJ)
 
 pcr_test_SOURCES = pcr.test.c pcr.c wordhood.c
@@ -45,6 +46,7 @@ comparison_test_LDADD = $(top_srcdir)/src/sequence/submat.o       \
                         $(top_srcdir)/src/sequence/codonsubmat.o  \
                         $(top_srcdir)/src/struct/recyclebin.o     \
                         $(top_srcdir)/src/struct/pqueue.o         \
+                        $(top_srcdir)/src/general/threadref.o     \
                         $(SEQUENCE_OBJ)
 
 match_test_SOURCES = match.test.c match.c
@@ -60,6 +62,7 @@ seeder_test_LDADD = $(top_srcdir)/src/sequence/submat.o      \
                     $(top_srcdir)/src/struct/fsm.o           \
                     $(top_srcdir)/src/struct/vfsm.o          \
                     $(top_srcdir)/src/struct/pqueue.o        \
+                    $(top_srcdir)/src/general/threadref.o    \
                     $(SEQUENCE_OBJ)
 
 # Files to clear away
diff --git a/src/comparison/Makefile.in b/src/comparison/Makefile.in
index 68f78b9..b4941d1 100644
--- a/src/comparison/Makefile.in
+++ b/src/comparison/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -95,7 +96,7 @@ wordhood_test_SOURCES = wordhood.test.c wordhood.c
 wordhood_test_LDADD = $(top_srcdir)/src/sequence/submat.o                            $(top_srcdir)/src/sequence/codonsubmat.o                       $(SEQUENCE_OBJ)
 
 hspset_test_SOURCES = hspset.test.c hspset.c match.c wordhood.c
-hspset_test_LDADD = $(top_srcdir)/src/sequence/submat.o                          $(top_srcdir)/src/sequence/codonsubmat.o                     $(top_srcdir)/src/struct/pqueue.o                            $(top_srcdir)/src/struct/recyclebin.o                        $(SEQUENCE_OBJ)
+hspset_test_LDADD = $(top_srcdir)/src/sequence/submat.o                          $(top_srcdir)/src/sequence/codonsubmat.o                     $(top_srcdir)/src/struct/pqueue.o                            $(top_srcdir)/src/struct/recyclebin.o                        $(top_srcdir)/src/general/threadref.o                        $(SEQUENCE_OBJ)
 
 
 pcr_test_SOURCES = pcr.test.c pcr.c wordhood.c
@@ -104,7 +105,7 @@ pcr_test_LDADD = $(top_srcdir)/src/sequence/submat.o                       $(top
 
 comparison_test_SOURCES = comparison.test.c comparison.c hspset.c                           match.c wordhood.c
 
-comparison_test_LDADD = $(top_srcdir)/src/sequence/submat.o                               $(top_srcdir)/src/sequence/codonsubmat.o                          $(top_srcdir)/src/struct/recyclebin.o                             $(top_srcdir)/src/struct/pqueue.o                                 $(SEQUENCE_OBJ)
+comparison_test_LDADD = $(top_srcdir)/src/sequence/submat.o                               $(top_srcdir)/src/sequence/codonsubmat.o                          $(top_srcdir)/src/struct/recyclebin.o                             $(top_srcdir)/src/struct/pqueue.o                                 $(top_srcdir)/src/general/threadref.o                             $(SEQUENCE_OBJ)
 
 
 match_test_SOURCES = match.test.c match.c
@@ -113,7 +114,7 @@ match_test_LDADD = $(top_srcdir)/src/sequence/submat.o                         $
 
 seeder_test_SOURCES = seeder.test.c seeder.c wordhood.c hspset.c                       match.c comparison.c
 
-seeder_test_LDADD = $(top_srcdir)/src/sequence/submat.o                          $(top_srcdir)/src/sequence/codonsubmat.o                     $(top_srcdir)/src/struct/recyclebin.o                        $(top_srcdir)/src/struct/fsm.o                               $(top_srcdir)/src/struct/vfsm.o                              $(top_srcdir)/src/struct/pqueue.o                            $(SEQUENCE_OBJ)
+seeder_test_LDADD = $(top_srcdir)/src/sequence/submat.o                          $(top_srcdir)/src/sequence/codonsubmat.o                     $(top_srcdir)/src/struct/recyclebin.o                        $(top_srcdir)/src/struct/fsm.o                               $(top_srcdir)/src/struct/vfsm.o                              $(top_srcdir)/src/struct/pqueue.o                            $(top_srcdir)/src/general/threadref.o                        $(SEQUENCE_OBJ)
 
 
 # Files to clear away
@@ -143,6 +144,7 @@ hspset_test_OBJECTS =  hspset.test.o hspset.o match.o wordhood.o
 hspset_test_DEPENDENCIES =  $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/struct/pqueue.o $(top_srcdir)/src/struct/recyclebin.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -168,6 +170,7 @@ match.o wordhood.o
 comparison_test_DEPENDENCIES =  $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/struct/recyclebin.o $(top_srcdir)/src/struct/pqueue.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
@@ -193,6 +196,7 @@ seeder_test_DEPENDENCIES =  $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/struct/recyclebin.o $(top_srcdir)/src/struct/fsm.o \
 $(top_srcdir)/src/struct/vfsm.o $(top_srcdir)/src/struct/pqueue.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/struct/matrix.o $(top_srcdir)/src/sequence/sequence.o \
 $(top_srcdir)/src/sequence/alphabet.o \
diff --git a/src/comparison/comparison.c b/src/comparison/comparison.c
index 1af89bf..85c4274 100644
--- a/src/comparison/comparison.c
+++ b/src/comparison/comparison.c
@@ -3,7 +3,7 @@
 *  Comparison : A module for pairwise sequence comparisons       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -36,7 +36,7 @@ static Comparison_Param *Comparison_Param_create_without_mirror(
                                           HSP_Param *codon_hsp_param,
                                           gboolean swap_param){
     register Comparison_Param *param = g_new(Comparison_Param, 1);
-    param->ref_count = 1;
+    param->thread_ref = NULL;
     param->query_type = query_type;
     param->target_type = target_type;
     param->dna_hsp_param = Comparison_Param_get_hsp_param(dna_hsp_param,
@@ -64,15 +64,10 @@ Comparison_Param *Comparison_Param_create(Alphabet_Type query_type,
                             dna_hsp_param, protein_hsp_param,
                             codon_hsp_param, TRUE);
     param->mirror->mirror = param;
+    param->mirror->thread_ref = param->thread_ref = ThreadRef_create();
     return param;
     }
 
-static gint Comparison_Param_ref_count(Comparison_Param *param){
-    g_assert(param);
-    g_assert(param->mirror);
-    return param->ref_count + param->mirror->ref_count;
-    }
-
 static void Comparison_Param_destroy_without_mirror(
             Comparison_Param *param){
     g_assert(param);
@@ -89,8 +84,7 @@ static void Comparison_Param_destroy_without_mirror(
 
 void Comparison_Param_destroy(Comparison_Param *param){
     g_assert(param);
-    param->ref_count--;
-    if(Comparison_Param_ref_count(param) > 1) /* Allow for mirror */
+    if(ThreadRef_destroy(param->thread_ref))
         return;
     Comparison_Param_destroy_without_mirror(param->mirror);
     Comparison_Param_destroy_without_mirror(param);
@@ -99,7 +93,7 @@ void Comparison_Param_destroy(Comparison_Param *param){
 
 Comparison_Param *Comparison_Param_share(Comparison_Param *param){
     g_assert(param);
-    param->ref_count++;
+    ThreadRef_share(param->thread_ref);
     return param;
     }
 
@@ -132,11 +126,12 @@ Comparison *Comparison_create(Comparison_Param *param,
     g_assert(param);
     g_assert(query);
     g_assert(target);
-    comparison->ref_count = 1;
+    comparison->thread_ref = ThreadRef_create();
     comparison->param = Comparison_Param_share(param);
     comparison->query = Sequence_share(query);
     comparison->target = Sequence_share(target);
-    comparison->dna_hspset = param->dna_hsp_param
+    ThreadRef_lock(comparison->param->thread_ref);
+    comparison->dna_hspset = comparison->param->dna_hsp_param
                            ? HSPset_create(query, target,
                                            param->dna_hsp_param)
                            : NULL;
@@ -148,17 +143,18 @@ Comparison *Comparison_create(Comparison_Param *param,
                              ? HSPset_create(query, target,
                                              param->codon_hsp_param)
                              : NULL;
+    ThreadRef_unlock(comparison->param->thread_ref);
     return comparison;
     }
 
 Comparison *Comparison_share(Comparison *comparison){
-    comparison->ref_count++;
+    ThreadRef_share(comparison->thread_ref);
     return comparison;
     }
 
 void Comparison_destroy(Comparison *comparison){
     g_assert(comparison);
-    if(--comparison->ref_count)
+    if(ThreadRef_destroy(comparison->thread_ref))
         return;
     Comparison_Param_destroy(comparison->param);
     Sequence_destroy(comparison->query);
@@ -217,7 +213,7 @@ void Comparison_finalise(Comparison *comparison){
 
 void Comparison_swap(Comparison *comparison){
     register Sequence *query;
-    g_assert(comparison->ref_count == 1);
+    g_assert(ThreadRef_get_count(comparison->thread_ref) == 1);
     /* Mirror parameters */
     comparison->param = Comparison_Param_share(comparison->param->mirror);
     Comparison_Param_destroy(comparison->param->mirror);
@@ -242,7 +238,7 @@ void Comparison_swap(Comparison *comparison){
 void Comparison_revcomp(Comparison *comparison){
     register Sequence *rc_query = Sequence_revcomp(comparison->query),
                       *rc_target = Sequence_revcomp(comparison->target);
-    g_assert(comparison->ref_count == 1);
+    g_assert(ThreadRef_get_count(comparison->thread_ref) == 1);
     g_assert(comparison->dna_hspset);
     g_assert(!comparison->protein_hspset);
     g_assert(!comparison->codon_hspset);
diff --git a/src/comparison/comparison.h b/src/comparison/comparison.h
index af14a07..cc3c568 100644
--- a/src/comparison/comparison.h
+++ b/src/comparison/comparison.h
@@ -3,7 +3,7 @@
 *  Comparison : A module for pairwise sequence comparisons       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -27,9 +27,10 @@ extern "C" {
 #include "translate.h"
 #include "submat.h"
 #include "hspset.h"
+#include "threadref.h"
 
 typedef struct Comparison_Param {
-                      gint  ref_count;
+                 ThreadRef *thread_ref;
              Alphabet_Type  query_type;
              Alphabet_Type  target_type;
                  HSP_Param *dna_hsp_param;
@@ -50,7 +51,7 @@ Comparison_Param *Comparison_Param_swap(Comparison_Param *param);
 /**/
 
 typedef struct {
-                gint  ref_count;
+           ThreadRef *thread_ref;
     Comparison_Param *param;
             Sequence *query;
             Sequence *target;
@@ -64,7 +65,8 @@ Comparison *Comparison_create(Comparison_Param *param,
 Comparison *Comparison_share(Comparison *comparison);
 void Comparison_destroy(Comparison *comparison);
 void Comparison_print(Comparison *comparison);
-HSPset_ArgumentSet *Comparison_Param_get_HSPSet_Argument_Set(Comparison_Param *param);
+HSPset_ArgumentSet *Comparison_Param_get_HSPSet_Argument_Set(
+                    Comparison_Param *param);
 
 gboolean  Comparison_has_hsps(Comparison *comparison);
     void  Comparison_finalise(Comparison *comparison);
diff --git a/src/comparison/comparison.test.c b/src/comparison/comparison.test.c
index 98bf55e..7a367db 100644
--- a/src/comparison/comparison.test.c
+++ b/src/comparison/comparison.test.c
@@ -3,7 +3,7 @@
 *  Comparison : A module for pairwise sequence comparisons       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/hspset.c b/src/comparison/hspset.c
index 85d97a9..2bc42d7 100644
--- a/src/comparison/hspset.c
+++ b/src/comparison/hspset.c
@@ -3,7 +3,7 @@
 *  Library for HSP sets (high-scoring segment pairs)             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -66,13 +66,13 @@ HSPset_ArgumentSet *HSPset_ArgumentSet_create(Argument *arg){
         /**/
         ArgumentSet_add_option(as, 0, "dnawordlimit", "score",
             "Score limit for dna word neighbourhood", "0",
-            Argument_parse_int, &has.dna_wordlimit);
+            Argument_parse_int, &has.dna_word_limit);
         ArgumentSet_add_option(as, 0, "proteinwordlimit", "score",
             "Score limit for protein word neighbourhood", "4",
-            Argument_parse_int, &has.protein_wordlimit);
+            Argument_parse_int, &has.protein_word_limit);
         ArgumentSet_add_option(as, 0, "codonwordlimit", "score",
             "Score limit for codon word neighbourhood", "4",
-            Argument_parse_int, &has.codon_wordlimit);
+            Argument_parse_int, &has.codon_word_limit);
         /**/
         ArgumentSet_add_option(as, '\0', "geneseed", "threshold",
              "Geneseed Threshold", "0",
@@ -142,6 +142,61 @@ void HSP_Param_set_codon_hsp_threshold(HSP_Param *hsp_param,
 
 /**/
 
+static void HSP_Param_refresh_wordhood(HSP_Param *hsp_param){
+    register WordHood_Alphabet *wha = NULL;
+    register Submat *submat;
+    if(hsp_param->wordhood)
+        WordHood_destroy(hsp_param->wordhood);
+    if(hsp_param->has->use_wordhood_dropoff && (!hsp_param->wordlimit)){
+        hsp_param->wordhood = NULL;
+    } else {
+        submat = (hsp_param->match->type == Match_Type_DNA2DNA)
+               ? hsp_param->match->mas->dna_submat
+               : hsp_param->match->mas->protein_submat;
+        wha = WordHood_Alphabet_create_from_Submat(
+                (gchar*)hsp_param->match->comparison_alphabet->member,
+                (gchar*)hsp_param->match->comparison_alphabet->member,
+                submat, FALSE);
+        g_assert(wha);
+        hsp_param->wordhood = WordHood_create(wha, hsp_param->wordlimit,
+                                       hsp_param->has->use_wordhood_dropoff);
+        WordHood_Alphabet_destroy(wha);
+        }
+    return;
+    }
+/* FIXME: optimisation: do not free/recreate wordhood when unnecessary */
+
+void HSP_Param_set_dna_word_limit(HSP_Param *hsp_param,
+                                  gint dna_word_limit){
+    if(hsp_param->match->type == Match_Type_DNA2DNA){
+        hsp_param->wordlimit = dna_word_limit;
+        HSP_Param_refresh_wordhood(hsp_param);
+        }
+    return;
+    }
+
+void HSP_Param_set_protein_word_limit(HSP_Param *hsp_param,
+                                      gint protein_word_limit){
+    if((hsp_param->match->type == Match_Type_PROTEIN2PROTEIN)
+    || (hsp_param->match->type == Match_Type_PROTEIN2DNA)
+    || (hsp_param->match->type == Match_Type_DNA2PROTEIN)){
+        hsp_param->wordlimit = protein_word_limit;
+        HSP_Param_refresh_wordhood(hsp_param);
+        }
+    return;
+    }
+
+void HSP_Param_set_codon_word_limit(HSP_Param *hsp_param,
+                                    gint codon_word_limit){
+    if(hsp_param->match->type == Match_Type_CODON2CODON){
+        hsp_param->threshold = codon_word_limit;
+        HSP_Param_refresh_wordhood(hsp_param);
+        }
+    return;
+    }
+
+/**/
+
 void HSP_Param_set_dna_hsp_dropoff(HSP_Param *hsp_param,
                                    gint dna_hsp_dropoff){
     if(hsp_param->match->type == Match_Type_DNA2DNA)
@@ -181,9 +236,7 @@ void HSP_Param_set_seed_repeat(HSP_Param *hsp_param,
 
 HSP_Param *HSP_Param_create(Match *match, gboolean use_horizon){
     register HSP_Param *hsp_param = g_new(HSP_Param, 1);
-    register WordHood_Alphabet *wha = NULL;
-    register Submat *submat;
-    hsp_param->ref_count = 1;
+    hsp_param->thread_ref = ThreadRef_create();
     hsp_param->has = HSPset_ArgumentSet_create(NULL);
     hsp_param->match = match;
     hsp_param->seed_repeat = hsp_param->has->seed_repeat;
@@ -192,7 +245,7 @@ HSP_Param *HSP_Param_create(Match *match, gboolean use_horizon){
             hsp_param->dropoff = hsp_param->has->dna_hsp_dropoff;
             hsp_param->threshold = hsp_param->has->dna_hsp_threshold;
             HSP_Param_set_wordlen(hsp_param, hsp_param->has->dna_wordlen);
-            hsp_param->wordlimit = hsp_param->has->dna_wordlimit;
+            hsp_param->wordlimit = hsp_param->has->dna_word_limit;
             break;
         case Match_Type_PROTEIN2PROTEIN: /*fallthrough*/
         case Match_Type_PROTEIN2DNA:     /*fallthrough*/
@@ -201,13 +254,13 @@ HSP_Param *HSP_Param_create(Match *match, gboolean use_horizon){
             hsp_param->threshold
                 = hsp_param->has->protein_hsp_threshold;
             HSP_Param_set_wordlen(hsp_param, hsp_param->has->protein_wordlen);
-            hsp_param->wordlimit = hsp_param->has->protein_wordlimit;
+            hsp_param->wordlimit = hsp_param->has->protein_word_limit;
             break;
         case Match_Type_CODON2CODON:
             hsp_param->dropoff = hsp_param->has->codon_hsp_dropoff;
             hsp_param->threshold = hsp_param->has->codon_hsp_threshold;
             HSP_Param_set_wordlen(hsp_param, hsp_param->has->codon_wordlen);
-            hsp_param->wordlimit = hsp_param->has->codon_wordlimit;
+            hsp_param->wordlimit = hsp_param->has->codon_word_limit;
             g_assert(!(hsp_param->wordlen % 3));
             break;
         default:
@@ -215,36 +268,36 @@ HSP_Param *HSP_Param_create(Match *match, gboolean use_horizon){
             break;
         }
     hsp_param->use_horizon = use_horizon;
-    if(hsp_param->has->use_wordhood_dropoff && (!hsp_param->wordlimit)){
-        hsp_param->wordhood = NULL;
-    } else {
-        submat = (match->type == Match_Type_DNA2DNA)
-               ? match->mas->dna_submat
-               : match->mas->protein_submat;
-        wha = WordHood_Alphabet_create_from_Submat(
-                (gchar*)match->comparison_alphabet->member,
-                (gchar*)match->comparison_alphabet->member, submat, FALSE);
-        g_assert(wha);
-        hsp_param->wordhood = WordHood_create(wha, hsp_param->wordlimit,
-                                          hsp_param->has->use_wordhood_dropoff);
-        WordHood_Alphabet_destroy(wha);
-        }
+#ifdef USE_PTHREADS
+    pthread_mutex_init(&hsp_param->hsp_recycle_lock, NULL);
+#endif /* USE_PTHREADS */
+    hsp_param->hsp_recycle = RecycleBin_create("HSP", sizeof(HSP), 64);
+    hsp_param->wordhood = NULL;
+    HSP_Param_refresh_wordhood(hsp_param);
     return hsp_param;
     }
 
 void HSP_Param_destroy(HSP_Param *hsp_param){
     g_assert(hsp_param);
-    if(--hsp_param->ref_count)
+    if(ThreadRef_destroy(hsp_param->thread_ref))
         return;
     if(hsp_param->wordhood)
         WordHood_destroy(hsp_param->wordhood);
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&hsp_param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
+    RecycleBin_destroy(hsp_param->hsp_recycle);
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&hsp_param->hsp_recycle_lock);
+    pthread_mutex_destroy(&hsp_param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
     g_free(hsp_param);
     return;
     }
 
 HSP_Param *HSP_Param_share(HSP_Param *hsp_param){
     g_assert(hsp_param);
-    hsp_param->ref_count++;
+    ThreadRef_share(hsp_param->thread_ref);
     return hsp_param;
     }
 
@@ -254,8 +307,6 @@ HSP_Param *HSP_Param_swap(HSP_Param *hsp_param){
                             hsp_param->use_horizon);
     }
 
-static RecycleBin *global_hsp_recycle_bin = NULL;
-
 HSPset *HSPset_create(Sequence *query, Sequence *target,
                       HSP_Param *hsp_param){
     register HSPset *hsp_set = g_new(HSPset, 1);
@@ -266,15 +317,9 @@ HSPset *HSPset_create(Sequence *query, Sequence *target,
     hsp_set->target = Sequence_share(target);
     hsp_set->param = HSP_Param_share(hsp_param);
     /**/
-    if(global_hsp_recycle_bin){
-        hsp_set->hsp_recycle = RecycleBin_share(global_hsp_recycle_bin);
-    } else {
-        global_hsp_recycle_bin = RecycleBin_create("HSP", sizeof(HSP), 64);
-        hsp_set->hsp_recycle = global_hsp_recycle_bin;
-        }
     if(hsp_param->use_horizon){
         hsp_set->horizon = (gint****)Matrix4d_create(
-                                   1 + ((hsp_param->seed_repeat > 1)?1:0),
+                                   1 + ((hsp_param->seed_repeat > 1)?2:0),
                                    query->len,
                                    hsp_param->match->query->advance,
                                    hsp_param->match->target->advance,
@@ -295,6 +340,11 @@ HSPset *HSPset_create(Sequence *query, Sequence *target,
     hsp_set->is_empty = TRUE;
     return hsp_set;
     }
+/* horizon[score(,repeat_count,diag)]
+ *        [query_len]
+ *        [query_advance]
+ *        [target_advance]
+ */
 
 /**/
 
@@ -322,9 +372,6 @@ void HSPset_destroy(HSPset *hsp_set){
         HSP_destroy(hsp);
         }
     g_ptr_array_free(hsp_set->hsp_list, TRUE);
-    if(hsp_set->hsp_recycle->ref_count == 1) /* last active hsp_set */
-        global_hsp_recycle_bin = NULL;
-    RecycleBin_destroy(hsp_set->hsp_recycle);
     if(hsp_set->horizon)
         g_free(hsp_set->horizon);
     g_free(hsp_set);
@@ -520,9 +567,9 @@ static void HSP_Display_print(HSP_Display *hd){
         }
     HSP_Display_print_ruler(hd, hd->top->len-pos, pos, TRUE);
     g_print(" query:[%.*s]\n       [%.*s]\ntarget:[%.*s]\n",
-            hd->top->len-pos, hd->top->str+pos,
-            hd->mid->len-pos, hd->mid->str+pos,
-            hd->low->len-pos, hd->low->str+pos);
+            (gint)(hd->top->len-pos), hd->top->str+pos,
+            (gint)(hd->mid->len-pos), hd->mid->str+pos,
+            (gint)(hd->low->len-pos), hd->low->str+pos);
     HSP_Display_print_ruler(hd, hd->top->len-pos, pos, FALSE);
     g_print("\n");
     return;
@@ -766,11 +813,18 @@ static void HSP_extend(HSP *nh, gboolean forbid_masked){
     return;
     }
 /* The score cannot be allowed to drop below zero in the HSP,
- * as this can result in overlapping HSPs in some circurmstances.
+ * as this can result in overlapping HSPs in some circumstances.
  */
 
 static HSP *HSP_create(HSP *nh){
-    register HSP *hsp = RecycleBin_alloc(nh->hsp_set->hsp_recycle);
+    register HSP *hsp;
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&nh->hsp_set->param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
+    hsp = RecycleBin_alloc(nh->hsp_set->param->hsp_recycle);
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&nh->hsp_set->param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
     hsp->hsp_set = nh->hsp_set;
     hsp->query_start = nh->query_start;
     hsp->target_start = nh->target_start;
@@ -782,7 +836,13 @@ static HSP *HSP_create(HSP *nh){
 
 void HSP_destroy(HSP *hsp){
     register HSPset *hsp_set = hsp->hsp_set;
-    RecycleBin_recycle(hsp_set->hsp_recycle, hsp);
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&hsp_set->param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
+    RecycleBin_recycle(hsp_set->param->hsp_recycle, hsp);
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&hsp_set->param->hsp_recycle_lock);
+#endif /* USE_PTHREADS */
     return;
     }
 
@@ -885,6 +945,16 @@ void HSPset_seed_hsp(HSPset *hsp_set,
     /**/
     g_assert(section_pos >= 0);
     g_assert(section_pos < hsp_set->query->len);
+    /* Clear if diag has changed */
+    if(hsp_set->param->seed_repeat > 1){
+        if(hsp_set->horizon[2][section_pos][query_frame][target_frame]
+               != (diag_pos + hsp_set->query->len)){
+            hsp_set->horizon[0][section_pos][query_frame][target_frame] = 0;
+            hsp_set->horizon[1][section_pos][query_frame][target_frame] = 0;
+            hsp_set->horizon[2][section_pos][query_frame][target_frame]
+                = diag_pos + hsp_set->query->len;
+            }
+        }
     /* Check whether we have seen this HSP already */
     if(target_start < hsp_set->horizon[0]
                                       [section_pos]
@@ -963,6 +1033,7 @@ static void HSPset_seed_hsp_sorted(HSPset *hsp_set,
         horizon[0][query_frame][target_frame] = 0;
         horizon[2][query_frame][target_frame] = 0;
         }
+/* FIXME: seedrepeat overflow here */
     if(++horizon[2][query_frame][target_frame] < hsp_set->param->seed_repeat)
         return;
     horizon[2][query_frame][target_frame] = 0;
diff --git a/src/comparison/hspset.h b/src/comparison/hspset.h
index 1609054..8bdb5b6 100644
--- a/src/comparison/hspset.h
+++ b/src/comparison/hspset.h
@@ -3,7 +3,7 @@
 *  Library for HSP sets (high-scoring segment pairs)             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -32,6 +32,7 @@ extern "C" {
 #include "matrix.h"
 #include "wordhood.h"
 #include "recyclebin.h"
+#include "threadref.h"
 
 typedef struct {
         gint filter_threshold;
@@ -50,9 +51,9 @@ typedef struct {
         gint protein_hsp_threshold;
         gint codon_hsp_threshold;
     /**/
-        gint dna_wordlimit;
-        gint protein_wordlimit;
-        gint codon_wordlimit;
+        gint dna_word_limit;
+        gint protein_word_limit;
+        gint codon_word_limit;
     /**/
         gint geneseed_threshold;
         gint geneseed_repeat;
@@ -137,7 +138,7 @@ void HSP_destroy(HSP *hsp);
 #define HSPset_is_empty(hspset) ((hspset)->is_empty)
 
 typedef struct HSP_Param {
-              gint   ref_count;
+         ThreadRef  *thread_ref;
 HSPset_ArgumentSet  *has;
              Match  *match;
               gint   wordlen;
@@ -148,6 +149,10 @@ HSPset_ArgumentSet  *has;
           WordHood  *wordhood;
           gboolean   use_horizon;
               gint   seed_repeat;
+        RecycleBin  *hsp_recycle;
+#ifdef USE_PTHREADS
+   pthread_mutex_t   hsp_recycle_lock;
+#endif /* USE_PTHREADS */
 } HSP_Param;
 
 HSP_Param *HSP_Param_create(Match *match, gboolean use_horizon);
@@ -160,9 +165,16 @@ HSP_Param *HSP_Param_swap(HSP_Param *hsp_param);
      void  HSP_Param_set_dna_hsp_threshold(HSP_Param *hsp_param,
                                            gint dna_hsp_threshold);
      void  HSP_Param_set_protein_hsp_threshold(HSP_Param *hsp_param,
-                                               gint dna_hsp_threshold);
+                                               gint protein_hsp_threshold);
      void  HSP_Param_set_codon_hsp_threshold(HSP_Param *hsp_param,
-                                             gint dna_hsp_threshold);
+                                             gint protein_hsp_threshold);
+     /**/
+     void  HSP_Param_set_dna_word_limit(HSP_Param *hsp_param,
+                                        gint dna_word_limit);
+     void  HSP_Param_set_protein_word_limit(HSP_Param *hsp_param,
+                                            gint protein_word_limit);
+     void  HSP_Param_set_codon_word_limit(HSP_Param *hsp_param,
+                                          gint codon_word_limit);
      /**/
      void  HSP_Param_set_dna_hsp_dropoff(HSP_Param *hsp_param,
                                          gint dna_hsp_dropoff);
@@ -181,7 +193,6 @@ typedef struct HSPset {
           Sequence    *query;
           Sequence    *target;
          HSP_Param    *param;
-        RecycleBin    *hsp_recycle;
               gint ****horizon;
          GPtrArray    *hsp_list;
           /**/
diff --git a/src/comparison/hspset.test.c b/src/comparison/hspset.test.c
index 9ce764e..f807079 100644
--- a/src/comparison/hspset.test.c
+++ b/src/comparison/hspset.test.c
@@ -3,7 +3,7 @@
 *  Library for HSP sets (high-scoring segment pairs)             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/match.c b/src/comparison/match.c
index 3e0c2a1..a2aca26 100644
--- a/src/comparison/match.c
+++ b/src/comparison/match.c
@@ -3,7 +3,7 @@
 *  Match : A module for pairwise symbol comparison               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -37,10 +37,6 @@ static void Match_Argument_cleanup(gpointer user_data){
 Match_ArgumentSet *Match_ArgumentSet_create(Argument *arg){
     register ArgumentSet *as;
     static Match_ArgumentSet mas = {0};
-    if(!mas.translate){
-        mas.translate = Translate_create(FALSE);
-        /* FIXME this should be freed somewhere */
-        }
     if(arg){
         as = ArgumentSet_create("Symbol Comparison Options");
         ArgumentSet_add_option(as, 0, "softmaskquery", NULL,
@@ -60,6 +56,11 @@ Match_ArgumentSet *Match_ArgumentSet_create(Argument *arg){
         Argument_absorb_ArgumentSet(arg, as);
         Argument_add_cleanup(arg, Match_Argument_cleanup, NULL);
         /**/
+    } else {
+        if(!mas.translate){
+            mas.translate = Translate_create(FALSE);
+            /* FIXME this should be freed somewhere */
+            }
         }
     return &mas;
     }
diff --git a/src/comparison/match.h b/src/comparison/match.h
index 2f8b790..4008a27 100644
--- a/src/comparison/match.h
+++ b/src/comparison/match.h
@@ -3,7 +3,7 @@
 *  Match : A module for pairwise symbol comparison               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/match.test.c b/src/comparison/match.test.c
index 2565873..a75658c 100644
--- a/src/comparison/match.test.c
+++ b/src/comparison/match.test.c
@@ -3,7 +3,7 @@
 *  Match : A module for pairwise symbol comparison               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/pcr.c b/src/comparison/pcr.c
index acc5e9f..b99127d 100644
--- a/src/comparison/pcr.c
+++ b/src/comparison/pcr.c
@@ -3,7 +3,7 @@
 *  Library for PCR simulation                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/pcr.h b/src/comparison/pcr.h
index cde0285..8c5dfb0 100644
--- a/src/comparison/pcr.h
+++ b/src/comparison/pcr.h
@@ -3,7 +3,7 @@
 *  Library for PCR simulation                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/pcr.test.c b/src/comparison/pcr.test.c
index 1ebddad..fc91cbf 100644
--- a/src/comparison/pcr.test.c
+++ b/src/comparison/pcr.test.c
@@ -3,7 +3,7 @@
 *  Library for PCR simulation                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/seeder.c b/src/comparison/seeder.c
index 4c2172c..98469bc 100644
--- a/src/comparison/seeder.c
+++ b/src/comparison/seeder.c
@@ -3,7 +3,7 @@
 *  Seeder : A module for seeding pairwise alignments             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -25,13 +25,17 @@
      (*(type*)((char*)(instance) + (offset)))
 #endif /* OFFSET_ITEM */
 
+#ifndef Swap
+#define Swap(x,y,temp) ((temp)=(x),(x)=(y),(y)=(temp))
+#endif /* Swap */
+
 Seeder_ArgumentSet *Seeder_ArgumentSet_create(Argument *arg){
     register ArgumentSet *as;
     static Seeder_ArgumentSet sas;
     if(arg){
         as = ArgumentSet_create("Alignment Seeding Options");
         ArgumentSet_add_option(as, 'M', "fsmmemory", "Mb",
-                "Memory limit for FSM scanning", "64",
+                "Memory limit for FSM scanning", "256",
                 Argument_parse_int, &sas.fsm_memory_limit);
         ArgumentSet_add_option(as, '\0', "forcefsm", "fsm type",
             "Force FSM type ( normal | compact )", "none",
@@ -39,6 +43,9 @@ Seeder_ArgumentSet *Seeder_ArgumentSet_create(Argument *arg){
         ArgumentSet_add_option(as, 0, "wordjump", NULL,
             "Jump between query words", "1",
             Argument_parse_int, &sas.word_jump);
+        ArgumentSet_add_option(as, 0, "wordambiguity", NULL,
+            "Number of ambiguous words to expand", "1",
+            Argument_parse_int, &sas.word_ambiguity);
         Argument_absorb_ArgumentSet(arg, as);
         }
     return &sas;
@@ -302,6 +309,14 @@ Seeder *Seeder_create(gint verbosity,
                       gpointer user_data){
     register Seeder *seeder = g_new0(Seeder, 1);
     seeder->sas = Seeder_ArgumentSet_create(NULL);
+    if(seeder->sas->word_ambiguity < 1)
+        g_error("Word ambiguity cannot be less than one.");
+    if(seeder->sas->word_ambiguity > 1){
+        if(comparison_param->protein_hsp_param)
+            g_error("Protein ambuiguity symbols not implemented");
+        g_warning("setting --wordambiguity in exonerate will be SLOW.");
+        g_warning("... use esd2esi --wordambiguity and exonerate-server instead");
+        }
     seeder->is_prepared = FALSE;
     seeder->verbosity = verbosity;
     seeder->report_func = report_func;
@@ -413,25 +428,25 @@ gsize Seeder_memory_usage(Seeder *seeder){
     }
 
 void Seeder_memory_info(Seeder *seeder){
-    g_message("Seeder Total = %dMb", Seeder_memory_usage(seeder)>>20);
+    g_message("Seeder Total = %dMb", (gint)(Seeder_memory_usage(seeder)>>20));
     g_assert(seeder);
     if(seeder->seeder_fsm)
         g_message(" -> FSM memory = %dMb",
-                Seeder_FSM_memory_usage(seeder->seeder_fsm)>>20);
+                (gint)(Seeder_FSM_memory_usage(seeder->seeder_fsm)>>20));
     else
         g_message(" -> VFSM memory = %dMb",
-                Seeder_VFSM_memory_usage(seeder->seeder_vfsm)>>20);
+                (gint)(Seeder_VFSM_memory_usage(seeder->seeder_vfsm)>>20));
     g_message(" -> QueryInfo memory = %dMb",
-           (seeder->query_info_list->len
+           (gint)(seeder->query_info_list->len
             *(sizeof(gpointer)+sizeof(Seeder_QueryInfo)))>>20);
     g_message(" -> Recycle_Wordinfo Memory = %dMb",
-           RecycleBin_memory_usage(seeder->recycle_wordinfo)>>20);
+           (gint)(RecycleBin_memory_usage(seeder->recycle_wordinfo)>>20));
     g_message(" -> Recycle_Seed Memory = %dMb",
-           RecycleBin_memory_usage(seeder->recycle_seed)>>20);
+           (gint)(RecycleBin_memory_usage(seeder->recycle_seed)>>20));
     g_message(" -> Recycle_Neighbour Memory = %dMb",
-           RecycleBin_memory_usage(seeder->recycle_neighbour)>>20);
+           (gint)(RecycleBin_memory_usage(seeder->recycle_neighbour)>>20));
     g_message(" -> Recycle_Context Memory = %dMb",
-           RecycleBin_memory_usage(seeder->recycle_context)>>20);
+           (gint)(RecycleBin_memory_usage(seeder->recycle_context)>>20));
     return;
     }
 
@@ -515,8 +530,10 @@ static void Seeder_insert_query(Seeder *seeder, Seeder_Context *context,
         } else {
             leaf = VFSM_state2leaf(vfsm, state);
             word_info = seeder->seeder_vfsm->leaf[leaf];
-            if(!word_info)
+            if(!word_info){
                 word_info = Seeder_WordInfo_create(seeder);
+                seeder->seeder_vfsm->leaf[leaf] = word_info;
+                }
             }
         g_assert(word_info);
         if(frame)
@@ -675,8 +692,8 @@ static void Seeder_FSM_traverse_func(guint seq_pos,
     return;
     }
 
-static void Seeder_VFSM_traverse(Seeder *seeder, gchar *seq,
-                                 Seeder_TargetInfo *target_info){
+static void Seeder_VFSM_traverse_single(Seeder *seeder, gchar *seq,
+                                        Seeder_TargetInfo *target_info){
     register gint i, ch;
     register VFSM_Int state = 0, leaf;
     register VFSM *vfsm = seeder->seeder_vfsm->vfsm;
@@ -700,6 +717,68 @@ static void Seeder_VFSM_traverse(Seeder *seeder, gchar *seq,
     return;
     }
 
+static void Seeder_VFSM_traverse_ambig(Seeder *seeder, gchar *seq,
+                                       Seeder_TargetInfo *target_info){
+    register gint i, j, k, ch;
+    register VFSM_Int state, next_state, leaf;
+    register VFSM *vfsm = seeder->seeder_vfsm->vfsm;
+    register Seeder_WordInfo *word_info;
+    register gchar *ambig;
+    register VFSM_Int *temp_state_list,
+                      *curr_state_list = g_new0(VFSM_Int,
+                                                seeder->sas->word_ambiguity),
+                      *next_state_list = g_new0(VFSM_Int,
+                                                seeder->sas->word_ambiguity);
+    register gint curr_state_list_len = 1, next_state_list_len = 0;
+    g_assert(vfsm);
+    for(i = 0; seq[i]; i++){
+        ch = toupper(seq[i]); /* FIXME: filter properly */
+        if((!(ambig = Alphabet_nt2ambig(ch)))
+        || ((strlen(ambig) * curr_state_list_len)
+        > seeder->sas->word_ambiguity)){
+            next_state_list_len = 0;
+            curr_state_list_len = 1;
+            curr_state_list[0] = 0;
+            continue;
+            }
+        for(j = 0; j < curr_state_list_len; j++){
+            state = curr_state_list[j];
+            for(k = 0; ambig[k]; k++){
+                g_assert(vfsm->index[(guchar)ambig[k]]);
+                next_state = VFSM_change_state_M(vfsm,
+                                  state, (guchar)ambig[k]);
+                /* FIXME: use POW2 versions where applicable */
+                if(next_state_list_len
+                && ((next_state == next_state_list[0])
+                 || (next_state == next_state_list[next_state_list_len-1])))
+                    break;
+                next_state_list[next_state_list_len++] = next_state;
+                if(VFSM_state_is_leaf(vfsm, next_state)){
+                    leaf = VFSM_state2leaf(vfsm, next_state);
+                    word_info = seeder->seeder_vfsm->leaf[leaf];
+                    if(word_info)
+                        Seeder_FSM_traverse_func(i, word_info, target_info);
+                    }
+                }
+            }
+        curr_state_list_len = next_state_list_len;
+        next_state_list_len = 0;
+        Swap(next_state_list, curr_state_list, temp_state_list);
+        }
+    g_free(curr_state_list);
+    g_free(next_state_list);
+    return;
+    }
+
+static void Seeder_VFSM_traverse(Seeder *seeder, gchar *seq,
+                                 Seeder_TargetInfo *target_info){
+    if(seeder->sas->word_ambiguity > 1)
+        Seeder_VFSM_traverse_ambig(seeder, seq, target_info);
+    else
+        Seeder_VFSM_traverse_single(seeder, seq, target_info);
+    return;
+    }
+
 static void Seeder_prepare(Seeder *seeder){
     g_assert(!seeder->is_prepared);
     if(seeder->seeder_fsm)
@@ -708,6 +787,67 @@ static void Seeder_prepare(Seeder *seeder){
     return;
     }
 
+static void Seeder_FSM_traverse_ambig(Seeder *seeder, gchar *seq,
+                                      FSM_Traverse_Func ftf, gpointer user_data){
+    register FSM *f = seeder->seeder_fsm->fsm;
+    register FSM_Node *n, *next_state;
+    register gint c;
+    register gchar *ambig;
+    register gint i, j, k;
+    register FSM_Node **temp_state_list,
+                      **curr_state_list = g_new0(FSM_Node*,
+                                                seeder->sas->word_ambiguity),
+                      **next_state_list = g_new0(FSM_Node*,
+                                                seeder->sas->word_ambiguity);
+    register gint curr_state_list_len = 1, next_state_list_len = 0;
+    g_assert(f->is_compiled);
+    curr_state_list[0] = f->root;
+    for(i = 0; seq[i]; i++){
+        if((!(ambig = Alphabet_nt2ambig(seq[i])))
+        || ((strlen(ambig) * curr_state_list_len)
+            > seeder->sas->word_ambiguity)){
+            next_state_list_len = 0;
+            curr_state_list_len = 1;
+            curr_state_list[0] = f->root;
+            continue;
+            }
+        for(j = 0; j < curr_state_list_len; j++){
+            n = curr_state_list[j];
+            for(k = 0; ambig[k]; k++){
+                c = f->traversal_filter[(guchar)ambig[k]];
+                if(n[c].data)
+                    ftf(i, n[c].data, user_data);
+                next_state = n[c].next;
+                if(next_state_list_len
+                && ((next_state == next_state_list[0])
+                   || (next_state ==
+                       next_state_list[next_state_list_len-1]))){
+                    break;
+                    }
+                next_state_list[next_state_list_len++] = next_state;
+                }
+            }
+        curr_state_list_len = next_state_list_len;
+        next_state_list_len = 0;
+        /* g_message("set curr [%d]", curr_state_list_len); */
+        Swap(next_state_list, curr_state_list, temp_state_list);
+        }
+    g_free(curr_state_list);
+    g_free(next_state_list);
+    return;
+    }
+/* Slow (ambiguous) version of FSM_traverse */
+/* FIXME: optimisation: remove strlen() etc */
+
+static void Seeder_FSM_traverse(Seeder *seeder, gchar *seq, FSM_Traverse_Func ftf,
+                                gpointer user_data){
+    if(seeder->sas->word_ambiguity > 1)
+        Seeder_FSM_traverse_ambig(seeder, seq, ftf, user_data);
+    else
+        FSM_traverse(seeder->seeder_fsm->fsm, seq, ftf, user_data);
+    return;
+    }
+
 void Seeder_add_target(Seeder *seeder, Sequence *target){
     register gint i;
     register Sequence *aa_seq;
@@ -735,8 +875,8 @@ void Seeder_add_target(Seeder *seeder, Sequence *target){
             seq = Sequence_get_str(target_masked);
             Sequence_destroy(target_masked);
             if(seeder->seeder_fsm)
-                FSM_traverse(seeder->seeder_fsm->fsm, seq,
-                             Seeder_FSM_traverse_func, &target_info);
+                Seeder_FSM_traverse(seeder, seq,
+                                    Seeder_FSM_traverse_func, &target_info);
             else
                 Seeder_VFSM_traverse(seeder, seq, &target_info);
             g_free(seq);
@@ -747,8 +887,8 @@ void Seeder_add_target(Seeder *seeder, Sequence *target){
         seq = Sequence_get_str(target_masked);
         Sequence_destroy(target_masked);
         if(seeder->seeder_fsm){
-            FSM_traverse(seeder->seeder_fsm->fsm, seq,
-                    Seeder_FSM_traverse_func, &target_info);
+            Seeder_FSM_traverse(seeder, seq,
+                                Seeder_FSM_traverse_func, &target_info);
         } else {
             Seeder_VFSM_traverse(seeder, seq, &target_info);
             }
diff --git a/src/comparison/seeder.h b/src/comparison/seeder.h
index ccfa2aa..cb3f4d0 100644
--- a/src/comparison/seeder.h
+++ b/src/comparison/seeder.h
@@ -3,7 +3,7 @@
 *  Seeder : A module for seeding pairwise alignments             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -32,6 +32,7 @@ typedef struct {
        gsize  fsm_memory_limit;
        gchar *force_fsm;
         gint  word_jump;
+        gint  word_ambiguity;
 } Seeder_ArgumentSet;
 
 Seeder_ArgumentSet *Seeder_ArgumentSet_create(Argument *arg);
diff --git a/src/comparison/seeder.test.c b/src/comparison/seeder.test.c
index a1144b0..250cb51 100644
--- a/src/comparison/seeder.test.c
+++ b/src/comparison/seeder.test.c
@@ -3,7 +3,7 @@
 *  Seeder : A module for seeding pairwise alignments             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/wordhood.c b/src/comparison/wordhood.c
index 5946ca0..ad4729c 100644
--- a/src/comparison/wordhood.c
+++ b/src/comparison/wordhood.c
@@ -3,7 +3,7 @@
 *  Library for word-neighbourhood generation                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/wordhood.h b/src/comparison/wordhood.h
index 635a204..f9eaaac 100644
--- a/src/comparison/wordhood.h
+++ b/src/comparison/wordhood.h
@@ -3,7 +3,7 @@
 *  Library for word-neighbourhood generation                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/comparison/wordhood.test.c b/src/comparison/wordhood.test.c
index 350f2d8..d490cf9 100644
--- a/src/comparison/wordhood.test.c
+++ b/src/comparison/wordhood.test.c
@@ -3,7 +3,7 @@
 *  Library for word-neighbourhood generation                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/database/Makefile.am b/src/database/Makefile.am
index e101cb6..cc10116 100644
--- a/src/database/Makefile.am
+++ b/src/database/Makefile.am
@@ -1,13 +1,16 @@
 
 TESTS = fastadb.test fastapipe.test dataset.test index.test
+# seqfmi.test
 noinst_PROGRAMS = $(TESTS)
 
 INCLUDES = -I$(top_srcdir)/src/sequence   \
            -I$(top_srcdir)/src/struct     \
            -I$(top_srcdir)/src/general    \
-           -I$(top_srcdir)/src/comparison
+           -I$(top_srcdir)/src/comparison \
+           -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""
 
 noinst_HEADERS = fastadb.h fastapipe.h dataset.h index.h
+# seqfmi.h
 
 SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
                $(top_srcdir)/src/struct/matrix.o       \
@@ -36,6 +39,7 @@ dataset_test_LDADD = fastadb.o                                \
 index_test_SOURCES = index.test.c index.c
 index_test_LDADD = fastadb.o dataset.o                        \
                    $(top_srcdir)/src/general/compoundfile.o   \
+                   $(top_srcdir)/src/general/threadref.o      \
                    $(top_srcdir)/src/struct/bitarray.o        \
                    $(top_srcdir)/src/struct/vfsm.o            \
                    $(top_srcdir)/src/struct/pqueue.o          \
@@ -50,6 +54,16 @@ index_test_LDADD = fastadb.o dataset.o                        \
                    $(top_srcdir)/src/sequence/codonsubmat.o   \
                    $(SEQUENCE_OBJ)
 
+# seqfmi_test_SOURCES = seqfmi.test.c seqfmi.c
+# seqfmi_test_LDADD = fastadb.o                                  \
+#                     $(top_srcdir)/src/general/compoundfile.o   \
+#                     $(top_srcdir)/src/struct/fmindex.o         \
+#                     $(top_srcdir)/src/struct/bitarray.o        \
+#                     $(top_srcdir)/src/struct/pqueue.o          \
+#                     $(top_srcdir)/src/struct/recyclebin.o      \
+#                     $(top_srcdir)/src/struct/huffman.o         \
+#                     $(SEQUENCE_OBJ)
+
 # Files to clear away
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/database/Makefile.in b/src/database/Makefile.in
index 42a35e8..08ceb42 100644
--- a/src/database/Makefile.in
+++ b/src/database/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -79,12 +80,14 @@ source_root_dir = @source_root_dir@
 use_pthreads = @use_pthreads@
 
 TESTS = fastadb.test fastapipe.test dataset.test index.test
+# seqfmi.test
 noinst_PROGRAMS = $(TESTS)
 
-INCLUDES = -I$(top_srcdir)/src/sequence              -I$(top_srcdir)/src/struct                -I$(top_srcdir)/src/general               -I$(top_srcdir)/src/comparison
+INCLUDES = -I$(top_srcdir)/src/sequence              -I$(top_srcdir)/src/struct                -I$(top_srcdir)/src/general               -I$(top_srcdir)/src/comparison            -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""
 
 
 noinst_HEADERS = fastadb.h fastapipe.h dataset.h index.h
+# seqfmi.h
 
 SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  -lm
 
@@ -101,9 +104,19 @@ dataset_test_LDADD = fastadb.o
 
 
 index_test_SOURCES = index.test.c index.c
-index_test_LDADD = fastadb.o dataset.o                                           $(top_srcdir)/src/general/compoundfile.o                      $(top_srcdir)/src/struct/bitarray.o                           $(top_srcdir)/src/struct/vfsm.o                               $(top_srcdir)/src/struct/pqueue.o                             $(top_srcdir)/src/struct/recyclebin.o                         $(top_srcdir)/src/struct/rangetree.o                          $(top_srcdir)/src/struct/splaytree.o    [...]
+index_test_LDADD = fastadb.o dataset.o                                           $(top_srcdir)/src/general/compoundfile.o                      $(top_srcdir)/src/general/threadref.o                         $(top_srcdir)/src/struct/bitarray.o                           $(top_srcdir)/src/struct/vfsm.o                               $(top_srcdir)/src/struct/pqueue.o                             $(top_srcdir)/src/struct/recyclebin.o                         $(top_srcdir)/src/struct/rangetree.o    [...]
 
 
+# seqfmi_test_SOURCES = seqfmi.test.c seqfmi.c
+# seqfmi_test_LDADD = fastadb.o                                  \
+#                     $(top_srcdir)/src/general/compoundfile.o   \
+#                     $(top_srcdir)/src/struct/fmindex.o         \
+#                     $(top_srcdir)/src/struct/bitarray.o        \
+#                     $(top_srcdir)/src/struct/pqueue.o          \
+#                     $(top_srcdir)/src/struct/recyclebin.o      \
+#                     $(top_srcdir)/src/struct/huffman.o         \
+#                     $(SEQUENCE_OBJ)
+
 # Files to clear away
 
 MAINTAINERCLEANFILES = Makefile.in
@@ -152,6 +165,7 @@ dataset_test_LDFLAGS =
 index_test_OBJECTS =  index.test.o index.o
 index_test_DEPENDENCIES =  fastadb.o dataset.o \
 $(top_srcdir)/src/general/compoundfile.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/struct/bitarray.o $(top_srcdir)/src/struct/vfsm.o \
 $(top_srcdir)/src/struct/pqueue.o $(top_srcdir)/src/struct/recyclebin.o \
 $(top_srcdir)/src/struct/rangetree.o \
diff --git a/src/database/dataset.c b/src/database/dataset.c
index 0b3db48..e0e010e 100644
--- a/src/database/dataset.c
+++ b/src/database/dataset.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of exonerate dataset files           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -23,7 +23,7 @@
 /**/
 
 #define DATASET_HEADER_MAGIC (('e' << 16)|('s' << 8)|('d'))
-#define DATASET_HEADER_VERSION 2
+#define DATASET_HEADER_VERSION 3
 
 static Dataset_Header *Dataset_Header_create(Alphabet_Type alphabet_type,
                                              gboolean softmask_input){
@@ -301,6 +301,23 @@ gsize Dataset_memory_usage(Dataset *dataset){
          + dataset_sequence_memory;
     }
 
+void Dataset_info(Dataset *dataset){
+    g_print("Sequence Dataset:\n"
+            "----------------\n"
+            "             version: %d\n"
+            "                type: %s, %s\n"
+            "          total size: %d Mb\n"
+            " number of sequences: %lld\n"
+            "    longest sequence: %lld\n\n",
+            (gint)dataset->header->version,
+            (dataset->header->type & 1)?"DNA":"PROTEIN",
+            (dataset->header->type & 2)?"masked":"unmasked",
+            (gint)(dataset->header->total_db_len >> 20),
+            dataset->header->number_of_seqs,
+            dataset->header->max_seq_len);
+    return;
+    }
+
 void Dataset_destroy(Dataset *dataset){
     register gint i;
     register Dataset_Sequence *seq;
@@ -378,10 +395,10 @@ static void Dataset_write_seq_data(Dataset *dataset, FILE *fp){
     }
 
 static void Dataset_read_seq_data(Dataset *dataset, FILE *fp){
-    register gint i, j = 0, ipos, dpos;
+    register gint64 i, j = 0, ipos, dpos;
     register Dataset_Sequence *ds;
-    register gint len = dataset->header->seq_info_offset
-                      - dataset->header->seq_data_offset;
+    register guint64 len = dataset->header->seq_info_offset
+                         - dataset->header->seq_data_offset;
     register gchar *buf = g_new(gchar, len+1);
     if(!fread(buf, sizeof(gchar), len, fp))
         g_error("Problem reading seq data");
diff --git a/src/database/dataset.h b/src/database/dataset.h
index 3eee050..9fa2a79 100644
--- a/src/database/dataset.h
+++ b/src/database/dataset.h
@@ -3,7 +3,7 @@
 *  Library for manipulation of exonerate dataset files           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -97,6 +97,7 @@ Dataset *Dataset_create(GPtrArray *path_list,
                         gboolean softmask_input);
  Dataset *Dataset_share(Dataset *dataset);
     void  Dataset_destroy(Dataset *dataset);
+    void  Dataset_info(Dataset *dataset);
    gsize  Dataset_memory_usage(Dataset *dataset);
 gboolean  Dataset_check_filetype(gchar *path);
 /* Returns TRUE when magic number is correct for this filetype */
diff --git a/src/database/dataset.test.c b/src/database/dataset.test.c
index a9e4ae8..165ddcf 100644
--- a/src/database/dataset.test.c
+++ b/src/database/dataset.test.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of FASTA format databases            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/database/fastadb.c b/src/database/fastadb.c
index 9296502..90c3565 100644
--- a/src/database/fastadb.c
+++ b/src/database/fastadb.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of FASTA format databases            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -202,6 +202,19 @@ FastaDB *FastaDB_share(FastaDB *fdb){
     return fdb;
     }
 
+FastaDB *FastaDB_dup(FastaDB *fdb){
+    register FastaDB *nfdb = g_new(FastaDB, 1);
+    nfdb->ref_count = 1;
+    nfdb->alphabet = Alphabet_create(fdb->alphabet->type,
+                                     fdb->alphabet->is_soft_masked);
+    nfdb->cf = CompoundFile_dup(fdb->cf);
+    nfdb->out_buffer_alloc = FASTADB_OUT_BUFFER_CHUNK_SIZE;
+    nfdb->out_buffer = g_malloc(sizeof(gchar)*nfdb->out_buffer_alloc);
+    nfdb->line_length = -1;
+    FastaDB_rewind(nfdb);
+    return nfdb;
+    }
+
 void FastaDB_close(FastaDB *fdb){
     g_assert(fdb);
     if(--fdb->ref_count)
@@ -238,6 +251,30 @@ CompoundFile_Pos FastaDB_find_next_start(FastaDB *fdb,
     return CompoundFile_ftell(fdb->cf)-1;
     }
 
+gboolean FastaDB_file_is_fasta(gchar *path){
+    register FILE *fp = fopen(path, "r");
+    register gint ch;
+    register gboolean result = FALSE;
+    if(!fp)
+        g_error("Could not open file [%s]", path);
+    while(((ch = getc(fp)) != EOF)){
+        if(isspace(ch))
+            continue;
+        else
+            if(ch == '>'){ /* Assume is fasta format */
+                result = TRUE;
+                break;
+                }
+        else
+            break;
+        }
+    fclose(fp);
+    return result;
+    }
+/* Assumes a file is fasta format
+ * if the first non-whitespace character is '>'
+ */
+
 gboolean FastaDB_is_finished(FastaDB *fdb){
     g_assert(fdb);
     return CompoundFile_is_finished(fdb->cf);
diff --git a/src/database/fastadb.h b/src/database/fastadb.h
index 8dd01c0..81301df 100644
--- a/src/database/fastadb.h
+++ b/src/database/fastadb.h
@@ -3,7 +3,7 @@
 *  Library for manipulation of FASTA format databases            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -73,6 +73,7 @@ typedef gboolean (*FastaDB_TraverseFunc)(FastaDB_Seq *fdbs,
              Alphabet *alphabet, gint chunk_id, gint chunk_total);
     FastaDB *FastaDB_open(gchar *path, Alphabet *alphabet);
     FastaDB *FastaDB_share(FastaDB *fdb);
+    FastaDB *FastaDB_dup(FastaDB *fdb); /* For use in a separate thread */
        void  FastaDB_close(FastaDB *fdb);
        void  FastaDB_rewind(FastaDB *fdb);
    gboolean  FastaDB_is_finished(FastaDB *fdb);
@@ -84,6 +85,9 @@ typedef gboolean (*FastaDB_TraverseFunc)(FastaDB_Seq *fdbs,
 CompoundFile_Pos  FastaDB_find_next_start(FastaDB *fdb,
                                           CompoundFile_Pos pos);
 
+    gboolean FastaDB_file_is_fasta(gchar *path);
+    /* Returns true if first non-whitespace character in file is '>' */
+
 typedef struct {
                 FastaDB *source;
   CompoundFile_Location *location;
diff --git a/src/database/fastadb.test.c b/src/database/fastadb.test.c
index a9e4ae8..165ddcf 100644
--- a/src/database/fastadb.test.c
+++ b/src/database/fastadb.test.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of FASTA format databases            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/database/fastapipe.c b/src/database/fastapipe.c
index daa45de..e336d7f 100644
--- a/src/database/fastapipe.c
+++ b/src/database/fastapipe.c
@@ -3,7 +3,7 @@
 *  Library for All-vs-All Fasta Database Comparisons             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -21,7 +21,8 @@ FastaPipe *FastaPipe_create(FastaDB *query_fdb, FastaDB *target_fdb,
                FastaPipe_Boundary_Func term_func,
                FastaPipe_NextSeq_Func query_func,
                FastaPipe_NextSeq_Func target_func,
-               FastaDB_Mask mask, gboolean translate_both){
+               FastaDB_Mask mask, gboolean translate_both,
+               gboolean use_revcomp){
     register FastaPipe *fasta_pipe = g_new(FastaPipe, 1);
     g_assert(init_func);
     g_assert(prep_func);
@@ -37,12 +38,17 @@ FastaPipe *FastaPipe_create(FastaDB *query_fdb, FastaDB *target_fdb,
     fasta_pipe->target_func = target_func;
     fasta_pipe->mask = mask;
     fasta_pipe->is_full = FALSE;
-    fasta_pipe->revcomp_query
-        = (query_fdb->alphabet->type == Alphabet_Type_DNA);
-    fasta_pipe->revcomp_target
-        = (((query_fdb->alphabet->type == Alphabet_Type_PROTEIN)
-            && (target_fdb->alphabet->type == Alphabet_Type_DNA))
-          || translate_both);
+    if(use_revcomp){
+        fasta_pipe->revcomp_query
+            = (query_fdb->alphabet->type == Alphabet_Type_DNA);
+        fasta_pipe->revcomp_target
+            = (((query_fdb->alphabet->type == Alphabet_Type_PROTEIN)
+                && (target_fdb->alphabet->type == Alphabet_Type_DNA))
+              || translate_both);
+    } else {
+        fasta_pipe->revcomp_query = FALSE;
+        fasta_pipe->revcomp_target = FALSE;
+        }
     fasta_pipe->prev_query = NULL;
     fasta_pipe->prev_target = NULL;
     return fasta_pipe;
diff --git a/src/database/fastapipe.h b/src/database/fastapipe.h
index 1a6ad26..7db108e 100644
--- a/src/database/fastapipe.h
+++ b/src/database/fastapipe.h
@@ -3,7 +3,7 @@
 *  Library for All-vs-All Fasta Database Comparisons             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -50,7 +50,8 @@ FastaPipe *FastaPipe_create(FastaDB *query_fdb, FastaDB *target_fdb,
                             FastaPipe_Boundary_Func term_func,
                             FastaPipe_NextSeq_Func query_func,
                             FastaPipe_NextSeq_Func target_func,
-                            FastaDB_Mask mask, gboolean translate_both);
+                            FastaDB_Mask mask, gboolean translate_both,
+                            gboolean use_revcomp);
 /* query_func can return TRUE to finish loading current pipeline
  * target_func can return TRUE to finish processing of the pipeline
  */
diff --git a/src/database/fastapipe.test.c b/src/database/fastapipe.test.c
index 9877250..9cd5392 100644
--- a/src/database/fastapipe.test.c
+++ b/src/database/fastapipe.test.c
@@ -3,7 +3,7 @@
 *  Library for All-vs-All Fasta Database Comparisons             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -68,7 +68,7 @@ gint Argument_main(Argument *arg){
         fasta_pipe = FastaPipe_create(query_fdb, target_fdb,
                 test_init_func, test_prep_func, test_term_func,
                 test_query_func, test_target_func, FastaDB_Mask_ALL,
-                FALSE);
+                FALSE, TRUE);
         Alphabet_destroy(alphabet);
         while(FastaPipe_process(fasta_pipe, &count)){
             g_message("Processing pipeline");
diff --git a/src/database/index.c b/src/database/index.c
index 9a5a1d7..1bc8824 100644
--- a/src/database/index.c
+++ b/src/database/index.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of exonerate index files             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -26,7 +26,7 @@
 #include "noitree.h"
 
 #define INDEX_HEADER_MAGIC (('e' << 16)|('s' << 8)|('i'))
-#define INDEX_HEADER_VERSION 2
+#define INDEX_HEADER_VERSION 3
 
 static off_t Index_ftell(FILE *fp){
     return ftello(fp);
@@ -38,7 +38,7 @@ static off_t Index_ftell(FILE *fp){
 static off_t Index_fseek(FILE *fp, off_t offset, int whence){
     return fseeko(fp, offset, whence);
     }
-/* FIXME: need alternatives in absence of ftello() 
+/* FIXME: need alternatives in absence of fseeko()
  *        lseek(fileno(fp), offset, whence); ??
  */
 
@@ -78,7 +78,9 @@ static gsize Index_Word_get_address_list_space(Index_Word *index_word,
 
 static Index_Header *Index_Header_create(gint dataset_path_len,
                                          gboolean is_translated,
-                                         gint word_length, gint word_jump,
+                                         gint word_length,
+                                         gint word_jump,
+                                         gint word_ambiguity,
                                          gint saturate_threshold){
     register Index_Header *index_header = g_new0(Index_Header, 1);
     index_header->magic = INDEX_HEADER_MAGIC;
@@ -88,6 +90,7 @@ static Index_Header *Index_Header_create(gint dataset_path_len,
     /**/
     index_header->word_length = word_length;
     index_header->word_jump = word_jump;
+    index_header->word_ambiguity = word_ambiguity;
     index_header->saturate_threshold = saturate_threshold;
     return index_header;
     }
@@ -100,21 +103,23 @@ static void Index_Header_destroy(Index_Header *index_header){
 #if 0
 static void Index_Header_info(Index_Header *index_header){
     g_message("Index_Header:\n"
-              "    magic [%d]\n"
-              "    version [%d]\n"
-              "    type [%d]\n"
-              "    dataset_path_len [%d]\n"
+              "    magic [%lld]\n"
+              "    version [%lld]\n"
+              "    type [%lld]\n"
+              "    dataset_path_len [%lld]\n"
               "\n"
-              "    word_length [%d]\n"
-              "    word_jump [%d]\n"
-              "    saturate_threshold [%d]\n",
-           (gint)index_header->magic,
-           (gint)index_header->version,
-           (gint)index_header->type,
-           (gint)index_header->dataset_path_len,
-           (gint)index_header->word_length,
-           (gint)index_header->word_jump,
-           (gint)index_header->saturate_threshold);
+              "    word_length [%lld]\n"
+              "    word_jump [%lld]\n"
+              "    word_ambiguity [%lld]\n"
+              "    saturate_threshold [%lld]\n",
+           index_header->magic,
+           index_header->version,
+           index_header->type,
+           index_header->dataset_path_len,
+           index_header->word_length,
+           index_header->word_jump,
+           index_header->word_ambiguity,
+           index_header->saturate_threshold);
     return;
     }
 #endif /* 0 */
@@ -128,6 +133,7 @@ static void Index_Header_write(Index_Header *index_header, FILE *fp){
     /**/
     BitArray_write_int(index_header->word_length, fp);
     BitArray_write_int(index_header->word_jump, fp);
+    BitArray_write_int(index_header->word_ambiguity, fp);
     BitArray_write_int(index_header->saturate_threshold, fp);
     /**/
     return;
@@ -146,6 +152,7 @@ static Index_Header *Index_Header_read(FILE *fp){
     /**/
     index_header->word_length = BitArray_read_int(fp);
     index_header->word_jump  = BitArray_read_int(fp);
+    index_header->word_ambiguity = BitArray_read_int(fp);
     index_header->saturate_threshold = BitArray_read_int(fp);
     /* Index_Header_info(index_header); */
     return index_header;
@@ -186,7 +193,7 @@ typedef void (*Index_WordVisit_Func)(Index *index, Index_Strand *strand,
                                      gint seq_pos, gint leaf_id,
                                      gpointer user_data);
 
-static void Index_visit_seq_words(Index *index, Index_Strand *index_strand,
+static void Index_visit_seq_words_single(Index *index, Index_Strand *index_strand,
                                   gint seq_id, Sequence *seq,
                                   Index_WordVisit_Func iwvf, gint frame,
                                   gpointer user_data){
@@ -215,6 +222,81 @@ static void Index_visit_seq_words(Index *index, Index_Strand *index_strand,
     }
 /* FIXME: needs to work with softmasked sequences */
 
+#ifndef Swap
+#define Swap(x,y,temp) ((temp)=(x),(x)=(y),(y)=(temp))
+#endif /* Swap */
+
+static void Index_visit_seq_words_ambig(Index *index, Index_Strand *index_strand,
+                                  gint seq_id, Sequence *seq,
+                                  Index_WordVisit_Func iwvf, gint frame,
+                                  gpointer user_data){
+    register gint i, j, k, jump_ctr = 0, pos;
+    register gchar *ambig, *str = Sequence_get_str(seq);
+    register VFSM_Int state, next_state, leaf;
+    register VFSM_Int *temp_state_list,
+                      *curr_state_list = g_new0(VFSM_Int,
+                                                index->header->word_ambiguity),
+                      *next_state_list = g_new0(VFSM_Int,
+                                                index->header->word_ambiguity);
+    register gint curr_state_list_len = 1, next_state_list_len = 0;
+    for(i = 0; str[i]; i++){
+        if(jump_ctr--)
+            continue;
+        jump_ctr = index->header->word_jump - 1;
+        if((!(ambig = Alphabet_nt2ambig(str[i])))
+        || ((strlen(ambig) * curr_state_list_len)
+             > index->header->word_ambiguity)){
+            next_state_list_len = 0; /* Clear next state list */
+            curr_state_list_len = 1; /* Set single null state */
+            curr_state_list[0] = 0;
+            continue;
+            }
+        for(j = 0; j < curr_state_list_len; j++){
+            state = curr_state_list[j];
+            for(k = 0; ambig[k]; k++){
+                g_assert(index->vfsm->index[(guchar)ambig[k]]);
+                next_state = VFSM_change_state_M(index->vfsm,
+                                                 state, (guchar)ambig[k]);
+                if(next_state_list_len
+                && ((next_state == next_state_list[0])
+                 || (next_state == next_state_list[next_state_list_len-1])))
+                    break;
+                next_state_list[next_state_list_len++] = next_state;
+                if(VFSM_state_is_leaf(index->vfsm, next_state)){
+                    leaf = VFSM_state2leaf(index->vfsm, next_state);
+                    pos = i-(index->vfsm->depth-1);
+                    if(frame)
+                        pos = (pos * 3) + frame - 1;
+                    iwvf(index, index_strand, seq_id, pos, leaf, user_data);
+                    }
+                }
+            }
+        curr_state_list_len = next_state_list_len;
+        next_state_list_len = 0;
+        Swap(next_state_list, curr_state_list, temp_state_list);
+        }
+    g_free(str);
+    g_free(curr_state_list);
+    g_free(next_state_list);
+    return;
+    }
+/* FIXME: needs to work with softmasked sequences */
+/* FIXME: optimisation: remove strlen() call */
+
+static void Index_visit_seq_words(Index *index, Index_Strand *index_strand,
+                                  gint seq_id, Sequence *seq,
+                                  Index_WordVisit_Func iwvf, gint frame,
+                                  gpointer user_data){
+    if(index->header->word_ambiguity > 1)
+        Index_visit_seq_words_ambig(index, index_strand, seq_id, seq,
+                              iwvf, frame, user_data);
+    else
+        Index_visit_seq_words_single(index, index_strand, seq_id, seq,
+                              iwvf, frame, user_data);
+    return;
+    }
+/* FIXME: needs to work with softmasked sequences */
+
 static void Index_visit_words(Index *index, Index_Strand *index_strand,
                               Index_WordVisit_Func iwvf,
                               gboolean is_forward, gpointer user_data){
@@ -292,7 +374,8 @@ static void Index_desaturate(Index *index, Index_Strand *index_strand){
             removed_instances += index_strand->word_table[i];
             index_strand->word_table[i] = -1;
             }
-    g_message("Removed [%lld] words, [%lld] instances",
+    g_message("Removed [%" CUSTOM_GUINT64_FORMAT
+              "] words, [%" CUSTOM_GUINT64_FORMAT "] instances",
               removed_words, removed_instances);
     return;
     }
@@ -663,8 +746,8 @@ static void Index_Strand_destroy(Index_Strand *index_strand){
     return;
     }
 
-Index *Index_create(Dataset *dataset, gboolean is_translated,
-                    gint word_length, gint word_jump, gint saturate_threshold,
+Index *Index_create(Dataset *dataset, gboolean is_translated, gint word_length,
+                    gint word_jump, gint word_ambiguity, gint saturate_threshold,
                     gchar *index_path, gchar *dataset_path, gint memory_limit){
     register Index *index = g_new0(Index, 1);
     register gchar *member;
@@ -684,7 +767,8 @@ Index *Index_create(Dataset *dataset, gboolean is_translated,
     index->dataset = Dataset_share(dataset);
     index->header = Index_Header_create(strlen(dataset_path),
                                         is_translated, word_length,
-                                        word_jump, saturate_threshold);
+                                        word_jump, word_ambiguity,
+                                        saturate_threshold);
     if(is_translated){
         alphabet = Alphabet_create(Alphabet_Type_PROTEIN, FALSE);
         member = (gchar*)alphabet->member;
@@ -781,6 +865,24 @@ void Index_destroy(Index *index){
     return;
     }
 
+void Index_info(Index *index){
+    g_print("Sequence Index:\n"
+            "--------------\n"
+            "                version: %d\n"
+            "                   type: %s\n"
+            "            word length: %d\n"
+            "              word jump: %d\n"
+            "         word ambiguity: %d\n"
+            "     saturate threshold: %d\n\n",
+            (gint)index->header->version,
+            (index->header->type & 1) ? "translated" : "normal",
+            (gint)index->header->word_length,
+            (gint)index->header->word_jump,
+            (gint)index->header->word_ambiguity,
+            (gint)index->header->saturate_threshold);
+    return;
+    }
+
 static Index_Word *Index_Strand_read_word_list(Index *index,
                                                Index_Strand *index_strand){
     register Index_Word *word_list = g_new(Index_Word,
diff --git a/src/database/index.h b/src/database/index.h
index 6b0ab06..b880734 100644
--- a/src/database/index.h
+++ b/src/database/index.h
@@ -3,7 +3,7 @@
 *  Library for manipulation of exonerate index files             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -60,6 +60,7 @@ typedef struct {
     /**/
     guint64  word_length;
     guint64  word_jump;
+    guint64  word_ambiguity;
     guint64  saturate_threshold;
 } Index_Header;
 
@@ -117,11 +118,12 @@ typedef struct {
 
 /**/
 
-   Index *Index_create(Dataset *dataset, gboolean is_translated,
-                       gint word_length, gint word_jump, gint saturate_threshold,
+   Index *Index_create(Dataset *dataset, gboolean is_translated, gint word_length,
+                       gint word_jump, gint word_ambiguity, gint saturate_threshold,
                        gchar *index_path, gchar *dataset_path, gint memory_limit);
    Index *Index_share(Index *index);
     void  Index_destroy(Index *index);
+    void  Index_info(Index *index);
    Index *Index_open(gchar *path);
  guint64  Index_memory_usage(Index *index);
     void  Index_preload_index(Index *index);
@@ -150,5 +152,5 @@ GPtrArray *Index_get_HSPsets_geneseed(Index *index, HSP_Param *hsp_param,
 }
 #endif /* __cplusplus */
 
-#endif /* INCLUDED_DATASET_H */
+#endif /* INCLUDED_INDEX_H */
 
diff --git a/src/database/index.test.c b/src/database/index.test.c
index 59a2cc7..cf2d32b 100644
--- a/src/database/index.test.c
+++ b/src/database/index.test.c
@@ -3,7 +3,7 @@
 *  Library for manipulation of FASTA format databases            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/Makefile.am b/src/general/Makefile.am
index 93898ee..0dec893 100644
--- a/src/general/Makefile.am
+++ b/src/general/Makefile.am
@@ -1,15 +1,24 @@
 
-TESTS = argument.test lineparse.test compoundfile.test socket.test
+TESTS = argument.test lineparse.test compoundfile.test socket.test \
+        jobqueue.test threadref.test
 noinst_PROGRAMS = $(TESTS)
 
-noinst_HEADERS = argument.h lineparse.h compoundfile.h socket.h
+noinst_HEADERS = argument.h lineparse.h compoundfile.h socket.h \
+                 jobqueue.h threadref.h
 
-INCLUDES = -DSOURCE_ROOT_DIR="\"@source_root_dir@\""
+INCLUDES = -DSOURCE_ROOT_DIR="\"@source_root_dir@\"" \
+           -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\"" \
+           -I$(top_srcdir)/src/struct
 
 argument_test_SOURCES = argument.test.c argument.c
 lineparse_test_SOURCES = lineparse.test.c lineparse.c
 compoundfile_test_SOURCES = compoundfile.test.c compoundfile.c
 socket_test_SOURCES = socket.test.c socket.c
+jobqueue_test_SOURCES = jobqueue.test.c jobqueue.c
+jobqueue_test_LDADD = $(top_srcdir)/src/struct/pqueue.o     \
+                      $(top_srcdir)/src/struct/recyclebin.o
+threadref_test_SOURCES = threadref.test.c threadref.c
+threadref_test_LDADD = -lpthread
 
 # Files to clear away
 
diff --git a/src/general/Makefile.in b/src/general/Makefile.in
index c8a672a..63c8049 100644
--- a/src/general/Makefile.in
+++ b/src/general/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -78,17 +79,25 @@ installed_util_list = @installed_util_list@
 source_root_dir = @source_root_dir@
 use_pthreads = @use_pthreads@
 
-TESTS = argument.test lineparse.test compoundfile.test socket.test
+TESTS = argument.test lineparse.test compoundfile.test socket.test         jobqueue.test threadref.test
+
 noinst_PROGRAMS = $(TESTS)
 
-noinst_HEADERS = argument.h lineparse.h compoundfile.h socket.h
+noinst_HEADERS = argument.h lineparse.h compoundfile.h socket.h                  jobqueue.h threadref.h
+
+
+INCLUDES = -DSOURCE_ROOT_DIR="\"@source_root_dir@\""            -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""            -I$(top_srcdir)/src/struct
 
-INCLUDES = -DSOURCE_ROOT_DIR="\"@source_root_dir@\""
 
 argument_test_SOURCES = argument.test.c argument.c
 lineparse_test_SOURCES = lineparse.test.c lineparse.c
 compoundfile_test_SOURCES = compoundfile.test.c compoundfile.c
 socket_test_SOURCES = socket.test.c socket.c
+jobqueue_test_SOURCES = jobqueue.test.c jobqueue.c
+jobqueue_test_LDADD = $(top_srcdir)/src/struct/pqueue.o                           $(top_srcdir)/src/struct/recyclebin.o
+
+threadref_test_SOURCES = threadref.test.c threadref.c
+threadref_test_LDADD = -lpthread
 
 # Files to clear away
 
@@ -118,6 +127,13 @@ socket_test_OBJECTS =  socket.test.o socket.o
 socket_test_LDADD = $(LDADD)
 socket_test_DEPENDENCIES = 
 socket_test_LDFLAGS = 
+jobqueue_test_OBJECTS =  jobqueue.test.o jobqueue.o
+jobqueue_test_DEPENDENCIES =  $(top_srcdir)/src/struct/pqueue.o \
+$(top_srcdir)/src/struct/recyclebin.o
+jobqueue_test_LDFLAGS = 
+threadref_test_OBJECTS =  threadref.test.o threadref.o
+threadref_test_DEPENDENCIES = 
+threadref_test_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -131,8 +147,8 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
 TAR = tar
 GZIP_ENV = --best
-SOURCES = $(argument_test_SOURCES) $(lineparse_test_SOURCES) $(compoundfile_test_SOURCES) $(socket_test_SOURCES)
-OBJECTS = $(argument_test_OBJECTS) $(lineparse_test_OBJECTS) $(compoundfile_test_OBJECTS) $(socket_test_OBJECTS)
+SOURCES = $(argument_test_SOURCES) $(lineparse_test_SOURCES) $(compoundfile_test_SOURCES) $(socket_test_SOURCES) $(jobqueue_test_SOURCES) $(threadref_test_SOURCES)
+OBJECTS = $(argument_test_OBJECTS) $(lineparse_test_OBJECTS) $(compoundfile_test_OBJECTS) $(socket_test_OBJECTS) $(jobqueue_test_OBJECTS) $(threadref_test_OBJECTS)
 
 all: all-redirect
 .SUFFIXES:
@@ -189,6 +205,14 @@ socket.test: $(socket_test_OBJECTS) $(socket_test_DEPENDENCIES)
 	@rm -f socket.test
 	$(LINK) $(socket_test_LDFLAGS) $(socket_test_OBJECTS) $(socket_test_LDADD) $(LIBS)
 
+jobqueue.test: $(jobqueue_test_OBJECTS) $(jobqueue_test_DEPENDENCIES)
+	@rm -f jobqueue.test
+	$(LINK) $(jobqueue_test_LDFLAGS) $(jobqueue_test_OBJECTS) $(jobqueue_test_LDADD) $(LIBS)
+
+threadref.test: $(threadref_test_OBJECTS) $(threadref_test_DEPENDENCIES)
+	@rm -f threadref.test
+	$(LINK) $(threadref_test_LDFLAGS) $(threadref_test_OBJECTS) $(threadref_test_LDADD) $(LIBS)
+
 tags: TAGS
 
 ID: $(HEADERS) $(SOURCES) $(LISP)
diff --git a/src/general/argument.c b/src/general/argument.c
index e6239d2..5b38fd4 100644
--- a/src/general/argument.c
+++ b/src/general/argument.c
@@ -3,7 +3,7 @@
 *  Library for command line argument processing                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -173,8 +173,6 @@ static void Argument_show_version(Argument *arg){
     g_print("Built on %s\n", __DATE__);
     if(strlen(branch) >= 10)
         g_print("Branch: %.*s\n", (gint)(strlen(branch)-9), branch+7);
-    else
-        g_print("Branch: unnamed branch\n");
     return;
     }
 
@@ -302,8 +300,13 @@ static void Argument_error_handler(const gchar *log_domain,
  */
 
 int main(int argc, char **argv){
-    register Argument *arg = Argument_create(argc, argv);
+    register Argument *arg;
     register gint retval;
+#ifdef USE_PTHREADS
+    if(!g_thread_supported())
+        g_thread_init(NULL);
+#endif /* USE_PTHREADS */
+    arg = Argument_create(argc, argv);
     g_log_set_handler(NULL, G_LOG_LEVEL_ERROR|G_LOG_FLAG_FATAL,
                       Argument_error_handler, arg);
     g_assert(Argument_assertion_warning());
diff --git a/src/general/argument.h b/src/general/argument.h
index 1c1df50..cc1678a 100644
--- a/src/general/argument.h
+++ b/src/general/argument.h
@@ -3,7 +3,7 @@
 *  Library for command line argument processing                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/argument.test.c b/src/general/argument.test.c
index 3b0107c..d6ab524 100644
--- a/src/general/argument.test.c
+++ b/src/general/argument.test.c
@@ -3,7 +3,7 @@
 *  Library for command line argument processing                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/compoundfile.c b/src/general/compoundfile.c
index 1cf1938..de18bcc 100644
--- a/src/general/compoundfile.c
+++ b/src/general/compoundfile.c
@@ -3,7 +3,7 @@
 *  Library for reading large and/or split files.                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -160,6 +160,48 @@ CompoundFile *CompoundFile_share(CompoundFile *cf){
     return cf;
     }
 
+static GPtrArray *CompoundFile_get_path_list(CompoundFile *cf){
+    register gint i;
+    register gchar *path;
+    register GPtrArray *path_list = g_ptr_array_new();
+    register CompoundFile_Element *element;
+    for(i = 0; i < cf->element_list->len; i++){
+        element = cf->element_list->pdata[i];
+        path = g_strdup(element->path);
+        g_ptr_array_add(path_list, path);
+        }
+    return path_list;
+    }
+
+CompoundFile *CompoundFile_dup(CompoundFile *cf){
+    register CompoundFile *ncf;
+    register CompoundFile_Location *nstart = NULL, *nstop = NULL;
+    register gint i;
+    register gchar *path;
+    register GPtrArray *path_list = CompoundFile_get_path_list(cf);
+    g_assert(path_list);
+    ncf = CompoundFile_create(path_list, FALSE);
+    if(cf->start_limit)
+        nstart = CompoundFile_Location_create(ncf,
+                                              cf->start_limit->pos,
+                                              cf->start_limit->element_id);
+    if(cf->stop_limit)
+        nstop  = CompoundFile_Location_create(ncf,
+                                              cf->stop_limit->pos,
+                                              cf->stop_limit->element_id);
+    CompoundFile_set_limits(ncf, nstart, nstop);
+    if(nstart)
+        CompoundFile_Location_destroy(nstart);
+    if(nstop)
+        CompoundFile_Location_destroy(nstop);
+    for(i = 0; i < path_list->len; i++){
+        path = path_list->pdata[i];
+        g_free(path);
+        }
+    g_ptr_array_free(path_list, TRUE);
+    return ncf;
+    }
+
 gchar *CompoundFile_current_path(CompoundFile *cf){
     register CompoundFile_Element *cfe
         = cf->element_list->pdata[cf->curr_element_id];
@@ -344,8 +386,10 @@ void CompoundFile_set_limits(CompoundFile *cf,
         CompoundFile_Location_destroy(cf->start_limit);
     if(cf->stop_limit)
         CompoundFile_Location_destroy(cf->stop_limit);
-    cf->start_limit = CompoundFile_Location_share(start);
-    cf->stop_limit = CompoundFile_Location_share(stop);
+    if(start)
+        cf->start_limit = CompoundFile_Location_share(start);
+    if(stop)
+        cf->stop_limit = CompoundFile_Location_share(stop);
     CompoundFile_rewind(cf);
     return;
     }
diff --git a/src/general/compoundfile.h b/src/general/compoundfile.h
index 8bd9d50..28743e9 100644
--- a/src/general/compoundfile.h
+++ b/src/general/compoundfile.h
@@ -3,7 +3,7 @@
 *  Library for reading large and/or split files.                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -25,6 +25,7 @@ extern "C" {
 
 #include <sys/types.h> /* For lseek() and off_t */
 #include <unistd.h>    /* For lseek() and off_t */
+#include <inttypes.h>  /* For PRIuPTR           */
 
 #ifdef USE_PTHREADS
 #include <pthread.h>
@@ -45,16 +46,19 @@ extern "C" {
 
 typedef off_t CompoundFile_Pos;
 
-#if _FILE_OFFSET_BITS==64
-#define CompoundFile_Pos_format "%lld"
-#else /* Assume _FILE_OFFSET_BITS==32 */
-#define CompoundFile_Pos_format "%ld"
-#endif /* _FILE_OFFSET_BITS */
-
+#if __STDC_VERSION__ >= 199901L
+#define CompoundFile_Pos_print(fp, pos) \
+    CompoundFile_Pragma fprintf((fp), "%jd", (intmax_t)(pos))
+typedef intmax_t CompoundFile_Pos_scan_type;
+#define CompoundFile_Pos_scan(src, dst) \
+    CompoundFile_Pragma sscanf((src), "%jd", (intmax_t*)(dst))
+#else /* __STDC_VERSION__  */
 #define CompoundFile_Pos_print(fp, pos) \
-    CompoundFile_Pragma fprintf((fp), CompoundFile_Pos_format, (pos))
+    CompoundFile_Pragma fprintf((fp), "%lld", (long long int)(pos))
+typedef long long int CompoundFile_Pos_scan_type;
 #define CompoundFile_Pos_scan(src, dst) \
-    CompoundFile_Pragma sscanf((src), CompoundFile_Pos_format, (dst))
+    CompoundFile_Pragma sscanf((src), "%lld", (dst))
+#endif /* __STDC_VERSION__  */
 
 typedef struct {
               gchar  *path;
@@ -81,6 +85,7 @@ CompoundFile *CompoundFile_create(GPtrArray *path_list,
                                   gboolean sort_on_file_size);
         void  CompoundFile_destroy(CompoundFile *cf);
 CompoundFile *CompoundFile_share(CompoundFile *cf);
+CompoundFile *CompoundFile_dup(CompoundFile *cf);
        gchar *CompoundFile_current_path(CompoundFile *cf);
 
 #define CompoundFile_buffer_is_empty(cf)              \
diff --git a/src/general/compoundfile.test.c b/src/general/compoundfile.test.c
index 4058714..63bee07 100644
--- a/src/general/compoundfile.test.c
+++ b/src/general/compoundfile.test.c
@@ -3,7 +3,7 @@
 *  Library for reading large and/or split files                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/jobqueue.c b/src/general/jobqueue.c
new file mode 100644
index 0000000..c7ea0d8
--- /dev/null
+++ b/src/general/jobqueue.c
@@ -0,0 +1,137 @@
+/****************************************************************\
+*                                                                *
+*  Library for Queueing Multi-Threaded Jobs                      *
+*                                                                *
+*  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
+*                                                                *
+*  This source code is distributed under the terms of the        *
+*  GNU General Public License, version 3. See the file COPYING   *
+*  or http://www.gnu.org/licenses/gpl.txt for details            *
+*                                                                *
+*  If you use this code, please keep this notice intact.         *
+*                                                                *
+\****************************************************************/
+
+#include "jobqueue.h"
+#include <unistd.h> /* For usleep() */
+
+#ifdef USE_PTHREADS
+static JobQueue_Task *JobQueue_Task_create(JobQueue_Func job_func,
+                                           gpointer job_data, gint priority){
+    register JobQueue_Task *task = g_new(JobQueue_Task, 1);
+    task->job_func = job_func;
+    task->job_data = job_data;
+    task->priority = priority;
+    return task;
+    }
+
+static void JobQueue_Task_destroy(JobQueue_Task *task){
+    g_free(task);
+    return;
+    }
+
+static void *JobQueue_thread_func(void *data){
+    register JobQueue *jq = data;
+    register JobQueue_Task *task;
+    do {
+        pthread_mutex_lock(&jq->queue_lock);
+        task = PQueue_pop(jq->pq);
+        if(task){
+            jq->running_count++;
+            pthread_mutex_unlock(&jq->queue_lock);
+            task->job_func(task->job_data);
+            JobQueue_Task_destroy(task);
+            pthread_mutex_lock(&jq->queue_lock);
+            jq->running_count--;
+            pthread_mutex_unlock(&jq->queue_lock);
+       } else {
+            pthread_mutex_unlock(&jq->queue_lock);
+            usleep(1000); /* wait before checking job queue again */
+            }
+    } while(!jq->is_complete);
+    return NULL;
+    }
+
+static gboolean JobQueue_Task_compare(gpointer low, gpointer high,
+                                      gpointer user_data){
+    register JobQueue_Task *low_task = (JobQueue_Task*)low,
+                           *high_task = (JobQueue_Task*)high;
+    return low_task->priority < high_task->priority;
+    }
+#endif /* USE_PTHREADS */
+
+JobQueue *JobQueue_create(gint thread_total){
+    register JobQueue *jq = g_new(JobQueue, 1);
+#ifdef USE_PTHREADS
+    register gint i;
+    jq->is_complete = FALSE;
+    jq->thread_total = thread_total;
+    jq->running_count = 0;
+    pthread_mutex_init(&jq->queue_lock, NULL);
+    jq->thread = g_new0(pthread_t, thread_total);
+    jq->pq_set = PQueueSet_create();
+    jq->pq = PQueue_create(jq->pq_set, JobQueue_Task_compare, NULL);
+    for(i = 0; i < thread_total; i++)
+        pthread_create(&jq->thread[i], NULL, JobQueue_thread_func, jq);
+#endif /* USE_PTHREADS */
+    return jq;
+    }
+
+static void JobQueue_Task_free_func(gpointer data, gpointer user_data){
+    register JobQueue_Task *task = data;
+    JobQueue_Task_destroy(task);
+    return;
+    }
+
+void JobQueue_destroy(JobQueue *jq){
+#ifdef USE_PTHREADS
+    g_assert(!PQueue_total(jq->pq));
+    PQueue_destroy(jq->pq, JobQueue_Task_free_func, NULL);
+    PQueueSet_destroy(jq->pq_set);
+    pthread_mutex_destroy(&jq->queue_lock);
+    g_free(jq->thread);
+#endif /* USE_PTHREADS */
+    g_free(jq);
+    return;
+    }
+
+void JobQueue_submit(JobQueue *jq, JobQueue_Func job_func,
+                     gpointer job_data, gint priority){
+#ifdef USE_PTHREADS
+    register JobQueue_Task *task;
+    g_assert(jq);
+    pthread_mutex_lock(&jq->queue_lock);
+    task = JobQueue_Task_create(job_func, job_data, priority);
+    PQueue_push(jq->pq, task);
+    pthread_mutex_unlock(&jq->queue_lock);
+#else /* USE_PTHREADS */
+    jq->job_func(job_data); /* when no threads available, just run the job */
+#endif /* USE_PTHREADS */
+    return;
+    }
+/* waits until less than (thread_total * 2) jobs are queued
+ */
+
+void JobQueue_complete(JobQueue *jq){
+#ifdef USE_PTHREADS
+    register gint i, job_total;
+    do { /* wait for job queue to empty */
+        pthread_mutex_lock(&jq->queue_lock);
+        job_total = PQueue_total(jq->pq) + jq->running_count;
+        pthread_mutex_unlock(&jq->queue_lock);
+        usleep(1000); /* wait before checking if queue is empty again */
+    } while(job_total);
+    jq->is_complete = TRUE;
+    /* wait for threads to finish */
+    for(i = 0; i < jq->thread_total; i++)
+        pthread_join(jq->thread[i], NULL);
+#endif /* USE_PTHREADS */
+    return;
+    }
+/* waits until the queue is empty and no jobs are running,
+ * to catch any jobs which are added to the queue by runnning jobs
+ */
+
+/**/
+
diff --git a/src/general/jobqueue.h b/src/general/jobqueue.h
new file mode 100644
index 0000000..73d05ea
--- /dev/null
+++ b/src/general/jobqueue.h
@@ -0,0 +1,67 @@
+/****************************************************************\
+*                                                                *
+*  Library for Queueing Multi-Threaded Jobs                      *
+*                                                                *
+*  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
+*                                                                *
+*  This source code is distributed under the terms of the        *
+*  GNU General Public License, version 3. See the file COPYING   *
+*  or http://www.gnu.org/licenses/gpl.txt for details            *
+*                                                                *
+*  If you use this code, please keep this notice intact.         *
+*                                                                *
+\****************************************************************/
+
+#ifndef INCLUDED_JOBQUEUE_H
+#define INCLUDED_JOBQUEUE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <glib.h>
+
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif /* USE_PTHREADS */
+
+#include "pqueue.h"
+
+typedef void (*JobQueue_Func)(gpointer job_data);
+
+typedef struct JobQueue_Task {
+    JobQueue_Func  job_func;
+         gpointer  job_data;
+             gint  priority;
+} JobQueue_Task;
+
+typedef struct {
+#ifdef USE_PTHREADS
+           gboolean  is_complete;
+               gint  thread_total;
+               gint  running_count;
+    pthread_mutex_t  queue_lock;
+          pthread_t *thread;
+             PQueue *pq;
+          PQueueSet *pq_set;
+#endif /* USE_PTHREADS */
+} JobQueue;
+
+JobQueue *JobQueue_create(gint thread_total);
+    void  JobQueue_destroy(JobQueue *jq);
+    void  JobQueue_submit(JobQueue *jq, JobQueue_Func job_func,
+                          gpointer job_data, gint priority);
+    void  JobQueue_complete(JobQueue *jq);
+
+/* Lower priority jobs are run first */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* INCLUDED_JOBQUEUE_H */
+
+
+/**/
+
diff --git a/src/struct/bitarray.test.c b/src/general/jobqueue.test.c
similarity index 50%
copy from src/struct/bitarray.test.c
copy to src/general/jobqueue.test.c
index bfcc0f7..19b2620 100644
--- a/src/struct/bitarray.test.c
+++ b/src/general/jobqueue.test.c
@@ -1,9 +1,9 @@
 /****************************************************************\
 *                                                                *
-*  A simple bitarray data structure                              *
+*  Library for Queueing Multi-Threaded Jobs                      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -13,15 +13,32 @@
 *                                                                *
 \****************************************************************/
 
-#include "bitarray.h"
+#include <unistd.h> /* For usleep() */
+#include "jobqueue.h"
+
+static void test_run_func(gpointer job_data){
+    register gchar *name = job_data;
+    g_message("running job [%s]", name);
+    usleep(1000000); /* test job length */
+    return;
+    }
 
 int main(void){
-    register BitArray *ba = BitArray_create();
     register gint i;
-    for(i = 0; i < 16; i++)
-        BitArray_append(ba, i, 4);
-    BitArray_info(ba);
-    BitArray_destroy(ba);
+    register JobQueue *jq = JobQueue_create(2);
+    gchar *test_str[10] = {"one", "two", "three", "four", "five",
+                           "six", "seven", "eight", "nine", "ten"};
+
+    /* Initialise threads as not using Argument library */
+#ifdef USE_PTHREADS
+    if(!g_thread_supported())
+        g_thread_init(NULL);
+#endif /* USE_PTHREADS */
+
+    for(i = 0; i < 10; i++)
+        JobQueue_submit(jq, test_run_func, test_str[i], 0);
+    JobQueue_complete(jq);
+    JobQueue_destroy(jq);
     return 0;
     }
 
diff --git a/src/general/lineparse.c b/src/general/lineparse.c
index 0163fbb..238dc94 100644
--- a/src/general/lineparse.c
+++ b/src/general/lineparse.c
@@ -3,7 +3,7 @@
 *  Library for basic line-by-line parsing of text files.         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/lineparse.h b/src/general/lineparse.h
index c3025c4..79ed9d3 100644
--- a/src/general/lineparse.h
+++ b/src/general/lineparse.h
@@ -3,7 +3,7 @@
 *  Library for basic line-by-line parsing of text files.         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/lineparse.test.c b/src/general/lineparse.test.c
index 5c193d6..2786220 100644
--- a/src/general/lineparse.test.c
+++ b/src/general/lineparse.test.c
@@ -3,7 +3,7 @@
 *  Library for basic line-by-line parsing of text files.         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/socket.c b/src/general/socket.c
index 571a6d8..4d0aa18 100644
--- a/src/general/socket.c
+++ b/src/general/socket.c
@@ -3,7 +3,7 @@
 *  Simple client-server code library                             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -56,8 +56,11 @@ SocketClient *SocketClient_create(gchar *host, gint port){
     struct sockaddr_in server;
     struct hostent *hp = gethostbyname(host);
     register gchar *reply;
+#ifdef USE_PTHREADS
+    pthread_mutex_init(&client->connection_mutex, NULL);
+#endif /* USE_PTHREADS */
     if(!hp){
-        perror("lookup up hostname");
+        perror("looking up hostname");
         exit(1);
         }
     client->connection = SocketConnection_create(host, port);
@@ -103,7 +106,7 @@ static void SocketConnection_destroy(SocketConnection *connection){
     }
 
 static gchar *SocketConnection_read(gint sock){
-    register gint i, len, line_complete = 0, line_expect = 1;
+    register gint i, len = 0, line_complete = 0, line_expect = 1;
     register gchar *reply;
     register GString *string = g_string_sized_new(Socket_BUFSIZE);
     register gboolean line_count_given = FALSE;
@@ -125,11 +128,12 @@ static gchar *SocketConnection_read(gint sock){
                     g_error("linecount: must be > 1");
                 }
         if(line_complete > line_expect){
-            if(line_count_given)
+            if(line_count_given){
                 g_error("Received [%d] socket message lines, but expected [%d]",
                    line_complete, line_count_given);
-            else
+            } else {
                 g_error("Multiline socket messages must use linecount:");
+                }
             }
         g_string_append(string, buffer);
     } while(line_complete < line_expect);
@@ -171,12 +175,24 @@ static void Socket_send(gint sock, gchar *msg, gchar *err_msg){
     }
 
 gchar *SocketClient_send(SocketClient *client, gchar *msg){
+    register gchar *reply;
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&client->connection_mutex);
+#endif /* USE_PTHREADS */
     Socket_send(client->connection->sock, msg, "writing client message");
-    return SocketConnection_read(client->connection->sock);
+    reply = SocketConnection_read(client->connection->sock);
+    g_assert(reply);
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&client->connection_mutex);
+#endif /* USE_PTHREADS */
+    return reply;
     }
 
 void SocketClient_destroy(SocketClient *client){
     SocketConnection_destroy(client->connection);
+#ifdef USE_PTHREADS
+    pthread_mutex_destroy(&client->connection_mutex);
+#endif /* USE_PTHREADS */
     g_free(client);
     return;
     }
@@ -199,6 +215,12 @@ static void SocketServer_shutdown(int signum){
     return;
     }
 
+static void SocketServer_broken_pipe(int signum){
+    g_message("Server detected broken pipe - closing thread");
+    pthread_exit(NULL);
+    return;
+    }
+
 SocketServer *SocketServer_create(gint port, gint max_connections,
               SocketProcessFunc server_process_func,
               SocketConnectionOpenFunc connection_open_func,
@@ -245,7 +267,13 @@ static void SocketServer_process_connection(SocketServer *server, int msgsock){
     register gboolean ok = TRUE;
     gchar *reply;
     do {
+#ifdef USE_PTHREADS
+        pthread_mutex_lock(&server->connection_mutex);
+#endif /* USE_PTHREADS */
         msg = SocketConnection_read(msgsock);
+#ifdef USE_PTHREADS
+        pthread_mutex_unlock(&server->connection_mutex);
+#endif /* USE_PTHREADS */
         reply = NULL;
         if(!msg)
             break;
@@ -253,8 +281,16 @@ static void SocketServer_process_connection(SocketServer *server, int msgsock){
                                          server->user_data);
         g_free(msg);
         if(reply){
+#ifdef USE_PTHREADS
+            pthread_mutex_lock(&server->connection_mutex);
+#endif /* USE_PTHREADS */
             Socket_send(msgsock, reply, "writing reply");
+#ifdef USE_PTHREADS
+            pthread_mutex_unlock(&server->connection_mutex);
+#endif /* USE_PTHREADS */
             g_free(reply);
+        } else {
+            g_error("no reply from server");
             }
     } while(ok);
     if(server->connection_close_func)
@@ -265,6 +301,7 @@ static void SocketServer_process_connection(SocketServer *server, int msgsock){
 #ifdef USE_PTHREADS
 static void *SocketServer_pthread_func(void* data){
     register SocketServer_pthread_Data *sspd = (SocketServer_pthread_Data*)data;
+    signal(SIGPIPE, SocketServer_broken_pipe);
     SocketServer_process_connection(sspd->server, sspd->msgsock);
     pthread_mutex_lock(&sspd->server->connection_mutex);
     g_message("cleaning up connection [%d]", global_connection_count);
@@ -279,10 +316,10 @@ static void *SocketServer_pthread_func(void* data){
 
 gboolean SocketServer_listen(SocketServer *server){
     register int msgsock;
-    register gint i;
     struct sockaddr_in client_addr;
     socklen_t client_len = sizeof(struct sockaddr_in);
 #ifdef USE_PTHREADS
+    register gint i;
     pthread_attr_t pt_attr;
     pthread_attr_init(&pt_attr);
     pthread_attr_setdetachstate(&pt_attr, PTHREAD_CREATE_DETACHED);
@@ -351,3 +388,4 @@ void SocketServer_destroy(SocketServer *server){
     return;
     }
 
+
diff --git a/src/general/socket.h b/src/general/socket.h
index 641721c..3fcb31a 100644
--- a/src/general/socket.h
+++ b/src/general/socket.h
@@ -3,7 +3,7 @@
 *  Simple client-server code library                             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -45,6 +45,9 @@ typedef struct {
 
 typedef struct {
     SocketConnection *connection;
+#ifdef USE_PTHREADS
+     pthread_mutex_t  connection_mutex;
+#endif /* USE_PTHREADS */
 } SocketClient;
 
 #ifdef USE_PTHREADS
diff --git a/src/general/socket.test.c b/src/general/socket.test.c
index 89b173e..adcdb8a 100644
--- a/src/general/socket.test.c
+++ b/src/general/socket.test.c
@@ -3,7 +3,7 @@
 *  Simple client-server code library                             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/general/threadref.c b/src/general/threadref.c
new file mode 100644
index 0000000..3814c73
--- /dev/null
+++ b/src/general/threadref.c
@@ -0,0 +1,69 @@
+/****************************************************************\
+*                                                                *
+*  Basic library for thread-safe reference counting.             *
+*                                                                *
+*  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
+*                                                                *
+*  This source code is distributed under the terms of the        *
+*  GNU General Public License, version 3. See the file COPYING   *
+*  or http://www.gnu.org/licenses/gpl.txt for details            *
+*                                                                *
+*  If you use this code, please keep this notice intact.         *
+*                                                                *
+\****************************************************************/
+
+#include "threadref.h"
+
+ThreadRef *ThreadRef_create(void){
+    register ThreadRef *threadref = g_new(ThreadRef, 1);
+    threadref->ref_count = 1;
+#ifdef USE_PTHREADS
+    pthread_mutex_init(&threadref->ref_lock, NULL);
+#endif /* USE_PTHREADS */
+    return threadref;
+    }
+
+ThreadRef *ThreadRef_destroy(ThreadRef *threadref){
+    ThreadRef_lock(threadref);
+    if(--threadref->ref_count){
+        ThreadRef_unlock(threadref);
+        return threadref;
+        }
+    ThreadRef_unlock(threadref);
+#ifdef USE_PTHREADS
+    pthread_mutex_destroy(&threadref->ref_lock);
+#endif /* USE_PTHREADS */
+    g_free(threadref);
+    return NULL;
+    }
+
+ThreadRef *ThreadRef_share(ThreadRef *threadref){
+    ThreadRef_lock(threadref);
+    threadref->ref_count++;
+    ThreadRef_unlock(threadref);
+    return threadref;
+    }
+
+gint ThreadRef_get_count(ThreadRef *threadref){
+    register gint ref_count;
+    ThreadRef_lock(threadref);
+    ref_count = threadref->ref_count;
+    ThreadRef_unlock(threadref);
+    return ref_count;
+    }
+
+void ThreadRef_lock(ThreadRef *threadref){
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&threadref->ref_lock);
+#endif /* USE_PTHREADS */
+    return;
+    }
+
+void ThreadRef_unlock(ThreadRef *threadref){
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&threadref->ref_lock);
+#endif /* USE_PTHREADS */
+    return;
+    }
+
diff --git a/src/hub/bsam.h b/src/general/threadref.h
similarity index 57%
copy from src/hub/bsam.h
copy to src/general/threadref.h
index 6c4448e..3ad4e48 100644
--- a/src/hub/bsam.h
+++ b/src/general/threadref.h
@@ -1,9 +1,9 @@
 /****************************************************************\
 *                                                                *
-*  BSAM: Big Sequence Alignment Manager                          *
+*  Basic library for thread-safe reference counting.             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -13,33 +13,37 @@
 *                                                                *
 \****************************************************************/
 
-#ifndef INCLUDED_BSAM_H
-#define INCLUDED_BSAM_H
+#ifndef INCLUDED_THREADREF_H
+#define INCLUDED_THREADREF_H
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
 #include <glib.h>
-#include "comparison.h"
 
-/**/
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif /* USE_PTHREADS */
 
-typedef struct {
-    Comparison_Param *comparison_param;
-                gint  saturate_threshold;
-                gint  verbosity;
-} BSAM;
-
-BSAM *BSAM_create(Comparison_Param *comparison_param,
-                  gint saturate_threshold, gint verbosity);
-void  BSAM_destroy(BSAM *bsam);
 
-Comparison *BSAM_compare(BSAM *bsam, Sequence *query, Sequence *target);
+typedef struct {
+               gint ref_count;
+#ifdef USE_PTHREADS
+    pthread_mutex_t ref_lock;
+#endif /* USE_PTHREADS */
+} ThreadRef;
+
+ThreadRef  *ThreadRef_create(void);
+ThreadRef  *ThreadRef_destroy(ThreadRef *threadref);
+ThreadRef  *ThreadRef_share(ThreadRef *threadref);
+     gint   ThreadRef_get_count(ThreadRef *threadref);
+     void   ThreadRef_lock(ThreadRef *threadref);
+     void   ThreadRef_unlock(ThreadRef *threadref);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* INCLUDED_BSAM_H */
+#endif /* INCLUDED_THREADREF_H */
 
diff --git a/src/c4/c4.test.c b/src/general/threadref.test.c
similarity index 70%
copy from src/c4/c4.test.c
copy to src/general/threadref.test.c
index 6f543a8..88624eb 100644
--- a/src/c4/c4.test.c
+++ b/src/general/threadref.test.c
@@ -1,9 +1,9 @@
 /****************************************************************\
 *                                                                *
-*  C4 dynamic programming library - code for models              *
+*  Basic library for thread-safe reference counting.             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -13,16 +13,16 @@
 *                                                                *
 \****************************************************************/
 
-#include <glib.h>
-
-#include "c4.h"
+#include <stdio.h>
+#include "threadref.h"
 
 int main(void){
-    register C4_Model *model = C4_Model_create("test model");
-    C4_Model_destroy(model);
+    register ThreadRef *tr = ThreadRef_create(), *tr2;
+    tr2 = ThreadRef_share(tr);
+    ThreadRef_destroy(tr2);
+    ThreadRef_lock(tr);
+    ThreadRef_unlock(tr);
+    ThreadRef_destroy(tr);
     return 0;
     }
 
-/* Testing for the main c4 module is done mostly by the model tests
- */
-
diff --git a/src/hub/Makefile.am b/src/hub/Makefile.am
index 02419e0..75cbf72 100644
--- a/src/hub/Makefile.am
+++ b/src/hub/Makefile.am
@@ -60,6 +60,7 @@ C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                \
              $(top_srcdir)/src/model/modeltype.o      \
              $(top_srcdir)/src/general/argument.o     \
              $(top_srcdir)/src/general/lineparse.o    \
+             $(top_srcdir)/src/general/jobqueue.o     \
              $(top_srcdir)/src/comparison/match.o     \
              $(top_srcdir)/src/sequence/submat.o      \
              $(top_srcdir)/src/sequence/codonsubmat.o \
@@ -71,11 +72,13 @@ gam_test_LDADD = $(top_srcdir)/src/comparison/hspset.o     \
                  $(top_srcdir)/src/comparison/wordhood.o   \
                  $(top_srcdir)/src/struct/sparsecache.o    \
                  $(top_srcdir)/src/general/compoundfile.o  \
+                 $(top_srcdir)/src/general/threadref.o     \
                  $(C4_OBJECTS)
 
 bsam_test_SOURCES = bsam.test.c bsam.c
 bsam_test_LDADD = $(top_srcdir)/src/general/argument.o       \
                   $(top_srcdir)/src/general/lineparse.o      \
+                  $(top_srcdir)/src/general/threadref.o      \
                   $(top_srcdir)/src/comparison/hspset.o      \
                   $(top_srcdir)/src/comparison/comparison.o  \
                   $(top_srcdir)/src/comparison/match.o       \
@@ -105,6 +108,7 @@ analysis_test_LDADD = $(top_srcdir)/src/comparison/hspset.o     \
                       $(top_srcdir)/src/struct/sparsecache.o    \
                       $(top_srcdir)/src/general/compoundfile.o  \
                       $(top_srcdir)/src/general/socket.o        \
+                      $(top_srcdir)/src/general/threadref.o      \
                       $(C4_OBJECTS)
 
 # Files to clear away
diff --git a/src/hub/Makefile.in b/src/hub/Makefile.in
index b0a4ec3..bfb2000 100644
--- a/src/hub/Makefile.in
+++ b/src/hub/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -86,18 +87,18 @@ INCLUDES = -I$(top_srcdir)/src/sequence              -I$(top_srcdir)/src/databas
 
 noinst_HEADERS = gam.h analysis.h bsam.h
 
-C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                             $(top_srcdir)/src/c4/codegen.o                        $(top_srcdir)/src/c4/cgutil.o                         $(top_srcdir)/src/c4/opair.o                          $(top_srcdir)/src/c4/alignment.o                      $(top_srcdir)/src/c4/optimal.o                        $(top_srcdir)/src/c4/viterbi.o                        $(top_srcdir)/src/c4/layout.o                         $(top_srcdir)/src/c4/region.o                   [...]
+C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                             $(top_srcdir)/src/c4/codegen.o                        $(top_srcdir)/src/c4/cgutil.o                         $(top_srcdir)/src/c4/opair.o                          $(top_srcdir)/src/c4/alignment.o                      $(top_srcdir)/src/c4/optimal.o                        $(top_srcdir)/src/c4/viterbi.o                        $(top_srcdir)/src/c4/layout.o                         $(top_srcdir)/src/c4/region.o                   [...]
 
 
 gam_test_SOURCES = gam.test.c gam.c
-gam_test_LDADD = $(top_srcdir)/src/comparison/hspset.o                      $(top_srcdir)/src/comparison/comparison.o                  $(top_srcdir)/src/comparison/wordhood.o                    $(top_srcdir)/src/struct/sparsecache.o                     $(top_srcdir)/src/general/compoundfile.o                   $(C4_OBJECTS)
+gam_test_LDADD = $(top_srcdir)/src/comparison/hspset.o                      $(top_srcdir)/src/comparison/comparison.o                  $(top_srcdir)/src/comparison/wordhood.o                    $(top_srcdir)/src/struct/sparsecache.o                     $(top_srcdir)/src/general/compoundfile.o                   $(top_srcdir)/src/general/threadref.o                      $(C4_OBJECTS)
 
 
 bsam_test_SOURCES = bsam.test.c bsam.c
-bsam_test_LDADD = $(top_srcdir)/src/general/argument.o                         $(top_srcdir)/src/general/lineparse.o                        $(top_srcdir)/src/comparison/hspset.o                        $(top_srcdir)/src/comparison/comparison.o                    $(top_srcdir)/src/comparison/match.o                         $(top_srcdir)/src/comparison/wordhood.o                      $(top_srcdir)/src/sequence/sequence.o                        $(top_srcdir)/src/sequence/alphabet.o           [...]
+bsam_test_LDADD = $(top_srcdir)/src/general/argument.o                         $(top_srcdir)/src/general/lineparse.o                        $(top_srcdir)/src/general/threadref.o                        $(top_srcdir)/src/comparison/hspset.o                        $(top_srcdir)/src/comparison/comparison.o                    $(top_srcdir)/src/comparison/match.o                         $(top_srcdir)/src/comparison/wordhood.o                      $(top_srcdir)/src/sequence/sequence.o           [...]
 
 analysis_test_SOURCES = analysis.test.c analysis.c gam.c bsam.c
-analysis_test_LDADD = $(top_srcdir)/src/comparison/hspset.o                           $(top_srcdir)/src/comparison/wordhood.o                         $(top_srcdir)/src/comparison/seeder.o                           $(top_srcdir)/src/comparison/comparison.o                       $(top_srcdir)/src/database/fastapipe.o                          $(top_srcdir)/src/database/fastadb.o                            $(top_srcdir)/src/struct/dejavu.o                               $(top_srcdir)/src/stru [...]
+analysis_test_LDADD = $(top_srcdir)/src/comparison/hspset.o                           $(top_srcdir)/src/comparison/wordhood.o                         $(top_srcdir)/src/comparison/seeder.o                           $(top_srcdir)/src/comparison/comparison.o                       $(top_srcdir)/src/database/fastapipe.o                          $(top_srcdir)/src/database/fastadb.o                            $(top_srcdir)/src/struct/dejavu.o                               $(top_srcdir)/src/stru [...]
 
 
 # Files to clear away
@@ -117,7 +118,8 @@ gam_test_DEPENDENCIES =  $(top_srcdir)/src/comparison/hspset.o \
 $(top_srcdir)/src/comparison/comparison.o \
 $(top_srcdir)/src/comparison/wordhood.o \
 $(top_srcdir)/src/struct/sparsecache.o \
-$(top_srcdir)/src/general/compoundfile.o $(top_srcdir)/src/c4/c4.o \
+$(top_srcdir)/src/general/compoundfile.o \
+$(top_srcdir)/src/general/threadref.o $(top_srcdir)/src/c4/c4.o \
 $(top_srcdir)/src/c4/codegen.o $(top_srcdir)/src/c4/cgutil.o \
 $(top_srcdir)/src/c4/opair.o $(top_srcdir)/src/c4/alignment.o \
 $(top_srcdir)/src/c4/optimal.o $(top_srcdir)/src/c4/viterbi.o \
@@ -146,6 +148,7 @@ $(top_srcdir)/src/model/frameshift.o $(top_srcdir)/src/model/phase.o \
 $(top_srcdir)/src/model/modeltype.o \
 $(top_srcdir)/src/general/argument.o \
 $(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/jobqueue.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o
@@ -160,7 +163,8 @@ $(top_srcdir)/src/database/fastadb.o $(top_srcdir)/src/struct/dejavu.o \
 $(top_srcdir)/src/struct/fsm.o $(top_srcdir)/src/struct/vfsm.o \
 $(top_srcdir)/src/struct/sparsecache.o \
 $(top_srcdir)/src/general/compoundfile.o \
-$(top_srcdir)/src/general/socket.o $(top_srcdir)/src/c4/c4.o \
+$(top_srcdir)/src/general/socket.o \
+$(top_srcdir)/src/general/threadref.o $(top_srcdir)/src/c4/c4.o \
 $(top_srcdir)/src/c4/codegen.o $(top_srcdir)/src/c4/cgutil.o \
 $(top_srcdir)/src/c4/opair.o $(top_srcdir)/src/c4/alignment.o \
 $(top_srcdir)/src/c4/optimal.o $(top_srcdir)/src/c4/viterbi.o \
@@ -189,6 +193,7 @@ $(top_srcdir)/src/model/frameshift.o $(top_srcdir)/src/model/phase.o \
 $(top_srcdir)/src/model/modeltype.o \
 $(top_srcdir)/src/general/argument.o \
 $(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/jobqueue.o \
 $(top_srcdir)/src/comparison/match.o \
 $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o
@@ -196,6 +201,7 @@ analysis_test_LDFLAGS =
 bsam_test_OBJECTS =  bsam.test.o bsam.o
 bsam_test_DEPENDENCIES =  $(top_srcdir)/src/general/argument.o \
 $(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o \
 $(top_srcdir)/src/comparison/hspset.o \
 $(top_srcdir)/src/comparison/comparison.o \
 $(top_srcdir)/src/comparison/match.o \
diff --git a/src/hub/analysis.c b/src/hub/analysis.c
index b428c5b..e27fa44 100644
--- a/src/hub/analysis.c
+++ b/src/hub/analysis.c
@@ -3,7 +3,7 @@
 *  Analysis module for exonerate                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -17,12 +17,17 @@
 #include "ungapped.h"
 #include "compoundfile.h"
 #include "hspset.h"
+#include "lineparse.h"
 
 #include <stdlib.h> /* For atoi() */
 #include <unistd.h> /* For sleep() */
 #include <string.h> /* For strcmp() */
 #include <ctype.h>  /* For isdigit() */
 
+#include <sys/types.h>  /* For stat() */
+#include <sys/stat.h>   /* For stat() */
+#include <unistd.h>     /* For stat() */
+
 Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg){
     register ArgumentSet *as;
     static Analysis_ArgumentSet aas;
@@ -34,6 +39,9 @@ Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg){
         ArgumentSet_add_option(as, 'B', "bigseq", NULL,
             "Allow rapid comparison between big sequences", "FALSE",
             Argument_parse_boolean, &aas.use_bigseq);
+        ArgumentSet_add_option(as, 'r', "revcomp", NULL,
+            "Also search reverse complement of query and target", "TRUE",
+            Argument_parse_boolean, &aas.use_revcomp);
         ArgumentSet_add_option(as, '\0', "forcescan", "[q|t]",
             "Force FSM scan on query or target sequences", "none",
             Argument_parse_string, &aas.force_scan);
@@ -45,6 +53,9 @@ Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg){
         ArgumentSet_add_option(as, 0, "customserver", "command",
             "Custom command to send non-standard server", "NULL",
             Argument_parse_string, &aas.custom_server_command);
+        ArgumentSet_add_option(as, 'c', "cores", "number",
+            "Number of cores/CPUs/threads for alignment computation", "1",
+            Argument_parse_int, &aas.thread_count);
         Argument_absorb_ArgumentSet(arg, as);
         }
     return &aas;
@@ -52,10 +63,43 @@ Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg){
 
 /**/
 
+typedef struct {
+           GAM *gam;
+    Comparison *comparison;
+} Analysis_HeuristicJob;
+
+static Analysis_HeuristicJob *Analysis_HeuristicJob_create(GAM *gam,
+                                       Comparison *comparison){
+    register Analysis_HeuristicJob *ahj = g_new(Analysis_HeuristicJob, 1);
+    ahj->gam = GAM_share(gam);
+    ahj->comparison = Comparison_share(comparison);
+    return ahj;
+    }
+
+static void Analysis_HeuristicJob_destroy(Analysis_HeuristicJob *ahj){
+    Comparison_destroy(ahj->comparison);
+    GAM_destroy(ahj->gam);
+    g_free(ahj);
+    return;
+    }
+
+static void Analysis_HeuristicJob_run(gpointer data){
+    register Analysis_HeuristicJob *ahj = data;
+    register GAM_Result *gam_result
+           = GAM_Result_heuristic_create(ahj->gam, ahj->comparison);
+    if(gam_result){
+        GAM_Result_submit(gam_result);
+        GAM_Result_destroy(gam_result);
+        }
+    Analysis_HeuristicJob_destroy(ahj);
+    return;
+    }
+
 static void Analysis_report_func(Comparison *comparison,
                                  gpointer user_data){
     register Analysis *analysis = user_data;
     register GAM_Result *gam_result;
+    register Analysis_HeuristicJob *ahj;
     g_assert(Comparison_has_hsps(comparison));
     if(analysis->scan_query){
         /* Swap back query and target after a query scan */
@@ -70,15 +114,21 @@ static void Analysis_report_func(Comparison *comparison,
             Comparison_revcomp(comparison);
         }
     if(Model_Type_is_gapped(analysis->gam->gas->type)){
-        gam_result = GAM_Result_heuristic_create(analysis->gam,
-                                                 comparison);
+        ahj = Analysis_HeuristicJob_create(analysis->gam, comparison);
+#ifdef USE_PTHREADS
+        g_assert(analysis->job_queue);
+        /* FIXME: need to use priority here */
+        JobQueue_submit(analysis->job_queue, Analysis_HeuristicJob_run, ahj, 2);
+#else /* USE_PTHREADS */
+        Analysis_HeuristicJob_run(ahj);
+#endif /* USE_PTHREADS */
     } else {
         gam_result = GAM_Result_ungapped_create(analysis->gam,
                                                 comparison);
-        }
-    if(gam_result){
-        GAM_Result_submit(gam_result);
-        GAM_Result_destroy(gam_result);
+        if(gam_result){
+            GAM_Result_submit(gam_result);
+            GAM_Result_destroy(gam_result);
+            }
         }
     return;
     }
@@ -108,7 +158,7 @@ static void Analysis_FastaPipe_Pair_term_func(gpointer user_data){
 /* Called after query pipeline analysis */
 
 static gboolean Analysis_FastaPipe_Pair_query_func(FastaDB_Seq *fdbs,
-                                                   gpointer user_data){
+                                                  gpointer user_data){
     register Analysis *analysis = user_data;
     g_assert(!analysis->curr_query);
     /*
@@ -139,22 +189,63 @@ static void Analysis_BSAM_compare(Analysis *analysis,
 
 /**/
 
+typedef struct {
+         GAM *gam;
+    Sequence *query;
+    Sequence *target;
+} Analysis_ExhaustiveJob;
+
+static Analysis_ExhaustiveJob *Analysis_ExhaustiveJob_create(GAM *gam,
+                                        Sequence *query, Sequence *target){
+    register Analysis_ExhaustiveJob *aej = g_new(Analysis_ExhaustiveJob, 1);
+    aej->gam = GAM_share(gam);
+    aej->query = Sequence_share(query);
+    aej->target = Sequence_share(target);
+    return aej;
+    }
+
+static void Analysis_ExhaustiveJob_destroy(Analysis_ExhaustiveJob *aej){
+    GAM_destroy(aej->gam);
+    Sequence_destroy(aej->query);
+    Sequence_destroy(aej->target);
+    g_free(aej);
+    return;
+    }
+
+static void Analysis_ExhaustiveJob_run(gpointer data){
+    register Analysis_ExhaustiveJob *aej = data;
+    register GAM_Result *gam_result;
+    gam_result = GAM_Result_exhaustive_create(aej->gam,
+                                              aej->query, aej->target);
+    if(gam_result){
+        GAM_Result_submit(gam_result);
+        GAM_Result_destroy(gam_result);
+        }
+    Analysis_ExhaustiveJob_destroy(aej);
+    return;
+    }
+
 static void Analysis_Pair_compare(Analysis *analysis,
                                   FastaDB_Seq *fdbs){
-    register GAM_Result *gam_result;
+    register Analysis_ExhaustiveJob *aej;
     if(analysis->aas->use_exhaustive){
-        gam_result = GAM_Result_exhaustive_create(analysis->gam,
-                         analysis->curr_query->seq, fdbs->seq);
-        if(gam_result){
-            GAM_Result_submit(gam_result);
-            GAM_Result_destroy(gam_result);
-            }
+        aej = Analysis_ExhaustiveJob_create(analysis->gam,
+                                            analysis->curr_query->seq,
+                                            fdbs->seq);
+#ifdef USE_PTHREADS
+        g_assert(analysis->job_queue);
+        JobQueue_submit(analysis->job_queue, Analysis_ExhaustiveJob_run, aej, 1);
+#else /* USE_PTHREADS */
+        Analysis_ExhaustiveJob_run(aej);
+#endif /* USE_PTHREADS */
     } else {
         Analysis_BSAM_compare(analysis, analysis->curr_query, fdbs);
         }
     return;
     }
 
+/**/
+
 static gboolean Analysis_FastaPipe_Pair_target_func(FastaDB_Seq *fdbs,
                                                     gpointer user_data){
     register Analysis *analysis = user_data;
@@ -420,6 +511,24 @@ static void Analysis_Client_set_param(Analysis_Client *aclient, GAM *gam){
     g_free(msg);
     g_free(reply);
     /**/
+    msg = g_strdup_printf("set param dnawordlimit %d",
+                          has->dna_word_limit);
+    reply = Analysis_Client_send(aclient, msg, "ok:", FALSE);
+    g_free(msg);
+    g_free(reply);
+    /**/
+    msg = g_strdup_printf("set param proteinwordlimit %d",
+                          has->protein_word_limit);
+    reply = Analysis_Client_send(aclient, msg, "ok:", FALSE);
+    g_free(msg);
+    g_free(reply);
+    /**/
+    msg = g_strdup_printf("set param codonwordlimit %d",
+                          has->codon_word_limit);
+    reply = Analysis_Client_send(aclient, msg, "ok:", FALSE);
+    g_free(msg);
+    g_free(reply);
+    /**/
     msg = g_strdup_printf("set param dnahspdropoff %d",
                           has->dna_hsp_dropoff);
     reply = Analysis_Client_send(aclient, msg, "ok:", FALSE);
@@ -465,6 +574,10 @@ static void Analysis_Client_set_param(Analysis_Client *aclient, GAM *gam){
     return;
     }
 
+static void Analysis_Client_info(Analysis_Client *aclient){
+    return;
+    }
+
 static Analysis_Client *Analysis_Client_create(gchar *path, gint verbosity){
     register Analysis_Client *aclient;
     register SocketClient *sc = Analysis_Client_connect(path);
@@ -473,6 +586,7 @@ static Analysis_Client *Analysis_Client_create(gchar *path, gint verbosity){
     if(!sc)
         return NULL;
     aclient = g_new(Analysis_Client, 1);
+    aclient->ref_count = 1;
     aclient->sc = sc;
     aclient->verbosity = verbosity;
     aclient->probe_fdb = NULL;
@@ -508,12 +622,20 @@ static Analysis_Client *Analysis_Client_create(gchar *path, gint verbosity){
     g_free(dbinfo);
     aclient->curr_query = NULL;
     aclient->seq_cache = g_new0(Sequence*, aclient->num_seqs);
+    Analysis_Client_info(aclient);
+    return aclient;
+    }
+
+static Analysis_Client *Analysis_Client_share(Analysis_Client *aclient){
+    aclient->ref_count++;
     return aclient;
     }
 
 static void Analysis_Client_destroy(Analysis_Client *aclient){
     register gint i;
     register Sequence *seq;
+    if(--aclient->ref_count)
+        return;
     if(aclient->curr_query)
         Sequence_destroy(aclient->curr_query);
     for(i = 0; i < aclient->num_seqs; i++){
@@ -533,7 +655,7 @@ static void Analysis_Client_destroy(Analysis_Client *aclient){
 static void Analysis_Client_set_probe_fdb(Analysis_Client *aclient,
                                           FastaDB *probe_fdb){
     g_assert(!aclient->probe_fdb);
-    aclient->probe_fdb = FastaDB_share(probe_fdb);
+    aclient->probe_fdb = FastaDB_dup(probe_fdb);
     return;
     }
 
@@ -592,13 +714,14 @@ typedef struct {
 static Analysis_Client_Key *Analysis_Client_Key_create(Analysis_Client *aclient,
                                                    gint target_id, gint seq_len){
     register Analysis_Client_Key *key = g_new(Analysis_Client_Key, 1);
-    key->aclient = aclient;
+    key->aclient = Analysis_Client_share(aclient);
     key->target_id = target_id;
     key->seq_len = seq_len;
     return key;
     }
 
 static void Analysis_Client_Key_destroy(Analysis_Client_Key *key){
+    Analysis_Client_destroy(key->aclient);
     g_free(key);
     return;
     }
@@ -848,7 +971,8 @@ static void Analysis_Client_process_query(Analysis_Client *aclient,
                                           Analysis *analysis,
                                           Sequence *query,
                                           gboolean swap_chains,
-                                          gboolean revcomp_target){
+                                          gboolean revcomp_target,
+                                          gint priority){
     Analysis_Client_set_query(aclient, query);
     Analysis_Client_get_hsp_sets(aclient, analysis, swap_chains, revcomp_target);
     /* Revcomp query if DNA */
@@ -861,19 +985,20 @@ static void Analysis_Client_process_query(Analysis_Client *aclient,
     }
 
 static void Analysis_Client_process(Analysis_Client *aclient, Analysis *analysis,
-                                    gboolean swap_chains){
+                                    gboolean swap_chains, gint priority){
     register FastaDB_Seq *fdbs;
     /* FIXME: need to check for appropriate database type */
     while((fdbs = FastaDB_next(aclient->probe_fdb, FastaDB_Mask_ALL))){
         Analysis_Client_process_query(aclient, analysis, fdbs->seq,
-                                      swap_chains, FALSE);
+                                      swap_chains, FALSE, priority);
         /* Revcomp target if protein vs DNA or translate_both */
         if(((aclient->curr_query->alphabet->type == Alphabet_Type_PROTEIN)
           && (aclient->server_alphabet->type == Alphabet_Type_DNA))
            || analysis->gam->translate_both){
             Analysis_Client_revcomp_target(aclient);
             Analysis_Client_process_query(aclient, analysis,
-                                          fdbs->seq, swap_chains, TRUE);
+                                          fdbs->seq, swap_chains, TRUE,
+                                          priority);
             Analysis_Client_revcomp_target(aclient);
             }
         FastaDB_Seq_destroy(fdbs);
@@ -883,6 +1008,163 @@ static void Analysis_Client_process(Analysis_Client *aclient, Analysis *analysis
 
 /**/
 
+static Analysis_Server *Analysis_Server_create(Analysis_Builder *ab,
+                                               gchar *name, gint priority){
+    register Analysis_Server *as = g_new(Analysis_Server, 1);
+    as->name = g_strdup(name);
+    as->ab = ab;
+    as->priority = priority;
+    return as;
+    }
+
+static void Analysis_Server_destroy(Analysis_Server *as){
+    g_free(as->name);
+    g_free(as);
+    return;
+    }
+
+/**/
+
+static Analysis_Builder *Analysis_Builder_create(GPtrArray *path_list,
+                                                 Analysis *analysis,
+                                                 gint verbosity){
+    register Analysis_Builder *ab;
+    register gint i;
+    register Analysis_Client *ac;
+    register Analysis_Server *as;
+    g_assert(path_list->len);
+    ac = Analysis_Client_create(path_list->pdata[0], analysis->verbosity);
+    if(!ac)
+        return NULL;
+    /**/
+    ab = g_new(Analysis_Builder, 1);
+    ab->verbosity = verbosity;
+    ab->server_list = g_ptr_array_new();
+    ab->server_type = ac->server_alphabet->type;
+    ab->probe_fdb = NULL;
+    ab->analysis = analysis;
+    Analysis_Client_destroy(ac);
+    for(i = 0; i < path_list->len; i++){
+        as = Analysis_Server_create(ab, path_list->pdata[i], i);
+        g_ptr_array_add(ab->server_list, as);
+        }
+    return ab;
+    }
+
+static void Analysis_Builder_destroy(Analysis_Builder *ab){
+    register gint i;
+    register Analysis_Server *as;
+    for(i = 0; i < ab->server_list->len; i++){
+        as = ab->server_list->pdata[i];
+        Analysis_Server_destroy(as);
+        }
+    g_ptr_array_free(ab->server_list, TRUE);
+    if(ab->probe_fdb)
+        FastaDB_close(ab->probe_fdb);
+    g_free(ab);
+    return;
+    }
+
+static void Analysis_Server_run(gpointer data){
+    register Analysis_Server *server = data;
+    register Analysis_Client *client
+                = Analysis_Client_create(server->name,
+                                         server->ab->analysis->verbosity);
+    if(!client)
+        g_error("Could not connect to server [%s]", server->name);
+    Analysis_Client_set_param(client, server->ab->analysis->gam);
+    Analysis_Client_set_probe_fdb(client, server->ab->probe_fdb);
+    Analysis_Client_process(client, server->ab->analysis,
+                            server->ab->swap_chains, server->priority);
+    /**/
+    Analysis_Client_destroy(client);
+    return;
+    }
+
+static void Analysis_Builder_process(Analysis_Builder *ab,
+                                     Analysis *analysis, gboolean swap_chains){
+    register gint i;
+    register Analysis_Server *as;
+    ab->swap_chains = swap_chains;
+    for(i = 0; i < ab->server_list->len; i++){
+        as = ab->server_list->pdata[i];
+#ifdef USE_PTHREADS
+        g_assert(analysis->job_queue);
+        JobQueue_submit(analysis->job_queue, Analysis_Server_run, as, i);
+#else /* USE_PTHREADS */
+        Analysis_Server_run(as);
+#endif /* USE_PTHREADS */
+        }
+    return;
+    }
+
+static void Analysis_Builder_set_probe_fdb(Analysis_Builder *ab,
+                                           FastaDB *probe_fdb){
+    g_assert(!ab->probe_fdb);
+    ab->probe_fdb = FastaDB_share(probe_fdb);
+    return;
+    }
+
+/**/
+
+static void Analysis_path_list_destroy(GPtrArray *path_list){
+    register gint i;
+    register gchar *path;
+    for(i = 0; i < path_list->len; i++){
+        path = path_list->pdata[i];
+        g_free(path);
+        }
+    g_ptr_array_free(path_list, TRUE);
+    return;
+    }
+
+static GPtrArray *Analysis_FOSN_expand_path_list(GPtrArray *path_list){
+    register gint i;
+    register gchar *path, *npath;
+    struct stat buf;
+    register gboolean expanded_list = FALSE;
+    register GPtrArray *npath_list = g_ptr_array_new();
+    register FILE *fp;
+    register LineParse *lp;
+    for(i = 0; i < path_list->len; i++){
+        path = path_list->pdata[i];
+        if((stat(path, &buf))              /* Cannot read file (ie. servername) */
+        || (S_ISDIR(buf.st_mode))          /* Is directory */
+        || (FastaDB_file_is_fasta(path))){ /* 1st non-whitespace char is '>' */
+            npath = g_strdup(path);
+            g_ptr_array_add(npath_list, npath);
+        } else { /* Assume to be fosn */
+            fp = fopen(path, "r");
+            if(!fp)
+                g_error("Could not open FOSN file [%s]", path);
+            lp = LineParse_create(fp);
+            while(LineParse_line(lp) != EOF){
+                g_strstrip(lp->line->str); /* strip whitespace */
+                if(lp->line->str[0]){
+                    npath = g_strdup(lp->line->str);
+                    g_ptr_array_add(npath_list, npath);
+                    expanded_list = TRUE;
+                    }
+                }
+            LineParse_destroy(lp);
+            fclose(fp);
+            }
+        }
+    if(!expanded_list){
+        for(i = 0; i < npath_list->len; i++){
+            npath = npath_list->pdata[i];
+            g_free(npath);
+            }
+        g_ptr_array_free(npath_list, TRUE);
+        return NULL;
+        }
+    return npath_list;
+    }
+/* If members of the path list are files
+ * where the first non-whitespace character is not '>',
+ * it is assumed to be a FOSN, and parsed to expand the path_list.
+ */
+
 Analysis *Analysis_create(
               GPtrArray *query_path_list, Alphabet_Type query_type,
               gint query_chunk_id, gint query_chunk_total,
@@ -899,26 +1181,33 @@ Analysis *Analysis_create(
                        *codon_hsp_param;
     register Match_ArgumentSet *mas = Match_ArgumentSet_create(NULL);
     register gboolean use_horizon;
+    register GPtrArray *expanded_query_path_list = NULL,
+                       *expanded_target_path_list = NULL;
     g_assert(query_path_list);
     g_assert(target_path_list);
     g_assert(query_path_list->len);
     g_assert(target_path_list->len);
     analysis->aas = Analysis_ArgumentSet_create(NULL);
-
     analysis->verbosity = verbosity;
+    analysis->job_queue = JobQueue_create(analysis->aas->thread_count);
+    /* Expand FOSN paths */
+    expanded_query_path_list = Analysis_FOSN_expand_path_list(
+                                                    query_path_list);
+    expanded_target_path_list = Analysis_FOSN_expand_path_list(
+                                                    target_path_list);
+    if(expanded_query_path_list)
+        query_path_list = expanded_query_path_list;
+    if(expanded_target_path_list)
+        target_path_list = expanded_target_path_list;
     /**/
-    if(query_path_list->len == 1)
-        analysis->query_ac
-                = Analysis_Client_create((gchar*)query_path_list->pdata[0],
-                                         verbosity);
-    if(target_path_list->len == 1)
-        analysis->target_ac
-                = Analysis_Client_create((gchar*)target_path_list->pdata[0],
-                                       verbosity);
+    analysis->query_builder = Analysis_Builder_create(query_path_list,
+                                                     analysis, verbosity);
+    analysis->target_builder = Analysis_Builder_create(target_path_list,
+                                                     analysis, verbosity);
     /**/
     if(query_type == Alphabet_Type_UNKNOWN){
-        if(analysis->query_ac){
-            query_type = analysis->query_ac->server_alphabet->type;
+        if(analysis->query_builder){
+            query_type = analysis->query_builder->server_type;
         } else {
             query_type = FastaDB_guess_type(
                               (gchar*)query_path_list->pdata[0]);
@@ -928,8 +1217,8 @@ Analysis *Analysis_create(
             }
         }
     if(target_type == Alphabet_Type_UNKNOWN){
-        if(analysis->target_ac){
-            target_type = analysis->target_ac->server_alphabet->type;
+        if(analysis->target_builder){
+            target_type = analysis->target_builder->server_type;
         } else {
             target_type = FastaDB_guess_type(
                               (gchar*)target_path_list->pdata[0]);
@@ -953,11 +1242,6 @@ Analysis *Analysis_create(
                                analysis->aas->use_exhaustive,
                                verbosity);
     /**/
-    if(analysis->query_ac)
-        Analysis_Client_set_param(analysis->query_ac, analysis->gam);
-    if(analysis->target_ac)
-        Analysis_Client_set_param(analysis->target_ac, analysis->gam);
-    /**/
     Analysis_find_matches(analysis, &dna_match, &protein_match,
                                     &codon_match);
     match = dna_match;
@@ -966,14 +1250,14 @@ Analysis *Analysis_create(
     if(!match)
         match = codon_match;
     g_assert(match);
-    if(!analysis->query_ac)
+    if(!analysis->query_builder)
         query_fdb = FastaDB_open_list_with_limit(query_path_list,
                 match->query->alphabet, query_chunk_id, query_chunk_total);
-    if(!analysis->target_ac)
+    if(!analysis->target_builder)
        target_fdb = FastaDB_open_list_with_limit(target_path_list,
                match->target->alphabet, target_chunk_id, target_chunk_total);
     if(analysis->aas->use_exhaustive){
-        if(analysis->query_ac || analysis->target_ac) /* FIXME: ni */
+        if(analysis->query_builder || analysis->target_builder) /* FIXME: ni */
             g_error("Exhaustive alignment against server not implemented");
         analysis->fasta_pipe = FastaPipe_create(
                                   query_fdb, target_fdb,
@@ -983,12 +1267,13 @@ Analysis *Analysis_create(
                                   Analysis_FastaPipe_Pair_query_func,
                                   Analysis_FastaPipe_Pair_target_func,
                                   FastaDB_Mask_ALL,
-                                  analysis->gam->translate_both);
+                                  analysis->gam->translate_both,
+                                  analysis->aas->use_revcomp);
         analysis->curr_query = NULL;
     } else { /* Not exhaustive */
         use_horizon = (analysis->aas->use_bigseq
-                    || analysis->query_ac
-                    || analysis->target_ac)?FALSE:TRUE;
+                    || analysis->query_builder
+                    || analysis->target_builder)?FALSE:TRUE;
         dna_hsp_param = dna_match
                       ? HSP_Param_create(dna_match, use_horizon)
                       : NULL;
@@ -1026,15 +1311,17 @@ Analysis *Analysis_create(
                     = analysis->gam->gas->threshold;
             }
         /* Don't need HSP horizon for bigseq comparison */
-        if(analysis->query_ac || analysis->target_ac){
-            if(analysis->query_ac && analysis->target_ac)
+        if(analysis->query_builder || analysis->target_builder){
+            if(analysis->query_builder && analysis->target_builder)
                 g_error("Server vs server comparison not impelemented");
             analysis->fasta_pipe = NULL;
-            if(analysis->query_ac){
-                Analysis_Client_set_probe_fdb(analysis->query_ac, target_fdb);
+            if(analysis->query_builder){
+                Analysis_Builder_set_probe_fdb(analysis->query_builder,
+                                              target_fdb);
             } else {
-                g_assert(analysis->target_ac);
-                Analysis_Client_set_probe_fdb(analysis->target_ac, query_fdb);
+                g_assert(analysis->target_builder);
+                Analysis_Builder_set_probe_fdb(analysis->target_builder,
+                                               query_fdb);
                 }
         } else {
             if(analysis->aas->use_bigseq){
@@ -1049,7 +1336,8 @@ Analysis *Analysis_create(
                                       Analysis_FastaPipe_Pair_query_func,
                                       Analysis_FastaPipe_Pair_target_func,
                                       FastaDB_Mask_ALL,
-                                      analysis->gam->translate_both);
+                                      analysis->gam->translate_both,
+                                      analysis->aas->use_revcomp);
                 analysis->curr_query = NULL;
             } else { /* Use Seeder */
                 analysis->scan_query = Analysis_decide_scan_query(query_fdb,
@@ -1076,7 +1364,8 @@ Analysis *Analysis_create(
                     Analysis_FastaPipe_Seeder_term_func,
                     Analysis_FastaPipe_Seeder_query_func,
                     Analysis_FastaPipe_Seeder_target_func,
-                    FastaDB_Mask_ALL, analysis->gam->translate_both);
+                    FastaDB_Mask_ALL, analysis->gam->translate_both,
+                    analysis->aas->use_revcomp);
                 }
             }
         }
@@ -1085,10 +1374,15 @@ Analysis *Analysis_create(
     if(target_fdb)
         FastaDB_close(target_fdb);
     /**/
+    if(expanded_query_path_list)
+        Analysis_path_list_destroy(expanded_query_path_list);
+    if(expanded_target_path_list)
+        Analysis_path_list_destroy(expanded_target_path_list);
     return analysis;
     }
 
 void Analysis_destroy(Analysis *analysis){
+    JobQueue_destroy(analysis->job_queue);
     if(analysis->fasta_pipe)
         FastaPipe_destroy(analysis->fasta_pipe);
     if(analysis->curr_query)
@@ -1099,23 +1393,31 @@ void Analysis_destroy(Analysis *analysis){
         BSAM_destroy(analysis->bsam);
     if(analysis->comparison_param)
         Comparison_Param_destroy(analysis->comparison_param);
+    /*
     if(analysis->query_ac)
         Analysis_Client_destroy(analysis->query_ac);
     if(analysis->target_ac)
         Analysis_Client_destroy(analysis->target_ac);
+    */
+    if(analysis->query_builder)
+        Analysis_Builder_destroy(analysis->query_builder);
+    if(analysis->target_builder)
+        Analysis_Builder_destroy(analysis->target_builder);
     GAM_destroy(analysis->gam);
     g_free(analysis);
     return;
     }
 
 void Analysis_process(Analysis *analysis){
-    if(analysis->query_ac){
-        Analysis_Client_process(analysis->query_ac, analysis, TRUE);
-    } else if(analysis->target_ac){
-        Analysis_Client_process(analysis->target_ac, analysis, FALSE);
+    if(analysis->query_builder){
+        Analysis_Builder_process(analysis->query_builder, analysis, TRUE);
+    } else if(analysis->target_builder){
+        Analysis_Builder_process(analysis->target_builder, analysis, FALSE);
     } else {
         while(FastaPipe_process(analysis->fasta_pipe, analysis));
         }
+    if(analysis->job_queue)
+        JobQueue_complete(analysis->job_queue);
     GAM_report(analysis->gam);
     return;
     }
diff --git a/src/hub/analysis.h b/src/hub/analysis.h
index c53eb99..bbcb77f 100644
--- a/src/hub/analysis.h
+++ b/src/hub/analysis.h
@@ -3,7 +3,7 @@
 *  Analysis module for exonerate                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -30,13 +30,16 @@ extern "C" {
 #include "seeder.h"
 #include "comparison.h"
 #include "socket.h"
+#include "jobqueue.h"
 
 typedef struct {
     gboolean  use_exhaustive;
     gboolean  use_bigseq;
+    gboolean  use_revcomp;
        gchar *force_scan;
         gint  saturate_threshold;
        gchar *custom_server_command;
+        gint  thread_count;
 } Analysis_ArgumentSet;
 
 Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg);
@@ -44,20 +47,36 @@ Analysis_ArgumentSet *Analysis_ArgumentSet_create(Argument *arg);
 /**/
 
 typedef struct {
-           SocketClient  *sc;
                    gint   verbosity;
+                   gint   ref_count;
                Alphabet  *server_alphabet;
                gboolean   is_masked;
                 guint64   num_seqs;
                 guint64   max_seq_len;
                 guint64   total_seq_len;
                 /**/
+           SocketClient  *sc;
                 FastaDB  *probe_fdb;
                Sequence  *curr_query;
                Sequence **seq_cache;
 } Analysis_Client;
 
 typedef struct {
+                      gchar *name;
+                       gint  priority;   /* used for job queues */
+    struct Analysis_Builder *ab;
+} Analysis_Server;
+
+typedef struct Analysis_Builder {
+               gint  verbosity;
+            FastaDB *probe_fdb;
+          GPtrArray *server_list; /* Contains Analysis_Server objects */
+      Alphabet_Type  server_type;
+    struct Analysis *analysis;
+           gboolean  swap_chains;
+} Analysis_Builder;
+
+typedef struct Analysis {
                FastaPipe *fasta_pipe;
                      GAM *gam;
                     BSAM *bsam;
@@ -67,8 +86,13 @@ typedef struct {
                 gboolean  scan_query;
         Comparison_Param *comparison_param;
                     gint  verbosity;
+                    /*
          Analysis_Client *query_ac;
          Analysis_Client *target_ac;
+         */
+        Analysis_Builder *query_builder;
+        Analysis_Builder *target_builder;
+                JobQueue *job_queue;
 } Analysis;
 
 Analysis *Analysis_create(
diff --git a/src/hub/analysis.test.c b/src/hub/analysis.test.c
index 8b0e984..f080b17 100644
--- a/src/hub/analysis.test.c
+++ b/src/hub/analysis.test.c
@@ -3,7 +3,7 @@
 *  Analysis module for exonerate                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/hub/bsam.c b/src/hub/bsam.c
index 356b873..3e125ba 100644
--- a/src/hub/bsam.c
+++ b/src/hub/bsam.c
@@ -3,7 +3,7 @@
 *  BSAM: Big Sequence Alignment Manager                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/hub/bsam.h b/src/hub/bsam.h
index 6c4448e..4ef43b6 100644
--- a/src/hub/bsam.h
+++ b/src/hub/bsam.h
@@ -3,7 +3,7 @@
 *  BSAM: Big Sequence Alignment Manager                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/hub/bsam.test.c b/src/hub/bsam.test.c
index fc40b84..a92eae2 100644
--- a/src/hub/bsam.test.c
+++ b/src/hub/bsam.test.c
@@ -3,7 +3,7 @@
 *  BSAM: Big Sequence Alignment Manager                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/hub/gam.c b/src/hub/gam.c
index d8c9cf6..8ee2236 100644
--- a/src/hub/gam.c
+++ b/src/hub/gam.c
@@ -3,7 +3,7 @@
 *  GAM: Gapped Alignment Manager                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -162,32 +162,18 @@ static gboolean GAM_StoredResult_compare(gpointer low,
 
 static void GAM_display_alignment(GAM *gam,
             Alignment *alignment, Sequence *query, Sequence *target,
-            gint result_id, gint rank, gpointer user_data, FILE *fp);
-
-#if 0
-static FILE *GAM_bestn_tmp_file = NULL;
-
-static void GAM_StoredResult_print(const gchar *string){
-    g_assert(GAM_bestn_tmp_file);
-    fprintf(GAM_bestn_tmp_file, "%s", string);
-    return;
-    }
-#endif /* 0 */
+            gint result_id, gint rank,
+            gpointer user_data, gpointer self_data, FILE *fp);
 
 static GAM_StoredResult *GAM_StoredResult_create(GAM *gam,
                          Sequence *query, Sequence *target,
-                         Alignment *alignment, gpointer user_data){
+                         Alignment *alignment,
+                         gpointer user_data, gpointer self_data){
     register GAM_StoredResult *gsr = g_new(GAM_StoredResult, 1);
-    /* register GPrintFunc prev_print_func; */
     gsr->score = alignment->score;
     gsr->pos = ftell(gam->bestn_tmp_file);
-    /*
-    GAM_bestn_tmp_file = gam->bestn_tmp_file;
-    prev_print_func = g_set_print_handler(GAM_StoredResult_print);
-    */
     GAM_display_alignment(gam, alignment, query, target,
-                          0, -1, user_data, gam->bestn_tmp_file);
-    /* g_set_print_handler(prev_print_func); */
+                          0, -1, user_data, self_data, gam->bestn_tmp_file);
     gsr->len = ftell(gam->bestn_tmp_file)
              - gsr->pos;
     return gsr;
@@ -268,7 +254,8 @@ static void GAM_QueryResult_push(GAM_QueryResult *gqr,
                                           gam_result->query,
                                           gam_result->target,
                                           alignment,
-                                          gam_result->user_data);
+                                          gam_result->user_data,
+                                          gam_result->self_data);
     PQueue_push(gqr->pq, gsr);
     return;
     }
@@ -337,7 +324,7 @@ static void GAM_QueryResult_submit(GAM_QueryResult *gqr,
 /**/
 
 static gboolean GAM_QueryResult_report_traverse_func(gpointer data,
-                                                   gpointer user_data){
+                                                     gpointer user_data){
     register GAM_StoredResult *gsr = data;
     register GPtrArray *result_list = user_data;
     g_ptr_array_add(result_list, gsr);
@@ -424,14 +411,14 @@ GAM *GAM_create(Alphabet_Type query_type, Alphabet_Type target_type,
     register GAM *gam = g_new0(GAM, 1);
     register gint i;
     register C4_Span *span;
-    gam->ref_count = 1;
+    gam->thread_ref = ThreadRef_create();
     gam->dna_submat = Submat_share(dna_submat);
     gam->protein_submat = Submat_share(protein_submat);
     gam->translate = Translate_share(translate);
     gam->gas = GAM_ArgumentSet_create(NULL);
     if(use_exhaustive && gam->gas->use_subopt)
         g_warning("Exhaustively generating suboptimal alignments"
-                  " will be VERY SLOW");
+                  " will be VERY SLOW: use -S no");
     gam->query_type = query_type;
     gam->target_type = target_type;
     if(gam->gas->best_n){
@@ -446,7 +433,7 @@ GAM *GAM_create(Alphabet_Type query_type, Alphabet_Type target_type,
     gam->model = Model_Type_get_model(gam->gas->type,
                                       query_type, target_type);
     if((!use_exhaustive) && (!C4_Model_is_local(gam->model)))
-        g_error("Cannot perform heuristic alignment using non-local model");
+        g_error("Cannot perform heuristic alignments using non-local models: use -E");
     gam->match_list = GAM_build_match_list(gam->model);
     if(use_exhaustive){
         gam->optimal = Optimal_create(gam->model, NULL,
@@ -480,12 +467,15 @@ GAM *GAM_create(Alphabet_Type query_type, Alphabet_Type target_type,
         if(gam->max_target_span < span->max_target)
             gam->max_target_span = span->max_target;
         }
+#ifdef USE_PTHREADS
+    pthread_mutex_init(&gam->gam_lock, NULL);
+#endif /* USE_PTHREADS */
     return gam;
     }
 
 GAM *GAM_share(GAM *gam){
     g_assert(gam);
-    gam->ref_count++;
+    ThreadRef_share(gam->thread_ref);
     return gam;
     }
 
@@ -557,8 +547,11 @@ static void GAM_percent_threshold_tree_destroy(
 
 void GAM_destroy(GAM *gam){
     g_assert(gam);
-    if(--gam->ref_count)
+    if(ThreadRef_destroy(gam->thread_ref))
         return;
+#ifdef USE_PTHREADS
+    pthread_mutex_destroy(&gam->gam_lock);
+#endif /* USE_PTHREADS */
     g_assert(gam->model);
     g_ptr_array_free(gam->match_list, TRUE);
     C4_Model_destroy(gam->model);
@@ -639,6 +632,8 @@ static GAM_Result *GAM_Result_create(GAM *gam,
     gam_result->target = Sequence_share(target);
     gam_result->user_data = Model_Type_create_data(gam->gas->type,
                                                    query, target);
+    gam_result->self_data = Model_Type_create_data(gam->gas->type,
+                                                   query, query);
     gam_result->subopt = SubOpt_create(query->len, target->len);
     return gam_result;
     }
@@ -1108,7 +1103,8 @@ static void GAM_Result_geneseed_filter(GAM *gam, Comparison *comparison){
     /* Keep HSPs marked as keep */
     hsp_id = GAM_Result_geneseed_select(comparison->dna_hspset,
                  gsd.fwd_keep, gsd.rev_keep, hsp_id);
-    hsp_id = GAM_Result_geneseed_select(comparison->protein_hspset, gsd.fwd_keep, gsd.rev_keep, hsp_id);
+    hsp_id = GAM_Result_geneseed_select(comparison->protein_hspset,
+                 gsd.fwd_keep, gsd.rev_keep, hsp_id);
     hsp_id = GAM_Result_geneseed_select(comparison->codon_hspset,
                  gsd.fwd_keep, gsd.rev_keep, hsp_id);
     /**/
@@ -1152,8 +1148,10 @@ GAM_Result *GAM_Result_heuristic_create(GAM *gam,
         /* Raise score threshold to geneseed
          * to prevent low-scoring subopt alignments.
          */
+        GAM_lock(gam);
         if(gam->gas->threshold < has->geneseed_threshold)
             gam->gas->threshold = has->geneseed_threshold;
+        GAM_unlock(gam);
         GAM_Result_geneseed_filter(gam, comparison);
         }
     if(!Comparison_has_hsps(comparison))
@@ -1179,18 +1177,26 @@ GAM_Result *GAM_Result_exhaustive_create(GAM *gam,
                                          Sequence *target){
     register Alignment *alignment;
     register C4_Score threshold;
-    register GAM_Result *gam_result = GAM_Result_create(gam,
-                                                        query, target);
+    register GAM_Result *gam_result;
     register OPair *opair;
     g_assert(gam->optimal);
+    GAM_lock(gam);
+    Sequence_lock(query);
+    Sequence_lock(target);
+    gam_result = GAM_Result_create(gam, query, target);
+    Sequence_unlock(query);
+    Sequence_unlock(target);
     opair = OPair_create(gam->optimal, gam_result->subopt,
                          query->len, target->len, gam_result->user_data);
+    GAM_unlock(gam);
     if(gam->verbosity > 1)
         g_message("Exhaustive alignment of [%s] [%s]",
-                 query->id, target->id);
+                  query->id, target->id);
     /**/
     do {
+        GAM_lock(gam);
         threshold = GAM_get_query_threshold(gam, query);
+        GAM_unlock(gam);
         alignment = OPair_next_path(opair, threshold);
         if(!alignment)
             break;
@@ -1224,17 +1230,22 @@ void GAM_Result_destroy(GAM_Result *gam_result){
         }
     Model_Type_destroy_data(gam_result->gam->gas->type,
                             gam_result->user_data);
+    Model_Type_destroy_data(gam_result->gam->gas->type,
+                            gam_result->self_data);
     Sequence_destroy(gam_result->query);
     Sequence_destroy(gam_result->target);
+    GAM_lock(gam_result->gam);
     GAM_destroy(gam_result->gam);
     SubOpt_destroy(gam_result->subopt);
+    GAM_unlock(gam_result->gam);
     g_free(gam_result);
     return;
     }
 
 static void GAM_display_alignment(GAM *gam, Alignment *alignment,
             Sequence *query, Sequence *target,
-            gint result_id, gint rank, gpointer user_data, FILE *fp){
+            gint result_id, gint rank,
+            gpointer user_data, gpointer self_data, FILE *fp){
     if(gam->gas->show_alignment)
         Alignment_display(alignment, query, target,
                           gam->dna_submat, gam->protein_submat,
@@ -1246,15 +1257,16 @@ static void GAM_display_alignment(GAM *gam, Alignment *alignment,
     if(gam->gas->show_vulgar)
         Alignment_display_vulgar(alignment, query, target, fp);
     if(gam->gas->show_query_gff)
-        Alignment_display_gff(alignment, query, target,
-                              TRUE, FALSE, result_id, fp);
+        Alignment_display_gff(alignment, query, target, gam->translate,
+                              TRUE, FALSE, result_id, user_data, fp);
     if(gam->gas->show_target_gff)
-        Alignment_display_gff(alignment, query, target, FALSE,
-             Model_Type_has_genomic_target(gam->gas->type), result_id, fp);
+        Alignment_display_gff(alignment, query, target, gam->translate,
+             FALSE, Model_Type_has_genomic_target(gam->gas->type),
+             result_id, user_data, fp);
     if(gam->gas->ryo)
         Alignment_display_ryo(alignment, query, target,
                               gam->gas->ryo, gam->translate, rank,
-                              user_data, fp);
+                              user_data, self_data, fp);
     fflush(fp);
     return;
     }
@@ -1267,7 +1279,7 @@ static void GAM_Result_display(GAM_Result *gam_result){
         alignment = gam_result->alignment_list->pdata[i];
         GAM_display_alignment(gam_result->gam, alignment,
                 gam_result->query, gam_result->target,
-                i+1, 0, gam_result->user_data, stdout);
+                i+1, 0, gam_result->user_data, gam_result->self_data, stdout);
         }
     return;
     }
@@ -1275,6 +1287,7 @@ static void GAM_Result_display(GAM_Result *gam_result){
 void GAM_Result_submit(GAM_Result *gam_result){
     register GAM_QueryResult *gqr;
     g_assert(gam_result);
+    GAM_lock(gam_result->gam);
     if(gam_result->gam->gas->best_n){
         gqr = g_tree_lookup(gam_result->gam->bestn_tree,
                             gam_result->query->id);
@@ -1290,6 +1303,21 @@ void GAM_Result_submit(GAM_Result *gam_result){
     } else {
         GAM_Result_display(gam_result);
         }
+    GAM_unlock(gam_result->gam);
+    return;
+    }
+
+void GAM_lock(GAM *gam){
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&gam->gam_lock);
+#endif /* USE_PTHREADS */
+    return;
+    }
+
+void GAM_unlock(GAM *gam){
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&gam->gam_lock);
+#endif /* USE_PTHREADS */
     return;
     }
 
diff --git a/src/hub/gam.h b/src/hub/gam.h
index 0daf905..9c69e61 100644
--- a/src/hub/gam.h
+++ b/src/hub/gam.h
@@ -3,7 +3,7 @@
 *  GAM: Gapped Alignment Manager                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -22,6 +22,10 @@ extern "C" {
 
 #include <glib.h>
 
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif /* USE_PTHREADS */
+
 #include "sequence.h"
 #include "c4.h"
 #include "heuristic.h"
@@ -36,6 +40,7 @@ extern "C" {
 #include "comparison.h"
 #include "sdp.h"
 #include "subopt.h"
+#include "threadref.h"
 
 typedef enum {
     GAM_Refinement_NONE,
@@ -84,7 +89,7 @@ typedef struct {
 } GAM_QueryInfo;
 
 typedef struct {
-                  gint  ref_count;
+             ThreadRef *thread_ref;
          Alphabet_Type  query_type;
          Alphabet_Type  target_type;
               C4_Model *model;
@@ -106,6 +111,9 @@ typedef struct {
              PQueueSet *pqueue_set;
                   gint  max_query_span;
                   gint  max_target_span;
+#ifdef USE_PTHREADS
+       pthread_mutex_t  gam_lock;
+#endif /* USE_PTHREADS */
 } GAM;
 
 GAM *GAM_create(Alphabet_Type query_type, Alphabet_Type target_type,
@@ -123,6 +131,7 @@ typedef struct {
      Sequence *target;
     GPtrArray *alignment_list;
      gpointer  user_data;
+     gpointer  self_data;
        SubOpt *subopt;
 } GAM_Result;
 
@@ -142,6 +151,9 @@ GAM_Result *GAM_Result_share(GAM_Result *gam_result);
       void  GAM_Result_destroy(GAM_Result *gam_result);
       void  GAM_Result_submit(GAM_Result *gam_result);
 
+void GAM_lock(GAM *gam);
+void GAM_unlock(GAM *gam);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/src/hub/gam.test.c b/src/hub/gam.test.c
index a53d2c6..a26d6bd 100644
--- a/src/hub/gam.test.c
+++ b/src/hub/gam.test.c
@@ -3,7 +3,7 @@
 *  GAM: Gapped Alignment Manager                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/Makefile.am b/src/model/Makefile.am
index ecca16a..f5d7e3d 100644
--- a/src/model/Makefile.am
+++ b/src/model/Makefile.am
@@ -26,6 +26,7 @@ SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
                $(top_srcdir)/src/sequence/translate.o  \
                $(top_srcdir)/src/general/argument.o    \
                $(top_srcdir)/src/general/lineparse.o   \
+               $(top_srcdir)/src/general/threadref.o   \
                -lm
 
 ALIGNMENT_OBJ = $(top_srcdir)/src/comparison/match.o     \
diff --git a/src/model/Makefile.in b/src/model/Makefile.in
index b148b3d..a01b14a 100644
--- a/src/model/Makefile.in
+++ b/src/model/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -86,7 +87,7 @@ noinst_PROGRAMS = $(TESTS) bootstrapper
 INCLUDES = -I$(top_srcdir)/src/c4                               -I$(top_srcdir)/src/bsdp                             -I$(top_srcdir)/src/sdp                              -I$(top_srcdir)/src/sequence                         -I$(top_srcdir)/src/general                          -I$(top_srcdir)/src/comparison                       -I$(top_srcdir)/src/struct                           -DSOURCE_ROOT_DIR="\"@source_root_dir@\""            -DGLIB_CFLAGS="\"@glib_cflags@\""
 
 
-SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  -lm
+SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  $(top_srcdir)/src/general/threadref.o [...]
 
 
 ALIGNMENT_OBJ = $(top_srcdir)/src/comparison/match.o                     $(top_srcdir)/src/sequence/codonsubmat.o                 $(top_srcdir)/src/sequence/submat.o                      $(SEQUENCE_OBJ)
@@ -187,7 +188,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 edit_distance_test_LDFLAGS = 
 affine_test_OBJECTS =  affine.test.o affine.o ungapped.o
 affine_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -206,7 +208,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 affine_test_LDFLAGS = 
 protein2dna_test_OBJECTS =  protein2dna.test.o protein2dna.o affine.o \
 ungapped.o frameshift.o
@@ -226,7 +229,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 protein2dna_test_LDFLAGS = 
 ner_test_OBJECTS =  ner.test.o ner.o affine.o ungapped.o
 ner_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -245,7 +249,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 ner_test_LDFLAGS = 
 est2genome_test_OBJECTS =  est2genome.test.o est2genome.o affine.o \
 ungapped.o intron.o
@@ -265,7 +270,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 est2genome_test_LDFLAGS = 
 ungapped_test_OBJECTS =  ungapped.test.o ungapped.o
 ungapped_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -284,7 +290,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 ungapped_test_LDFLAGS = 
 intron_test_OBJECTS =  intron.test.o intron.o
 intron_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -303,7 +310,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 intron_test_LDFLAGS = 
 protein2genome_test_OBJECTS =  protein2genome.test.o protein2genome.o \
 protein2dna.o ungapped.o intron.o affine.o frameshift.o phase.o
@@ -323,7 +331,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 protein2genome_test_LDFLAGS = 
 coding2coding_test_OBJECTS =  coding2coding.test.o coding2coding.o \
 affine.o ungapped.o frameshift.o
@@ -343,7 +352,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 coding2coding_test_LDFLAGS = 
 frameshift_test_OBJECTS =  frameshift.test.o frameshift.o
 frameshift_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -362,7 +372,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 frameshift_test_LDFLAGS = 
 coding2genome_test_OBJECTS =  coding2genome.test.o coding2genome.o \
 coding2coding.o affine.o ungapped.o frameshift.o intron.o phase.o
@@ -382,7 +393,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 coding2genome_test_LDFLAGS = 
 cdna2genome_test_OBJECTS =  cdna2genome.test.o cdna2genome.o affine.o \
 ungapped.o frameshift.o intron.o phase.o coding2coding.o \
@@ -403,7 +415,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 cdna2genome_test_LDFLAGS = 
 genome2genome_test_OBJECTS =  genome2genome.test.o genome2genome.o \
 coding2coding.o affine.o ungapped.o frameshift.o intron.o phase.o \
@@ -424,7 +437,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 genome2genome_test_LDFLAGS = 
 phase_test_OBJECTS =  phase.test.o phase.o intron.o
 phase_test_DEPENDENCIES =  $(top_srcdir)/src/struct/slist.o \
@@ -443,7 +457,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 phase_test_LDFLAGS = 
 modeltype_test_OBJECTS =  modeltype.test.o modeltype.o ungapped.o \
 affine.o est2genome.o ner.o protein2dna.o protein2genome.o \
@@ -465,7 +480,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 modeltype_test_LDFLAGS = 
 bootstrapper_OBJECTS =  bootstrapper.o modeltype.o ungapped.o affine.o \
 est2genome.o ner.o protein2dna.o protein2genome.o coding2coding.o \
@@ -493,7 +509,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 bootstrapper_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/src/model/affine.c b/src/model/affine.c
index 9722cf6..616291b 100644
--- a/src/model/affine.c
+++ b/src/model/affine.c
@@ -3,7 +3,7 @@
 *  Module for various affine gapped models                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/affine.h b/src/model/affine.h
index 494c268..bb5257a 100644
--- a/src/model/affine.h
+++ b/src/model/affine.h
@@ -3,7 +3,7 @@
 *  Module for various affine gapped models                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/affine.test.c b/src/model/affine.test.c
index baed183..adcd02b 100644
--- a/src/model/affine.test.c
+++ b/src/model/affine.test.c
@@ -3,7 +3,7 @@
 *  Module for various affine gapped models                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/bootstrapper.c b/src/model/bootstrapper.c
index 3dba0f0..97c1f51 100755
--- a/src/model/bootstrapper.c
+++ b/src/model/bootstrapper.c
@@ -3,7 +3,7 @@
 *  bootstrapper: required prior to static model linking          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/cdna2genome.c b/src/model/cdna2genome.c
index 07056b5..117c40c 100644
--- a/src/model/cdna2genome.c
+++ b/src/model/cdna2genome.c
@@ -3,7 +3,7 @@
 *  cDNA <-> genomic alignment model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/cdna2genome.h b/src/model/cdna2genome.h
index 2a2026c..51febe4 100644
--- a/src/model/cdna2genome.h
+++ b/src/model/cdna2genome.h
@@ -3,7 +3,7 @@
 *  cDNA <-> genomic alignment model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/cdna2genome.test.c b/src/model/cdna2genome.test.c
index 38b10d2..8040f72 100644
--- a/src/model/cdna2genome.test.c
+++ b/src/model/cdna2genome.test.c
@@ -3,7 +3,7 @@
 *  cDNA <-> genomic alignment model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -32,7 +32,7 @@ static void test_cdna2genome(Sequence *query, Sequence *target){
                                             query->len, target->len);
     score = Optimal_find_score(optimal, region, cd2gd, NULL);
     g_message("Score is [%d]", score);
-    g_assert(score == 1290);
+    g_assert(score == 1281);
     alignment = Optimal_find_path(optimal, region, cd2gd,
                                   C4_IMPOSSIBLY_LOW_SCORE, NULL);
     g_message("Alignment score is [%d]", alignment->score);
diff --git a/src/model/coding2coding.c b/src/model/coding2coding.c
index 5f291c5..45c3f21 100644
--- a/src/model/coding2coding.c
+++ b/src/model/coding2coding.c
@@ -3,7 +3,7 @@
 *  Coding DNA comparison model                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/coding2coding.h b/src/model/coding2coding.h
index 349bcb3..a5a92c2 100644
--- a/src/model/coding2coding.h
+++ b/src/model/coding2coding.h
@@ -3,7 +3,7 @@
 *  Coding DNA comparison model                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/coding2coding.test.c b/src/model/coding2coding.test.c
index 2526e8e..f4cbe37 100644
--- a/src/model/coding2coding.test.c
+++ b/src/model/coding2coding.test.c
@@ -3,7 +3,7 @@
 *  Coding DNA comparison model                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/coding2genome.c b/src/model/coding2genome.c
index 2b78ce3..873ba3a 100644
--- a/src/model/coding2genome.c
+++ b/src/model/coding2genome.c
@@ -3,7 +3,7 @@
 *  Coding <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/coding2genome.h b/src/model/coding2genome.h
index bf8f56f..96bce7b 100644
--- a/src/model/coding2genome.h
+++ b/src/model/coding2genome.h
@@ -3,7 +3,7 @@
 *  Coding <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/coding2genome.test.c b/src/model/coding2genome.test.c
index bbbc0c8..f41d9da 100644
--- a/src/model/coding2genome.test.c
+++ b/src/model/coding2genome.test.c
@@ -3,7 +3,7 @@
 *  Coding <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/edit_distance.c b/src/model/edit_distance.c
index dda7702..e0a0586 100644
--- a/src/model/edit_distance.c
+++ b/src/model/edit_distance.c
@@ -3,7 +3,7 @@
 *  edit distance model                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/edit_distance.h b/src/model/edit_distance.h
index 8c4a0e5..23c46ea 100644
--- a/src/model/edit_distance.h
+++ b/src/model/edit_distance.h
@@ -3,7 +3,7 @@
 *  edit distance model                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/edit_distance.test.c b/src/model/edit_distance.test.c
index feffdcf..436f34d 100644
--- a/src/model/edit_distance.test.c
+++ b/src/model/edit_distance.test.c
@@ -3,7 +3,7 @@
 *  edit distance model                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/est2genome.c b/src/model/est2genome.c
index d294253..897968c 100644
--- a/src/model/est2genome.c
+++ b/src/model/est2genome.c
@@ -3,7 +3,7 @@
 *  Module for EST <-> genome alignments                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/est2genome.h b/src/model/est2genome.h
index 65c4d26..fc272df 100644
--- a/src/model/est2genome.h
+++ b/src/model/est2genome.h
@@ -3,7 +3,7 @@
 *  Module for EST <-> genome alignments                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/est2genome.test.c b/src/model/est2genome.test.c
index 2c1ee14..1da0fff 100644
--- a/src/model/est2genome.test.c
+++ b/src/model/est2genome.test.c
@@ -3,7 +3,7 @@
 *  Module for EST <-> genome alignments                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -60,7 +60,7 @@ int Argument_main(Argument *arg){
     e2gd = EST2Genome_Data_create(query, target);
     score = Optimal_find_score(optimal, region, e2gd, NULL);
     g_message("Score is [%d]", score);
-    g_assert(score == 159);
+    g_assert(score == 157);
 /**/
     alignment = Optimal_find_path(optimal, region, e2gd,
                                   C4_IMPOSSIBLY_LOW_SCORE, NULL);
diff --git a/src/model/frameshift.c b/src/model/frameshift.c
index e237fa3..e148925 100644
--- a/src/model/frameshift.c
+++ b/src/model/frameshift.c
@@ -3,7 +3,7 @@
 *  Module for frameshift modelling                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/frameshift.h b/src/model/frameshift.h
index 4dc54a0..6e2a07b 100644
--- a/src/model/frameshift.h
+++ b/src/model/frameshift.h
@@ -3,7 +3,7 @@
 *  Module for frameshift modelling                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/frameshift.test.c b/src/model/frameshift.test.c
index 00001d5..9409c79 100644
--- a/src/model/frameshift.test.c
+++ b/src/model/frameshift.test.c
@@ -3,7 +3,7 @@
 *  Module for frameshift modelling                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/genome2genome.c b/src/model/genome2genome.c
index d3ed0ba..03b054e 100644
--- a/src/model/genome2genome.c
+++ b/src/model/genome2genome.c
@@ -3,7 +3,7 @@
 *  Genome <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/genome2genome.h b/src/model/genome2genome.h
index 31d4bd3..2656504 100644
--- a/src/model/genome2genome.h
+++ b/src/model/genome2genome.h
@@ -3,7 +3,7 @@
 *  Genome <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/genome2genome.test.c b/src/model/genome2genome.test.c
index e45c9ee..085b604 100644
--- a/src/model/genome2genome.test.c
+++ b/src/model/genome2genome.test.c
@@ -3,7 +3,7 @@
 *  Genome <-> Genome comparison model                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/intron.c b/src/model/intron.c
index 5b6fdb8..894fb53 100644
--- a/src/model/intron.c
+++ b/src/model/intron.c
@@ -3,7 +3,7 @@
 *  Module of splice site and intron modelling                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/intron.h b/src/model/intron.h
index e6def88..c1aae35 100644
--- a/src/model/intron.h
+++ b/src/model/intron.h
@@ -3,7 +3,7 @@
 *  Module of splice site and intron modelling                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/intron.test.c b/src/model/intron.test.c
index 8be48f1..dee11f5 100644
--- a/src/model/intron.test.c
+++ b/src/model/intron.test.c
@@ -3,7 +3,7 @@
 *  Module for splice site and intron modelling                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/modeltype.c b/src/model/modeltype.c
index 088f61c..8a11a16 100644
--- a/src/model/modeltype.c
+++ b/src/model/modeltype.c
@@ -3,7 +3,7 @@
 *  Interface for different types of alignment model              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/modeltype.h b/src/model/modeltype.h
index e1c762e..a0a863c 100644
--- a/src/model/modeltype.h
+++ b/src/model/modeltype.h
@@ -3,7 +3,7 @@
 *  Interface for different types of alignment model              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/modeltype.test.c b/src/model/modeltype.test.c
index a2b4ead..9186530 100644
--- a/src/model/modeltype.test.c
+++ b/src/model/modeltype.test.c
@@ -3,7 +3,7 @@
 *  Interface for different types of alignment model              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/ner.c b/src/model/ner.c
index 84868fa..ed295d7 100644
--- a/src/model/ner.c
+++ b/src/model/ner.c
@@ -3,7 +3,7 @@
 *  Model for alignments with non-equivalenced regions            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/ner.h b/src/model/ner.h
index 34d7602..a02fce7 100644
--- a/src/model/ner.h
+++ b/src/model/ner.h
@@ -3,7 +3,7 @@
 *  Model for alignments with non-equivalenced regions            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/ner.test.c b/src/model/ner.test.c
index 90b17b2..c0e1d1a 100644
--- a/src/model/ner.test.c
+++ b/src/model/ner.test.c
@@ -3,7 +3,7 @@
 *  Model for alignments with non-equivalenced regions            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/phase.c b/src/model/phase.c
index 0387ab0..98bd7b4 100644
--- a/src/model/phase.c
+++ b/src/model/phase.c
@@ -3,7 +3,7 @@
 *  Model for phased introns.                                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/phase.h b/src/model/phase.h
index cd60a10..142fb48 100644
--- a/src/model/phase.h
+++ b/src/model/phase.h
@@ -3,7 +3,7 @@
 *  Model for phased introns.                                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/phase.test.c b/src/model/phase.test.c
index 711e5c1..fa467eb 100644
--- a/src/model/phase.test.c
+++ b/src/model/phase.test.c
@@ -3,7 +3,7 @@
 *  Model for phased introns.                                     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2dna.c b/src/model/protein2dna.c
index 2fdb6ef..754dd9d 100644
--- a/src/model/protein2dna.c
+++ b/src/model/protein2dna.c
@@ -3,7 +3,7 @@
 *  Protein <-> DNA comparison model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2dna.h b/src/model/protein2dna.h
index ba11989..61af923 100644
--- a/src/model/protein2dna.h
+++ b/src/model/protein2dna.h
@@ -3,7 +3,7 @@
 *  Protein <-> DNA comparison model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2dna.test.c b/src/model/protein2dna.test.c
index 2de3a20..4b15d2b 100644
--- a/src/model/protein2dna.test.c
+++ b/src/model/protein2dna.test.c
@@ -3,7 +3,7 @@
 *  Protein <-> DNA comparison model                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2genome.c b/src/model/protein2genome.c
index 2e95316..1fd7c3b 100644
--- a/src/model/protein2genome.c
+++ b/src/model/protein2genome.c
@@ -3,7 +3,7 @@
 *  Protein <-> Genome comparison model                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2genome.h b/src/model/protein2genome.h
index c89267e..322dc91 100644
--- a/src/model/protein2genome.h
+++ b/src/model/protein2genome.h
@@ -3,7 +3,7 @@
 *  Protein <-> Genome comparison model                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/protein2genome.test.c b/src/model/protein2genome.test.c
index 40954b7..4a24e78 100644
--- a/src/model/protein2genome.test.c
+++ b/src/model/protein2genome.test.c
@@ -3,7 +3,7 @@
 *  Protein <-> Genome comparison model                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -30,8 +30,8 @@ static void test_alignment(C4_Model *model,
     register Region *region = Region_create(0, 0,
                                            query->len, target->len);
     score = Optimal_find_score(optimal, region, p2gd, NULL);
-    g_message("Score is [%d] (expect 131)", score);
-    g_assert(score == 129);
+    g_message("Score is [%d] (expect 125)", score);
+    g_assert(score == 125);
     alignment = Optimal_find_path(optimal, region, p2gd,
                                   C4_IMPOSSIBLY_LOW_SCORE, NULL);
     g_message("Alignment score is [%d]", alignment->score);
diff --git a/src/model/ungapped.c b/src/model/ungapped.c
index e4a316a..406f4f5 100644
--- a/src/model/ungapped.c
+++ b/src/model/ungapped.c
@@ -3,7 +3,7 @@
 *  Module for various ungapped alignment models                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/ungapped.h b/src/model/ungapped.h
index cf996a7..d0bf1c4 100644
--- a/src/model/ungapped.h
+++ b/src/model/ungapped.h
@@ -3,7 +3,7 @@
 *  Module for various ungapped alignment models                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/model/ungapped.test.c b/src/model/ungapped.test.c
index 796fca8..a35b583 100644
--- a/src/model/ungapped.test.c
+++ b/src/model/ungapped.test.c
@@ -3,7 +3,7 @@
 *  Module for various ungapped alignment models                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/program/Makefile.am b/src/program/Makefile.am
index fa351d4..f9b3344 100644
--- a/src/program/Makefile.am
+++ b/src/program/Makefile.am
@@ -12,7 +12,8 @@ INCLUDES = -I$(top_srcdir)/src/sequence   \
            -I$(top_srcdir)/src/hub        \
            -I$(top_srcdir)/src/general    \
            -DHOSTTYPE="\"@host@\""        \
-           -DSOURCE_ROOT_DIR="\"@source_root_dir@\""
+           -DSOURCE_ROOT_DIR="\"@source_root_dir@\"" \
+           -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""
 
 # Missing viterb.o and scheduler.o so codegen versions may be substituted
 C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                \
@@ -58,6 +59,7 @@ C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                \
              $(top_srcdir)/src/general/argument.o     \
              $(top_srcdir)/src/general/lineparse.o    \
              $(top_srcdir)/src/general/socket.o       \
+             $(top_srcdir)/src/general/jobqueue.o     \
              $(top_srcdir)/src/comparison/match.o     \
              $(top_srcdir)/src/sequence/submat.o      \
              $(top_srcdir)/src/sequence/codonsubmat.o
@@ -96,6 +98,7 @@ exonerate_COMPONENTS = @codegen_extra_ldadd@                     \
                        $(top_srcdir)/src/hub/bsam.o              \
                        $(top_srcdir)/src/hub/analysis.o          \
                        $(top_srcdir)/src/general/compoundfile.o  \
+                       $(top_srcdir)/src/general/threadref.o     \
                        $(C4_OBJECTS)
 
 exonerate_SOURCES = exonerate.c
@@ -157,6 +160,7 @@ exonerate_server_LDADD   = $(top_srcdir)/src/general/socket.o       \
                            $(top_srcdir)/src/sequence/codonsubmat.o \
                            $(top_srcdir)/src/general/compoundfile.o \
                            $(top_srcdir)/src/general/lineparse.o    \
+                           $(top_srcdir)/src/general/threadref.o    \
                            -lm
 
 CLEANFILES = $(EXTRA_exonerate_SOURCES) @codegen_extra_sources@ \
diff --git a/src/program/Makefile.in b/src/program/Makefile.in
index 30c1dcb..7eb171e 100644
--- a/src/program/Makefile.in
+++ b/src/program/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -80,11 +81,11 @@ use_pthreads = @use_pthreads@
 
 bin_PROGRAMS = exonerate ipcress exonerate-server
 
-INCLUDES = -I$(top_srcdir)/src/sequence              -I$(top_srcdir)/src/database              -I$(top_srcdir)/src/comparison            -I$(top_srcdir)/src/struct                -I$(top_srcdir)/src/c4                    -I$(top_srcdir)/src/bsdp                  -I$(top_srcdir)/src/sdp                   -I$(top_srcdir)/src/model                 -I$(top_srcdir)/src/hub                   -I$(top_srcdir)/src/general               -DHOSTTYPE="\"@host@\""                   -DSOURCE_ROOT_DIR=" [...]
+INCLUDES = -I$(top_srcdir)/src/sequence              -I$(top_srcdir)/src/database              -I$(top_srcdir)/src/comparison            -I$(top_srcdir)/src/struct                -I$(top_srcdir)/src/c4                    -I$(top_srcdir)/src/bsdp                  -I$(top_srcdir)/src/sdp                   -I$(top_srcdir)/src/model                 -I$(top_srcdir)/src/hub                   -I$(top_srcdir)/src/general               -DHOSTTYPE="\"@host@\""                   -DSOURCE_ROOT_DIR=" [...]
 
 
 # Missing viterb.o and scheduler.o so codegen versions may be substituted
-C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                             $(top_srcdir)/src/c4/codegen.o                        $(top_srcdir)/src/c4/cgutil.o                         $(top_srcdir)/src/c4/opair.o                          $(top_srcdir)/src/c4/alignment.o                      $(top_srcdir)/src/c4/optimal.o                        $(top_srcdir)/src/c4/layout.o                         $(top_srcdir)/src/c4/region.o                         $(top_srcdir)/src/c4/subopt.o                   [...]
+C4_OBJECTS = $(top_srcdir)/src/c4/c4.o                             $(top_srcdir)/src/c4/codegen.o                        $(top_srcdir)/src/c4/cgutil.o                         $(top_srcdir)/src/c4/opair.o                          $(top_srcdir)/src/c4/alignment.o                      $(top_srcdir)/src/c4/optimal.o                        $(top_srcdir)/src/c4/layout.o                         $(top_srcdir)/src/c4/region.o                         $(top_srcdir)/src/c4/subopt.o                   [...]
 
 
 EXTRA_exonerate_SOURCES = c4_model_archive.a c4_model_archive.h
@@ -92,7 +93,7 @@ EXTRA_exonerate_SOURCES = c4_model_archive.a c4_model_archive.h
 BUILT_SOURCES = c4_model_archive.a
 BOOTSTRAPPER = $(top_srcdir)/src/model/bootstrapper
 
-exonerate_COMPONENTS = @codegen_extra_ldadd@                                            $(top_srcdir)/src/comparison/wordhood.o                          $(top_srcdir)/src/comparison/hspset.o                            $(top_srcdir)/src/comparison/seeder.o                            $(top_srcdir)/src/comparison/comparison.o                        $(top_srcdir)/src/database/fastapipe.o                           $(top_srcdir)/src/database/fastadb.o                             $(top_srcdir)/ [...]
+exonerate_COMPONENTS = @codegen_extra_ldadd@                                            $(top_srcdir)/src/comparison/wordhood.o                          $(top_srcdir)/src/comparison/hspset.o                            $(top_srcdir)/src/comparison/seeder.o                            $(top_srcdir)/src/comparison/comparison.o                        $(top_srcdir)/src/database/fastapipe.o                           $(top_srcdir)/src/database/fastadb.o                             $(top_srcdir)/ [...]
 
 
 exonerate_SOURCES = exonerate.c
@@ -106,7 +107,7 @@ ipcress_LDADD = $(top_srcdir)/src/comparison/pcr.o                       $(top_s
 # Files to clear away
 
 exonerate_server_SOURCES = exonerate-server.c
-exonerate_server_LDADD = $(top_srcdir)/src/general/socket.o                                  $(top_srcdir)/src/general/argument.o                                $(top_srcdir)/src/comparison/hspset.o                               $(top_srcdir)/src/comparison/match.o                                $(top_srcdir)/src/comparison/wordhood.o                             $(top_srcdir)/src/database/dataset.o                                $(top_srcdir)/src/database/index.o                          [...]
+exonerate_server_LDADD = $(top_srcdir)/src/general/socket.o                                  $(top_srcdir)/src/general/argument.o                                $(top_srcdir)/src/comparison/hspset.o                               $(top_srcdir)/src/comparison/match.o                                $(top_srcdir)/src/comparison/wordhood.o                             $(top_srcdir)/src/database/dataset.o                                $(top_srcdir)/src/database/index.o                          [...]
 
 
 CLEANFILES = $(EXTRA_exonerate_SOURCES) @codegen_extra_sources@              @codegen_extra_ld_add@
@@ -160,7 +161,8 @@ $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/sequence/splice.o $(top_srcdir)/src/sequence/submat.o \
 $(top_srcdir)/src/sequence/codonsubmat.o \
 $(top_srcdir)/src/general/compoundfile.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 exonerate_server_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/src/program/exonerate-server.c b/src/program/exonerate-server.c
index 99ac905..29c40c1 100644
--- a/src/program/exonerate-server.c
+++ b/src/program/exonerate-server.c
@@ -3,7 +3,7 @@
 *  The exonerate server                                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -66,6 +66,10 @@ static Exonerate_Server *Exonerate_Server_create(gchar *input_path,
     if(preload)
         Dataset_preload_seqs(exonerate_server->dataset);
     exonerate_server->verbosity = verbosity;
+    if(verbosity >= 1){
+        Dataset_info(exonerate_server->dataset);
+        Index_info(exonerate_server->index);
+        }
     return exonerate_server;
     }
 
@@ -93,6 +97,9 @@ typedef struct {
                gint  dna_hsp_threshold;
                gint  protein_hsp_threshold;
                gint  codon_hsp_threshold;
+               gint  dna_word_limit;
+               gint  protein_word_limit;
+               gint  codon_word_limit;
                gint  dna_hsp_dropoff;
                gint  protein_hsp_dropoff;
                gint  codon_hsp_dropoff;
@@ -118,6 +125,9 @@ static Exonerate_Server_Connection *Exonerate_Server_Connection_create(void){
     connection->dna_hsp_threshold = has->dna_hsp_threshold;
     connection->protein_hsp_threshold = has->protein_hsp_threshold;
     connection->codon_hsp_threshold = has->codon_hsp_threshold;
+    connection->dna_word_limit = has->dna_word_limit;
+    connection->protein_word_limit = has->protein_word_limit;
+    connection->codon_word_limit = has->codon_word_limit;
     connection->dna_hsp_dropoff = has->dna_hsp_dropoff;
     connection->protein_hsp_dropoff = has->protein_hsp_dropoff;
     connection->codon_hsp_dropoff = has->codon_hsp_dropoff;
@@ -143,7 +153,6 @@ static void Exonerate_Server_Connection_destroy(
 /**/
 
 static gpointer Exonerate_Server_Connection_open(gpointer user_data){
-    g_message("[%s]", __FUNCTION__);
     return Exonerate_Server_Connection_create();
     }
 
@@ -151,7 +160,6 @@ static void Exonerate_Server_Connection_close(gpointer connection_data,
                                               gpointer user_data){
     register Exonerate_Server_Connection *server_connection
         = connection_data;
-    g_message("[%s]", __FUNCTION__);
     Exonerate_Server_Connection_destroy(server_connection);
     return;
     }
@@ -221,10 +229,15 @@ static gchar *Exonerate_Server_help(void){
         "\n"
         "    valid parameters:\n"
         "        seedrepeat\n"
+        "\n"
         "        dnahspthreshold\n"
         "        proteinhspthreshold\n"
         "        codonhspthreshold\n"
         "\n"
+        "        dnawordlimit\n"
+        "        proteinwordlimit\n"
+        "        codonwordlimit\n"
+        "\n"
         "        geneseedthreshold\n"
         "        geneseedrepeat\n"
         "        maxqueryspan\n"
@@ -392,6 +405,13 @@ static Sequence *Exonerate_Server_get_query(Index *index,
         HSP_Param_set_codon_hsp_threshold(connection->hsp_param,
                                           connection->codon_hsp_threshold);
         /**/
+        HSP_Param_set_dna_word_limit(connection->hsp_param,
+                                     connection->dna_word_limit);
+        HSP_Param_set_protein_word_limit(connection->hsp_param,
+                                         connection->protein_word_limit);
+        HSP_Param_set_codon_word_limit(connection->hsp_param,
+                                       connection->codon_word_limit);
+        /**/
         HSP_Param_set_dna_hsp_dropoff(connection->hsp_param,
                                       connection->dna_hsp_dropoff);
         HSP_Param_set_protein_hsp_dropoff(connection->hsp_param,
@@ -458,6 +478,43 @@ static gchar *Exonerate_Server_set_param_codonhspthreshold(
 
 /**/
 
+static gchar *Exonerate_Server_set_param_dnawordlimit(
+              Exonerate_Server_Connection *connection, GPtrArray *word_list){
+    register gint dnawordlimit = atoi(word_list->pdata[3]);
+    if(dnawordlimit < 0)
+        return g_strdup_printf("error: dnawordlimit must be >= 0\n");
+    connection->dna_word_limit = dnawordlimit;
+    if(connection->hsp_param)
+        HSP_Param_set_dna_word_limit(connection->hsp_param, dnawordlimit);
+    return g_strdup_printf("ok: set\n");
+    }
+
+static gchar *Exonerate_Server_set_param_proteinwordlimit(
+              Exonerate_Server_Connection *connection, GPtrArray *word_list){
+    register gint proteinwordlimit = atoi(word_list->pdata[3]);
+    if(proteinwordlimit < 0)
+        return g_strdup_printf("error: proteinwordlimit must be >= 0\n");
+    connection->protein_word_limit = proteinwordlimit;
+    if(connection->hsp_param)
+        HSP_Param_set_protein_word_limit(connection->hsp_param,
+                                         proteinwordlimit);
+    return g_strdup_printf("ok: set\n");
+    }
+
+static gchar *Exonerate_Server_set_param_codonwordlimit(
+              Exonerate_Server_Connection *connection, GPtrArray *word_list){
+    register gint codonwordlimit = atoi(word_list->pdata[3]);
+    if(codonwordlimit < 0)
+        return g_strdup_printf("error: codonwordlimit must be >= 0\n");
+    connection->codon_word_limit = codonwordlimit;
+    if(connection->hsp_param)
+        HSP_Param_set_codon_word_limit(connection->hsp_param,
+                                       codonwordlimit);
+    return g_strdup_printf("ok: set\n");
+    }
+
+/**/
+
 static gchar *Exonerate_Server_set_param_dnahspdropoff(
               Exonerate_Server_Connection *connection, GPtrArray *word_list){
     register gint dnahspdropoff = atoi(word_list->pdata[3]);
@@ -545,6 +602,15 @@ static gchar *Exonerate_Server_set_param(Exonerate_Server_Connection *connection
     } else if(!strcmp(name, "codonhspthreshold")){
         reply = Exonerate_Server_set_param_codonhspthreshold(connection,
                                                              word_list);
+    } else if(!strcmp(name, "dnawordlimit")){
+        reply = Exonerate_Server_set_param_dnawordlimit(connection,
+                                                          word_list);
+    } else if(!strcmp(name, "proteinwordlimit")){
+        reply = Exonerate_Server_set_param_proteinwordlimit(connection,
+                                                              word_list);
+    } else if(!strcmp(name, "codonwordlimit")){
+        reply = Exonerate_Server_set_param_codonwordlimit(connection,
+                                                            word_list);
     } else if(!strcmp(name, "dnahspdropoff")){
         reply = Exonerate_Server_set_param_dnahspdropoff(connection, word_list);
     } else if(!strcmp(name, "proteinhspdropoff")){
@@ -600,7 +666,10 @@ static gboolean Exonerate_Server_process(gchar *msg, gchar **reply,
             (*reply) = NULL;
             keep_connection = FALSE;
         } else if(!strcmp(word, "dbinfo")){
-            (*reply) = g_strdup_printf("dbinfo: %s %s %lld %lld %lld\n",
+            (*reply) = g_strdup_printf("dbinfo: %s %s"
+                   " %" CUSTOM_GUINT64_FORMAT
+                   " %" CUSTOM_GUINT64_FORMAT
+                   " %" CUSTOM_GUINT64_FORMAT "\n",
                   (server->dataset->header->type & 1)?"dna":"protein",
                   (server->dataset->header->type & (1<<1))
                       ?"softmasked":"unmasked",
diff --git a/src/program/exonerate.c b/src/program/exonerate.c
index aa03f2b..fac862a 100644
--- a/src/program/exonerate.c
+++ b/src/program/exonerate.c
@@ -3,7 +3,7 @@
 *  exonerate : a generic sequence comparison tool                *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -77,6 +77,7 @@ int Argument_main(Argument *arg){
     Argument_parse_int, &verbosity);
     /**/
     Argument_absorb_ArgumentSet(arg, as_input);
+    Translate_ArgumentSet_create(arg);
     Analysis_ArgumentSet_create(arg);
     FastaDB_ArgumentSet_create(arg);
     GAM_ArgumentSet_create(arg);
@@ -94,7 +95,6 @@ int Argument_main(Argument *arg){
     Intron_ArgumentSet_create(arg);
     Frameshift_ArgumentSet_create(arg);
     Alphabet_ArgumentSet_create(arg);
-    Translate_ArgumentSet_create(arg);
     HSPset_ArgumentSet_create(arg);
     Alignment_ArgumentSet_create(arg);
     SAR_ArgumentSet_create(arg);
@@ -102,7 +102,7 @@ int Argument_main(Argument *arg){
     /**/
     Argument_process(arg, "exonerate",
       "A generic sequence comparison tool\n"
-      "Guy St.C. Slater. guy at ebi.ac.uk. 2000-2008.\n",
+      "Guy St.C. Slater. guy at ebi.ac.uk. 2000-2009.\n",
       "\n"
       "Examples of use:\n"
       "\n"
@@ -136,3 +136,5 @@ int Argument_main(Argument *arg){
     return 0;
     }
 
+/**/
+
diff --git a/src/program/ipcress.c b/src/program/ipcress.c
index df06eee..ee65c6b 100644
--- a/src/program/ipcress.c
+++ b/src/program/ipcress.c
@@ -3,7 +3,7 @@
 *  ipcress : in-silico PCR experiment simulation system          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/Makefile.am b/src/sdp/Makefile.am
index ef63756..eb0a64d 100644
--- a/src/sdp/Makefile.am
+++ b/src/sdp/Makefile.am
@@ -23,6 +23,7 @@ SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o  \
                $(top_srcdir)/src/sequence/translate.o  \
                $(top_srcdir)/src/general/argument.o    \
                $(top_srcdir)/src/general/lineparse.o   \
+               $(top_srcdir)/src/general/threadref.o   \
                -lm
 
 C4_OBJ = $(top_srcdir)/src/c4/c4.o        \
diff --git a/src/sdp/Makefile.in b/src/sdp/Makefile.in
index 2308465..da25bd7 100644
--- a/src/sdp/Makefile.in
+++ b/src/sdp/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -88,7 +89,7 @@ INCLUDES = -I$(top_srcdir)/src/struct                           -I$(top_srcdir)/
 
 noinst_HEADERS = scheduler.h sdp.h lookahead.h boundary.h straceback.h
 
-SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  -lm
+SEQUENCE_OBJ = $(top_srcdir)/src/struct/sparsecache.o                 $(top_srcdir)/src/struct/matrix.o                      $(top_srcdir)/src/sequence/sequence.o                  $(top_srcdir)/src/sequence/alphabet.o                  $(top_srcdir)/src/sequence/splice.o                    $(top_srcdir)/src/sequence/translate.o                 $(top_srcdir)/src/general/argument.o                   $(top_srcdir)/src/general/lineparse.o                  $(top_srcdir)/src/general/threadref.o [...]
 
 
 C4_OBJ = $(top_srcdir)/src/c4/c4.o                 $(top_srcdir)/src/c4/alignment.o          $(top_srcdir)/src/c4/optimal.o            $(top_srcdir)/src/c4/codegen.o            $(top_srcdir)/src/c4/region.o             $(top_srcdir)/src/c4/layout.o             $(top_srcdir)/src/c4/viterbi.o            $(top_srcdir)/src/c4/subopt.o             $(top_srcdir)/src/c4/cgutil.o
@@ -150,7 +151,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 sdp_test_LDFLAGS = 
 lookahead_test_OBJECTS =  lookahead.test.o lookahead.o
 lookahead_test_LDADD = $(LDADD)
@@ -177,7 +179,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 scheduler_test_LDFLAGS = 
 straceback_test_OBJECTS =  straceback.test.o straceback.o
 straceback_test_DEPENDENCIES =  $(top_srcdir)/src/struct/recyclebin.o \
@@ -192,7 +195,8 @@ $(top_srcdir)/src/sequence/alphabet.o \
 $(top_srcdir)/src/sequence/splice.o \
 $(top_srcdir)/src/sequence/translate.o \
 $(top_srcdir)/src/general/argument.o \
-$(top_srcdir)/src/general/lineparse.o
+$(top_srcdir)/src/general/lineparse.o \
+$(top_srcdir)/src/general/threadref.o
 straceback_test_LDFLAGS = 
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
diff --git a/src/sdp/boundary.c b/src/sdp/boundary.c
index 9539598..676506c 100644
--- a/src/sdp/boundary.c
+++ b/src/sdp/boundary.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Boundary Object              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/boundary.h b/src/sdp/boundary.h
index 1624830..076c782 100644
--- a/src/sdp/boundary.h
+++ b/src/sdp/boundary.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Boundary Object              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/boundary.test.c b/src/sdp/boundary.test.c
index 72564de..0527dd0 100644
--- a/src/sdp/boundary.test.c
+++ b/src/sdp/boundary.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Boundary Object              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/lookahead.c b/src/sdp/lookahead.c
index 008ce56..ea9365d 100644
--- a/src/sdp/lookahead.c
+++ b/src/sdp/lookahead.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - SDP Lookahead Object         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/lookahead.h b/src/sdp/lookahead.h
index 5a2419a..f542e1e 100644
--- a/src/sdp/lookahead.h
+++ b/src/sdp/lookahead.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - SDP Lookahead Object         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/lookahead.test.c b/src/sdp/lookahead.test.c
index 4c6165b..ea32e67 100644
--- a/src/sdp/lookahead.test.c
+++ b/src/sdp/lookahead.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - SDP Lookahead Object         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/scheduler.c b/src/sdp/scheduler.c
index 6e3874d..d2db25d 100644
--- a/src/sdp/scheduler.c
+++ b/src/sdp/scheduler.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP Scheduler                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/scheduler.h b/src/sdp/scheduler.h
index b1f20dc..f72bf8f 100644
--- a/src/sdp/scheduler.h
+++ b/src/sdp/scheduler.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP Scheduler                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/scheduler.test.c b/src/sdp/scheduler.test.c
index 72370d5..ef0f997 100644
--- a/src/sdp/scheduler.test.c
+++ b/src/sdp/scheduler.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - DP Scheduler                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/sdp.c b/src/sdp/sdp.c
index cd126af..beb0a49 100644
--- a/src/sdp/sdp.c
+++ b/src/sdp/sdp.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Seeded Dynamic Programming   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -300,7 +300,7 @@ SDP *SDP_create(C4_Model *model){
     register SDP *sdp = g_new0(SDP, 1);
     register C4_Portal *portal;
     /**/
-    sdp->ref_count = 1;
+    sdp->thread_ref = ThreadRef_create();
     sdp->sas = SDP_ArgumentSet_create(NULL);
     g_assert(model);
     g_assert(!model->is_open);
@@ -356,13 +356,13 @@ SDP *SDP_create(C4_Model *model){
 
 SDP *SDP_share(SDP *sdp){
     g_assert(sdp);
-    sdp->ref_count++;
+    ThreadRef_share(sdp->thread_ref);
     return sdp;
     }
 
 void SDP_destroy(SDP *sdp){
     g_assert(sdp);
-    if(--sdp->ref_count)
+    if(ThreadRef_destroy(sdp->thread_ref))
         return;
     if(sdp->find_starts_scheduler)
         Scheduler_destroy(sdp->find_starts_scheduler);
diff --git a/src/sdp/sdp.h b/src/sdp/sdp.h
index 26980c2..87457ca 100644
--- a/src/sdp/sdp.h
+++ b/src/sdp/sdp.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Seeded Dynamic Programming   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -33,6 +33,7 @@ extern "C" {
 #include "sparsecache.h"
 #include "boundary.h"
 #include "scheduler.h"
+#include "threadref.h"
 
 /**/
 
@@ -66,7 +67,7 @@ typedef struct SDP_Seed {
 /**/
 
 typedef struct {
-               gint  ref_count;
+          ThreadRef *thread_ref;
     SDP_ArgumentSet *sas;
            C4_Model *model;
            gboolean  use_boundary;
diff --git a/src/sdp/sdp.test.c b/src/sdp/sdp.test.c
index 1f113eb..0302bf1 100644
--- a/src/sdp/sdp.test.c
+++ b/src/sdp/sdp.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Seeded Dynamic Programming   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/straceback.c b/src/sdp/straceback.c
index 95475c8..fadc8b1 100644
--- a/src/sdp/straceback.c
+++ b/src/sdp/straceback.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Scheduler Traceback          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/straceback.h b/src/sdp/straceback.h
index a177d88..de643bb 100644
--- a/src/sdp/straceback.h
+++ b/src/sdp/straceback.h
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Scheduler Traceback          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sdp/straceback.test.c b/src/sdp/straceback.test.c
index 4438d77..be912da 100644
--- a/src/sdp/straceback.test.c
+++ b/src/sdp/straceback.test.c
@@ -3,7 +3,7 @@
 *  C4 dynamic programming library - Scheduler Traceback          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/Makefile.in b/src/sequence/Makefile.in
index a7e1049..57e9a89 100644
--- a/src/sequence/Makefile.in
+++ b/src/sequence/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/src/sequence/alphabet.c b/src/sequence/alphabet.c
index af9d78e..1bf81fd 100644
--- a/src/sequence/alphabet.c
+++ b/src/sequence/alphabet.c
@@ -3,7 +3,7 @@
 *  Simple Alphabet Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -151,6 +151,7 @@ Alphabet *Alphabet_create(Alphabet_Type type, gboolean is_soft_masked){
     register Alphabet *a = g_new0(Alphabet, 1);
     a->ref_count = 1;
     a->type = type;
+    a->is_soft_masked = is_soft_masked;
     /* Set look-up tables */
     a->unmasked = Alphabet_Filter_get(Alphabet_Filter_TO_UPPER);
     if(is_soft_masked){
@@ -372,3 +373,44 @@ gchar *Alphabet_aa2tla(gchar aa){
     return short_names[index[(guchar)aa]];
     }
 
+gchar *Alphabet_nt2ambig(gchar nt){
+    static gchar *ambig[16] = {
+        /* - */ NULL,
+        /* G */ "G",
+        /* A */ "A",
+        /* R */ "AG",
+        /* T */ "T",
+        /* K */ "GT",
+        /* W */ "AT",
+        /* D */ "AGT",
+        /* C */ "C",
+        /* S */ "CG",
+        /* M */ "AC",
+        /* V */ "ACG",
+        /* Y */ "CT",
+        /* B */ "CGT",
+        /* H */ "ACT",
+        /* N */ "ACGT"
+         };
+    static guchar index[(1<<8)] = { /* GARTKWDCSMVYBHN */
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  2, 13,  8,  7,  0,  0,  1, 14,  0,  0,  5,  0, 10, 15,  0,
+         0,  0,  3,  9,  4,  0, 11,  6,  0, 12,  0,  0,  0,  0,  0,  0,
+         0,  2, 13,  8,  7,  0,  0,  1, 14,  0,  0,  5,  0, 10, 15,  0,
+         0,  0,  3,  9,  4,  0, 11,  6,  0, 12,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+        };
+    g_assert(index[(guchar)nt]);
+    return ambig[index[(guchar)nt]];
+    }
+
diff --git a/src/sequence/alphabet.h b/src/sequence/alphabet.h
index 1cea022..c4d5b1e 100644
--- a/src/sequence/alphabet.h
+++ b/src/sequence/alphabet.h
@@ -3,7 +3,7 @@
 *  Simple Alphabet Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -49,6 +49,7 @@ gchar *Alphabet_Argument_parse_alphabet_type(gchar *arg_string, gpointer data);
 
 typedef struct {
              gint  ref_count;
+         gboolean  is_soft_masked;
            guchar *member;
     Alphabet_Type  type;
            guchar *is_member;
@@ -113,6 +114,12 @@ gchar *Alphabet_aa2tla(gchar aa);
 /* Give three-letter-abbreviation for amino acid.
  * eg 'M' -> "Met" etc */
 
+gchar *Alphabet_nt2ambig(gchar nt);
+/* Returns the ambiguity bases for the given nucleotide
+ * The returned string does not need to be freed.
+ */
+
+
 /**/
 
 #ifdef __cplusplus
diff --git a/src/sequence/alphabet.test.c b/src/sequence/alphabet.test.c
index eef56b6..8f63b90 100644
--- a/src/sequence/alphabet.test.c
+++ b/src/sequence/alphabet.test.c
@@ -3,7 +3,7 @@
 *  Simple Alphabet Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/codonsubmat.c b/src/sequence/codonsubmat.c
index 779e927..709509e 100644
--- a/src/sequence/codonsubmat.c
+++ b/src/sequence/codonsubmat.c
@@ -3,7 +3,7 @@
 *  Codon Substutition Matrix Object                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/codonsubmat.h b/src/sequence/codonsubmat.h
index 41b908e..bab6357 100644
--- a/src/sequence/codonsubmat.h
+++ b/src/sequence/codonsubmat.h
@@ -3,7 +3,7 @@
 *  Codon Substitution Matrix Object                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/codonsubmat.test.c b/src/sequence/codonsubmat.test.c
index f144984..c6129ac 100644
--- a/src/sequence/codonsubmat.test.c
+++ b/src/sequence/codonsubmat.test.c
@@ -3,7 +3,7 @@
 *  Codon Substitution Matrix Object                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/sequence.c b/src/sequence/sequence.c
index 21af91c..9a47588 100644
--- a/src/sequence/sequence.c
+++ b/src/sequence/sequence.c
@@ -3,7 +3,7 @@
 *  Simple Sequence Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -181,6 +181,9 @@ static Sequence *Sequence_create_internal(gchar *id, gchar *def, guint len,
                   ? g_tree_lookup(sas->annotation_tree, s->id)
                   : NULL;
     s->len = len;
+#ifdef USE_PTHREADS
+    pthread_mutex_init(&s->seq_lock, NULL);
+#endif /* USE_PTHREADS */
     return s;
     }
 
@@ -236,8 +239,10 @@ void Sequence_preload_extmem(Sequence *s){
 
 Sequence *Sequence_share(Sequence *s){
     g_assert(s);
+    Sequence_lock(s);
     g_assert(s->ref_count);
     s->ref_count++;
+    Sequence_unlock(s);
     return s;
     }
 
@@ -540,6 +545,7 @@ Sequence *Sequence_translate(Sequence *s, Translate *translate, gint frame){
 
 /**/
 
+#if 0
 static void Sequence_print_type(Sequence *s){
     register Sequence_Subseq *subseq;
     register Sequence *revcomp;
@@ -580,6 +586,8 @@ static void Sequence_print_type(Sequence *s){
         }
     return;
     }
+#endif /* 0 */
+
 
 void Sequence_strncpy(Sequence *s, gint start, gint length, gchar *dst){
     register gint i;
@@ -647,8 +655,18 @@ gchar *Sequence_get_str(Sequence *s){
 
 void Sequence_destroy(Sequence *s){
     g_assert(s);
-    if(--s->ref_count)
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&s->seq_lock);
+#endif /* USE_PTHREADS */
+    if(--s->ref_count){
+#ifdef USE_PTHREADS
+        pthread_mutex_unlock(&s->seq_lock);
+#endif /* USE_PTHREADS */
         return;
+        }
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&s->seq_lock);
+#endif /* USE_PTHREADS */
     if(s->id)
         g_free(s->id);
     if(s->def)
@@ -679,6 +697,9 @@ void Sequence_destroy(Sequence *s){
             }
         }
     Alphabet_destroy(s->alphabet);
+#ifdef USE_PTHREADS
+    pthread_mutex_destroy(&s->seq_lock);
+#endif /* USE_PTHREADS */
     g_free(s);
     return;
     }
@@ -785,3 +806,83 @@ gsize Sequence_memory_usage(Sequence *s){
     }
 
 
+void Sequence_lock(Sequence *s){
+    register Sequence_Subseq *subseq;
+    register Sequence_Filter *filter;
+    register Sequence_Translation *translation;
+    register Sequence *revcomp;
+    g_assert(s);
+#ifdef USE_PTHREADS
+    pthread_mutex_lock(&s->seq_lock);
+    if(s->data){
+        switch(s->type){
+            case Sequence_Type_INTMEM:
+                break;
+            case Sequence_Type_EXTMEM:
+                break;
+            case Sequence_Type_SUBSEQ:
+                subseq = s->data;
+                Sequence_lock(subseq->sequence);
+                break;
+            case Sequence_Type_REVCOMP:
+                revcomp = s->data;
+                Sequence_lock(revcomp);
+                break;
+            case Sequence_Type_FILTER:
+                filter = s->data;
+                Sequence_lock(filter->sequence);
+                break;
+            case Sequence_Type_TRANSLATE:
+                translation = s->data;
+                Sequence_lock(translation->sequence);
+                break;
+            default:
+                g_error("Unknown Sequence type [%d]", s->type);
+                break;
+            }
+        }
+#endif /* USE_PTHREADS */
+    return;
+    }
+
+void Sequence_unlock(Sequence *s){
+    register Sequence_Subseq *subseq;
+    register Sequence_Filter *filter;
+    register Sequence_Translation *translation;
+    register Sequence *revcomp;
+    g_assert(s);
+#ifdef USE_PTHREADS
+    pthread_mutex_unlock(&s->seq_lock);
+    if(s->data){
+        switch(s->type){
+            case Sequence_Type_INTMEM:
+                break;
+            case Sequence_Type_EXTMEM:
+                break;
+            case Sequence_Type_SUBSEQ:
+                subseq = s->data;
+                Sequence_unlock(subseq->sequence);
+                break;
+            case Sequence_Type_REVCOMP:
+                revcomp = s->data;
+                Sequence_unlock(revcomp);
+                break;
+            case Sequence_Type_FILTER:
+                filter = s->data;
+                Sequence_unlock(filter->sequence);
+                break;
+            case Sequence_Type_TRANSLATE:
+                translation = s->data;
+                Sequence_unlock(translation->sequence);
+                break;
+            default:
+                g_error("Unknown Sequence type [%d]", s->type);
+                break;
+            }
+        }
+#endif /* USE_PTHREADS */
+    return;
+    }
+
+
+
diff --git a/src/sequence/sequence.h b/src/sequence/sequence.h
index f182f1c..d7788a6 100644
--- a/src/sequence/sequence.h
+++ b/src/sequence/sequence.h
@@ -3,7 +3,7 @@
 *  Simple Sequence Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -23,6 +23,10 @@ extern "C" {
 #include <stdio.h>
 #include <glib.h>
 
+#ifdef USE_PTHREADS
+#include <pthread.h>
+#endif /* USE_PTHREADS */
+
 #include "alphabet.h"
 #include "translate.h"
 #include "sparsecache.h"
@@ -83,6 +87,9 @@ typedef struct {
                gpointer   data;
           Sequence_Type   type;
                    gint (*get_symbol)(gpointer data, gint pos);
+#ifdef USE_PTHREADS
+        pthread_mutex_t   seq_lock;
+#endif /* USE_PTHREADS */
 } Sequence;
 
 #define Sequence_get_symbol(sequence, pos) \
@@ -134,6 +141,8 @@ Sequence *Sequence_filter(Sequence *s,
 Sequence *Sequence_translate(Sequence *s, Translate *translate, gint frame);
 
 Sequence *Sequence_mask(Sequence *s);
+void Sequence_lock(Sequence *s);
+void Sequence_unlock(Sequence *s);
 
 /**/
 
diff --git a/src/sequence/sequence.test.c b/src/sequence/sequence.test.c
index ab8e6af..9801b38 100644
--- a/src/sequence/sequence.test.c
+++ b/src/sequence/sequence.test.c
@@ -3,7 +3,7 @@
 *  Simple Sequence Object                                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/splice.c b/src/sequence/splice.c
index 00874ec..761cf0c 100644
--- a/src/sequence/splice.c
+++ b/src/sequence/splice.c
@@ -3,7 +3,7 @@
 *  Library for Splice site prediction.                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -282,7 +282,7 @@ SplicePredictor *SplicePredictor_create(SpliceType type){
          for(j = 0; j < 4; j++){
              sp->model_data[i][j] = (((gfloat)(1+sp->model_data[i][j]))
                                   /((25.0+1.0)));
-             sp->model_data[i][j] = log(sp->model_data[i][j]) * 2.0;
+             sp->model_data[i][j] = log(sp->model_data[i][j]) * 1.5;
              }
          sp->model_data[i][4] = 0.0;
          }
diff --git a/src/sequence/splice.h b/src/sequence/splice.h
index 1123a3c..fd98449 100644
--- a/src/sequence/splice.h
+++ b/src/sequence/splice.h
@@ -3,7 +3,7 @@
 *  Library for Splice site prediction.                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/splice.test.c b/src/sequence/splice.test.c
index 6ad7b96..7e536fd 100644
--- a/src/sequence/splice.test.c
+++ b/src/sequence/splice.test.c
@@ -3,7 +3,7 @@
 *  Library for Splice site prediction.                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/submat.c b/src/sequence/submat.c
index 42ac020..2977a48 100644
--- a/src/sequence/submat.c
+++ b/src/sequence/submat.c
@@ -3,7 +3,7 @@
 *  Substutition Matrix Object                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -266,7 +266,7 @@ static void Submat_read_matrix(SubmatMatrix matrix, gchar *path){
                     }
                 break;
             case '0': case '1': case '2': case '3': case '4':
-            case '5': case '6': case '7': case '8': case '9': 
+            case '5': case '6': case '7': case '8': case '9':
                 num *= 10;
                 num += (ch-'0');
                 seen = TRUE;
diff --git a/src/sequence/submat.h b/src/sequence/submat.h
index 679cdcf..d5c38ee 100644
--- a/src/sequence/submat.h
+++ b/src/sequence/submat.h
@@ -3,7 +3,7 @@
 *  Substitution Matrix Object                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/submat.test.c b/src/sequence/submat.test.c
index c5a5737..c5b2e69 100644
--- a/src/sequence/submat.test.c
+++ b/src/sequence/submat.test.c
@@ -3,7 +3,7 @@
 *  Substitution Matrix Object                                    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/translate.c b/src/sequence/translate.c
index b052ed1..d02187c 100644
--- a/src/sequence/translate.c
+++ b/src/sequence/translate.c
@@ -3,7 +3,7 @@
 *  Nucleotide Translation Code                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -20,6 +20,7 @@
 #include "translate.h"
 
 /* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+     CTAG
  0 - 0000 - blank          Representation of Nucleotides
  1 G 0001 C                -----------------------------
  2 A 0010 T
@@ -72,7 +73,7 @@ static void Translate_initialise_peptide_data(Translate *t){
      "pon", "jihP", "fCcd", "rHmpi", "xfrj", "Xx*" };
     for(i = 0; i < Translate_AA_SET_SIZE; i++)
         t->aa2d[t->aa[i]] = i;
-    for(i = 1; i < 22; i++)
+    for(i = 1; i < 23; i++)
         t->aamask[i] = (1L<<(i-1));  /* First is zero  */
     for(i = 0; i < Translate_PIMA_SET_SIZE; i++){
         t->aamask[t->aa2d[pimagrp[i][0]]]
@@ -138,7 +139,6 @@ static gchar *Translate_convert_genetic_code(gchar *code){
                 result[n++] = code[(table[a] << 4)
                                  | (table[b] << 2)
                                  |  table[c]];
-    /* g_print("generated genetic code [%s]\n", result); */
     return result;
     }
 /* Converts genetic code from NCBI format (TCAG order)
diff --git a/src/sequence/translate.h b/src/sequence/translate.h
index 9eb8fb7..9a2ea1d 100644
--- a/src/sequence/translate.h
+++ b/src/sequence/translate.h
@@ -3,7 +3,7 @@
 *  Nucleotide Translation Code                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/sequence/translate.test.c b/src/sequence/translate.test.c
index 5246483..a8c5ca6 100644
--- a/src/sequence/translate.test.c
+++ b/src/sequence/translate.test.c
@@ -3,7 +3,7 @@
 *  Nucleotide Translation Code                                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -24,8 +24,8 @@ static void reverse_func(gchar *dna, gint length, gpointer user_data){
 
 static void check_translate(Translate *t, gchar *codon, gchar crib){
     register gchar aa = Translate_codon(t, codon);
-    g_assert(aa == crib);
     g_message("Translate [%s] -> [%c] (crib:[%c]", codon, aa, crib);
+    g_assert(aa == crib);
     return;
     }
 
@@ -39,10 +39,14 @@ static void check_reverse_translate(Translate *t, gchar *word, gint crib){
     }
 
 gint Argument_main(Argument *arg){
-    register Translate *t = Translate_create(FALSE);
+    register Translate *t;
+    Translate_ArgumentSet_create(arg);
+    Argument_process(arg, "translate.test", NULL, NULL);
+    t = Translate_create(FALSE);
     check_translate(t, "ATG", 'M');
     check_translate(t, "GGX", 'G');
     check_translate(t, "NGT", 'X');
+    check_translate(t, "TGA", '*');
     /**/
     check_reverse_translate(t, "S*MXG",   72);
     check_reverse_translate(t, "SSSSS", 7776);
diff --git a/src/struct/Makefile.am b/src/struct/Makefile.am
index ab6f2bd..8b60d60 100644
--- a/src/struct/Makefile.am
+++ b/src/struct/Makefile.am
@@ -1,12 +1,17 @@
 
 TESTS = fsm.test matrix.test pqueue.test slist.test rangetree.test \
         vfsm.test recyclebin.test sparsecache.test dejavu.test     \
-        bitarray.test splaytree.test noitree.test
+        bitarray.test splaytree.test noitree.test 
+#       huffman.test fmindex.test
+
 noinst_PROGRAMS = $(TESTS)
 
 noinst_HEADERS = fsm.h matrix.h pqueue.h slist.h rangetree.h vfsm.h \
                  recyclebin.h sparsecache.h dejavu.h bitarray.h     \
                  splaytree.h noitree.h
+#                huffman.h fmindex.h
+
+INCLUDES = -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""
 
 fsm_test_SOURCES = fsm.test.c fsm.c
 fsm_test_LDADD = recyclebin.o
@@ -31,6 +36,12 @@ splaytree_test_LDADD = recyclebin.o
 noitree_test_SOURCES = noitree.test.c noitree.c
 noitree_test_LDADD = recyclebin.o splaytree.o
 
+# huffman_test_SOURCES = huffman.test.c huffman.c
+# huffman_test_LDADD = bitarray.o pqueue.o recyclebin.o
+
+# fmindex_test_SOURCES = fmindex.test.c fmindex.c
+# fmindex_test_LDADD = bitarray.o pqueue.o recyclebin.o huffman.o
+
 # Files to clear away
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/struct/Makefile.in b/src/struct/Makefile.in
index 34a1db8..d2f6b07 100644
--- a/src/struct/Makefile.in
+++ b/src/struct/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -78,12 +79,17 @@ installed_util_list = @installed_util_list@
 source_root_dir = @source_root_dir@
 use_pthreads = @use_pthreads@
 
-TESTS = fsm.test matrix.test pqueue.test slist.test rangetree.test         vfsm.test recyclebin.test sparsecache.test dejavu.test             bitarray.test splaytree.test noitree.test
+TESTS = fsm.test matrix.test pqueue.test slist.test rangetree.test         vfsm.test recyclebin.test sparsecache.test dejavu.test             bitarray.test splaytree.test noitree.test 
+
+#       huffman.test fmindex.test
 
 noinst_PROGRAMS = $(TESTS)
 
 noinst_HEADERS = fsm.h matrix.h pqueue.h slist.h rangetree.h vfsm.h                  recyclebin.h sparsecache.h dejavu.h bitarray.h                      splaytree.h noitree.h
 
+#                huffman.h fmindex.h
+
+INCLUDES = -DCUSTOM_GUINT64_FORMAT="\"@custom_guint64_format@\""
 
 fsm_test_SOURCES = fsm.test.c fsm.c
 fsm_test_LDADD = recyclebin.o
@@ -108,6 +114,12 @@ splaytree_test_LDADD = recyclebin.o
 noitree_test_SOURCES = noitree.test.c noitree.c
 noitree_test_LDADD = recyclebin.o splaytree.o
 
+# huffman_test_SOURCES = huffman.test.c huffman.c
+# huffman_test_LDADD = bitarray.o pqueue.o recyclebin.o
+
+# fmindex_test_SOURCES = fmindex.test.c fmindex.c
+# fmindex_test_LDADD = bitarray.o pqueue.o recyclebin.o huffman.o
+
 # Files to clear away
 
 MAINTAINERCLEANFILES = Makefile.in
diff --git a/src/struct/bitarray.c b/src/struct/bitarray.c
index b4a877b..d1733c3 100644
--- a/src/struct/bitarray.c
+++ b/src/struct/bitarray.c
@@ -3,7 +3,7 @@
 *  A simple bitarray data structure                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/bitarray.h b/src/struct/bitarray.h
index 5f0f8ce..825bb40 100644
--- a/src/struct/bitarray.h
+++ b/src/struct/bitarray.h
@@ -3,7 +3,7 @@
 *  A simple bitarray data structure                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -52,6 +52,8 @@ gboolean  BitArray_get_bit(BitArray *ba, guint64 pos);
 
     void  BitArray_write_int(guint64 num, FILE *fp);
  guint64  BitArray_read_int(FILE *fp);
+    void  BitArray_int_print(guint64 num);
+   gchar *BitArray_int_sprintf(guint64 num);
 
 #ifdef __cplusplus
 }
diff --git a/src/struct/bitarray.test.c b/src/struct/bitarray.test.c
index bfcc0f7..2fef2df 100644
--- a/src/struct/bitarray.test.c
+++ b/src/struct/bitarray.test.c
@@ -3,7 +3,7 @@
 *  A simple bitarray data structure                              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/dejavu.c b/src/struct/dejavu.c
index 62c8076..9468462 100644
--- a/src/struct/dejavu.c
+++ b/src/struct/dejavu.c
@@ -3,7 +3,7 @@
 *  Deja-vu library for fast linear space repeat finding          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -69,9 +69,8 @@ static gint DejaVu_init(DejaVu *dv, guchar *filter){
             continue;
         if(first[ch] == -1)
             first[ch] = i;
-        if(last[ch] != -1){
+        if(last[ch] != -1)
             dv->next[last[ch]] = i;
-            }
         last[ch] = i;
         }
     for(i = 0; i < ALPHABET_SIZE; i++){
diff --git a/src/struct/dejavu.h b/src/struct/dejavu.h
index 5422991..e45187d 100644
--- a/src/struct/dejavu.h
+++ b/src/struct/dejavu.h
@@ -3,7 +3,7 @@
 *  Deja-vu library for fast linear space repeat finding          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/dejavu.test.c b/src/struct/dejavu.test.c
index db6b887..ecab9da 100644
--- a/src/struct/dejavu.test.c
+++ b/src/struct/dejavu.test.c
@@ -3,7 +3,7 @@
 *  Deja-vu library for fast linear space repeat finding          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/fsm.c b/src/struct/fsm.c
index 17626b0..e288108 100644
--- a/src/struct/fsm.c
+++ b/src/struct/fsm.c
@@ -3,7 +3,7 @@
 *  Library for FSM-based word matching.                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -218,3 +218,5 @@ void FSM_add_traversal_filter(FSM *f, guchar *filter){
     return;
     }
 
+/**/
+
diff --git a/src/struct/fsm.h b/src/struct/fsm.h
index e3c96a8..06b3f9e 100644
--- a/src/struct/fsm.h
+++ b/src/struct/fsm.h
@@ -3,7 +3,7 @@
 *  Library for FSM-based word matching.                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/fsm.test.c b/src/struct/fsm.test.c
index 4b3b495..af16068 100644
--- a/src/struct/fsm.test.c
+++ b/src/struct/fsm.test.c
@@ -3,7 +3,7 @@
 *  Library for FSM-based word matching.                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/matrix.c b/src/struct/matrix.c
index 36c62d6..18247c3 100644
--- a/src/struct/matrix.c
+++ b/src/struct/matrix.c
@@ -3,7 +3,7 @@
 *  Simple matrix creation routines                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/matrix.h b/src/struct/matrix.h
index 2cf428e..9147258 100644
--- a/src/struct/matrix.h
+++ b/src/struct/matrix.h
@@ -3,7 +3,7 @@
 *  Simple matrix creation routines                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/matrix.test.c b/src/struct/matrix.test.c
index cb869d6..e55cf25 100644
--- a/src/struct/matrix.test.c
+++ b/src/struct/matrix.test.c
@@ -3,7 +3,7 @@
 *  Simple matrix creation routines                               *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/noitree.c b/src/struct/noitree.c
index e117220..c9f707b 100644
--- a/src/struct/noitree.c
+++ b/src/struct/noitree.c
@@ -3,7 +3,7 @@
 *  NOI_Tree : non-overlapping interval tree                      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/noitree.h b/src/struct/noitree.h
index ba0f647..0081f1f 100644
--- a/src/struct/noitree.h
+++ b/src/struct/noitree.h
@@ -3,7 +3,7 @@
 *  NOI_Tree : non-overlapping interval tree                      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/noitree.test.c b/src/struct/noitree.test.c
index d67324a..0d8ff2b 100644
--- a/src/struct/noitree.test.c
+++ b/src/struct/noitree.test.c
@@ -3,7 +3,7 @@
 *  NOI_Tree : non-overlapping interval tree                      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/pqueue.c b/src/struct/pqueue.c
index 7f715e8..b655895 100644
--- a/src/struct/pqueue.c
+++ b/src/struct/pqueue.c
@@ -3,7 +3,7 @@
 *  Priority queue library using pairing heaps.                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/pqueue.h b/src/struct/pqueue.h
index 7d84474..2038a47 100644
--- a/src/struct/pqueue.h
+++ b/src/struct/pqueue.h
@@ -3,7 +3,7 @@
 *  Priority queue library using pairing heaps.                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/pqueue.test.c b/src/struct/pqueue.test.c
index 6d624dc..1aa4495 100644
--- a/src/struct/pqueue.test.c
+++ b/src/struct/pqueue.test.c
@@ -3,7 +3,7 @@
 *  Priority queue library using pairing heaps.                   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/rangetree.c b/src/struct/rangetree.c
index b5637f7..a835f53 100644
--- a/src/struct/rangetree.c
+++ b/src/struct/rangetree.c
@@ -3,7 +3,7 @@
 *  Trees for 2D range searching.                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/rangetree.h b/src/struct/rangetree.h
index c20ae31..0a3f4ca 100644
--- a/src/struct/rangetree.h
+++ b/src/struct/rangetree.h
@@ -3,7 +3,7 @@
 *  Trees for 2D range searching.                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/rangetree.test.c b/src/struct/rangetree.test.c
index ff96cd0..2715877 100644
--- a/src/struct/rangetree.test.c
+++ b/src/struct/rangetree.test.c
@@ -3,7 +3,7 @@
 *  Trees for 2D range searching.                                 *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/recyclebin.c b/src/struct/recyclebin.c
index a623aac..4a6bb01 100644
--- a/src/struct/recyclebin.c
+++ b/src/struct/recyclebin.c
@@ -3,7 +3,7 @@
 *  Efficient Memory Allocation Routines                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -16,12 +16,16 @@
 #include <string.h>
 #include "recyclebin.h"
 
+#ifndef USE_PTHREADS
 static GTree *global_recycle_bin_tree = NULL;
+#endif /* USE_PTHREADS */
 
+#ifndef USE_PTHREADS
 static gint RecycleBin_compare(gconstpointer a,
                                gconstpointer b){
     return a - b;
     }
+#endif /* USE_PTHREADS */
 
 RecycleBin *RecycleBin_create(gchar *name, gsize node_size,
                               gint nodes_per_chunk){
@@ -36,9 +40,11 @@ RecycleBin *RecycleBin_create(gchar *name, gsize node_size,
     recycle_bin->node_size = node_size;
     recycle_bin->count = 0;
     recycle_bin->recycle = NULL;
+#ifndef USE_PTHREADS
     if(!global_recycle_bin_tree)
         global_recycle_bin_tree = g_tree_new(RecycleBin_compare);
     g_tree_insert(global_recycle_bin_tree, recycle_bin, recycle_bin);
+#endif /* USE_PTHREADS */
     return recycle_bin;
     }
 
@@ -46,6 +52,7 @@ void RecycleBin_destroy(RecycleBin *recycle_bin){
     register gint i;
     if(--recycle_bin->ref_count)
         return;
+#ifndef USE_PTHREADS
     g_assert(global_recycle_bin_tree);
     g_assert(g_tree_lookup(global_recycle_bin_tree, recycle_bin));
     g_tree_remove(global_recycle_bin_tree, recycle_bin);
@@ -53,6 +60,7 @@ void RecycleBin_destroy(RecycleBin *recycle_bin){
         g_tree_destroy(global_recycle_bin_tree);
         global_recycle_bin_tree = NULL;
         }
+#endif /* USE_PTHREADS */
     for(i = 0; i < recycle_bin->chunk_list->len; i++)
         g_free(recycle_bin->chunk_list->pdata[i]);
     g_ptr_array_free(recycle_bin->chunk_list, TRUE);
@@ -115,6 +123,7 @@ void RecycleBin_recycle(RecycleBin *recycle_bin, gpointer data){
     return;
     }
 
+#ifndef USE_PTHREADS
 static gint RecycleBin_profile_traverse(gpointer key,
                                         gpointer value,
                                         gpointer data){
@@ -126,14 +135,19 @@ static gint RecycleBin_profile_traverse(gpointer key,
               recycle_bin->count);
     return FALSE;
     }
+#endif /* USE_PTHREADS */
 
 void RecycleBin_profile(void){
     g_message("BEGIN RecycleBin profile");
+#ifdef USE_PTHREADS
+    g_message("multi-threaded RecycleBin_profile() not implemented");
+#else /* USE_PTHREADS */
     if(global_recycle_bin_tree)
         g_tree_traverse(global_recycle_bin_tree,
                         RecycleBin_profile_traverse, G_IN_ORDER, NULL);
     else
         g_message("no active RecycleBins");
+#endif /* USE_PTHREADS */
     g_message("END RecycleBin profile");
     return;
     }
diff --git a/src/struct/recyclebin.h b/src/struct/recyclebin.h
index c2dd1e6..d20ecbe 100644
--- a/src/struct/recyclebin.h
+++ b/src/struct/recyclebin.h
@@ -3,7 +3,7 @@
 *  Efficient Memory Allocation Routines                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/recyclebin.test.c b/src/struct/recyclebin.test.c
index d5a9bf4..02e16e9 100644
--- a/src/struct/recyclebin.test.c
+++ b/src/struct/recyclebin.test.c
@@ -3,7 +3,7 @@
 *  Efficient Memory Allocation Routines                          *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/slist.c b/src/struct/slist.c
index 864a232..0ae4a9f 100644
--- a/src/struct/slist.c
+++ b/src/struct/slist.c
@@ -3,7 +3,7 @@
 *  Efficient single-linked list routines.                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/slist.h b/src/struct/slist.h
index 74e61ba..d19120e 100644
--- a/src/struct/slist.h
+++ b/src/struct/slist.h
@@ -3,7 +3,7 @@
 *  Efficient single-linked list routines.                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/slist.test.c b/src/struct/slist.test.c
index 9663acf..e7a3235 100644
--- a/src/struct/slist.test.c
+++ b/src/struct/slist.test.c
@@ -3,7 +3,7 @@
 *  Efficient single-linked list routines.                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/sparsecache.c b/src/struct/sparsecache.c
index f228cb2..3e6e6a5 100644
--- a/src/struct/sparsecache.c
+++ b/src/struct/sparsecache.c
@@ -3,7 +3,7 @@
 *  Sparse Cache Object                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/sparsecache.h b/src/struct/sparsecache.h
index 13e6897..8b43fdd 100644
--- a/src/struct/sparsecache.h
+++ b/src/struct/sparsecache.h
@@ -3,7 +3,7 @@
 *  Sparse Cache Object                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/sparsecache.test.c b/src/struct/sparsecache.test.c
index 254ad17..bbd60dc 100644
--- a/src/struct/sparsecache.test.c
+++ b/src/struct/sparsecache.test.c
@@ -3,7 +3,7 @@
 *  Sparse Cache Object                                           *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/splaytree.c b/src/struct/splaytree.c
index c70e2c9..5801c37 100644
--- a/src/struct/splaytree.c
+++ b/src/struct/splaytree.c
@@ -3,7 +3,7 @@
 *  Splay Tree Library                                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/splaytree.h b/src/struct/splaytree.h
index ea3b1d7..14308dc 100644
--- a/src/struct/splaytree.h
+++ b/src/struct/splaytree.h
@@ -3,7 +3,7 @@
 *  Splay Tree Library                                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/splaytree.test.c b/src/struct/splaytree.test.c
index 879ab00..82cefc8 100644
--- a/src/struct/splaytree.test.c
+++ b/src/struct/splaytree.test.c
@@ -3,7 +3,7 @@
 *  Splay Tree Library                                            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/vfsm.c b/src/struct/vfsm.c
index cb53134..2447ca6 100644
--- a/src/struct/vfsm.c
+++ b/src/struct/vfsm.c
@@ -3,7 +3,7 @@
 *  VFSM Library : complete trie navigation                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/struct/vfsm.h b/src/struct/vfsm.h
index 5a8486c..399b472 100644
--- a/src/struct/vfsm.h
+++ b/src/struct/vfsm.h
@@ -3,7 +3,7 @@
 *  VFSM Library : complete trie navigation                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -22,7 +22,11 @@
 #ifdef G_HAVE_GINT64
 typedef guint64 VFSM_Int;
 #define VFSM_MAX G_GINT64_CONSTANT(18446744073709551615U)
+#ifdef CUSTOM_GUINT64_FORMAT
+#define VFSM_PRINT_FORMAT CUSTOM_GUINT64_FORMAT
+#else /* CUSTOM_GUINT64_FORMAT */
 #define VFSM_PRINT_FORMAT "llu"
+#endif /* CUSTOM_GUINT64_FORMAT */
 #else /* G_HAVE_GINT64 */
 typedef guint32 VFSM_Int;
 #define VFSM_MAX 4294967295U
diff --git a/src/struct/vfsm.test.c b/src/struct/vfsm.test.c
index 857127b..17ac981 100644
--- a/src/struct/vfsm.test.c
+++ b/src/struct/vfsm.test.c
@@ -3,7 +3,7 @@
 *  VFSM Library : complete trie navigation                       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index 3f1eddb..2f3e847 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -57,6 +57,7 @@ fasta2esd_LDADD  = $(top_srcdir)/src/database/dataset.o \
 
 esd2esi_LDADD  = $(top_srcdir)/src/database/dataset.o     \
                  $(top_srcdir)/src/database/index.o       \
+                 $(top_srcdir)/src/general/threadref.o    \
                  $(top_srcdir)/src/struct/bitarray.o      \
                  $(top_srcdir)/src/struct/vfsm.o          \
                  $(top_srcdir)/src/struct/pqueue.o        \
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
index ed7a68d..0c278de 100644
--- a/src/util/Makefile.in
+++ b/src/util/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
@@ -116,7 +117,7 @@ esd2esi_SOURCES = esd2esi.c
 fasta2esd_LDADD = $(top_srcdir)/src/database/dataset.o                    $(top_srcdir)/src/struct/bitarray.o                     $(LDADD)
 
 
-esd2esi_LDADD = $(top_srcdir)/src/database/dataset.o                      $(top_srcdir)/src/database/index.o                        $(top_srcdir)/src/struct/bitarray.o                       $(top_srcdir)/src/struct/vfsm.o                           $(top_srcdir)/src/struct/pqueue.o                         $(top_srcdir)/src/struct/recyclebin.o                     $(top_srcdir)/src/struct/rangetree.o                      $(top_srcdir)/src/struct/noitree.o                        $(top_srcdir [...]
+esd2esi_LDADD = $(top_srcdir)/src/database/dataset.o                      $(top_srcdir)/src/database/index.o                        $(top_srcdir)/src/general/threadref.o                     $(top_srcdir)/src/struct/bitarray.o                       $(top_srcdir)/src/struct/vfsm.o                           $(top_srcdir)/src/struct/pqueue.o                         $(top_srcdir)/src/struct/recyclebin.o                     $(top_srcdir)/src/struct/rangetree.o                      $(top_srcdir [...]
 
 
 EXTRA_fastavalidcds_SOURCES = fastavalidcds.c
@@ -436,9 +437,10 @@ $(top_srcdir)/src/struct/matrix.o
 fastaannotatecdna_LDFLAGS = 
 esd2esi_OBJECTS =  esd2esi.o
 esd2esi_DEPENDENCIES =  $(top_srcdir)/src/database/dataset.o \
-$(top_srcdir)/src/database/index.o $(top_srcdir)/src/struct/bitarray.o \
-$(top_srcdir)/src/struct/vfsm.o $(top_srcdir)/src/struct/pqueue.o \
-$(top_srcdir)/src/struct/recyclebin.o \
+$(top_srcdir)/src/database/index.o \
+$(top_srcdir)/src/general/threadref.o \
+$(top_srcdir)/src/struct/bitarray.o $(top_srcdir)/src/struct/vfsm.o \
+$(top_srcdir)/src/struct/pqueue.o $(top_srcdir)/src/struct/recyclebin.o \
 $(top_srcdir)/src/struct/rangetree.o $(top_srcdir)/src/struct/noitree.o \
 $(top_srcdir)/src/struct/splaytree.o \
 $(top_srcdir)/src/sequence/submat.o \
diff --git a/src/util/esd2esi.c b/src/util/esd2esi.c
index 35b62b2..a6b7183 100644
--- a/src/util/esd2esi.c
+++ b/src/util/esd2esi.c
@@ -3,7 +3,7 @@
 *  esd2esi - generate an exonerate index file from a dataset     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -26,7 +26,8 @@ int Argument_main(Argument *arg){
     gboolean is_translated = FALSE;
     register gint word_length;
     gint dna_word_length, protein_word_length,
-         word_jump, saturate_threshold, memory_limit;
+         word_jump, word_ambiguity,
+         saturate_threshold, memory_limit;
     /**/
     ArgumentSet_add_option(as, 'd', "dataset", "path",
         "Exonerate dataset file", NULL,
@@ -48,6 +49,9 @@ int Argument_main(Argument *arg){
     ArgumentSet_add_option(as, 0, "wordjump", NULL,
         "Jump between database words", "1",
         Argument_parse_int, &word_jump);
+    ArgumentSet_add_option(as, 0, "wordambiguity", NULL,
+        "Number of ambiguous words to index", "1",
+        Argument_parse_int, &word_ambiguity);
     ArgumentSet_add_option(as, 0, "saturatethreshold", NULL,
         "Word saturation threshold", "10",
         Argument_parse_int, &saturate_threshold);
@@ -65,8 +69,14 @@ int Argument_main(Argument *arg){
                   || (dataset->alphabet->type == Alphabet_Type_PROTEIN))
                 ? protein_word_length
                 : dna_word_length;
+    if(word_ambiguity < 1)
+        g_error("Word ambiguity cannot be less than one.");
+    if((word_ambiguity > 1)
+    && (dataset->alphabet->type == Alphabet_Type_PROTEIN))
+        g_error("Protein ambuigity symbols not implemented");
     g_message("Building index");
-    index = Index_create(dataset, is_translated, word_length, word_jump,
+    index = Index_create(dataset, is_translated, word_length,
+                         word_jump, word_ambiguity,
                          saturate_threshold, index_path, dataset_path,
                          memory_limit);
     Index_destroy(index);
diff --git a/src/util/fasta2esd.c b/src/util/fasta2esd.c
index 736fab9..1bbe782 100644
--- a/src/util/fasta2esd.c
+++ b/src/util/fasta2esd.c
@@ -3,7 +3,7 @@
 *  fasta2esd - generate an exonerate sequence database file      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaannotatecdna.c b/src/util/fastaannotatecdna.c
index fe2905c..f794e6a 100644
--- a/src/util/fastaannotatecdna.c
+++ b/src/util/fastaannotatecdna.c
@@ -3,7 +3,7 @@
 *  fastaannotatecdna : a utility to annotate cDNA with a protein *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastachecksum.c b/src/util/fastachecksum.c
index f42e843..f56bbed 100644
--- a/src/util/fastachecksum.c
+++ b/src/util/fastachecksum.c
@@ -3,7 +3,7 @@
 *  fastachecksum : a utility to print GCG checksums              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaclean.c b/src/util/fastaclean.c
index c0ee55b..a7c292d 100644
--- a/src/util/fastaclean.c
+++ b/src/util/fastaclean.c
@@ -3,7 +3,7 @@
 *  fastaclean : a utility to clean fasta format files            *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaclip.c b/src/util/fastaclip.c
index e725009..b0acabb 100644
--- a/src/util/fastaclip.c
+++ b/src/util/fastaclip.c
@@ -3,7 +3,7 @@
 *  fastaclip : clip terminal Ns from fasta format sequences      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastacomposition.c b/src/util/fastacomposition.c
index aab347b..b7ae348 100644
--- a/src/util/fastacomposition.c
+++ b/src/util/fastacomposition.c
@@ -3,7 +3,7 @@
 *  fastacomposition : a utility to dump sequence composition      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastadiff.c b/src/util/fastadiff.c
index 0e79423..83c930f 100644
--- a/src/util/fastadiff.c
+++ b/src/util/fastadiff.c
@@ -3,7 +3,7 @@
 *  fastadiff : a utility to compare fasta sequence files         *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaexplode.c b/src/util/fastaexplode.c
index 3a0febf..02f2a54 100644
--- a/src/util/fastaexplode.c
+++ b/src/util/fastaexplode.c
@@ -3,7 +3,7 @@
 *  fastaexplode : break a fasta file into individual sequences   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastafetch.c b/src/util/fastafetch.c
index 449474c..188a0a2 100644
--- a/src/util/fastafetch.c
+++ b/src/util/fastafetch.c
@@ -3,7 +3,7 @@
 *  fastafetch : fetch a sequence from a fasta format file        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -44,7 +44,7 @@ static gint fasta_index_read_to_char(FILE *fp, gchar c, GString *str){
 static CompoundFile_Pos fasta_index_lookup(FastaDB *fdb, FILE *index_fp,
                                            gchar *id){
     register long left, right, pos;
-    CompoundFile_Pos result = -1;
+    CompoundFile_Pos_scan_type result = -1;
     register GString *curr = g_string_sized_new(100);
     register gint cond;
     left = 0;
@@ -80,7 +80,7 @@ static CompoundFile_Pos fasta_index_lookup(FastaDB *fdb, FILE *index_fp,
             }
         }
     g_string_free(curr, TRUE);
-    return result;
+    return (CompoundFile_Pos)result;
     }
 
 static FastaDB_Seq *fasta_index_fetch(FastaDB *fdb, FILE *index_fp,
diff --git a/src/util/fastahardmask.c b/src/util/fastahardmask.c
index e0f2be0..3a3f2f0 100644
--- a/src/util/fastahardmask.c
+++ b/src/util/fastahardmask.c
@@ -3,7 +3,7 @@
 *  fastahardmask : convert lower case chars to 'N's              *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaindex.c b/src/util/fastaindex.c
index 522a8ac..7e45c19 100644
--- a/src/util/fastaindex.c
+++ b/src/util/fastaindex.c
@@ -3,7 +3,7 @@
 *  fastaindex : index a fasta format file                        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastalength.c b/src/util/fastalength.c
index ddb73ab..c210e87 100644
--- a/src/util/fastalength.c
+++ b/src/util/fastalength.c
@@ -3,7 +3,7 @@
 *  fastalength : a utility to print fasta sequence length        *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastanrdb.c b/src/util/fastanrdb.c
index a82fe72..41f6f2c 100644
--- a/src/util/fastanrdb.c
+++ b/src/util/fastanrdb.c
@@ -3,7 +3,7 @@
 *  fastanrdb : create non-redundant versions of fasta database   *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaoverlap.c b/src/util/fastaoverlap.c
index 6c43dae..2a0faf9 100644
--- a/src/util/fastaoverlap.c
+++ b/src/util/fastaoverlap.c
@@ -3,7 +3,7 @@
 *  fastaoverlap: generate overlapping sequences                  *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastareformat.c b/src/util/fastareformat.c
index 036ffd6..6cd78f3 100644
--- a/src/util/fastareformat.c
+++ b/src/util/fastareformat.c
@@ -3,7 +3,7 @@
 *  fastalength : a utility to reformat fasta format sequences    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastaremove.c b/src/util/fastaremove.c
index 3cf3ccd..abf7398 100644
--- a/src/util/fastaremove.c
+++ b/src/util/fastaremove.c
@@ -3,7 +3,7 @@
 *  fastaremove : remove sequences from a fasta format file       *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastarevcomp.c b/src/util/fastarevcomp.c
index 0ed05e6..8dfe259 100644
--- a/src/util/fastarevcomp.c
+++ b/src/util/fastarevcomp.c
@@ -3,7 +3,7 @@
 *  fastarevcomp : a utility to revcomp fasta format sequences    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastasoftmask.c b/src/util/fastasoftmask.c
index bc66b72..9df4c39 100644
--- a/src/util/fastasoftmask.c
+++ b/src/util/fastasoftmask.c
@@ -3,7 +3,7 @@
 *  fastasoftmask: merge masked and unmasked files to softmask    *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastasort.c b/src/util/fastasort.c
index 6e5e6d8..7bda2a7 100644
--- a/src/util/fastasort.c
+++ b/src/util/fastasort.c
@@ -3,7 +3,7 @@
 *  fastasort : a utility for sorting fasta format databases      *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastasplit.c b/src/util/fastasplit.c
index 4a066fc..bcf3e31 100644
--- a/src/util/fastasplit.c
+++ b/src/util/fastasplit.c
@@ -3,7 +3,7 @@
 *  fastasplit: split a fasta format file into chunks             *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastasubseq.c b/src/util/fastasubseq.c
index 5923130..575dc6e 100644
--- a/src/util/fastasubseq.c
+++ b/src/util/fastasubseq.c
@@ -3,7 +3,7 @@
 *  fastasubseq: extract subsequences from fasta format sequences *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/src/util/fastatranslate.c b/src/util/fastatranslate.c
index 8cd6cea..0925922 100644
--- a/src/util/fastatranslate.c
+++ b/src/util/fastatranslate.c
@@ -3,7 +3,7 @@
 *  fastatranslate: a utility to translate fasta format sequences *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
@@ -37,7 +37,8 @@ static void fasta_translate_seq(FastaDB_Seq *fdbs,
     } else {
         aa_seq = Sequence_translate(fdbs->seq, translate, frame);
         }
-    Sequence_print_fasta(aa_seq, stdout, FALSE);
+    if(aa_seq->len)
+        Sequence_print_fasta(aa_seq, stdout, FALSE);
     Sequence_destroy(aa_seq);
     return;
     }
@@ -47,7 +48,7 @@ int Argument_main(Argument *arg){
     register FastaDB_Seq *fdbs;
     register ArgumentSet *as
            = ArgumentSet_create("Sequence Input Options");
-    register Translate *translate = Translate_create(FALSE);
+    register Translate *translate;
     register Alphabet *dna_alphabet
            = Alphabet_create(Alphabet_Type_DNA, FALSE);
     register Alphabet *protein_alphabet
@@ -66,6 +67,7 @@ int Argument_main(Argument *arg){
         "A utility to translate fasta format sequences\n"
         "Guy St.C. Slater. guy at ebi.ac.uk. 2000-2003.\n", NULL);
     fdb = FastaDB_open(query_path, dna_alphabet);
+    translate = Translate_create(FALSE);
     while((fdbs = FastaDB_next(fdb, FastaDB_Mask_ALL))){
         fasta_translate_seq(fdbs, translate, frame, protein_alphabet);
         FastaDB_Seq_destroy(fdbs);
diff --git a/src/util/fastavalidcds.c b/src/util/fastavalidcds.c
index c2294ba..bf0779c 100644
--- a/src/util/fastavalidcds.c
+++ b/src/util/fastavalidcds.c
@@ -3,7 +3,7 @@
 *  fastavalidcds: a utility to check for valid CDS sequences     *
 *                                                                *
 *  Guy St.C. Slater..   mailto:guy at ebi.ac.uk                     *
-*  Copyright (C) 2000-2008.  All Rights Reserved.                *
+*  Copyright (C) 2000-2009.  All Rights Reserved.                *
 *                                                                *
 *  This source code is distributed under the terms of the        *
 *  GNU General Public License, version 3. See the file COPYING   *
diff --git a/test/Makefile.in b/test/Makefile.in
index 928d88d..6b93264 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/data/Makefile.in b/test/data/Makefile.in
index ae6f9b9..ad8f1cb 100644
--- a/test/data/Makefile.in
+++ b/test/data/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/data/cdna/Makefile.in b/test/data/cdna/Makefile.in
index 32e264a..44bd6c9 100644
--- a/test/data/cdna/Makefile.in
+++ b/test/data/cdna/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/data/protein/Makefile.in b/test/data/protein/Makefile.in
index 94ded24..4c0d735 100644
--- a/test/data/protein/Makefile.in
+++ b/test/data/protein/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/exonerate/Makefile.in b/test/exonerate/Makefile.in
index 742ace3..4480e3e 100644
--- a/test/exonerate/Makefile.in
+++ b/test/exonerate/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/ipcress/Makefile.in b/test/ipcress/Makefile.in
index 75df25b..edca276 100644
--- a/test/ipcress/Makefile.in
+++ b/test/ipcress/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@
diff --git a/test/util/Makefile.in b/test/util/Makefile.in
index 647c99c..9869823 100644
--- a/test/util/Makefile.in
+++ b/test/util/Makefile.in
@@ -70,6 +70,7 @@ PKG_CONFIG = @PKG_CONFIG@
 VERSION = @VERSION@
 codegen_extra_ldadd = @codegen_extra_ldadd@
 codegen_extra_sources = @codegen_extra_sources@
+custom_guint64_format = @custom_guint64_format@
 datarootdir = @datarootdir@
 glib_cflags = @glib_cflags@
 glib_libs = @glib_libs@

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/exonerate.git



More information about the debian-med-commit mailing list