[med-svn] [fsa] 07/10: Imported Upstream version 1.15.9+dfsg

Andreas Tille tille at debian.org
Mon Dec 21 18:43:33 UTC 2015


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

tille pushed a commit to branch master
in repository fsa.

commit 5dd84fe710be9a73091d930c3a55149693c1968c
Author: Andreas Tille <tille at debian.org>
Date:   Mon Dec 21 19:41:12 2015 +0100

    Imported Upstream version 1.15.9+dfsg
---
 COPYING                                    |   674 ++
 LICENSE                                    |    18 +
 MW/COPYING                                 |     0
 MW/INSTALL                                 |    55 +
 MW/Makefile.in                             |   119 +
 MW/README                                  |    15 +
 MW/acinclude.m4                            |    21 +
 MW/aclocal.m4                              |    15 +
 MW/configure                               |  5669 ++++++++++++
 MW/configure.in                            |   268 +
 MW/doxygen.conf                            |  1117 +++
 MW/install-sh                              |   251 +
 MW/missing                                 |     0
 MW/mkinstalldirs                           |    40 +
 MW/src/BlackBox/MWDriver_blackbox.C        |    92 +
 MW/src/BlackBox/MWDriver_blackbox.h        |    77 +
 MW/src/BlackBox/MWTask_blackbox.C          |   247 +
 MW/src/BlackBox/MWTask_blackbox.h          |    95 +
 MW/src/BlackBox/MWWorkerMain_blackbox.C    |    57 +
 MW/src/BlackBox/MWWorker_blackbox.C        |   138 +
 MW/src/BlackBox/MWWorker_blackbox.h        |    49 +
 MW/src/BlackBox/Makefile.in                |   181 +
 MW/src/MW.C                                |    24 +
 MW/src/MW.h                                |   136 +
 MW/src/MWControlTasks/MWNWSTask.C          |   229 +
 MW/src/MWControlTasks/MWNWSTask.h          |   110 +
 MW/src/MWControlTasks/Makefile.in          |   133 +
 MW/src/MWDriver.C                          |  4517 ++++++++++
 MW/src/MWDriver.h                          |  1274 +++
 MW/src/MWGroup.C                           |    99 +
 MW/src/MWGroup.h                           |    49 +
 MW/src/MWList.C                            |   873 ++
 MW/src/MWList.h                            |  1088 +++
 MW/src/MWMasterMain.C                      |    43 +
 MW/src/MWStats.C                           |   539 ++
 MW/src/MWStats.h                           |   153 +
 MW/src/MWSystem.h                          |    15 +
 MW/src/MWTask.C                            |   129 +
 MW/src/MWTask.h                            |   191 +
 MW/src/MWTaskContainer.C                   |   157 +
 MW/src/MWTaskContainer.h                   |   112 +
 MW/src/MWUnixSystem.C                      |    52 +
 MW/src/MWWinSystem.C                       |    47 +
 MW/src/MWWorker.C                          |   541 ++
 MW/src/MWWorker.h                          |   190 +
 MW/src/MWWorkerID.C                        |   659 ++
 MW/src/MWWorkerID.h                        |   395 +
 MW/src/MWWorkerMain.C                      |    42 +
 MW/src/MWprintf.C                          |   106 +
 MW/src/MWprintf.h                          |    82 +
 MW/src/Makefile.in                         |   171 +
 MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C |  1290 +++
 MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h |   287 +
 MW/src/RMComm/MW-CondorPVM/Makefile.in     |   140 +
 MW/src/RMComm/MW-File/MWFileError.h        |    35 +
 MW/src/RMComm/MW-File/MWFileRC.C           |  2992 +++++++
 MW/src/RMComm/MW-File/MWFileRC.h           |   397 +
 MW/src/RMComm/MW-File/MWFileRCSymbol.h     |    37 +
 MW/src/RMComm/MW-File/MWFileSend.h         |    58 +
 MW/src/RMComm/MW-File/MWFileTypes.h        |    42 +
 MW/src/RMComm/MW-File/MWFileWorker.h       |    68 +
 MW/src/RMComm/MW-File/Makefile.in          |   143 +
 MW/src/RMComm/MW-File/chirp_client.c       |   623 ++
 MW/src/RMComm/MW-File/chirp_client.h       |   202 +
 MW/src/RMComm/MW-File/chirp_protocol.h     |    50 +
 MW/src/RMComm/MW-Independent/MWIndRC.C     |   500 ++
 MW/src/RMComm/MW-Independent/MWIndRC.h     |   230 +
 MW/src/RMComm/MW-Independent/Makefile.in   |   122 +
 MW/src/RMComm/MW-Socket/MWSocketRC.C       |  2114 +++++
 MW/src/RMComm/MW-Socket/MWSocketRC.h       |   434 +
 MW/src/RMComm/MW-Socket/Makefile.in        |   139 +
 MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C |   754 ++
 MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h |   371 +
 MW/src/RMComm/MW-StaticMPI/Makefile.in     |   120 +
 MW/src/RMComm/MWRMComm.C                   |   457 +
 MW/src/RMComm/MWRMComm.h                   |   493 ++
 MW/src/RMComm/Makefile.in                  |   155 +
 Makefile.am                                |    91 +
 Makefile.in                                |   872 ++
 README                                     |   357 +
 acinclude.m4                               |   114 +
 aclocal.m4                                 |  1210 +++
 build-aux/ar-lib                           |   270 +
 build-aux/compile                          |   347 +
 build-aux/config.guess                     |  1501 ++++
 build-aux/config.sub                       |  1705 ++++
 build-aux/depcomp                          |   630 ++
 build-aux/install-sh                       |   520 ++
 build-aux/missing                          |   376 +
 build-aux/test-driver                      |   127 +
 config.h.in                                |   167 +
 configure                                  |  8958 +++++++++++++++++++
 configure.ac                               |   303 +
 debian/changelog                           |    10 -
 debian/compat                              |     1 -
 debian/control                             |    50 -
 debian/copyright                           |    53 -
 debian/docs                                |     3 -
 debian/examples                            |     1 -
 debian/patches/no-display.patch            |    17 -
 debian/patches/removed-pdf-only-docs.patch |    22 -
 debian/patches/series                      |     2 -
 debian/rules                               |    50 -
 debian/source/format                       |     1 -
 debian/upstream/metadata                   |    12 -
 debian/watch                               |     2 -
 display/Makefile.am                        |    78 +
 display/Makefile.in                        |   503 ++
 display/classnoinst.stamp                  |     1 +
 display/mad/AlignDAG.java                  |   641 ++
 display/mad/Alignment.java                 |   328 +
 display/mad/AlignmentPanel.java            |   337 +
 display/mad/Alignments.java                |   364 +
 display/mad/BatchDocument.java             |    87 +
 display/mad/JpegImagesToMovie.java         |   530 ++
 display/mad/MAD.java                       |    67 +
 display/mad/MadApplet.java                 |    37 +
 display/mad/MadPanel.java                  |   792 ++
 display/mad/Node.java                      |   618 ++
 display/mad/ProbabilityMatrices.java       |   169 +
 display/mad/PropertyChangeHandler.java     |    37 +
 display/mad/PropertyChangeIDs.java         |    11 +
 display/mad/SaveAsFastaAction.java         |    59 +
 display/mad/SaveAsMovAction.java           |    31 +
 display/mad/SaveAsTiffAction.java          |    53 +
 display/mad/SparseMatrix.java              |   257 +
 display/mad/legend.jpg                     |   Bin 0 -> 2289 bytes
 display/mad/manifest.mf                    |     4 +
 display/mad/manifest.mf.in                 |     4 +
 examples/Makefile.am                       |    23 +
 examples/Makefile.in                       |   431 +
 examples/README                            |    36 +
 examples/RV12.BBS12030.fasta               |    36 +
 examples/RV12.BBS12030.fasta.gui           |  2599 ++++++
 examples/RV12.BBS12030.fasta.probs         | 12627 +++++++++++++++++++++++++++
 examples/RV12.BBS12030.mfa                 |    13 +
 examples/RV12.BBS12030.reference.mfa       |    36 +
 examples/RV12.BBS12030.reference.stock     |     8 +
 examples/RV12.BBS12030.stock               |    10 +
 examples/U5.aln1.fasta                     |    20 +
 examples/U5.aln1.fasta.gui                 |  1048 +++
 examples/U5.aln1.fasta.probs               |  5984 +++++++++++++
 examples/U5.aln1.mfa                       |    11 +
 examples/U5.aln1.reference.mfa             |    20 +
 examples/U5.aln1.reference.stock           |    13 +
 examples/U5.aln1.stock                     |     9 +
 examples/tRNA.aln1.fasta                   |    15 +
 examples/tRNA.aln1.fasta.gui               |   636 ++
 examples/tRNA.aln1.fasta.probs             |  3731 ++++++++
 examples/tRNA.aln1.mfa                     |    11 +
 examples/tRNA.aln1.reference.mfa           |    15 +
 examples/tRNA.aln1.reference.stock         |    13 +
 examples/tRNA.aln1.stock                   |     9 +
 html/FAQ.html                              |   532 ++
 html/Makefile.am                           |     3 +
 html/Makefile.in                           |   411 +
 html/pretty.css                            |    12 +
 perl/FSA/Model.pm                          |   493 ++
 perl/FSA/SparseMatrices.pm                 |   490 ++
 perl/GFF.pm                                |   271 +
 perl/GFF/Database.pm                       |   201 +
 perl/Makefile.am                           |    14 +
 perl/Makefile.in                           |   422 +
 perl/Stockholm.pm                          |  1788 ++++
 perl/Stockholm/Database.pm                 |   284 +
 perl/accuracy.pl                           |    97 +
 perl/cmpalign.pl                           |   277 +
 perl/dartlog.pl                            |   168 +
 perl/fasta2stockholm.pl                    |    59 +
 perl/prettify.pl                           |    36 +
 perl/seqdotplot.pl                         |   173 +
 perl/stockholm2fasta.pl                    |    63 +
 src/annealing/Makefile.am                  |    35 +
 src/annealing/Makefile.in                  |   569 ++
 src/annealing/SparseMatrix.h               |   530 ++
 src/annealing/alignment_DAG.cc             |  1666 ++++
 src/annealing/alignment_DAG.h              |   742 ++
 src/annealing/dotplot.cc                   |    53 +
 src/annealing/dotplot.h                    |    62 +
 src/annealing/tree_weights.cc              |   100 +
 src/annealing/tree_weights.h               |    96 +
 src/fsa/Makefile.am                        |    37 +
 src/fsa/Makefile.in                        |   583 ++
 src/fsa/algebras.cc                        |    52 +
 src/fsa/algebras.h                         |   554 ++
 src/fsa/aminoacid_indel2dp.cc              |  2445 ++++++
 src/fsa/aminoacid_indel2dp.h               |   315 +
 src/fsa/aminoaciddp.cc                     |  2205 +++++
 src/fsa/aminoaciddp.h                      |   315 +
 src/fsa/anchors.cc                         |  1536 ++++
 src/fsa/anchors.h                          |   818 ++
 src/fsa/constraints.cc                     |   101 +
 src/fsa/constraints.h                      |   195 +
 src/fsa/dptables.h                         |   438 +
 src/fsa/fsa.cc                             |  1887 ++++
 src/fsa/fsa.h                              |   406 +
 src/fsa/model.cc                           |   392 +
 src/fsa/model.h                            |   915 ++
 src/fsa/mybanding.h                        |   111 +
 src/fsa/nucleotide_indel2dp.cc             |  2253 +++++
 src/fsa/nucleotide_indel2dp.h              |   315 +
 src/fsa/nucleotidedp.cc                    |  2013 +++++
 src/fsa/nucleotidedp.h                     |   315 +
 src/fsa/sequence_pair_selector.cc          |   360 +
 src/fsa/sequence_pair_selector.h           |   122 +
 src/main/Makefile.am                       |    55 +
 src/main/Makefile.in                       |   806 ++
 src/main/gapcleaner.cc                     |   116 +
 src/main/isect_mercator_alignment_gff.cc   |   244 +
 src/main/main.cc                           |    59 +
 src/main/map_coords.cc                     |   205 +
 src/main/map_gff_coords.cc                 |   204 +
 src/main/percentid.cc                      |   108 +
 src/main/prot2codon.cc                     |   133 +
 src/main/slice_fasta.cc                    |   170 +
 src/main/slice_fasta_gff.cc                |   173 +
 src/main/slice_mercator_alignment.cc       |   227 +
 src/main/translate.cc                      |   107 +
 src/manager/Makefile.am                    |    49 +
 src/manager/Makefile.in                    |   585 ++
 src/manager/db_adapter.cc                  |   263 +
 src/manager/db_adapter.h                   |   108 +
 src/manager/db_misc.cc                     |    36 +
 src/manager/db_misc.h                      |   162 +
 src/manager/db_postgres.cc                 |  1011 +++
 src/manager/db_postgres.h                  |   301 +
 src/manager/manager.cc                     |   772 ++
 src/manager/manager.h                      |   217 +
 src/manager/mw_adapter.cc                  |    31 +
 src/manager/mw_adapter.h                   |    54 +
 src/manager/mw_master.cc                   |   530 ++
 src/manager/mw_master.h                    |    93 +
 src/manager/mw_task.cc                     |    62 +
 src/manager/mw_task.h                      |    63 +
 src/manager/mw_worker.cc                   |   232 +
 src/manager/mw_worker.h                    |    63 +
 src/manager/transfer_data.cc               |   634 ++
 src/math/Makefile.am                       |    10 +
 src/math/Makefile.in                       |   549 ++
 src/math/mathematics.cc                    |    36 +
 src/math/mathematics.h                     |   195 +
 src/math/mst.cc                            |   101 +
 src/math/mst.h                             |   166 +
 src/seq/Makefile.am                        |    22 +
 src/seq/Makefile.in                        |   567 ++
 src/seq/alignment.cc                       |  1154 +++
 src/seq/alignment.h                        |   729 ++
 src/seq/alphabet.cc                        |   193 +
 src/seq/alphabet.h                         |   320 +
 src/seq/gff.cc                             |   364 +
 src/seq/gff.h                              |   531 ++
 src/seq/interval.h                         |   130 +
 src/seq/mercator.cc                        |   856 ++
 src/seq/mercator.h                         |   465 +
 src/seq/sequence.cc                        |   587 ++
 src/seq/sequence.h                         |   506 ++
 src/seq/similarity_matrix.cc               |   204 +
 src/seq/similarity_matrix.h                |   198 +
 src/util/Makefile.am                       |    24 +
 src/util/Makefile.in                       |   570 ++
 src/util/array2d.h                         |   421 +
 src/util/dexception.cc                     |   120 +
 src/util/dexception.h                      |    58 +
 src/util/hash_fcn.h                        |   200 +
 src/util/logfile.cc                        |   337 +
 src/util/logfile.h                         |   277 +
 src/util/logtags.h                         |    13 +
 src/util/macros.h                          |    84 +
 src/util/memcheck.cc                       |    51 +
 src/util/memcheck.h                        |    17 +
 src/util/misc.cc                           |    90 +
 src/util/misc.h                            |   390 +
 src/util/opts_list.cc                      |   433 +
 src/util/opts_list.h                       |   160 +
 src/util/regexp.cc                         |  1758 ++++
 src/util/regexp.h                          |    49 +
 src/util/sstring.cc                        |   159 +
 src/util/sstring.h                         |   131 +
 tests/Makefile.am                          |     3 +
 tests/Makefile.in                          |  1198 +++
 version.m4                                 |     1 +
 281 files changed, 134147 insertions(+), 224 deletions(-)

diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..bca5e08
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,18 @@
+
+==================================================================
+                        LICENSE
+==================================================================
+
+FSA is licensed under the GNU GPL.
+MAD is licensed under the GNU GPL.
+
+Please see the file COPYING for the text of version 3 of the
+GNU General Public License.
+
+The bundled Java Media Framework 2.1.1e API,
+located in display/JMF-2.1.1e/
+is covered by the
+JavaTM Media Framework (JMF) 2.1.x Binary Code License Agreement.
+
+Please see the file display/JMF-2.1.1e/readme.html for a 
+copy of the JavaTM Media Framework (JMF) 2.1.x Binary Code License Agreement.
diff --git a/MW/COPYING b/MW/COPYING
new file mode 100644
index 0000000..e69de29
diff --git a/MW/INSTALL b/MW/INSTALL
new file mode 100644
index 0000000..38f41d7
--- /dev/null
+++ b/MW/INSTALL
@@ -0,0 +1,55 @@
+#$Id: INSTALL,v 1.3 2004/05/28 18:35:47 linderot Exp $
+
+# ------------- Prepare to install MW -----------------------
+1) Install Condor first, and make sure that the condor execs
+   are in your path. For example, you can add the following 
+   lines in your .cshrc file. 
+
+	set path = ( $path /unsup/condor/bin )
+	set path = ( $path /unsup/condor/sbin )
+
+   For bash and other sh type shells, the command would be
+	export PATH = $PATH:/unsup/condor/bin:/unsup/condor/sbin	
+
+2) Install Condor-PVM or PVM with proper changes (refer the 
+   README.Condor-PVM file under /afs/cs.wisc.edu/p/condor/workspaces/pvm) 
+   so that it works with Condor. Also update your environment variables:
+	setenv PVM_ROOT  /p/condor/workspaces/pvm/pvm3.4.2
+	setenv PVM_ARCH  <proper_name: LINUX X86SOL2 SGI6 etc>
+
+	sh style shells
+
+	export PVM_ROOT=/p/condor/workspaces/pvm/pvm3.4.2
+	export PVM_ARCH=LINUX
+
+3) There are several options for debugging: 
+   -- The default result of "make check" will produce master and worker
+      application using MW-Independent (which is developed for debugging).
+      You can "setenv MW_DEBUG no" to turn this off.
+   -- You can also use Insure to detect memory related bugs. To do this, 
+      you need to "setenv DEBUG_BUILD insure" and setup the path variable.
+      As insure doesn't work with MW-File, this setting will produce 
+      master and worker app using MW-File. 
+
+
+# -------------- How to build MW -----------------------------
+tar zxf mw.tar.gz
+cd mw; ./configure #--prefix=/tmp/mw
+make; make check 	# The typical command to build MW
+
+  --with-condor           Use the given condor installation path
+  --with-pvm              Use the given pvm installation path
+  --with-measure          Build with -DMEASURE
+  --with-independent      Build MW-Independent library
+
+
+# -------------- Other targets --------------------------------
+make 		# Build MW libraries, without installing them
+make install 	# (Build and) install MW libraries
+make check	# Build examples (after building libraries)
+make clean	# Cleanup the exes, libs, and object files
+make distclean  # Cleanup for distribution
+
+# ------------- How to run the examples ----------------------
+cd examples/fib
+condor_submit submit_mwfile	# submit the job using MW File
diff --git a/MW/Makefile.in b/MW/Makefile.in
new file mode 100644
index 0000000..ebfa06d
--- /dev/null
+++ b/MW/Makefile.in
@@ -0,0 +1,119 @@
+#-------------------------------------------------------------------------
+# 
+# $Id: Makefile.in,v 1.5 2005/06/10 15:39:49 gthain Exp $
+#
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+PVM_ROOT = @PVM_ROOT@
+PVM_ARCH = @PVM_ARCH@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS = src # examples
+LIBRARIES =  
+
+# Files to be cleaned
+CLEANFILES = $(MW_LIBDIR)/* src/MWDriverInd.ii src/MWWorkerInd.ii src/RMComm/MW-File/MWFileRCW.ii src/RMComm/MW-File/MWFileRCM.ii src/RMComm/MW-CondorPVM/MWCondorPvmRCM.ii src/RMComm/MW-CondorPVM/MWCondorPvmRCW.ii src/RMComm/MW-Socket/MWSocketRCM.ii src/RMComm/MW-Socket/MWSocketRCW.ii
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: 
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.SUFFIXES: 
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules
+#-------------------------------------------------------------------------
+
+install: 
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check: 
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+clean: 
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+	-test -z "$(CLEANFILES)" || rm -fr $(CLEANFILES)
+
+distclean: 
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+	-test -z "$(CLEANFILES)" || rm -fr $(CLEANFILES)
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps lib lib_debug debug_lib
+	-rm -f config.cache config.status config.log stamp-h stamp-h[0-9]* 
+	-rm -rf autom4te.cache/
+	-rm -f ${PACKAGE}-${VERSION}.tar.gz
+	-find . -name "tca.map" -exec rm {} \;
+	-find . -name ".inslog2" -exec rm {} \;
+	-find . -name "*~" -exec rm {} \;
+	-find . -name "*#*#" -exec rm {} \;
+	@ echo "Cleaning intermediate results"
+	-find . -name "out_master.*" -exec rm {} \;
+	-find . -name "out_worker.*" -exec rm {} \;
+	-find . -name "submitfiles" -exec rm -r {} \;
+	-find . -name "worker_input" -exec rm -r {} \;
+	-find . -name "worker_output" -exec rm -r {} \;
+
+#
+# A target to build a (clean) source distribution
+#
+srcdist: distclean
+	echo -e "AUTHORS\nBUGS\nChangeLog\nCHANGES\nCVS\nNEWS\nTAGS\nTODO\nnmi_glue" > ../exclude-list
+	cd ..; tar cvzf ${PACKAGE}-${VERSION}.tgz --exclude-from=exclude-list mw
+	rm -f ../exclude-list
+
+#
+# A target for doc
+#
+doc:
+	doxygen doxygen.conf
+
+Makefile: configure.in
+	./configure
+
+.PHONY: all check clean distclean doc srcdist install
diff --git a/MW/README b/MW/README
new file mode 100644
index 0000000..b453869
--- /dev/null
+++ b/MW/README
@@ -0,0 +1,15 @@
+$Id: README,v 1.2 2004/04/05 19:54:19 linderot Exp $
+
+For how to build MW, please read INSTALL;
+
+To run the existing examples, go to examples/ directory, and try 
+    the fib, matmul or n-queen. There is also a skel subdirectory
+    that contains skeleton files to build your own simple MW app;
+
+For how to write your MW applications, please read matmul.html 
+    in examples/matmul directory; 
+
+For details of MW API, please refer to the DOC++ files in doc 
+    directory;
+
+For other information, please email to mw at cs.wisc.edu. 
diff --git a/MW/acinclude.m4 b/MW/acinclude.m4
new file mode 100644
index 0000000..0f5cae8
--- /dev/null
+++ b/MW/acinclude.m4
@@ -0,0 +1,21 @@
+dnl Starting here is a bunch of local macros
+
+
+
+AC_DEFUN([AC_CXX_DYNAMIC_CAST],
+        [AC_CACHE_CHECK(whether the compiler supports dynamic_cast<>,
+        ac_cv_cxx_dynamic_cast,
+        [AC_LANG_SAVE
+         AC_LANG_CPLUSPLUS
+         AC_TRY_COMPILE([#include <typeinfo>
+        class Base { public : Base () {} virtual void f () = 0;};
+        class Derived : public Base { public : Derived () {} virtual void f () {} };],[
+        Derived d; Base& b=d; return dynamic_cast<Derived*>(&b) ? 0 : 1;],
+         ac_cv_cxx_dynamic_cast=yes, ac_cv_cxx_dynamic_cast=no)
+         AC_LANG_RESTORE
+        ])
+        if test "$ac_cv_cxx_dynamic_cast" = yes; then
+          AC_DEFINE(HAVE_DYNAMIC_CAST,,[define if the compiler supports dynamic_cast<>])
+        fi
+        ])
+
diff --git a/MW/aclocal.m4 b/MW/aclocal.m4
new file mode 100644
index 0000000..44df97e
--- /dev/null
+++ b/MW/aclocal.m4
@@ -0,0 +1,15 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_include([acinclude.m4])
diff --git a/MW/configure b/MW/configure
new file mode 100755
index 0000000..475f193
--- /dev/null
+++ b/MW/configure
@@ -0,0 +1,5669 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="src/MWDriver.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
+LIBOBJS
+MW_LIBDIR_DEBUG
+MW_LIBDIR
+ENABLE_MWINDEPENDENT
+MEASURE_DEFN
+MISC_LIB
+MISC_DEFN
+USE_POLL
+SOCKET_LIB
+MPICXX
+JUNK5
+PVM_ARCH
+PVM_ROOT
+JUNK3
+USE_CHIRP
+USE_MWFILE
+CONDOR_DIR
+JUNK1
+EGREP
+GREP
+CPP
+ac_ct_CC
+CFLAGS
+CC
+AUTOCONF
+RANLIB
+SET_MAKE
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+OBJEXT
+EXEEXT
+ac_ct_CXX
+CPPFLAGS
+LDFLAGS
+CXXFLAGS
+CXX
+VERSION
+PACKAGE
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_condor
+with_mwfile
+with_chirp
+with_pvm_arch
+with_pvm
+with_mpi
+with_measure
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-condor           Use the given condor installation path --without-condor means only build indp
+  --with-mwfile				Use MWfile RMCOMM
+  --with-chirp              Use chirp for mw-file on clipped platforms
+  --with-pvm-arch              Use the given pvm architectures
+  --with-pvm              Use the given pvm installation path
+  --with-mpi              Build the Static MPI RMComm
+  --with-measure          Build with -DMEASURE
+
+Some influential environment variables:
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+PACKAGE=mw
+VERSION=0.3.0
+
+
+
+
+
+
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C++ compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+# Extract the first word of "g++", so it can be a program name with args.
+set dummy g++; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $CXX in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CXX="$CXX" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_CXX="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+CXX=$ac_cv_path_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+# Extract the first word of "autoconf", so it can be a program name with args.
+set dummy autoconf; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_AUTOCONF+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $AUTOCONF in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_AUTOCONF="$AUTOCONF" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_AUTOCONF="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+AUTOCONF=$ac_cv_path_AUTOCONF
+if test -n "$AUTOCONF"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AUTOCONF" >&5
+$as_echo "$AUTOCONF" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in fcntl.h limits.h sys/time.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if ${ac_cv_c_const+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this sort of thing.  */
+  typedef int charset[2];
+  const charset cs = { 0, 0 };
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if ${ac_cv_struct_tm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm tm;
+				     int *p = &tm.tm_sec;
+				     return !p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_struct_tm=time.h
+else
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "uid_t" >/dev/null 2>&1; then :
+  ac_cv_type_uid_t=yes
+else
+  ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
+if test $ac_cv_type_uid_t = no; then
+
+$as_echo "#define uid_t int" >>confdefs.h
+
+
+$as_echo "#define gid_t int" >>confdefs.h
+
+fi
+
+
+for ac_func in vprintf
+do :
+  ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+for ac_func in getcwd gethostname gettimeofday mkdir strstr
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports dynamic_cast<>" >&5
+$as_echo_n "checking whether the compiler supports dynamic_cast<>... " >&6; }
+if ${ac_cv_cxx_dynamic_cast+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+
+         ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <typeinfo>
+        class Base { public : Base () {} virtual void f () = 0;};
+        class Derived : public Base { public : Derived () {} virtual void f () {} };
+int
+main ()
+{
+
+        Derived d; Base& b=d; return dynamic_cast<Derived*>(&b) ? 0 : 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_cxx_dynamic_cast=yes
+else
+  ac_cv_cxx_dynamic_cast=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+         ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_dynamic_cast" >&5
+$as_echo "$ac_cv_cxx_dynamic_cast" >&6; }
+        if test "$ac_cv_cxx_dynamic_cast" = yes; then
+
+$as_echo "#define HAVE_DYNAMIC_CAST /**/" >>confdefs.h
+
+        fi
+
+
+
+# Check whether --with-condor was given.
+if test "${with_condor+set}" = set; then :
+  withval=$with_condor; CONDOR_DIR=$withval
+fi
+
+if test -z "$CONDOR_DIR"; then
+        # Extract the first word of "condor_status", so it can be a program name with args.
+set dummy condor_status; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_JUNK1+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $JUNK1 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_JUNK1="$JUNK1" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_JUNK1="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+JUNK1=$ac_cv_path_JUNK1
+if test -n "$JUNK1"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JUNK1" >&5
+$as_echo "$JUNK1" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+        if test -z "$JUNK1"; then
+                echo "-- Can't build MW without Condor, please install Condor first."
+		exit 1
+	else
+                JUNK2=`dirname $JUNK1`
+		                CONDOR_DIR=`dirname $JUNK2`
+                echo "-- Using Condor installed in $CONDOR_DIR"
+
+        fi
+else
+	echo "-- Using Condor installed in $CONDOR_DIR"
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define CONDOR_DIR "$CONDOR_DIR"
+_ACEOF
+
+
+
+# Check whether --with-mwfile was given.
+if test "${with_mwfile+set}" = set; then :
+  withval=$with_mwfile; USE_MWFILE=$withval
+else
+  USE_MWFILE=no
+fi
+
+if test -z $USE_MWFILE
+then
+	USE_MWFILE=true
+	echo "-- configuring MW to use MW-FILE RMCOMM Layer"
+else
+	if test $USE_MWFILE = no
+	then
+			USE_MWFILE=no
+			echo "-- configuring MW not to use MW-FILE RMCOMM Layer"
+	else
+			USE_MWFILE=true
+			echo "-- configuring MW to use MW-FILE RMCOMM Layer"
+	fi
+fi
+
+
+machtype=`uname -m`
+case $machtype in
+	x86_64)
+		echo "On x86_64, forcing mwfile implementation off"
+		USE_MWFILE=no
+	;;
+esac
+
+
+
+# Check whether --with-chirp was given.
+if test "${with_chirp+set}" = set; then :
+  withval=$with_chirp; USE_CHIRP=$withval
+fi
+
+
+if test -z $USE_CHIRP
+then
+echo "-- Not using chirp with MW-File"
+else
+echo "-- Using chirp with MW-File"
+$as_echo "#define USE_CHIRP 1" >>confdefs.h
+
+
+fi
+
+
+
+# Check whether --with-pvm-arch was given.
+if test "${with_pvm_arch+set}" = set; then :
+  withval=$with_pvm_arch; PVM_ARCH=$withval
+fi
+
+
+# Check whether --with-pvm was given.
+if test "${with_pvm+set}" = set; then :
+  withval=$with_pvm; PVM_ROOT=$withval
+else
+  PVM_ROOT=no
+fi
+
+if test -z "$PVM_ROOT"; then
+        # Extract the first word of "pvm", so it can be a program name with args.
+set dummy pvm; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_JUNK3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $JUNK3 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_JUNK3="$JUNK3" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_JUNK3="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+JUNK3=$ac_cv_path_JUNK3
+if test -n "$JUNK3"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JUNK3" >&5
+$as_echo "$JUNK3" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+        if test -z "$JUNK3"; then
+                echo "-- Can't build MW without PVM, please install CondorPvm first."
+		exit 1
+        else
+                JUNK4=`dirname $JUNK3`
+                PVM_ROOT=`dirname $JUNK4`/
+                echo "-- Using PVM lib installed in $PVM_ROOT/lib/$PVM_ARCH"
+
+
+        fi
+else
+        if test $PVM_ROOT = no
+	then
+	   echo "-- Not using PVM"
+	else
+           echo "-- Using PVM lib installed in $PVM_ROOT/lib/$PVM_ARCH"
+	fi
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi-directory" >&5
+$as_echo_n "checking for mpi-directory... " >&6; }
+
+# Check whether --with-mpi was given.
+if test "${with_mpi+set}" = set; then :
+  withval=$with_mpi; USE_MPI=$withval
+else
+  USE_MPI=no
+fi
+
+if test -z $USE_MPI
+then
+    # Extract the first word of "mpicxx", so it can be a program name with args.
+set dummy mpicxx; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_JUNK5+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $JUNK5 in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_JUNK5="$JUNK5" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_JUNK5="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+JUNK5=$ac_cv_path_JUNK5
+if test -n "$JUNK5"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JUNK5" >&5
+$as_echo "$JUNK5" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    if test -z "$JUNK5"; then
+       echo "-- Can't find mpicxx, please install mpi first."
+       exit 1
+    else
+	echo "-- MPI is set to $USE_MPI"
+	echo "-- Using MPI lib $JUNK5"
+	MPICXX=mpicxx
+
+	echo "-- The MPI Compiler MPICXX is set at $MPICXX"
+    fi
+    else
+    if test $USE_MPI = no
+    then
+        echo "-- Not using MPI"
+    else
+        MPICXX=mpicxx
+
+	echo "-- The MPI Compiler MPICXX is set at $MPICXX"
+    fi
+fi
+
+
+if opsys=`uname -s`
+then
+	echo "-- Operating system is $opsys"
+else
+	echo "-- Can't find the 'uname' program!"
+	exit 1
+fi
+
+case $opsys in
+    SunOS*)
+		SOCKET_LIB="-lnsl -lsocket " ;;
+	*)
+		SOCKET_LIB= ;;
+esac
+
+
+if test $opsys = "Linux"
+then
+		echo "-- Using poll instead of select for supporting > 1024 socket workers"
+		$as_echo "#define USE_POLL 1" >>confdefs.h
+
+
+fi
+
+
+USE_NWS=no
+
+case $USE_NWS in
+	yes*)
+		MISC_DEFN=-DNWSENABLED;
+		NWS_SENSOR_PATH=`dirname $NWS_SENSOR_PING`
+		NWS_PATH=`dirname $NWS_SENSOR_PATH`
+		MISC_LIB=$NWS_PATH/libnws
+		;;
+	*)
+		MISC_DEFN=
+		MISC_LIB=-lNWS;
+		;;
+esac
+
+
+
+
+
+# Check whether --with-measure was given.
+if test "${with_measure+set}" = set; then :
+  withval=$with_measure; MEASURE_DEFN='-DMEASURE'
+fi
+
+
+
+ENABLE_MWINDEPENDENT=yes
+
+
+MW_LIBDIR=`pwd`/lib
+
+MW_LIBDIR_DEBUG=`pwd`/debug_lib
+
+
+if test -d lib; then
+	echo "-- The lib directory already exists, no need to create"
+else
+	echo "-- Creating lib directory"
+	mkdir lib
+fi
+
+if test -d debug_lib; then
+	echo "-- The debug_lib directory already exists, no need to create"
+else
+	echo "-- Creating debug_lib directory"
+	mkdir debug_lib
+fi
+
+EXTRA_MAKEFILES=`echo "src/RMComm/MW-Independent/Makefile"`
+ac_config_files="$ac_config_files Makefile src/Makefile src/RMComm/Makefile src/RMComm/MW-File/Makefile src/RMComm/MW-CondorPVM/Makefile src/RMComm/MW-Socket/Makefile src/RMComm/MW-StaticMPI/Makefile src/MWControlTasks/Makefile src/BlackBox/Makefile $EXTRA_MAKEFILES"
+
+ac_config_commands="$ac_config_commands default"
+
+
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[	 `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+	g
+	s/^\n//
+	s/\n/ /g
+	p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h |  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
+    "src/RMComm/Makefile") CONFIG_FILES="$CONFIG_FILES src/RMComm/Makefile" ;;
+    "src/RMComm/MW-File/Makefile") CONFIG_FILES="$CONFIG_FILES src/RMComm/MW-File/Makefile" ;;
+    "src/RMComm/MW-CondorPVM/Makefile") CONFIG_FILES="$CONFIG_FILES src/RMComm/MW-CondorPVM/Makefile" ;;
+    "src/RMComm/MW-Socket/Makefile") CONFIG_FILES="$CONFIG_FILES src/RMComm/MW-Socket/Makefile" ;;
+    "src/RMComm/MW-StaticMPI/Makefile") CONFIG_FILES="$CONFIG_FILES src/RMComm/MW-StaticMPI/Makefile" ;;
+    "src/MWControlTasks/Makefile") CONFIG_FILES="$CONFIG_FILES src/MWControlTasks/Makefile" ;;
+    "src/BlackBox/Makefile") CONFIG_FILES="$CONFIG_FILES src/BlackBox/Makefile" ;;
+    "$EXTRA_MAKEFILES") CONFIG_FILES="$CONFIG_FILES $EXTRA_MAKEFILES" ;;
+    "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X "  :F $CONFIG_FILES      :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "default":C) echo timestamp > stamp-h  ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/MW/configure.in b/MW/configure.in
new file mode 100644
index 0000000..d9b9dc1
--- /dev/null
+++ b/MW/configure.in
@@ -0,0 +1,268 @@
+<<<<<<<dnl Caching is usually WRONG for systems with cross-mounted file systems
+dnl (the cache file may correspond to a different system).  Since configure
+dnl is not on a performance-critical path, go for robustness over speed.
+dnl
+
+define([AC_CACHE_LOAD], )dnl
+define([AC_CACHE_SAVE], )dnl
+
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(src/MWDriver.h)
+
+PACKAGE=mw
+VERSION=0.3.0
+
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl Check for the autoconf version
+AC_PREREQ(2.13)
+	
+dnl Set the header
+dnl AM_CONFIG_HEADER(config.h)
+
+AC_ARG_PROGRAM
+
+dnl Checks for programs.
+AC_PROG_CXX
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+AC_PATH_PROG(CXX,g++)
+AC_PATH_PROG(AUTOCONF,autoconf)
+
+AC_SUBST(CXX)
+AC_SUBST(AUTOCONF)
+
+dnl Checks for libraries.
+dnl We're just build libraries now, so you shouldn't 
+dnl need to check all these until you build the exec
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(fcntl.h limits.h sys/time.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_TYPE_UID_T
+
+dnl Checks for library functions.
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(getcwd gethostname gettimeofday mkdir strstr)
+
+dnl
+dnl Starting here are Jeff's (non-auto) additions
+dnl
+
+dnl Some C++ support macros
+AC_CXX_DYNAMIC_CAST
+
+dnl Jeff's check for condor
+AC_ARG_WITH(condor, [  --with-condor           Use the given condor installation path --without-condor means only build indp], CONDOR_DIR=$withval)
+if test -z "$CONDOR_DIR"; then
+        AC_PATH_PROG(JUNK1, condor_status)
+        if test -z "$JUNK1"; then
+                echo "-- Can't build MW without Condor, please install Condor first."
+		exit 1        
+	else
+                JUNK2=`dirname $JUNK1`
+		dnl -- better if we can report condor versioni, will add later.
+                CONDOR_DIR=`dirname $JUNK2`  
+                echo "-- Using Condor installed in $CONDOR_DIR"
+                AC_SUBST(CONDOR_DIR)
+        fi
+else 
+	echo "-- Using Condor installed in $CONDOR_DIR"
+fi
+AC_DEFINE_UNQUOTED(CONDOR_DIR, "$CONDOR_DIR", [condor release directory])
+
+dnl Check for mw-file RMCOMM usage
+AC_ARG_WITH(mwfile, [  --with-mwfile				Use MWfile RMCOMM], USE_MWFILE=$withval, USE_MWFILE=no)
+if test -z $USE_MWFILE
+then
+	USE_MWFILE=true
+	echo "-- configuring MW to use MW-FILE RMCOMM Layer"
+else
+	if test $USE_MWFILE = no
+	then
+			USE_MWFILE=no
+			echo "-- configuring MW not to use MW-FILE RMCOMM Layer"
+	else 
+			USE_MWFILE=true
+			echo "-- configuring MW to use MW-FILE RMCOMM Layer"
+	fi
+fi
+
+
+machtype=`uname -m`
+case $machtype in
+	x86_64)
+		echo "On x86_64, forcing mwfile implementation off"
+		USE_MWFILE=no
+	;;
+esac
+AC_SUBST(USE_MWFILE)
+
+dnl Check for chirp-file support
+AC_ARG_WITH(chirp, [  --with-chirp              Use chirp for mw-file on clipped platforms], USE_CHIRP=$withval)
+
+if test -z $USE_CHIRP 
+then
+echo "-- Not using chirp with MW-File"
+else
+echo "-- Using chirp with MW-File"
+AC_DEFINE(USE_CHIRP)
+AC_SUBST(USE_CHIRP)
+fi
+
+
+dnl Jeff's check for (Condor) PVM
+dnl  -- Probably this should check if it really is 
+dnl     a Condor PVM library, or just a PVM library
+AC_ARG_WITH(pvm-arch, [  --with-pvm-arch              Use the given pvm architectures], PVM_ARCH=$withval)
+AC_ARG_WITH(pvm, [  --with-pvm              Use the given pvm installation path], PVM_ROOT=$withval, PVM_ROOT=no)
+if test -z "$PVM_ROOT"; then
+        AC_PATH_PROG(JUNK3, pvm)
+        if test -z "$JUNK3"; then
+                echo "-- Can't build MW without PVM, please install CondorPvm first."
+		exit 1
+        else
+                JUNK4=`dirname $JUNK3`
+                PVM_ROOT=`dirname $JUNK4`/
+                echo "-- Using PVM lib installed in $PVM_ROOT/lib/$PVM_ARCH"
+                AC_SUBST(PVM_ROOT)
+                AC_SUBST(PVM_ARCH)
+        fi
+else 
+        if test $PVM_ROOT = no
+	then
+	   echo "-- Not using PVM"
+	else
+           echo "-- Using PVM lib installed in $PVM_ROOT/lib/$PVM_ARCH"
+	fi
+fi
+
+dnl Some rudimentary stuff to setup for MPI build if required
+AC_MSG_CHECKING([for mpi-directory])
+AC_ARG_WITH(mpi, [  --with-mpi              Build the Static MPI RMComm], USE_MPI=$withval, USE_MPI=no)
+if test -z $USE_MPI
+then
+dnl Check if it is setup
+    AC_PATH_PROG(JUNK5, mpicxx) 
+    if test -z "$JUNK5"; then
+       echo "-- Can't find mpicxx, please install mpi first."
+       exit 1
+    else
+	echo "-- MPI is set to $USE_MPI"
+	echo "-- Using MPI lib $JUNK5"
+	MPICXX=mpicxx
+	AC_SUBST(MPICXX)
+	echo "-- The MPI Compiler MPICXX is set at $MPICXX"
+    fi
+    else
+    if test $USE_MPI = no
+    then
+        echo "-- Not using MPI"
+    else
+        MPICXX=mpicxx
+	AC_SUBST(MPICXX)
+	echo "-- The MPI Compiler MPICXX is set at $MPICXX" 
+    fi
+fi
+
+
+dnl Check for System and Socket	
+if opsys=`uname -s`
+then
+	echo "-- Operating system is $opsys"
+else
+	echo "-- Can't find the 'uname' program!"
+	exit 1
+fi
+
+case $opsys in
+    SunOS*)
+		SOCKET_LIB="-lnsl -lsocket " ;;
+	*)
+		SOCKET_LIB= ;;
+esac
+AC_SUBST(SOCKET_LIB)
+
+if test $opsys = "Linux" 
+then
+		echo "-- Using poll instead of select for supporting > 1024 socket workers"
+		AC_DEFINE(USE_POLL)
+		AC_SUBST(USE_POLL)
+fi
+
+dnl Check for NWS library
+dnl if nwspresence=`nm $CONDOR_DIR/lib/libcondorsyscall.a | grep callBack`
+dnl then
+dnl 	echo "-- You have fork capable condor_compile version, will check NWS."
+dnl	AC_PATH_PROG(NWS_SENSOR_PING, nws_ping)
+dnl	if test -z "$NWS_SENSOR_PING"; then
+dnl		USE_NWS=no
+dnl	else 
+dnl		USE_NWS=yes
+dnl	fi
+dnl else
+dnl	echo "-- You don't have fork capable condor_compile version, won't use NWS."
+dnl	USE_NWS=no
+dnl fi
+
+dnl Jeff changed to NOT use nws -- ever (and thus print no warning message)
+USE_NWS=no
+
+case $USE_NWS in 
+	yes*)
+		MISC_DEFN=-DNWSENABLED;
+		NWS_SENSOR_PATH=`dirname $NWS_SENSOR_PING`
+		NWS_PATH=`dirname $NWS_SENSOR_PATH`
+		MISC_LIB=$NWS_PATH/libnws
+		;;
+	*)
+		MISC_DEFN=
+		MISC_LIB=-lNWS;
+		;;
+esac
+
+AC_SUBST(MISC_DEFN)
+AC_SUBST(MISC_LIB)
+
+dnl Whether to support runtime measurement (ifdef MEASURE)
+AC_ARG_WITH(measure, [  --with-measure          Build with -DMEASURE], MEASURE_DEFN='-DMEASURE')
+AC_SUBST(MEASURE_DEFN)
+
+dnl Check for --with-independent
+dnl AC_ARG_WITH(independent, [  --with-independent      Build MW-Independent library], 
+dnl 	ENABLE_MWINDEPENDENT=yes)
+dnl We now always build independent
+ENABLE_MWINDEPENDENT=yes
+AC_SUBST(ENABLE_MWINDEPENDENT)
+
+dnl Define the MW_LIBDIR 
+MW_LIBDIR=`pwd`/lib
+AC_SUBST(MW_LIBDIR)
+MW_LIBDIR_DEBUG=`pwd`/debug_lib
+AC_SUBST(MW_LIBDIR_DEBUG)
+
+if test -d lib; then
+	echo "-- The lib directory already exists, no need to create"
+else
+	echo "-- Creating lib directory"
+	mkdir lib
+fi
+
+if test -d debug_lib; then
+	echo "-- The debug_lib directory already exists, no need to create"
+else
+	echo "-- Creating debug_lib directory"
+	mkdir debug_lib
+fi
+
+dnl Generate output files
+EXTRA_MAKEFILES=`echo "src/RMComm/MW-Independent/Makefile"`
+dnl AC_OUTPUT(Makefile src/Makefile src/RMComm/Makefile src/RMComm/MW-File/Makefile src/RMComm/MW-CondorPVM/Makefile src/RMComm/MW-Socket/Makefile src/RMComm/MW-StaticMPI/Makefile src/MWControlTasks/Makefile src/BlackBox/Makefile examples/Makefile examples/fib/Makefile examples/n-queens/Makefile examples/matmul/Makefile $EXTRA_MAKEFILES, echo timestamp > stamp-h )
+AC_OUTPUT(Makefile src/Makefile src/RMComm/Makefile src/RMComm/MW-File/Makefile src/RMComm/MW-CondorPVM/Makefile src/RMComm/MW-Socket/Makefile src/RMComm/MW-StaticMPI/Makefile src/MWControlTasks/Makefile src/BlackBox/Makefile $EXTRA_MAKEFILES, echo timestamp > stamp-h )
diff --git a/MW/doxygen.conf b/MW/doxygen.conf
new file mode 100644
index 0000000..eddb90f
--- /dev/null
+++ b/MW/doxygen.conf
@@ -0,0 +1,1117 @@
+# Doxyfile 1.3.6-20040222
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = MW
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 0.2
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, 
+# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en 
+# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, 
+# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is used 
+# as the annotated text. Otherwise, the brief description is used as-is. If left 
+# blank, the following values are used ("$name" is automatically replaced with the 
+# name of the entity): "The $name class" "The $name widget" "The $name file" 
+# "is" "provides" "specifies" "contains" "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited 
+# members of a class in the documentation of that class as if those members were 
+# ordinary class members. Constructors, destructors and assignment operators of 
+# the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources 
+# only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = src/MW.h src/MWprintf.h src/MWDriver.h src/MWDriver.C src/MWTask.h src/MWTask.C src/MWWorker.h src/MWWorker.C src/RMComm/MWRMComm.h src/RMComm/MWRMComm.h
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = examples
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = examples
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = YES
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = NO
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse the 
+# parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superseded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yields more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes that 
+# lay further from the root node will be omitted. Note that setting this option to 
+# 1 or 2 may greatly reduce the computation time needed for large code bases. Also 
+# note that a graph may be further truncated if the graph's image dimensions are 
+# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). 
+# If 0 is used for the depth value (the default), the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/MW/install-sh b/MW/install-sh
new file mode 100755
index 0000000..e9de238
--- /dev/null
+++ b/MW/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission.  M.I.T. makes no representations about the
+# suitability of this software for any purpose.  It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-d) dir_arg=true
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	-t=*) transformarg=`echo $1 | sed 's/-t=//'`
+	    shift
+	    continue;;
+
+	-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		# this colon is to work around a 386BSD /bin/sh bug
+		:
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:	no input file specified"
+	exit 1
+else
+	true
+fi
+
+if [ x"$dir_arg" != x ]; then
+	dst=$src
+	src=""
+	
+	if [ -d $dst ]; then
+		instcmd=:
+		chmodcmd=""
+	else
+		instcmd=mkdir
+	fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad 
+# if $src (and thus $dsttmp) contains '*'.
+
+	if [ -f $src -o -d $src ]
+	then
+		true
+	else
+		echo "install:  $src does not exist"
+		exit 1
+	fi
+	
+	if [ x"$dst" = x ]
+	then
+		echo "install:	no destination specified"
+		exit 1
+	else
+		true
+	fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+	if [ -d $dst ]
+	then
+		dst="$dst"/`basename $src`
+	else
+		true
+	fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+#  this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='	
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+	pathcomp="${pathcomp}${1}"
+	shift
+
+	if [ ! -d "${pathcomp}" ] ;
+        then
+		$mkdirprog "${pathcomp}"
+	else
+		true
+	fi
+
+	pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+	$doit $instcmd $dst &&
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+	if [ x"$transformarg" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		dstfile=`basename $dst $transformbasename | 
+			sed $transformarg`$transformbasename
+	fi
+
+# don't allow the sed command to completely eliminate the filename
+
+	if [ x"$dstfile" = x ] 
+	then
+		dstfile=`basename $dst`
+	else
+		true
+	fi
+
+# Make a temp file name in the proper directory.
+
+	dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+	$doit $instcmd $src $dsttmp &&
+
+	trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing.  If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+	if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+	if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+	if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+	if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+	$doit $rmcmd -f $dstdir/$dstfile &&
+	$doit $mvcmd $dsttmp $dstdir/$dstfile 
+
+fi &&
+
+
+exit 0
diff --git a/MW/missing b/MW/missing
new file mode 100644
index 0000000..e69de29
diff --git a/MW/mkinstalldirs b/MW/mkinstalldirs
new file mode 100644
index 0000000..ffce33c
--- /dev/null
+++ b/MW/mkinstalldirs
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman at prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.1.1.1 2004/02/10 22:29:30 psilord Exp $
+
+errstatus=0
+
+for file
+do
+   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+   shift
+
+   pathcomp=
+   for d
+   do
+     pathcomp="$pathcomp$d"
+     case "$pathcomp" in
+       -* ) pathcomp=./$pathcomp ;;
+     esac
+
+     if test ! -d "$pathcomp"; then
+        echo "mkdir $pathcomp"
+
+        mkdir "$pathcomp" || lasterr=$?
+
+        if test ! -d "$pathcomp"; then
+          errstatus=$lasterr
+        fi
+     fi
+
+     pathcomp="$pathcomp/"
+   done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/MW/src/BlackBox/MWDriver_blackbox.C b/MW/src/BlackBox/MWDriver_blackbox.C
new file mode 100644
index 0000000..8fb470f
--- /dev/null
+++ b/MW/src/BlackBox/MWDriver_blackbox.C
@@ -0,0 +1,92 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* These methods will be implemented to reflect the application behavior */
+
+#include "MW.h"
+#include "MWDriver_blackbox.h"
+#include "MWWorker_blackbox.h"
+#include <unistd.h>
+
+/* Statstics for how many bytes are packed (sent) and unpacked (received) */
+extern double RMCOMM_bytes_packed;
+extern double RMCOMM_bytes_unpacked;
+
+/* initialization */
+MWDriver_blackbox::MWDriver_blackbox() 
+{
+}
+
+/* destruction */
+MWDriver_blackbox::~MWDriver_blackbox() 
+{
+}
+
+/* */
+MWReturn 
+MWDriver_blackbox::pack_worker_init_data( void ) 
+{
+	string exe = get_executable();
+	list<string> l;
+	l.push_back(exe);
+
+	for (set<string>::const_iterator it = stageFiles_.begin(); 
+		 it != stageFiles_.end(); ++it) {
+		l.push_back(*it);
+	}
+
+	MWTask_blackbox::send_files(l);
+
+	
+
+	return OK;
+}
+
+/* Print out the result when MW is done. MW assume that the application 
+ * is keeping track of the results :-) */
+void 
+MWDriver_blackbox::printresults() 
+{
+	MWprintf ( 10, "BlackBox Driver Complete\n");
+}
+
+/* Return a new application task object */
+MWTask*
+MWDriver_blackbox::gimme_a_task() 
+{
+	return new MWTask_blackbox;
+}
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/BlackBox/MWDriver_blackbox.h b/MW/src/BlackBox/MWDriver_blackbox.h
new file mode 100644
index 0000000..f8e2635
--- /dev/null
+++ b/MW/src/BlackBox/MWDriver_blackbox.h
@@ -0,0 +1,77 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef _blackbox_DRIVER_H
+#define _blackbox_DRIVER_H
+
+#include "MWDriver.h"
+#include "MWTask_blackbox.h"
+
+#include <set>
+
+/** Blackbox Driver subclass derived from MWDriver */
+
+class MWDriver_blackbox : public MWDriver 
+{
+public:
+	MWDriver_blackbox();
+	~MWDriver_blackbox();
+
+	virtual MWReturn get_userinfo( int argc, char *argv[] ) = 0;
+	virtual MWReturn setup_initial_tasks( int *, MWTask *** ) = 0;
+	virtual MWReturn act_on_completed_task( MWTask * ) = 0;
+
+		// Made final here -- you pass the executable -- worker can't pack initial data.
+		//  Rather, they are allowed set set the "stage files"
+	MWReturn pack_worker_init_data( void );
+	virtual void printresults();
+	virtual void write_master_state(FILE *fp) {}
+	virtual void read_master_state(FILE *fp) {}
+
+	void add_staged_file(const string &s) { stageFiles_.insert(s); }
+	string get_executable() const { return theExecutable_; }
+	void set_executable(const string &s) { theExecutable_ = s; }
+	MWTask* gimme_a_task();
+
+private: 
+	string theExecutable_;
+	std::set<string> stageFiles_;
+	
+};
+
+#endif
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq c-tab-always-indent nil)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/BlackBox/MWTask_blackbox.C b/MW/src/BlackBox/MWTask_blackbox.C
new file mode 100644
index 0000000..3d9dd0a
--- /dev/null
+++ b/MW/src/BlackBox/MWTask_blackbox.C
@@ -0,0 +1,247 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWTask_blackbox.h"
+#include "MW.h"
+#include <fstream>
+
+/* init */
+MWTask_blackbox::MWTask_blackbox() 
+{
+}
+
+
+MWTask_blackbox::MWTask_blackbox(const list<string> &args,
+								 const list<string> &input_files,
+								 const list<string> &output_files)
+{
+	this->args_ = args;
+	this->input_files_ = input_files;
+	this->output_files_ = output_files;
+}
+
+
+/* destruction */
+MWTask_blackbox::~MWTask_blackbox() {
+}
+
+/* print the task to stdout */
+void
+MWTask_blackbox::printself( int level ) 
+{
+	printList( level, "args: ", args_);
+	printList( level, "inputs: ", input_files_);
+	printList( level, "outputs: ", output_files_);
+}
+
+void
+MWTask_blackbox::printList(int level, char *prefix, list<string>& l) {
+	MWprintf(level, "%s", prefix);
+	for (list<string>::iterator it = l.begin();	
+		 it != l.end();
+		 it++) {
+		MWprintf(level, "%s ", (*it).c_str());
+	}
+	MWprintf (level, "\n");
+}
+
+/* The driver packs the input data via RMC, the data which will be sent to a worker. */
+void 
+MWTask_blackbox::pack_work( void ) 
+{
+	int size = args_.size();
+
+	RMC->pack(&size, 1);
+	MWprintf(30, "MWTask::pack_work packed arg size of %d\n", size);
+	for (list<string>::iterator it = args_.begin();
+		 it != args_.end();
+		 it++) {
+		RMC->pack((char *)(*it).c_str());
+	}
+	MWprintf(30, "MWTask::pack_work packing input files\n");
+	send_files(input_files_);
+
+	int num_output_files = output_files_.size();
+	RMC->pack(&num_output_files, 1);
+	for (list<string>::iterator it = output_files_.begin();
+		 it != output_files_.end();
+		 it++) {
+		RMC->pack((char *)(*it).c_str());
+	}
+}
+
+/* The worker unpacks input data via RMC, need to allocate space for data */
+void 
+MWTask_blackbox::unpack_work( void ) 
+{
+	args_.clear();
+	int size;
+	RMC->unpack(&size, 1);
+	MWprintf(30,"MWTask::unpack_work unpacked arg size of %d\n", size);
+	while (size--) {
+		char str[8096];
+		RMC->unpack(str);
+		args_.push_back(str);
+	}
+	MWprintf(30, "MWTask::pack_work unpacking input files\n");
+	recv_files(input_files_);
+
+	int num_output_files = 0;
+	output_files_.clear();
+	RMC->unpack(&num_output_files, 1);
+	while (num_output_files--) {
+		char str[8096];
+		RMC->unpack(str);
+		output_files_.push_back(str);
+	}
+}
+
+/* The worker packs result data via RMC, the result will be sent back to driver */
+void 
+MWTask_blackbox::pack_results( void ) 
+{
+	RMC->pack(&retVal_, 1);
+	send_files(output_files_);
+	remove("stdout");
+	remove("stderr");
+}
+
+/* The driver unpacks result data via RMC */
+void 
+MWTask_blackbox::unpack_results( void ) 
+{
+	RMC->unpack(&retVal_, 1);
+	recv_files(output_files_);
+}
+
+/* write checkpoint info per task, for each task haven't been finished */
+void 
+MWTask_blackbox::write_ckpt_info( FILE *fp ) 
+{
+  //list<string> args_;
+  //list<string> input_files_;
+  //list<string> output_files_;
+  //int retVal_;
+
+  fprintf(fp, "%d\n", retVal_);
+  saveStringList(fp, args_);
+  saveStringList(fp, input_files_);
+  saveStringList(fp, output_files_);
+}
+
+/* Read checkpoint info, in the order written into the file */
+void 
+MWTask_blackbox::read_ckpt_info( FILE *fp ) 
+{
+  fscanf(fp, "%d", &retVal_);
+  restoreStringList(fp, args_);
+  restoreStringList(fp, input_files_);
+  restoreStringList(fp, output_files_);
+}
+
+
+void 
+MWTask_blackbox::send_files(list<string> &files) {
+	int num_files = files.size();
+	RMC->pack(&num_files, 1);
+	for (list<string>::iterator i = files.begin(); i != files.end(); i++) {
+		const char *file_name = i->c_str();
+
+		fstream file(file_name);
+		file.seekg(0, ios::end);
+		size_t file_size = file.tellg();
+
+			// If file doesn't exist, force file_size to 0
+		if (file_size == (size_t) -1) {
+			file_size = 0;
+		}
+
+		char *b = new char[file_size];
+		file.seekg(0, ios::beg);
+		file.read(b, file_size);
+
+		RMC->pack((char *)file_name); 
+		RMC->pack(&file_size, 1, 1);
+		RMC->pack(b, file_size, 1);
+
+		delete [] b;
+		MWprintf(30, "packed file named %s of length %d\n", i->c_str(), file_size);
+	}
+}
+
+void 
+MWTask_blackbox::recv_files(list<string> &files) {
+	int num_files;
+	RMC->unpack(&num_files, 1);
+	for ( int i = 0; i < num_files; i++) {
+		char file_name[4096];
+		int file_size;
+
+		RMC->unpack(file_name);
+		RMC->unpack(&file_size, 1);
+		MWprintf(30, "unpacked file named %s of size %d\n", file_name, file_size);
+		
+		ofstream file(file_name);
+		char *b = new char[file_size];
+		RMC->unpack(b, file_size, 1);
+		file.write(b, file_size);
+		delete [] b;
+
+		files.push_back(string(file_name));
+	}
+}
+
+void
+MWTask_blackbox::saveStringList(FILE *fp, list<string> &sl) {
+	fprintf(fp, "%d\n", sl.size());
+	for (list<string>::iterator i = sl.begin(); i != sl.end(); i++) {
+		const char *name = i->c_str();
+		fprintf(fp, "%s\n", name);
+	}
+}
+
+void
+MWTask_blackbox::restoreStringList(FILE *fp, list<string> &sl) {
+	int size = 0;
+	fscanf(fp, "%d", &size);
+	while (size--) {
+		char name[4096];
+		fscanf(fp, "%s", name);
+		sl.push_back(string(name));
+	}
+}
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/BlackBox/MWTask_blackbox.h b/MW/src/BlackBox/MWTask_blackbox.h
new file mode 100644
index 0000000..2b548b1
--- /dev/null
+++ b/MW/src/BlackBox/MWTask_blackbox.h
@@ -0,0 +1,95 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef _blackbox_TASK_H
+#define _blackbox_TASK_H
+
+#include "MWTask.h"
+
+using namespace std;
+
+#include <string>
+#include <list>
+
+class MWTask_blackbox : public MWTask 
+{
+public:
+	/* constructors */
+  MWTask_blackbox();
+  MWTask_blackbox(const list<string> &args,
+		  const list<string> &input_files,
+		  const list<string> &output_files);
+  
+  /* destructor */
+  virtual ~MWTask_blackbox();
+
+	const std::list<string> & getArgs() const { return args_; }
+	const std::list<string> & getInputFiles() const { return input_files_; }
+	const std::list<string> & getOutputFiles() const { return output_files_; }
+
+	int getReturnVal() const { return retVal_; }
+	void setReturnVal(int rv){ retVal_ = rv; }
+  
+  /* App is required to implement the following functions. */
+  void pack_work( void );
+  void unpack_work( void );
+  void pack_results( void );
+  void unpack_results( void );
+  
+  /* The following functions have default implementation. */
+  void printself( int level = 70 );
+  void printList(int level, char *prefix, list<string>& l);
+  void write_ckpt_info( FILE *fp );
+  void read_ckpt_info( FILE *fp );
+
+  /* The application specific information goes here */
+  static void send_files(list<string> &files);
+  static void recv_files(list<string> &files);
+	
+  static void saveStringList(FILE *fp, list<string> &sl);
+  static void restoreStringList(FILE *fp, list<string> &sl);
+
+protected:  
+  list<string> args_;
+  list<string> input_files_;
+  list<string> output_files_;
+  int retVal_;
+};
+
+#endif
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq c-tab-always-indent nil)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/BlackBox/MWWorkerMain_blackbox.C b/MW/src/BlackBox/MWWorkerMain_blackbox.C
new file mode 100644
index 0000000..e6b7a5a
--- /dev/null
+++ b/MW/src/BlackBox/MWWorkerMain_blackbox.C
@@ -0,0 +1,57 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* The main() of worker executable. Simply instantiate a Worker_blackbox 
+ * class and go()!  */
+
+#include "MW.h"
+#include "MWWorker_blackbox.h"
+
+int main(int argc, char *argv[]) 
+{
+		/* init a worker object */
+	MWWorker_blackbox graduate_student;
+
+		/* How much information you want the workers to print */
+	set_MWprintf_level ( 75 );
+	MWprintf ( 10, "A worker is starting.\n" );
+
+		/* Go ! */ 
+	graduate_student.go(argc, argv);
+	return 0;
+}
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/BlackBox/MWWorker_blackbox.C b/MW/src/BlackBox/MWWorker_blackbox.C
new file mode 100644
index 0000000..d52065e
--- /dev/null
+++ b/MW/src/BlackBox/MWWorker_blackbox.C
@@ -0,0 +1,138 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWWorker_blackbox.h"
+#include "MWTask_blackbox.h"
+
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* init */
+MWWorker_blackbox::MWWorker_blackbox() 
+{
+  workingTask = new MWTask_blackbox;
+}
+
+/* destruct */
+MWWorker_blackbox::~MWWorker_blackbox() 
+{
+    delete workingTask;
+}
+
+/* Do benchmark and return result (usually the time to task t), t is supposed
+ * to be a benchmark task.  In this app, it just send back a PI. */
+double
+MWWorker_blackbox::benchmark( MWTask *t ) 
+{
+        MWTask_blackbox *bb = dynamic_cast<MWTask_blackbox *> ( t );
+		bb->printself(30);
+        return 1.0;
+}
+
+/* unpack the init data from the driver */
+MWReturn 
+MWWorker_blackbox::unpack_init_data( void ) 
+{
+		// Get the executable
+	list<string> l;
+	MWTask_blackbox::recv_files(l);
+	MWprintf(10, "Worker_blackbox got %d files\n", l.size());
+	if (l.size() < 1) {
+	  MWprintf(1, "Warning!?!  Where is your executable!?!?!\n");
+	}
+	else {
+	   list<string>::const_iterator i = l.begin();
+	   const char *c = i->c_str();	
+	   executable_ = *i;
+	   MWprintf(20, "marking worker executable %s as 0755\n", c);
+	   ::chmod(c, 0755);  // and make it executable
+	}
+	return OK;
+}
+
+/* Execute each task */
+void 
+MWWorker_blackbox::execute_task( MWTask *t ) 
+{
+	int retVal;
+	
+	MWprintf(30, "Enter Worker_blackbox::execute_task\n");
+	MWTask_blackbox *bb = dynamic_cast<MWTask_blackbox *> ( t );
+	
+	MWprintf(40, "     task is \n");
+	bb->printself(40);
+
+	const list<string>& args = bb->getArgs();
+	int argc = args.size() + 2;
+
+	char **argv = (char **)malloc( sizeof(char *) * argc);
+	
+	int index = 0;
+	argv[index] = (char *) executable_.c_str();
+	index++;
+
+	for (list<string>::const_iterator i = args.begin(); i != args.end(); i++) {
+		argv[index] = (char *) (*i).c_str();
+		MWprintf(50, "execute_task:: argv[%d] is %s\n", index, argv[index]);
+		index++;
+	}
+	argv[index] = 0;
+
+	int pid = fork();
+	if (pid == 0) {
+			// Child
+
+			// make stdout to to the file named "stdout"
+		close(1);
+		close(2);
+		
+		open("stdout", O_CREAT | O_TRUNC);
+		open("stderr", O_CREAT | O_TRUNC);
+
+		execve(argv[0], argv, 0);
+		MWprintf(10, "execute_task failed to exec %s errno = %d (%s)\n",	
+				 argv[0], errno, strerror(errno));
+
+		exit(-1);
+	} 
+
+	::waitpid(pid, &retVal, 0);
+	bb->setReturnVal(retVal);
+	MWprintf(30, "Leave Worker_blackbox::execute_task retVal was %d\n", retVal);
+}
+
+MWTask* 
+MWWorker_blackbox::gimme_a_task()
+{
+	return new MWTask_blackbox;
+}
+
+/* Just return a newly created application worker object */
+MWWorker*
+gimme_a_worker ()
+{
+       	return new MWWorker_blackbox;
+}
diff --git a/MW/src/BlackBox/MWWorker_blackbox.h b/MW/src/BlackBox/MWWorker_blackbox.h
new file mode 100644
index 0000000..c76e991
--- /dev/null
+++ b/MW/src/BlackBox/MWWorker_blackbox.h
@@ -0,0 +1,49 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef _blackbox_WORKER_H
+#define _blackbox_WORKER_H
+
+#include "MWWorker.h"
+#include "MWTask_blackbox.h"
+
+class MWWorker_blackbox : public MWWorker 
+{
+public:
+       	MWWorker_blackbox();
+       	~MWWorker_blackbox();
+
+	/* Benchmarking */
+	double benchmark( MWTask *t );
+
+	/* unpack init data */    
+	MWReturn unpack_init_data( void );
+
+	/* do the real work for each task */
+	void execute_task( MWTask * );
+
+	MWTask* gimme_a_task();
+
+private:
+  string executable_;
+};
+#endif
diff --git a/MW/src/BlackBox/Makefile.in b/MW/src/BlackBox/Makefile.in
new file mode 100644
index 0000000..3afbdb1
--- /dev/null
+++ b/MW/src/BlackBox/Makefile.in
@@ -0,0 +1,181 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+ENABLE_MWINDEPENDENT = @ENABLE_MWINDEPENDENT@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+MW_BASICLIB = -lMW -lMWRMComm -lMWutil -lNWS  $(SOCKET_LIB)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS =  
+
+# Make independent?
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+LIBRARIES = libMWblackbox_indp.a libMWblackbox.a
+else 
+LIBRARIES = libMWblackbox.a
+endif
+
+# If building without Condor, you need not build the worker executable
+EXECUTABLES := 
+ifeq ($(CONDOR_DIR), no)
+EXECUTABLES := 
+else
+EXECUTABLES = worker_blackbox_socket
+endif
+
+
+libMWblackbox_a_SOURCES = MWDriver_blackbox.C MWTask_blackbox.C
+libMWblackbox_a_OBJECTS = MWDriver_blackbox.o MWTask_blackbox.o
+
+libMWblackbox_indp_a_SOURCES = MWWorker_blackbox.C
+libMWblackbox_indp_a_OBJECTS = MWWorker_blackbox.o
+
+worker_blackbox_socket_SOURCES = MWWorker_blackbox.C MWTask_blackbox.C MWWorkerMain_blackbox.C
+worker_blackbox_socket_OBJECTS =  MWWorker_blackbox.o MWTask_blackbox.o MWWorkerMain_blackbox.o
+worker_blackbox_socket_LDADD = -L$(MW_LIBDIR) $(MW_BASICLIB) -lMWsocketworker
+worker_blackbox_socket_DEPENDENCIES =
+worker_blackbox_socket_LDFLAGS =
+
+
+
+INCLUDES = -I. -I.. -I../RMComm
+INCLUDEFILES = MWDriver_blackbox.h MWTask_blackbox.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES) $(EXECUTABLES)
+
+libMWblackbox.a: $(libMWblackbox_a_OBJECTS)
+	-rm -f libMWblackbox.a
+	$(AR) cru libMWblackbox.a $(libMWblackbox_a_OBJECTS)
+	$(RANLIB) libMWblackbox.a
+#	cp libMWblackbox.a $(MW_LIBDIR) 
+
+libMWblackbox_indp.a: $(libMWblackbox_indp_a_OBJECTS)
+	-rm -f libMWblackbox_indp.a
+	$(AR) cru libMWblackbox_indp.a $(libMWblackbox_indp_a_OBJECTS)
+	$(RANLIB) libMWblackbox_indp.a
+#	cp libMWblackbox.a $(MW_LIBDIR) 
+
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+libMWblackbox_indp.a: $(libMWblackbox_indp_a_OBJECTS)
+	-rm -f libMWblackbox_indp.a
+	$(AR) cru libMWblackbox_indp.a $(libMWblackbox_indp_a_OBJECTS)
+	$(RANLIB) libMWblackbox_indp.a
+# Install should copy lib file, no?
+#	cp libMWblackbox.a $(MW_LIBDIR) 
+endif
+
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+worker_blackbox_indp: $(worker_blackbox_indp_OBJECTS)
+	$(CXXLINK) $(worker_blackbox_indp_LDFLAGS) $(worker_blackbox_indp_OBJECTS) $(worker_blackbox_indp_LDADD) $(LIBS)	
+endif
+
+# This just builds your worker executable...
+worker_blackbox_socket: $(worker_blackbox_socket_OBJECTS) $(worker_blackbox_socket_DEPENDENCIES)
+	@rm -f worker_blackbox_socket
+	$(CXXLINK) $(worker_blackbox_socket_LDFLAGS) $(worker_blackbox_socket_OBJECTS) $(worker_blackbox_socket_LDADD) $(LIBS)
+
+# (Probably need better handling of dependencies?)
+MWDriver_blackbox.o: MWDriver_blackbox.C MWDriver_blackbox.h MWTask_blackbox.h
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $< -o $@
+
+MWTask_blackbox.o: MWTask_blackbox.C MWTask_blackbox.h
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $< -o $@
+
+# (Probably need better handling of dependencies?)
+MWDriver_blackbox_indp.o: MWDriver_blackbox.C MWDriver_blackbox.h MWTask_blackbox.h
+	$(CXX) -c -DINDEPENDENT $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $< -o $@
+
+MWTask_blackbox_indp.o: MWTask_blackbox.C MWTask_blackbox.h
+	$(CXX) -c -DINDEPENDENT $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $< -o $@
+
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $< -o $@
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/MW/src/MW.C b/MW/src/MW.C
new file mode 100644
index 0000000..f313790
--- /dev/null
+++ b/MW/src/MW.C
@@ -0,0 +1,24 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MW.h"
+
diff --git a/MW/src/MW.h b/MW/src/MW.h
new file mode 100644
index 0000000..64092cf
--- /dev/null
+++ b/MW/src/MW.h
@@ -0,0 +1,136 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MW_H
+#define MW_H
+
+
+#include "MWprintf.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <float.h>
+
+/// FALSE is defined as 0
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/// TRUE is defined as 1
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/// UNDEFINED is defined as -1
+#ifndef UNDEFINED
+#define UNDEFINED -1
+#endif
+
+/** An upper limit on the number of workers -- so we can allocated arrays
+    to keep statistics */
+const int MW_MAX_WORKERS = 8192;
+
+/**@name Introduction.
+
+   MW is a class library that can be a useful tool for building
+   opportunistic, fault-tolerant applications for high throughput
+   computing.  
+
+   In order to build an application, there are three classes
+   that the user {\rm must} rederive.
+
+   \begin{itemize}
+   \item \Ref{MWDriver}
+   \item \Ref{MWWorker}
+   \item \Ref{MWTask}
+   \end{itemize}
+
+   The documentation of these classes includes a description 
+   of the pure virtual methods that must be implemented for 
+   a user's particular application.
+
+   Using the MW library allows the user to focus on the application
+   specific implementation at hand.  All details related to
+   being fault tolerant and opportunistic are implemented in the
+   MW library.
+
+   Also included is a small, naive, example of how to create
+   an application with the MW class library.  The three classes
+
+   \begin{itemize}
+   \item \Ref{Driver_Fib}
+   \item \Ref{Worker_Fib}
+   \item \Ref{Task_Fib}
+   \end{itemize}
+   
+   are concrete classes derived from MW's abstract classes.  
+   Using these classes, a simple program that makes a lot of 
+   fibonacci sequences is created.
+
+ */
+
+/**
+   A list of the message tags that the Master-Worker application
+   will send and receive.  See the switch statement in master_mainloop 
+   for more information.
+ */
+
+enum MWmessages{
+  HOSTADD = 33,
+  HOSTDELETE,   
+  HOSTSUSPEND, 
+  HOSTRESUME, 
+  TASKEXIT,   
+  DO_THIS_WORK, 
+  RESULTS,      
+  INIT,         
+  INIT_REPLY,   
+  BENCH_RESULTS,
+  KILL_YOURSELF,
+  CHECKSUM_ERROR,
+  RE_INIT,
+  REFRESH,
+  SUBRESULTS,
+  /* added for async message: */
+  UPDATE_FROM_WORKER, /* worker send to driver a update message */
+  UPDATE_FROM_DRIVER,  /* driver send to worker a new message */
+  NO_MESSAGE,
+  STOP_WORK 
+};
+
+/** Possible return values from many virtual functions */
+enum MWReturn {
+		/// Normal return
+	OK, 
+		/// We want to exit, not an error.
+	QUIT, 
+		/// We want to exit immediately; a bad error ocurred
+	ABORT,
+		/// by jae
+		/// Some job is still running
+	PENDING
+};
+
+typedef enum { MWNORMAL, MWNWS, MWNUMTASKTYPES } MWTaskType;
+
+#endif
diff --git a/MW/src/MWControlTasks/MWNWSTask.C b/MW/src/MWControlTasks/MWNWSTask.C
new file mode 100644
index 0000000..65d40e4
--- /dev/null
+++ b/MW/src/MWControlTasks/MWNWSTask.C
@@ -0,0 +1,229 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MW.h"
+#include "MWNWSTask.h"
+#include "MWSystem.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <unistd.h>
+#include <errno.h>
+#include <strings.h>
+
+
+MWNWSTask::MWNWSTask ( int nu, double interval, int length, int port, char *addr )
+{
+	taskType = MWNWS;
+	timeInterval = interval;
+	iterations = length;
+	min = max = median = -1;
+	portNo = port;
+	number = nu;
+	strcpy ( machineAddress, addr );
+}
+
+MWNWSTask::MWNWSTask ( )
+{
+	taskType = MWNWS;
+	min = max = median = -1;
+	portNo = 7;
+	number = -1;
+}
+
+MWNWSTask::~MWNWSTask()
+{
+}
+
+void 
+MWNWSTask::pack_work( void )
+{
+	RMC->pack ( &timeInterval, 1, 1 );
+	RMC->pack ( &iterations, 1, 1 );
+	RMC->pack ( &portNo, 1, 1 );
+	RMC->pack ( machineAddress );
+}
+
+void 
+MWNWSTask::unpack_work( void )
+{
+	RMC->unpack ( &timeInterval, 1, 1 );
+	RMC->unpack ( &iterations, 1, 1 );
+	RMC->unpack ( &portNo, 1, 1 );
+	RMC->unpack ( machineAddress );
+}
+
+void 
+MWNWSTask::pack_results( void )
+{
+	RMC->pack ( &max, 1, 1 );
+	RMC->pack ( &min, 1, 1 );
+	RMC->pack ( &median, 1, 1 );
+}
+    
+void 
+MWNWSTask::unpack_results( void )
+{
+	double temp;
+	MWprintf ( 10, "NWS Unpacking results\n");
+	RMC->unpack ( &temp, 1, 1 );
+	MWprintf ( 10, "%f\n", temp );
+	max = temp;
+	RMC->unpack ( &min, 1, 1 );
+	RMC->unpack ( &median, 1, 1 );
+}
+
+void 
+MWNWSTask::pack_subresults( int )
+{
+}
+    
+void 
+MWNWSTask::unpack_subresults( int )
+{
+}
+
+void 
+MWNWSTask::printself(int level)
+{
+	MWprintf ( level, "Interval:%f Iterations:%d PortNum:%d \n", timeInterval, 
+								iterations, portNo );
+	if ( max > 0 )
+		MWprintf ( level, "results:- min:%f max:%f median:%f\n",
+						min, max, median );
+}
+
+void 
+MWNWSTask::write_ckpt_info( FILE *fp )
+{
+	fprintf ( fp, "%f %d ", timeInterval, iterations );
+	if ( max >= 0 )
+		fprintf ( fp, "%f %f %f", max, min, median );
+	else
+		fprintf ( fp, "-1 " );
+}
+
+void 
+MWNWSTask::read_ckpt_info( FILE *fp )
+{
+	fscanf ( fp, "%lf %d ", &timeInterval, &iterations );
+	fscanf ( fp, "%lf ", &max );
+	if ( max >= 0 )
+		fscanf ( fp, "%lf %lf ", &min, &median );
+}
+
+void
+NWSControlTask ( MWTask *task )
+{
+	int listenFd;
+	struct sockaddr_in servaddr;
+	struct sockaddr_in cliaddr;
+	MWNWSTask *nwsTask = (MWNWSTask *)task;
+	char sendData = 'a';
+	char recvData;
+	double startTime, endTime;
+	double tempStart, tempEnd;
+	int cc;
+	int iter = 0;
+	int temp;
+
+	MWprintf (10, "In NWSControlTask\n");
+	
+	listenFd = socket( AF_INET, SOCK_DGRAM, 0);
+	if ( listenFd < 0 )
+	{
+		MWprintf( 10, "TCP socket creation error. %d\n", errno);
+		::exit(1);
+	}
+
+	bzero( &cliaddr, sizeof(cliaddr));
+	cliaddr.sin_family = AF_INET;
+	cliaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+	cliaddr.sin_port = htons(0);
+
+
+	if ( bind( listenFd, (struct sockaddr *) &cliaddr, sizeof(cliaddr)) < 0)
+	{
+		MWprintf( 10, "TCP socket bind error %d.\n", errno);
+		::exit(2);
+	}
+  
+	bzero( &servaddr, sizeof(servaddr));
+	servaddr.sin_family = AF_INET;
+	servaddr.sin_addr.s_addr = inet_addr( nwsTask->machineAddress);
+	servaddr.sin_port = htons(nwsTask->portNo);
+
+	startTime = MWSystem::gettimeofday();
+	nwsTask->min = -1;
+	nwsTask->max = -1;
+	nwsTask->median = -1;
+	do
+	{
+		tempStart = MWSystem::gettimeofday();
+		cc = sendto ( listenFd, &sendData, 1, 0, (struct sockaddr *)&servaddr, sizeof(servaddr) );
+		if ( cc < 0 )
+		{
+			MWprintf ( 10, "Could not sendto %d\n", errno);
+			// XXX Instead of 
+			// 	::exit(4);
+			// which will cause a worker goes down (because the master's portNo is not open.
+			// 
+			// We probably just need to ignore the error. 
+			
+		}
+
+		temp = sizeof(servaddr);	// XXX Added because error when checkpointing
+		cc = recvfrom ( listenFd, &recvData, 1, 0, (struct sockaddr *)&servaddr,
+						(socklen_t *)&temp);
+		if ( cc < 0 )
+		{
+			MWprintf ( 10, "Could not recvfrom %d\n", errno);
+			// XXX Instead of 
+			// 	::exit(5);
+			// which will cause a worker goes down (because the master's portNo is not open.
+			// 
+			// We probably just need to ignore the error. 
+		}
+		tempEnd = MWSystem::gettimeofday();
+		iter++;
+
+		if ( nwsTask->min < 0 || tempEnd - tempStart < nwsTask->min )
+			nwsTask->min = tempEnd - tempStart;
+		if ( nwsTask->max < 0 || tempEnd - tempStart > nwsTask->max )
+			nwsTask->max = tempEnd - tempStart;
+	} while ( iter < nwsTask->iterations );
+
+	endTime = MWSystem::gettimeofday();
+	nwsTask->median = ( endTime - startTime ) / nwsTask->iterations;
+
+	close(listenFd);
+}
+
+MWTask*
+NWSNewTask ( )
+{
+	return new MWNWSTask ( );
+}
diff --git a/MW/src/MWControlTasks/MWNWSTask.h b/MW/src/MWControlTasks/MWNWSTask.h
new file mode 100644
index 0000000..7aee838
--- /dev/null
+++ b/MW/src/MWControlTasks/MWNWSTask.h
@@ -0,0 +1,110 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWNWSTASK_H
+#define MWNWSTASK_H
+
+#include <stdio.h>
+#include "MWTask.h"
+
+/** The task class specific to NWS weather monitoring
+*/
+
+class MWNWSTask : public MWTask {
+
+ public:
+    
+    /// Default Constructor
+    MWNWSTask();
+
+    /** 
+    */
+    MWNWSTask( int, double, int, int, char* );
+
+    MWNWSTask( const MWNWSTask& );
+
+    /// Default Destructor
+    ~MWNWSTask();
+
+    MWNWSTask& operator = ( const MWNWSTask& );
+
+    /**@name Implemented methods
+       
+       These are the task methods that must be implemented 
+       in order to create an application.
+    */
+    //@{
+    /// Pack the work for this task into the PVM buffer
+    void pack_work( void );
+    
+    /// Unpack the work for this task from the PVM buffer
+    void unpack_work( void );
+    
+    /// Pack the results from this task into the PVM buffer
+    void pack_results( void );
+    
+    /// Unpack the results from this task into the PVM buffer
+    void unpack_results( void );
+    //@}
+
+	// not used in this class
+    void pack_subresults( int );
+    void unpack_subresults( int );   
+
+        /// dump self to screen:
+    void printself( int level = 60 );
+
+    /**@name Checkpointing Implementation 
+       These members used when checkpointing. */
+    //@{
+        /// Write state
+    void write_ckpt_info( FILE *fp );
+        /// Read state
+    void read_ckpt_info( FILE *fp );
+    //@}
+
+    /**@name Input Parameters.
+       These parameters are sent to the other side */
+    //@{
+    	/// the number of measurements.
+    int iterations;
+	/// the interval between measurements
+    double timeInterval;
+    	/// the port to connect to.
+    int portNo;
+    	/// the machine name.
+    char machineAddress[1024];
+    //@}
+
+    /**@name Output Parameters.
+       These parameters are returned by the workers */
+    //@{
+    	/// the maximum latency observed.
+    double max;
+    	/// the minimum latency observed.
+    double min ;
+    	/// the median latency observed.
+    double median ;
+    //@}
+};
+
+#endif
diff --git a/MW/src/MWControlTasks/Makefile.in b/MW/src/MWControlTasks/Makefile.in
new file mode 100644
index 0000000..57953ad
--- /dev/null
+++ b/MW/src/MWControlTasks/Makefile.in
@@ -0,0 +1,133 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+DOCXX = @DOCXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+ENABLE_MWINDEPENDENT = @ENABLE_MWINDEPENDENT@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# Subdirectories
+SUBDIRS = 
+
+### Libraries to be built, and dependent source files
+# If ENDABLE_INDEPENDENT is yes (you can do that by configure --with-independent). 
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+LIBRARIES = libNWS.a libNWS_indp.a
+else 
+LIBRARIES = libNWS.a
+endif
+
+libNWS_a_SOURCES = MWNWSTask.C
+libNWS_a_OBJECTS =  MWNWSTask.o
+libNWS_indp_a_OBJECTS = MWNWSTaskInd.o
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+INCLUDES = -I. -I.. -I../RMComm -I../RMComm/MW-File -I../RMComm/MW-CondorPVM -I../RMComm/MW-Socket $(MISC_DEFN) $(MEASURE_DEFN)
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+INDP_CXXCOMPILE = $(CXXCOMPILE) -DINDEPENDENT
+
+INCLUDEFILES = MWNWSTask.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+libNWS.a: $(libNWS_a_OBJECTS) $(libNWS_a_DEPENDENCIES)
+	-rm -f libNWS.a
+	$(AR) cru libNWS.a $(libNWS_a_OBJECTS) $(libNWS_a_LIBADD)
+	$(RANLIB) libNWS.a
+	cp libNWS.a $(MW_LIBDIR)
+
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+libNWS_indp.a: $(libNWS_indp_a_OBJECTS)
+	-rm -f libNWS_indp.a
+	$(AR) cru libNWS_indp.a $(libNWS_indp_a_OBJECTS)
+	$(RANLIB) libNWS_indp.a
+	cp libNWS_indp.a $(MW_LIBDIR)
+MWNWSTaskInd.o:MWNWSTask.C
+	$(INDP_CXXCOMPILE) -o MWNWSTaskInd.o -c MWNWSTask.C
+endif
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a core
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a core
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/MW/src/MWDriver.C b/MW/src/MWDriver.C
new file mode 100644
index 0000000..57f1cfa
--- /dev/null
+++ b/MW/src/MWDriver.C
@@ -0,0 +1,4517 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#include <cassert>
+#include <cerrno>
+#include <cstdarg>
+#include <cstdlib>
+#include <ctime>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+//by jae
+#include <pthread.h>
+#include <sys/time.h>
+
+#include "MW.h"
+#include "MWDriver.h"
+#include "MWWorkerID.h"
+#include "MWWorker.h"
+#include "MWTask.h"
+#include "MWGroup.h"
+#include "MWSystem.h"
+
+#ifndef NWSENABLED
+#include "MWNWSTask.h"
+#endif
+
+/* 8/28/00
+   Qun Chen wrote signal handling code that Michael likes.
+   We add it here */
+
+#include <setjmp.h>
+
+void statsgather ( MWList<MWWorkerID>* workers, MWStatistics * st );
+MWTask * first_task_in_group(MWList<MWTask> * tasks, MWGroup * grp);
+
+/// Indication of how many workers in each group.
+int MWworkClasses = 0;
+int *MWworkClassWorkers;
+int *MWworkClassTasks;
+MWWorkerID *MWcurrentWorker;
+
+
+//by jae
+pthread_mutex_t global_mw_mutex = PTHREAD_MUTEX_INITIALIZER;
+int num_completed_tasks = 0;
+// Signal code not used now
+// jmp_buf env; 
+// static void signal_handler(int sig){
+  
+//   switch ( sig ){
+//   case SIGINT:       /* process for interrupt */
+//     longjmp(env,sig);
+//     /* break never reached */
+//   case SIGCONT:     /* process for alarm */
+//     longjmp(env,sig);
+//     /* break never reached */
+//   default:        exit(sig);
+//   }
+  
+//   return;
+// }
+/* end Qun */
+
+MWDriver::MWDriver() 
+{
+	stats = new MWStatistics();
+	workers = new MWList<MWWorkerID>("workers");
+	todo = new MWList<MWTask>("TODO_tasks");
+	running = new MWList<MWTask>("running_tasks");
+
+		/* Task_Swap */
+	has_task_swapped = false;
+	max_task_key = DBL_MAX;
+	
+		/* XXX DEBUG value for swap for ATR */
+	MIN_IN_MEM = 256;    			/* == 256            */
+	MAX_IN_MEM = MIN_IN_MEM * 800;   	/* == MIN_IN_MEM*800 */
+	NUM_IN_MEM_LO = MIN_IN_MEM * 8; 	/* == MIN_IN_MEM*8   */
+	NUM_IN_MEM_HI = MIN_IN_MEM * 100; 	/* == MIN_IN_MEM*100 */
+
+		// XXX reassigned
+	reassigned_tasks = new MWList<int>();
+	reassigned_tasks_done = new MWList<int>();
+	normal_tasks_all_done = false;
+    
+	task_counter = 0;
+    
+	checkpoint_frequency = 0;
+	checkpoint_time_freq = 0;
+	next_ckpt_time = 0;
+	bench_task = NULL;
+
+		// These are for list management
+	addmode = ADD_AT_END;
+	getmode = GET_FROM_BEGIN;
+	machine_ordering_policy = NO_ORDER;
+	listsorted = false;
+	task_key = NULL;
+	worker_key = NULL;
+
+	ckpt_filename = "checkpoint";
+
+	suspensionPolicy = DEFAULT;
+  
+	worker_timeout = false;
+	worker_timeout_limit = 0.0;
+	worker_timeout_check_frequency = 0;
+	next_worker_timeout_check = 0;
+
+	defaultTimeInterval = 10;
+	defaultIterations = 5;
+	defaultPortNo = 7;
+
+	MWworkClasses = 0;
+	MWworkClassWorkers = NULL;
+	MWworkClassTasks = NULL;
+	MWcurrentWorker = NULL;
+
+#if defined( XML_OUTPUT )
+  
+	xml_menus_filename = "menus";
+	xml_jobinfo_filename = "job_info";
+	xml_pbdescrib_filename = "pbdescrib";
+	xml_filename = "/u/m/e/metaneos/public/html/iMW/status.xml";
+
+	CondorLoadAvg = NO_VAL;
+	LoadAvg = NO_VAL;
+	Memory = NO_VAL;
+	Cpus = NO_VAL;
+	VirtualMemory = NO_VAL;
+	Disk = NO_VAL;
+	KFlops = NO_VAL;
+	Mips = NO_VAL;
+
+	memset(OpSys, 0, sizeof(OpSys)); 
+	memset(Arch, 0 , sizeof(Arch)); 
+	memset(mach_name, 0 , sizeof(mach_name)); 
+
+	get_machine_info();
+#endif    
+
+	normal_tasks_all_done = false;
+
+#ifdef MEASURE
+	strcpy(_measure_opt_file_name, "_measure_opt");
+	strcpy(_measure_rec_fname_prefix, "_measure_rec");
+	strcpy(_measure_ProcID_prefix, "_ProcID.");
+	_measure_read_opt_interval = 1200;
+	_measure_dump_rec_interval = 10;
+	_measure_use_adaptation = 0;
+	_measure_read_options(_measure_opt_file_name);
+#endif //MEASURE
+
+	m_pending_num = 0;
+	pthread_mutex_init(&m_pending_mutex, NULL);
+	pthread_cond_init(&m_pending_cond, NULL);
+}
+
+
+MWDriver::~MWDriver() 
+{
+	MWTask *t;
+	MWWorkerID *w;
+	
+	while ( ( t = (MWTask *)todo->Remove() ) != NULL )
+		delete t;
+	delete todo;
+
+	while ( ( t = (MWTask *)running->Remove() ) != NULL )
+		delete t;
+	delete running;
+
+	while ( ( w = (MWWorkerID *)workers->Remove() ) != NULL )
+		delete w;
+	delete workers;
+
+	if ( bench_task ) 
+		{
+			delete bench_task;
+		}
+
+	if ( MWworkClassWorkers )
+		delete [] MWworkClassWorkers;
+	if ( MWworkClassTasks )
+		delete [] MWworkClassTasks;
+	if ( stats )
+		delete stats;
+}
+
+void 
+MWDriver::go( int argc, char *argv[] ) 
+{
+	MWReturn ustat;
+
+		// do some setup when we start:
+	
+	ustat = master_setup( argc, argv );
+
+	if ( ustat != OK ) 
+		{
+			MWprintf(10, "master_setup did not return OK, exiting\n");
+			RMC->exit(1);
+			return; 
+		}
+    
+		// the main processing loop:
+	ustat = master_mainloop ();
+	
+	if( ustat == OK || ustat == QUIT || ustat == PENDING ) 
+		{
+				// We're done - now print the results.
+				
+			printresults();
+
+				//JTL  Since kill_workers can take a long time --we like
+				//   to collect the statistics beforehand.  Therefore, 
+				//   we gather all the stats from the currently workign workers,
+				//   then call makestats here (before kill_workers).
+		
+			statsgather(workers, stats);
+				// tell the stats class to do its magic
+			stats->makestats();
+		}else{
+			MWprintf(10,"no print results because ustat is %d  %d\n",ustat,HOSTRESUME);
+		}
+
+	kill_workers();
+
+		// remove checkpoint file.
+	//remove(ckpt_filename);
+
+		/* Does not return. */
+	RMC->exit(0);
+}
+
+void
+statsgather ( MWList<MWWorkerID>* workers, MWStatistics * st )
+{
+	MWWorkerID * w = workers->First();
+	while ( workers->AfterEnd() == false ) {
+		w = workers->Current();
+		st->gather(w);
+		workers->Next();
+	}
+}
+
+MWReturn 
+MWDriver::master_setup( int argc, char *argv[] ) 
+{
+	MWReturn ustat = OK;
+	int myid, master_id;
+	int num_curr_hosts, i;
+	MWWorkerID **tempWorkers = NULL;
+
+	MWprintf ( 70, "MWDriver is pid %ld.\n", MWSystem::getpid() );
+    
+	RMC->setup( argc, argv, &myid, &master_id );
+
+#ifdef MEASURE
+	{
+			// First set the file name for the measurement records
+		int hasProcID = 0;
+		for (i=0; i<argc; i++) {
+			if ( strstr(argv[i], _measure_ProcID_prefix) != NULL ) {
+					// Use the %(ProcID)
+				hasProcID = 1;
+				sprintf(_measure_rec_file_name, "%s%s", _measure_rec_fname_prefix, argv[i]);
+			}
+		}
+		if (hasProcID == 0) {
+				// No ProcID info from the arguments, so use getpid()
+			sprintf(_measure_rec_file_name, "%s.%d", _measure_rec_fname_prefix, getpid());
+		}
+		MWprintf(31, "MEASURE|Setting measurement record fname = %s\n", _measure_rec_file_name);
+	}
+		
+		// Now start counting until next time read-opt-file/dump_rec-file
+	_measure_last_read_opt_time = _measure_last_dump_rec_time = time(0);
+		// Write the header lines into the record file
+	_measure_dump_header();
+
+		// Init/Reset the measurement data
+	_measure_reset();
+#endif // MEASURE
+    
+		// See if checkpoint file exists
+	FILE *chp_file = NULL;
+	if (  (chp_file = fopen(ckpt_filename, "r")) == NULL)
+		{
+				// checkpoint file not found - start from scratch:
+			MWprintf ( 50, "Starting from the beginning.\n" );
+			MWprintf ( 50, "argc=%d, argv[0]=%s\n", argc, argv[0] );
+
+			ustat = get_userinfo( argc, argv );
+		
+			if( ustat == OK ) 
+				{
+					if ( RMC->MW_exec_class_num_workers == NULL )
+						{
+							MWprintf ( 10, "In Get User Info set_exec_classes not called\n");
+							MWprintf ( 10, "Aborting\n");
+							assert(0);
+						}
+					ustat = create_initial_tasks();
+						/* Memory for workers allocated in here: */
+					RMC->init_beginning_workers ( &num_curr_hosts, &tempWorkers );
+				} 
+			else 
+				{
+					return ustat;
+				}
+		}
+	else 
+		{  // restart from that checkpoint file.
+			fclose(chp_file);
+			MWprintf ( 50, "Restarting from a checkpoint.\n" );
+
+#if 0
+				// Yet another Hack for Michael
+			get_userinfo( argc, argv );
+#endif
+			restart_from_ckpt();
+				/* Memory for workers allocated in here: */
+			RMC->restart_beginning_workers ( &num_curr_hosts, &tempWorkers, RE_INIT );
+		}
+
+	MWprintf ( 70, "Good to go.\n" );
+
+	if ( tempWorkers ) 
+		{ /* there are indeed workers... */
+
+			for ( i=0 ; i<num_curr_hosts ; i++ ) 
+				{
+					if ( tempWorkers[i]->get_id1() == -1 ) 
+						{
+								/* There was a problem with this worker! */
+							tempWorkers[i]->started();
+							tempWorkers[i]->ended();
+							stats->gather( tempWorkers[i] );
+						} 
+					else 
+						{
+								/* Success! */
+								/* Memory now taken care of by list... */
+							addWorker ( tempWorkers[i] );
+						}
+				}
+				/* don't forget to remove the array of ptrs .. */
+			delete [] tempWorkers;
+		}
+
+	return OK;
+}
+
+MWReturn 
+MWDriver::create_initial_tasks() 
+{    
+	int orig_ntasks;
+	MWTask **orig_tasks;
+    
+	MWReturn ustat = setup_initial_tasks( &orig_ntasks, &orig_tasks );
+	if ( MWworkClassWorkers == NULL )
+		workClasses_set ( 1 );
+	if( ustat == OK ) 
+		{
+			addTasks( orig_ntasks, orig_tasks );    
+		}
+	else 
+		{
+			MWprintf( 10, "setup_initial_tasks() returned %d\n", ustat );
+		}
+	delete [] orig_tasks;
+
+	return ustat;
+}
+
+
+MWReturn 
+MWDriver::master_mainloop() 
+{
+
+    call_hostaddlogic();
+#ifdef INDEPENDENT
+
+    ControlPanel ( );
+    return OK;
+#else
+
+	MWReturn ustat = OK;
+
+	while(1) {
+
+		bool need_continue = false;
+
+		// while there is at least one job in the todo or running queue:
+		bool has_something = !is_TODO_empty() || 
+			( !running->isEmpty() && (ustat == OK || ustat == PENDING) 
+			  && !normal_tasks_all_done );
+
+		if( has_something ) {
+
+			// while there is at least one job in the todo or running queue:
+			int buf_id = 0;
+			int sending_host = 0;
+			ustat = master_mainloop_oneshot(buf_id, sending_host);
+			if (ustat != OK && ustat != PENDING ) {
+				break;
+			}
+
+		}else {
+
+			struct timespec ts;
+			struct timeval tp;
+
+			pthread_mutex_lock(&m_pending_mutex);
+			while( m_pending_num > 0 ) {
+
+				// Get current Time
+				gettimeofday(&tp, NULL);
+
+				// Convert from timeval to timespec
+				ts.tv_sec = tp.tv_sec;
+				ts.tv_nsec = tp.tv_usec * 1000;
+				ts.tv_sec += 5; // pthread_cond_wait will wake up every 5 secs
+
+				pthread_mutex_lock(&global_mw_mutex);
+				if( !is_TODO_empty() ) {
+					need_continue = true;
+					pthread_mutex_unlock(&global_mw_mutex);
+					break;
+				}
+				pthread_mutex_unlock(&global_mw_mutex);
+
+				pthread_cond_timedwait(&m_pending_cond, 
+						&m_pending_mutex, &ts);
+
+				pthread_mutex_lock(&global_mw_mutex);
+				if( !is_TODO_empty() ) {
+					need_continue = true;
+					pthread_mutex_unlock(&global_mw_mutex);
+					break;
+				}
+				pthread_mutex_unlock(&global_mw_mutex);
+			}
+			pthread_mutex_unlock(&m_pending_mutex);
+
+			if( need_continue ) {
+				continue;
+			}
+
+			// Now, we have no todo, running, and pending jobs
+			break;
+		}
+	}
+
+	return ustat;
+#endif
+}
+
+MWReturn
+MWDriver::master_mainloop_oneshot(int buf_id, int sending_host)
+{
+	MWWorkerID *w = NULL;
+	MWReturn ustat = OK;
+	int len, tag, info;
+
+	int tasknum=0;
+	int subtasknum=0;
+	MWTask *t;
+#ifdef MEASURE
+	double _task_recv_time = 0.0;
+	double _task_recv_cpu_time = 0.0;
+#endif
+
+
+	MWprintf(90, "num_TODO = %d, num_run = %d, num_done = %d\n", 
+			 todo->Number(), running->Number(), num_completed_tasks );
+
+		/*	if (todo->Number() > MAX_IN_MEM)
+			swap_out_todo_tasks(NUM_IN_MEM_LO, MAX_IN_MEM);
+			else if (todo->Number() < MIN_IN_MEM)
+			swap_in_todo_tasks(MIN_IN_MEM, NUM_IN_MEM_HI);
+		*/	
+	if( !todo->isEmpty() ) 
+		MWprintf( 99, " CONTINUE -- todo list has at least task number: %d\n", todo->number()); 
+	else if( !running->isEmpty() ) 
+		MWprintf( 60, " CONTINUE -- running list has at least task number: %d\n", running->number() ); 
+
+#ifdef MEASURE	
+		// _measure: accumulate the _measure_master_recv_time value
+	double _recv_start_time = _measure_cur_wall_time();
+	double _recv_start_cpu_time = _measure_cur_cpu_time();
+#endif // MEASURE
+
+	// get any message from anybody
+	//		MWList<void> * recv_buf_list = RMC->recv_buffers();
+
+	// BUFFER: move to the next buffer
+	//		RMC->recv_all(-1, -1);
+
+	//		if (recv_buf_list == NULL || recv_buf_list->number()==0) {
+	buf_id = RMC->recv( -1, -1 );
+	//			MWprintf(91, "BUFFER: Have to use the blocking recv(), got buffer %d.\n", buf_id);
+	//		} else {
+	//			int* bid =  (int*) recv_buf_list->Remove();
+	//			buf_id = *bid;
+	//			recv_buf_list->Prepend(bid);
+	//		}
+
+#ifdef MEASURE	
+	_measure_master_recv_time += _measure_cur_wall_time() - _recv_start_time;
+	_measure_master_recv_cpu_time += _measure_cur_cpu_time() - _recv_start_cpu_time;
+#endif // MEASURE
+
+	if ( buf_id < 0 ) 
+		{
+			MWprintf ( 10, "ERROR, Problem with RMC->recv!\n" );
+#ifdef INDEPENDENT
+			return QUIT;
+#else
+				// GGT -- was continue
+				//continue;
+				
+			//by jae	
+			rematch_tasks_to_workers(NULL);
+			return OK;
+#endif
+		}
+
+	info = RMC->bufinfo ( buf_id, &len, &tag, &sending_host );
+
+		/* 8/28/00
+		   Qun Chen's signal handling code for Michael Ferris
+		*/
+/*
+
+int returned_from_longjump, processing = 1;
+	
+if ((returned_from_longjump = setjmp(env)) != 0)
+switch (returned_from_longjump)     {
+case SIGINT:
+MWprintf( 10, "!!!! Get user interruption.\n" );
+checkpoint();
+	//printresults();
+	return QUIT;
+	case SIGCONT: //Our program normally won't have this signal
+	MWprintf( 10, "FATCOP was signaled to checkpoint...\n" );
+	checkpoint();
+	MWprintf( 10, "finish checkpointing ...\n" );
+	break; 
+	}
+	(void) signal(SIGINT, signal_handler);
+	(void) signal(SIGCONT, signal_handler);
+		// alarm( 10 );
+		*/
+	switch ( tag ) 
+		{
+		case INIT: 
+#ifdef MEASURE
+			if (_measure_target_num_workers < workers->number()) {
+				MWprintf ( 31, "MEASURE|Got INIT message, but we need to remove workers ...\n");
+				RMC->initsend ( );
+				RMC->send ( sending_host, KILL_YOURSELF );
+				break;
+			}
+#endif // MEASURE
+			if ( (w = lookupWorker ( sending_host )) == NULL ) 
+				{
+					MWprintf ( 10, "We got an INIT message from worker %08x "
+							   "who we don't have records for.\n", sending_host);
+					RMC->initsend ( );
+					RMC->send ( sending_host, KILL_YOURSELF );
+					break;
+				}
+			ustat = worker_init( w );
+			break;
+
+		case BENCH_RESULTS:
+#ifdef MEASURE
+			if (_measure_target_num_workers < workers->number()) {
+				MWprintf ( 31, "MEASURE|Got BENCH_RESULTS message, but we need to remove workers ...\n");
+				RMC->initsend ( );
+				RMC->send ( sending_host, KILL_YOURSELF );
+				break;
+			}
+#endif // MEASURE
+		    if ( (w = lookupWorker ( sending_host )) == NULL ) 
+				{
+					MWprintf ( 10, "We got an BENCH_RESULTS message from (%08x), "
+							   "who we don't have records for.\n", sending_host);
+					RMC->initsend ( );
+					RMC->send ( sending_host, KILL_YOURSELF );
+					break;
+				}
+	
+			ustat = handle_benchmark( w );
+		    if ( ustat == OK ) 
+				{
+					printWorkers();
+					//send_task_to_worker( w );		
+					lockSendTaskToWorker( w );
+				} 
+		    else 
+				{
+					ustat = OK;  // we don't want to shut down...
+				}
+		    break;
+		    
+		case SUBRESULTS:
+            if ( (w = lookupWorker ( sending_host )) == NULL )
+				{                    
+					MWprintf ( 10, "We got a RESULTS message from worker %08x who we don't have records for.\n",sending_host);
+					RMC->initsend ();
+					RMC->send ( sending_host, KILL_YOURSELF );
+					break;
+				}
+				// deal with subresults
+		    RMC->unpack( &tasknum, 1, 1 );
+			MWprintf(51,"Received SUBRESULT message for tasknum %d\n",tasknum);
+		    RMC->unpack( &subtasknum, 1,1);
+		    t = rmFromRunQ( tasknum );
+			if(t == NULL) MWprintf(51,"huh, task is not in runQ\n");
+		    w->runningtask->unpack_subresults(tasknum);
+				// computational steering
+/*
+  if(subtasknum==t->randomstop)
+  {
+  RMC->initsend();
+  RMC->pack(&tasknum, 1, 1);
+  RMC->send(sending_host, STOP_WORK);
+  }
+*/
+		    act_on_completed_subtask(t);
+				//act_on_completed_task(t);
+		    putOnRunQ(t); // return task to run queue to complete the other tasks - with task container model, this task is done
+			break;
+		  
+		case RESULTS:
+
+			MWprintf ( 10, "We got a RESULTS message from worker %08x.\n", sending_host);
+
+		    if ( (w = lookupWorker ( sending_host )) == NULL ) 
+				{
+	    		    MWprintf ( 10, "We got a RESULTS message from worker %08x who we don't have records for.\n", 
+							   sending_host);
+					RMC->initsend ();
+					RMC->send ( sending_host, KILL_YOURSELF );
+					break;
+				}
+
+		    ustat = handle_worker_results ( w );
+
+		    if ( w->is_doomed() ) 
+				{
+						/* This worker has been marked for removal */
+					worker_last_rites ( w );
+				} 
+		    else 
+				{
+					if ( ustat == OK ) 
+						{
+							//send_task_to_worker( w );		
+							lockSendTaskToWorker( w );
+						}
+					else if( ustat != PENDING )
+						{
+							RMC->initsend ( );
+							RMC->send ( w->get_id1(), KILL_YOURSELF );
+							worker_last_rites ( w );
+							call_hostaddlogic ( );
+						}
+				}
+
+#ifdef MEASURE
+    		    // Summarize the measurement results
+			_measure_current_worker = w;
+		    _measure();
+#endif // MEASURE	
+		    break;
+
+		case HOSTADD:
+			{
+				MWWorkerID *w = new MWWorkerID;
+
+				int r=0;
+				r = RMC->start_worker( w );
+				if ( r >= 0 )
+					addWorker( w );
+				else
+					{
+						delete w;
+					}
+		
+				MWprintf(50, "Got a HOSTADD message.\n");
+				call_hostaddlogic();
+				break;
+			}
+
+		case HOSTDELETE:
+			handle_hostdel();
+			break;
+
+		case TASKEXIT:
+			handle_taskexit();
+			break;
+
+		case CHECKSUM_ERROR:
+		    handle_checksum();
+		    break;
+
+		case HOSTSUSPEND:
+			handle_hostsuspend();
+			break;
+
+		case HOSTRESUME:
+			handle_hostresume();
+			break;
+
+		default:
+			MWprintf ( 10, "Unknown message %d.  What the heck?\n", tag );
+
+		} // switch
+		
+		/* Jeff's addition.  At this point, we need to do some assigning of
+		   tasks.  If many tasks are added all in a batch, then many 
+		   "SEND_WORK" commands are ignored, and the workers sit
+		   idle.  Checking again here whether or not there are workers
+		   waiting (or suspended) is a good idea.
+		*/
+	rematch_tasks_to_workers( w );
+
+#if defined( SIMULATE_FAILURE )
+		// Fail with probability p
+	const double p = 0.0025;
+	
+	if( drand48() < p ) 
+		{
+			MWprintf ( 10, "Simulating FAILURE!\n" );
+			kill_workers();
+			RMC->exit(1);
+		}
+#endif	
+	
+		// If there is a worker_timeout_limit check all workers if there are
+		// timed-out workers in working state
+
+	if (worker_timeout)
+		{
+			time_t now = time(0);
+
+			if (next_worker_timeout_check  <= now)
+				{
+					next_worker_timeout_check = now + worker_timeout_check_frequency; 
+					MWprintf ( 80, "About to check timedout workers\n"); 
+					reassign_tasks_timedout_workers();
+				}
+		}
+
+	if( ustat != OK ) 
+		{
+			MWprintf( 10, "The user signalled %d to stop execution.\n", ustat );
+		}
+	
+	return ustat;
+}
+
+int 
+MWDriver::stop_work()
+{
+    int who;
+    RMC->who ( &who );
+	MWWorkerID *w = lookupWorker ( who );
+	RMC->initsend();
+	RMC->send ( w->get_id1(), STOP_WORK );
+	return 0;
+}
+
+void
+MWDriver::printresults ( )
+{
+	MWprintf ( 0, "In MWDriver packed %lf and unpacked %lf\n", RMC->get_bytes_packed(), 
+			   RMC->get_bytes_unpacked() );
+	MWprintf ( 0, "The MWDriver is done\n");
+}
+
+int
+MWDriver::refreshWorkers ( int i, MWREFRESH_TYPE type )
+{
+		// send only to idle workers
+	MWWorkerID *so = MWcurrentWorker;
+	int j;
+
+	if ( type == MW_NONE )
+		return 0;
+	if ( type == MW_THIS )
+		{
+			for ( j = 0; j < MWworkClasses; j++ )
+				{
+					if ( MWcurrentWorker->doesBelong ( j ) )
+						MWcurrentWorker->deleteGroup ( j );
+				}
+			RMC->initsend ( );
+			pack_worker_init_data ( );
+			RMC->send ( MWcurrentWorker->get_id1(), REFRESH );
+			return 0;
+		}
+
+	int num = 0;
+	int max = workers->number();
+	MWWorkerID *w;
+
+	while ( num < max )
+		{
+			w = (MWWorkerID *)workers->Remove();
+			if ( w != MWcurrentWorker && w->currentState() != IDLE )
+				workers->Append ( w );
+			else if ( !w->doesBelong ( i ) )
+				workers->Append ( w );
+			else
+				{
+						// You have to remove them from the list.
+					for ( j = 0; j < MWworkClasses; j++ )
+						{
+							if ( w->doesBelong ( j ) )
+								w->deleteGroup ( j );
+						}
+					RMC->initsend();
+					MWcurrentWorker = w;
+					pack_worker_init_data ( );
+					RMC->send ( w->get_id1(), REFRESH );
+					workers->Append ( w );
+				}
+			num++;
+		}
+	MWcurrentWorker = so;
+	return 0;
+}
+
+void
+MWDriver::worker_last_rites ( MWWorkerID *w )
+{
+	w->ended();
+	stats->gather(w);
+	rmWorker ( w->get_id1() );
+	RMC->removeWorker ( w );
+	RMC->MW_exec_class_num_workers[w->get_exec_class()]--;
+	
+		/* Commented out by Jichuan, to avoid calling deleteGroup() twice */
+		/*
+		  for ( int i = 0; i < MWworkClasses; i++ )
+		  {
+		  if ( w->doesBelong ( i ) )
+		  w->deleteGroup ( i );
+		  }
+		*/
+}
+
+MWReturn 
+MWDriver::worker_init( MWWorkerID *w ) 
+{
+	char workerhostname[64];
+	MWReturn ustat = OK;
+
+		/* We pack the hostname on the worker side... */
+	RMC->unpack( workerhostname );
+    
+	MWprintf ( 40, "The MWDriver recognizes the existence of worker \"%s\".\n",
+			   workerhostname );
+
+		// 9/5/00 Jeff changes this at Jim Basney's behest.  
+		//          Now, MWPvmRC will return the proper hostname, so we
+		//          check to see if the name has already been set before
+		//          setting it here
+	
+	w->set_machine_name( workerhostname );
+	w->started();
+
+	unpack_worker_initinfo( w );
+
+	w->get_machine_info();
+
+	int stat = RMC->initsend();
+	if( stat < 0 ) 
+		{
+			MWprintf( 10, "Error in initializing send in pack_worker_init_data\n");
+			worker_last_rites ( w );
+			return OK;
+		}
+
+	if ( RMC->pack ( getHostName() ) != 0 )
+		{
+			MWprintf ( 10, "packing of hostName returned !OK.\n");
+			worker_last_rites ( w );
+			return ustat;
+		}
+	MWcurrentWorker = w;
+	if ( (ustat = pack_worker_init_data()) != OK ) 
+		{
+			MWprintf ( 10, "pack_worker_init_data returned !OK.\n" );
+			w->printself(10);
+			worker_last_rites ( w );
+			return ustat;
+		}
+
+	MWTask *b = get_benchmark_task();
+	int benchmarking = b ? TRUE : FALSE;
+	
+	RMC->pack( &benchmarking, 1 );
+	if ( b ) 
+		{
+			b->pack_work();
+		}
+
+	MWprintf ( 10, "Master sending an INIT_REPLY\n");
+	RMC->send( w->get_id1(), INIT_REPLY );
+		// Note the fact that the worker is doing a benchmark. 
+	w->benchmark();
+	return ustat;
+}
+
+MWReturn
+MWDriver::handle_benchmark ( MWWorkerID *w ) 
+{
+	int okay = TRUE;
+	double bres = 0.0;
+
+	RMC->unpack( &okay, 1 );
+	if ( okay == -1 ) 
+		{
+				/* Very bad! */
+			MWprintf ( 10, "A worker failed to initialize!\n" );
+			w->printself(10);
+			worker_last_rites ( w );
+			return QUIT;
+		} 
+
+	RMC->unpack( &bres, 1 );
+	w->set_bench_result( bres );
+
+	MWprintf( 10, "Received bench result %lf from %s (%08x)\n", 
+			  bres, w->machine_name(), w->get_id1() );
+
+	stats->update_best_bench_results( bres );
+
+	w->benchmarkOver();
+
+		//JTL -- Now you need to order the workerlist
+	sort_worker_list();
+
+	return OK;
+}
+
+void 
+MWDriver::kill_workers() 
+{
+
+	MWprintf( 40, "Killing workers:\n");
+
+    MWWorkerID *w = (MWWorkerID *)workers->Remove();
+    
+    while ( w ) 
+		{
+			RMC->initsend ( );
+			RMC->send ( w->get_id1(), KILL_YOURSELF );
+			w->ended();
+			stats->gather(w);
+			RMC->MW_exec_class_num_workers[w->get_exec_class()]--;
+			for ( int i = 0; i < MWworkClasses; i++ )
+				{
+					if ( w->doesBelong ( i ) )
+						w->deleteGroup ( i );
+				}
+			RMC->removeWorker( w );
+		
+			w = (MWWorkerID *)workers->Remove();
+		}
+}
+
+void
+MWDriver::give_work ( MWWorkerID *w, MWTask *t)
+{
+	RMC->initsend();
+	int itmp = t->taskType;
+	RMC->pack ( &itmp, 1, 1 );
+	RMC->pack( &(t->number), 1, 1 );
+	pack_driver_task_data();
+	t->pack_work();
+	RMC->send( w->get_id1(), DO_THIS_WORK );
+}
+
+void
+MWDriver::lockSendTaskToWorker( MWWorkerID *w ) 
+{
+	pthread_mutex_lock(&global_mw_mutex);
+	send_task_to_worker(w);
+	pthread_mutex_unlock(&global_mw_mutex);
+}
+
+void 
+MWDriver::send_task_to_worker( MWWorkerID *w ) 
+{
+
+		/* Jeff added this!  Due to the "rematch" function,
+		 * it can be the case that a worker who asks for work might
+		 * already have some work, in which case we don't want to give
+		 * him another task.  (If he goes down then only one of the tasks
+		 * will be rescheduled.
+		 */
+
+	MWTask *t = NULL;
+	if( w->currentState() != IDLE ) 
+		{
+			return;
+		}
+		/* End of Jeff's kludgy fix */
+
+	double lastMeasured;
+	double nowTime;
+	w->getNetworkConnectivity ( lastMeasured );
+	nowTime = MWSystem::gettimeofday();
+
+#ifndef NWSENABLED
+/*
+  if ( nowTime > lastMeasured + 60 * 120 )
+  {
+  MWprintf ( 10, "Creating NWSTask: nowTime = %f, lastMeasured = %f\n", nowTime, lastMeasured);
+  t = new MWNWSTask ( task_counter++, defaultTimeInterval, defaultIterations, defaultPortNo, getHostName() );
+	  // t->printself ( 10 );
+	  MWprintf ( 10, "Sending MWNWSTask %f %d\n", defaultTimeInterval, defaultIterations);
+	  }
+	  else 
+*/
+		// in the future, there will be some policy to determine how many tasks go into one container
+	int tasks_per_container = 1;
+	for(int i = 0; i < tasks_per_container; i++)
+		{
+			t = getNextTask( w->getGroup() );
+			if( t != NULL) {
+				w->gottask(t->number);
+				putOnRunQ(t);
+			}
+		}
+#else
+	int tasks_per_container = 1;
+    for(int i = 0; i < tasks_per_container; i++)
+		{
+			t = getNextTask( w->getGroup() );
+			if( t == NULL)
+				break;
+			tc->addTask(t);
+			w->gottask(t->number);
+			putOnRunQ(t);
+		}
+#endif
+
+	if ( t != 0)
+		{
+			give_work ( w, t);
+			w->runningtask = t;
+			t->worker = w;
+
+			MWprintf ( 10, "Sent following task to %s (%08x).\n",
+					   w->machine_name(), w->get_id1() );
+			MWprintf(10,"%d\n",t->number);
+	
+				//MWprintf ( 10, "Sent task (%d-%d) to %s  (%08x).\n",
+				//       tc->FirstNum(), tc->LastNum(), w->machine_name(), w->get_id1() );
+				//remember to delete tc when you are done
+		}	
+/*
+  if ( t != NULL ) 
+  {
+  give_work ( w, tc );
+  w->gottask( t->number );
+  w->runningtask = t;
+  t->worker = w;
+  putOnRunQ( t );
+        
+  MWprintf ( 10, "Sent task %d to %s  (%08x).\n", 
+  t->number, w->machine_name(), w->get_id1() );
+
+  }
+  else 
+  {
+  this added to make things work better at program's end:
+  The end result will be that a suspended worker will have its
+  task adopted.  We first look for a task with a suspended worker.
+  We call it t.  The suspended worker's 'runningtask' pointer 
+  will still point to t, but t->worker will point to this
+  worker (w).  Now there will be two workers working on the 
+  same task.  The first one to finish reports the results, and
+  the other worker's results get discarded when (if) they come in.
+		
+
+  if ( !running->isEmpty() ) 
+  {
+	  // here there are no tasks on the todo list, but there are 
+		  // tasks in the run queue.  See if any of those tasks are
+			  // being held by a suspended worker.  If so, adopt that task.
+			
+				  // will reimplement later
+					  //reassignSuspendedTask(running, w);
+					  }
+
+					  XXX Jichuan's hack to avoid the master and workers busy working on 
+					  * NWSTasks only, this happens if there are many workers starting from 
+					  * different time which happen to make this cycle of NWSTasks overlap 
+					  * with the next. So we will check to see if all the tasks in runQ are
+					  * NWSTasks, and stop the application if so! 
+					  *
+		
+					  XXX A fix to solve the waiting for already finished task problem. 
+					  * The problem is that because a task can be assigned to more than one workers, 
+					  * it can happen that the some of the workers already return the result, but
+					  * either the master is waiting for the other workers to finish (if the task is
+					  * the last one), or the master will reassign the task to more workers. 
+					  * 
+					  * To fix it, we use two marker lists to record the set (no dup) of tasks that 
+					  * can were reassigned and already finished: List "reassigned_tasks" and List
+					  * "reassigned_tasks_done". A task id is inserted to "reassigned_tasks" when 
+					  * a its worker is suspended or timed-out, and inserted to "reassigned_tasks_done"
+					  * when a result is reported back. The difference of two set can be problematic
+					  * tasks.
+					  * 
+					  * If the TODO list is empty, and all running task is in the "reassigned_tasks_done"
+					  * set, then QUIT; if a task is suspended or timed-out, and it's in the 
+					  * "reassigned_tasks_done" set, it will not be reassigned.
+					  *
+		
+					  bool all_NWS = true, all_reassigned = true, all_done = true;
+		
+						  // MWprintf ( 60, "Now that no task in TODO list, let's see if all tasks in the runQ are NWSTaks.\n");
+						  MWTask *tmp_t = running->First();
+
+						  while (running->AfterEnd() == false) {
+						  tmp_t = running->Current();
+						  if (tmp_t->taskType != MWNWS )
+						  all_NWS = false;
+						  if (!in_set(reassigned_tasks, tmp_t->number))
+						  all_reassigned = false;
+						  else if (!in_set(reassigned_tasks_done, tmp_t->number))
+						  all_done = false;
+						  running->Next();
+						  }
+
+						  if (all_NWS) {
+						  MWprintf( 10, "Since all running tasks are NWSTask, and no TODO task, we are done! \n");
+						  normal_tasks_all_done = true;
+						  } else if (all_reassigned && all_done) {
+						  MWprintf( 10, "Since all running tasks are reassigned and all done, and no TODO task, we are done! \n");
+						  normal_tasks_all_done = true;
+						  }
+						  }
+*/
+}
+
+void
+MWDriver::reassignSuspendedTask ( MWList<MWTask> * running, MWWorkerID * w )
+{
+	MWGroup *grp1, *grp2;
+	grp2 = w->getGroup();
+
+	MWTask *t = running->First();
+	while (running->AfterEnd() == false) {
+		t = running->Current();
+		grp1 = t->getGroup();
+	
+		if ( grp1->doesOverlap ( grp2 ) && t->worker->isSusp() ) 
+			{
+		       	MWprintf ( 60, "Re-assigning task %d to %s (%08x).\n", 
+						   t->number, w->machine_name(), w->get_id1() );
+		       	t->worker->printself( 60 ); // temp
+		       	w->gottask( t->number );
+		       	t->worker = w;
+		       	w->runningtask = t;
+					// note that old wkr->runningtask points to t also.
+				give_work ( w, t );
+		       	break;
+	       	}
+
+		running->Next();
+	}
+}
+
+void 
+MWDriver::handle_hostdel () 
+{
+	
+		// Here we find out a host has gone down.
+		// this tells us who died:
+	int who;
+	RMC->who ( &who );
+
+	MWWorkerID *w = rmWorker( who );
+	if ( w == NULL ) 
+		{
+			MWprintf ( 40, "Got HOSTDELETE of worker %08x, but it isn't in the worker list.\n", who );
+		}
+	else 
+		{
+			MWprintf ( 40, "Got HOSTDELETE!  \" %s \" (%08x) went down.\n", 
+					   w->machine_name(), who );   
+
+			hostPostmortem ( w );
+			MWprintf ( 40, "There are now %d workers\n", workers->number() );
+
+				/* We may have to ask for some hosts at this time... */
+			delete w;
+			call_hostaddlogic();
+		}
+}
+
+void 
+MWDriver::handle_taskexit () 
+{
+
+		/*   I have found that we usually get this message just before a HOSTDELETE, 
+			 so I'm not going to do anything like remove that host...
+		*/
+
+	int who;
+	RMC->who ( &who );
+		// search workers for that id2.
+	MWWorkerID *w = rmWorker ( who );
+	if ( w == NULL ) 
+		{
+			MWprintf ( 40, "Got TASKEXIT of worker %08x, but it isn't in "
+					   "the worker list.\n", who );
+			return;
+		}
+
+	MWprintf ( 40, "Got TASKEXIT from machine %s (%08x).\n", 
+			   w->machine_name(), w->get_id1());
+
+	hostPostmortem( w );
+	RMC->removeWorker ( w );
+		/* We may have to ask for some hosts at this time... */
+	call_hostaddlogic();
+}
+
+MWReturn
+MWDriver::act_on_starting_worker ( MWWorkerID *wid )
+{
+	return OK;
+}
+
+void
+MWDriver::handle_checksum ( )
+{
+		// Some worker returned us a checksum error message
+		// Actually there may be some bootstrapping problem here
+	int who;
+	RMC->who ( &who );
+
+	MWReturn ustat = OK;
+	MWWorkerID *w = lookupWorker ( who );
+
+	MWprintf( 10, "Worker \" %s \" (%08x) returned a checksum error!\n", 
+			  w->machine_name(), who );
+
+	if ( w == NULL )
+		{
+			MWprintf ( 10, "Got CHECKSUM_ERROR from worker %08x, but it isn't in "
+					   "the worker list.\n", who );
+			return;
+		}
+	else
+		{
+			switch ( w->currentState ( ) ) 
+				{
+				case BENCHMARKING:
+					{
+						int stat = RMC->initsend();
+						if( stat < 0 ) 
+							{
+								MWprintf( 10, "Error in initializing send in pack_worker_init_data\n");
+							}
+						MWcurrentWorker = w;
+						if ( (ustat = pack_worker_init_data()) != OK ) 
+							{
+								MWprintf ( 10, "pack_worker_init_data returned !OK.\n" );
+								w->printself(10);
+								w->started();
+								w->ended();
+								RMC->MW_exec_class_num_workers[w->get_exec_class()]--;
+								rmWorker ( w->get_id1() );
+								RMC->removeWorker ( w );
+								return;
+							}
+
+						MWTask *b = get_benchmark_task();
+						int benchmarking = b ? TRUE : FALSE;
+
+						RMC->pack( &benchmarking, 1 );
+						if ( b ) 
+							{
+								b->pack_work();
+							}
+
+						RMC->send( w->get_id1(), INIT_REPLY );
+							// Note the fact that the worker is doing a benchmark.
+						w->benchmark();
+						return;
+						break;
+					}
+				case WORKING:
+					{
+						if ( w->runningtask )
+							{
+									// It was running a task
+									// See if this task is there in the done list
+									// implement this later
+									//	if ( w->runningtask->taskType == MWNORMAL )
+									//		pushTask ( w->runningtask );
+
+								//send_task_to_worker( w );		
+								lockSendTaskToWorker( w );
+								return;
+							}
+						else
+							{
+									// How is this possible that a worker is not working on something
+								MWprintf ( 10, "Worker was not working on any task but still gave a CHECKSUM_ERROR\n");
+								return;
+							}
+						break;
+					}
+			
+				default:
+					MWprintf(30, "MWDriver::handle_checksum() - other worker state.\n");
+				}
+		}
+}
+
+void 
+MWDriver::handle_hostsuspend () 
+{
+	int who;
+	RMC->who ( &who );
+	MWprintf(40,"Got HOSTSUSPEND\n");
+
+	MWWorkerID *w = lookupWorker ( who );
+	if ( w != NULL ) 
+		{
+			w->suspended();
+			MWprintf ( 40, "Got HOSTSUSPEND!  \"%s\" is suspended.\n", w->machine_name() );   
+
+			int task;
+			if ( w->runningtask && w->runningtask->taskType == MWNORMAL )
+				{
+					task = w->runningtask->number;
+					MWprintf ( 60, " --> It was running task %d.\n", task );
+
+					switch ( suspensionPolicy ) 
+						{
+						case REASSIGN: 
+							{
+									// remove task from running list; push on todo.
+
+// 						 First see if it's *on* the running list.  If it's 
+// 						not, then it's either back on the todo list or
+//						its already done.  If this is the case, ignore. 
+
+								MWTask *rmTask = rmFromRunQ( task );
+								if ( !rmTask ) 
+									{
+										MWprintf ( 60, "Not Re-Assigning task %d.\n", task );
+										break;
+									}
+								MWTask *rt = w->runningtask;
+								if ( rt != rmTask ) 
+									{
+										MWprintf ( 10, "REASSIGN: something big-time screwy.\n");
+									}
+
+// 						 Now we put that task on the todo list and rematch
+// 						the tasks to workers, in case any are waiting around.
+
+								if (!in_set(reassigned_tasks_done, rt->number)) {
+									insert_into_set(reassigned_tasks, rt->number);
+									MWprintf(60,"REASSIGN: Will reassign task %d.\n", rt->number);
+									pushTask( rt );
+										// just in case...
+									rematch_tasks_to_workers ( w );
+								}
+								break;
+							}
+						case DEFAULT: 
+							{
+									// we only take action if the todo list is empty.
+								if ( todo->isEmpty() ) 
+									{
+											// here there are no more tasks left to do, we want
+											// to re-allocate this job.  First, find idle worker:
+											//will reimplement later
+											//reassignIdleTask(workers, w);
+									}
+							}
+						} // switch
+				}
+			else if ( w->runningtask && w->runningtask->taskType != MWNORMAL )
+				{
+					MWprintf ( 60, " --> It was running a control task.\n");
+				}
+			else 
+				{
+					MWprintf ( 60, " --> It was not running a task.\n" );
+				}
+    	}
+	else
+		{
+			MWprintf ( 40, "Got HOSTSUSPEND of worker %08x, but it isn't in "
+					   "the worker list.\n", who );
+		}
+}
+
+void
+MWDriver::reassignIdleTask (MWList<MWWorkerID> * workers, MWWorkerID * w)
+{
+	MWGroup *grp1, *grp2; 
+	grp2 = w->runningtask->getGroup();
+
+	MWWorkerID *o = workers->First();
+	while (workers->AfterEnd() == false) {
+		o = workers->Current();
+		grp1 = o->getGroup();
+		
+		if ( o->isIdle() && grp1->doesOverlap ( grp2 ) ) 
+			{
+		       	MWprintf ( 60, "Reassigning task %d. to %s\n", 
+						   w->runningtask->number, o->machine_name() );
+		       	w->runningtask->worker = o;
+		       	o->runningtask = w->runningtask;
+		       	o->gottask( o->runningtask->number );
+
+				give_work ( o, o->runningtask );
+				break;
+	       	}
+		o = workers->Next();
+	}
+}
+
+void 
+MWDriver::handle_hostresume () 
+{
+
+		/* Do nothing; applaud politely */
+
+	int who;
+	RMC->who ( &who );
+
+	MWWorkerID *w = lookupWorker ( who );
+	if ( w != NULL ) 
+		{
+			w->resumed();
+			MWprintf ( 40, "Got HOSTRESUME.  \"%s\" has resumed.\n", 
+					   w->machine_name() );
+			if ( w->runningtask != NULL ) 
+				{
+					MWprintf ( 60, " --> It's still running task %d.\n", 
+							   w->runningtask->number );
+				}
+			else 
+				{
+					MWprintf ( 60, " --> It's not running a task.\n" );
+				}
+		}
+	else 
+		{
+			MWprintf ( 40, "Got HOSTRESUME of worker %08x, but it isn't in "
+					   "the worker list.\n", who );
+		}
+}
+
+void 
+MWDriver::hostPostmortem ( MWWorkerID *w ) 
+{
+	MWTask *t = 0;
+	w->ended();
+	RMC->MW_exec_class_num_workers[w->get_exec_class()]--;
+	for ( int i = 0; i < MWworkClasses; i++ )
+		{
+			if ( w->doesBelong ( i ) )
+				w->deleteGroup ( i );
+		}
+	t = w->runningtask;	
+
+	if ( t == NULL ) 
+		{
+			MWprintf ( 60, " %s (%08x) was not running a task.\n", 
+					   w->machine_name(), w->get_id1() );
+		}
+	else if ( t->taskType == MWNORMAL )
+		{
+			MWprintf ( 60, " %s (%08x) was running task %d.\n", 
+					   w->machine_name(), w->get_id1(), t->number );
+				// remove that task from the running queue...iff that
+				// task hasn't ALREADY been reassigned.  
+
+			w->runningtask = NULL;
+			MWWorkerID *o;
+			if ( !(o = task_assigned( t )) ) 
+				{
+					MWTask *check = rmFromRunQ( t->number );
+					if ( t == check ) 
+						{
+							t->worker = NULL;
+							rmFromRunQ(t->number);
+							pushTask( t );
+						}
+				}		
+			else 
+				{
+					t->worker = o;
+					MWprintf ( 60, " Task %d already has been reassigned\n", 
+							   t->number );
+				}
+		}
+	else
+		{
+				// It is a control task
+				// XXX Maybe also need to delete the task from RunQ, Insure complained about this.
+			MWTask *check = rmFromRunQ( t->number );
+			if ( t == check )	// GGT gcc complains about t used before set here, I think this is a bug
+				MWprintf(21, "The control task IS in the RunQ, and should haven't been deleted!");
+			delete t;
+		}
+	stats->gather( w );
+}
+		
+MWReturn 
+MWDriver::handle_worker_results( MWWorkerID *w ) 
+{
+	MWReturn ustat = OK;
+
+	int tasknum;  
+	double wall_time = 0;
+	double cpu_time = 0;
+    
+	RMC->unpack( &tasknum, 1, 1 );
+
+#ifdef MEASURE
+		// get the _task_recv_time 
+	double _task_recv_time = 0.0;
+	double _task_recv_cpu_time = 0.0;
+	RMC->unpack( &_task_recv_time, 1, 1);
+	RMC->unpack( &_task_recv_cpu_time, 1, 1);
+#endif // MEASURE
+	
+	RMC->unpack( &wall_time, 1, 1 );
+	RMC->unpack( &cpu_time, 1, 1 );
+
+		// We once received CPU times that were NAN from a worker,
+		// and this messes EVERYTHING up
+
+	if( cpu_time != cpu_time ) 
+		{
+			MWprintf( 10, "Error.  cpu_time of %lf, assigning to wall_time of %lf\n",
+					  cpu_time, wall_time );
+		}
+	
+		// Jeff's CPU time sanity check!!!!
+	if( cpu_time > 0.1 && (cpu_time > 1.1 * wall_time || cpu_time < 0.01 * wall_time ))
+		{
+			MWprintf( 10, "Warning.  Cpu time =%lf,  wall time = %lf seems weird.\n", 
+					  cpu_time, wall_time );
+			MWprintf( 10, "Assigning cpu time to be %lf\n", wall_time );
+			cpu_time = wall_time;
+		}
+		//	total_time = now - start_time;	
+
+
+	MWprintf ( 60, "Unpacked task %d result from %s (%08x).\n", 
+			   tasknum, w->machine_name(), w->get_id1() );
+
+	MWprintf ( 81, "It took %5.2f secs wall clock and %5.2f secs cpu time\n", 
+			   wall_time, cpu_time );
+
+	int mwtasknum = w->runningtask ? w->runningtask->number : -2;
+	if( tasknum != mwtasknum ) 
+		{
+			MWprintf( 10, "What the $%!^$!^!!!.  MW thought that %s (%08x) was running %d, not %d\n", 
+					  w->machine_name(), w->get_id1(), mwtasknum, tasknum );
+			return QUIT;
+		}
+
+	if ( w->isSusp() ) 
+		{
+			MWprintf ( 60, "Got results from a suspended worker!\n" );
+		}
+
+	MWTask *t = rmFromRunQ( tasknum );
+
+		/* The task *could* have been suspended, REASSIGNed, and put
+		   on the todo list.  Let's just check the first entry on the
+		   todo list and see if it's there.  If so, remove it and handle. */
+	if ( suspensionPolicy == REASSIGN )
+		{
+			MWTask * tmp_t = todo->First();
+			while (todo->AfterEnd() == false) {
+				tmp_t = todo->Current();
+				if (tmp_t->number == t->number)
+					todo->RemoveCurrent();
+				else todo->Next();
+			}
+		}
+
+		// in_TODO inited to be 0
+	int in_TODO = 0;
+	
+	if ( t == NULL ) {		
+			// XXX Check to see if the task is in TODO list
+			// It is possible that when re-assigning a task for many times, 
+			// the task can be temporarily in TODO list, but a worker at the 
+			// same time can return the result for this task. In this case, 
+			// we will just process the result (t = tmp_t) and remove the task from TODO 
+			// list. 
+			// 		-- Reported by Jeff
+			// 		-- temp fix by Jichuan
+	
+		if (in_set(reassigned_tasks_done, tasknum))
+			MWprintf ( 60, "Task %d already done, no need to process it.\n", tasknum);
+		else {
+			if (!in_set(reassigned_tasks, tasknum)) 
+				MWprintf ( 30, "Something wrong with REASSIGN, task %d.\n", tasknum);
+			
+			MWTask * tmp_t = todo->First();
+			while (todo->AfterEnd() == false) {
+				tmp_t = todo->Current();
+				if (tmp_t->number == tasknum) { /* found */
+					todo->RemoveCurrent();
+					in_TODO = 1;
+					t = tmp_t;
+					MWprintf(60, "Done task %d found in TODO, delete from it.\n", tasknum);
+				} else todo->Next();
+			}
+		}
+	}
+		
+	if ( ( !in_TODO ) && ( t == NULL ) ) {
+		
+		w->completedtask( wall_time, cpu_time );
+
+			// XXX Delete the task if there is no other workers are running it. 
+			// It's possible that the same task is assigned to many different
+			// workers (everytime a worker suspend, it's running task may be 
+			// reassigned to another worker). 
+			// 
+			// 	if ( w->runningtask ) 
+			//
+			// The original statement assumes that the number of workers running
+			// task t is maximally 2, so when the second worker report result, 
+			// MW delete the task. If a new task is created using the same region
+			// of memory, the runningtask pointer is corrupted. 
+
+		if (w->runningtask ) {
+			if (task_assigned(w->runningtask) == NULL) {
+				delete w->runningtask;
+			}
+			w->runningtask = NULL;
+		}
+	}
+	else 
+		{
+				// tell t the results
+			t->unpack_results();
+				/* give these to the task class; now the user can use them. */
+			t->working_time = wall_time;
+			t->cpu_time = cpu_time;
+			stats->update_best_task_results( cpu_time);
+
+#ifdef MEASURE
+				// set the task's _measure_MP_worker_time
+			t->_measure_MP_worker_time = _task_recv_time;
+			t->_measure_MP_worker_cpu_time = _task_recv_cpu_time;
+#endif // MEASURE
+	
+			if ( t->taskType == MWNORMAL )
+				{
+					MWcurrentWorker = w;
+#ifdef MEASURE
+						// _measure: accumulate the _measure_master_act_on_completed_task_time (and cpu)values
+					double act_start_time = _measure_cur_wall_time();
+					double act_start_cpu_time = _measure_cur_cpu_time();
+#endif // MEASURE
+
+					ustat = act_on_completed_task( t );
+#ifdef MEASURE
+					_measure_master_act_on_completed_task_time += _measure_cur_wall_time() - act_start_time;
+					_measure_master_act_on_completed_task_cpu_time += _measure_cur_cpu_time() - act_start_cpu_time;
+					_measure_num_task_Done ++;
+#endif // MEASURE
+			
+					if (in_set(reassigned_tasks, t->number)) {
+						insert_into_set(reassigned_tasks_done, t->number);
+						MWprintf(60, "REASSIGN: Task %d once reassigned and now finished.\n", t->number);
+					}
+			
+					num_completed_tasks++;
+
+					if ( (checkpoint_frequency > 0) && 
+						 (num_completed_tasks % checkpoint_frequency) == 0 ) 
+						{
+							checkpoint();
+						} 
+					else 
+						{
+							if ( checkpoint_time_freq > 0 ) 
+								{
+									time_t now = time(0);
+									MWprintf ( 91, "Trying ckpt-time, %d %d\n", 
+											   next_ckpt_time, now );
+									if ( next_ckpt_time <= now ) 
+										{
+											next_ckpt_time = now + checkpoint_time_freq;
+											MWprintf ( 80, "About to...next_ckpt_time = %d\n", 
+													   next_ckpt_time );
+											checkpoint();
+										}
+								}
+						}
+				}
+			else
+				{
+#ifndef NWSENABLED
+					if ( t->taskType == MWNWS )
+						{
+							if ( w ) 
+								w->setNetworkConnectivity ( ((MWNWSTask *)t)->median );
+							MWprintf ( 10, "Got results of NWSTask\n");
+						}
+#endif
+				}
+
+			if ( t->worker == NULL ) 
+				{
+					MWprintf ( 40, "Task had no worker...huh?\n" );
+				}
+
+			if ( w != t->worker ) 
+				{
+					MWprintf ( 90, "This task not done by 'primary' worker, "
+							   "but that's ok.\n" );
+				}
+			else 
+				{
+					MWprintf ( 90, "Task from 'primary' worker %s.\n", 
+							   w->machine_name() );
+				}
+
+			//by jae
+			if( ustat != PENDING ) {	
+				w->runningtask = NULL;
+				w->completedtask( wall_time, cpu_time );
+				t->worker = NULL;
+
+				if( ! task_assigned( t ) ) 
+				{
+					MWprintf( 80, "Deleting task %d\n", t->number );
+
+					for ( int tempi = 0; tempi < MWworkClasses; tempi++ )
+						{
+							if ( t->doesBelong ( tempi ) )
+								t->deleteGroup ( tempi );
+						}
+
+#ifdef MEASURE
+						// When a task is done, accumulate the following values:
+						// 	_measure_num_task_Done, task-related summary values
+						// _measure_task_RoundTrip_time += _measure_cur_wall_time() - t->_measure_start_time;
+					_measure_task_Exe_wall_time += t->working_time;
+					_measure_task_Exe_cpu_time += t->cpu_time;
+						// _measure_task_MP_master_time += t->_measure_MP_master_time;
+					_measure_task_MP_worker_time += t->_measure_MP_worker_time;
+					_measure_task_MP_worker_cpu_time += t->_measure_MP_worker_cpu_time;
+#endif // MEASURE
+					delete t;
+				}
+			}
+		}
+	return ustat;
+}
+
+void 
+MWDriver::rematch_tasks_to_workers( MWWorkerID *nosend )
+{
+	pthread_mutex_lock(&global_mw_mutex);
+
+		// For each worker that is "waiting for work", you can safely(?)
+		// now do a send_task_to_worker.  Don't send it to the id "nosend"
+		// (He just reported in).  
+	MWWorkerID *w;
+	int ns = nosend ? nosend->get_id1() : -1;
+    
+	w = workers->First();
+	while (workers->AfterEnd() == false) {
+		w = workers->Current();
+		if ( (w->currentState() == IDLE) && ( (w->get_id1() != ns) || (w->get_id2() != ns) ) ) {
+			MWprintf ( 90, "In rematch_tasks_to_workers(), trying send...\n" );
+			send_task_to_worker(w);		
+		}
+		workers->Next();
+	}	
+
+	pthread_mutex_unlock(&global_mw_mutex);
+}
+
+MWTask * 
+MWDriver::getNextTask( MWGroup *grp )  
+{
+	MWTask *t = NULL;
+		// return next task to do.  NULL if none.
+	if ( todo->isEmpty() ) 
+		return NULL;
+	
+	switch( getmode ) {
+		
+	case GET_FROM_BEGIN: 
+		{
+			t = first_task_in_group(todo, grp);
+			break;
+		}
+	case GET_FROM_KEY: 
+		{
+			if( task_key == NULL ) 
+				{
+					MWprintf ( 10, " GET_FROM_KEY retrieval mode, "
+							   "but no key function set.\n"); 
+					MWprintf ( 10, " Returning task at head of list\n");
+					t = first_task_in_group(todo, grp);
+				}
+			else 
+				{
+					if ( listsorted )
+						t = first_task_in_group(todo, grp);
+					else
+						{
+							MWKey retval;
+
+							if( task_key == NULL )
+								{
+									MWprintf( 10, " return_bst_keyval:  no task key "
+											  "function defined!\n");      
+									assert(0);
+								}
+							else
+								{
+									retval = -DBL_MAX;
+									t = NULL;
+									MWListElement<MWTask> * pos = NULL;
+									todo->ToHead();
+									while (todo->AfterEnd() == false) {
+										MWTask * tt = todo->Current();
+										MWKey tmp = (*task_key) (tt);
+										MWGroup * g = tt->getGroup();
+										if ( (retval < tmp) && g->doesOverlap ( grp ) ) {
+											pos = todo->CurPosition();
+											retval = tmp;
+											t = tt;
+										}
+										todo->Next();
+									}
+									todo->Remove(pos);
+								}
+						}
+				}
+			break;
+		}
+	default: 
+		{
+			MWprintf ( 10, "Unknown getmode %d\n", getmode );
+			assert( 0 );
+		}
+	} // switch
+	return t;
+}
+
+MWTask * 
+first_task_in_group ( MWList<MWTask> * tasks, MWGroup * grp)
+{
+	MWTask *t = tasks->First();
+	MWGroup *grp2;
+	while (tasks->AfterEnd() == false) {
+		t = tasks->Current();
+		grp2 = t->getGroup();
+		if ( grp->doesOverlap ( grp2 ) ) {
+			tasks->RemoveCurrent();
+			return t;
+		}
+		else tasks->Next();
+	}
+	return NULL;
+}
+
+void 
+MWDriver::pushTask( MWTask *push_task ) 
+{
+	switch( addmode ) 
+		{
+		case ADD_AT_BEGIN: 
+			{
+				todo->Prepend ( push_task );
+				break;
+			}
+		case ADD_AT_END: 
+			{
+				todo->Append ( push_task );
+				break;
+			}
+		case ADD_BY_KEY: 
+			{
+					// This will insert at the first key WORSE than the 
+					// given one
+				if( task_key == NULL ) 
+					{
+						MWprintf ( 10, "ERROR!  Adding by key, but no key "
+								   "function defined!\n" );
+						assert(0);
+					}
+
+				if ((*task_key)(push_task)<=max_task_key) {
+					todo->SortedInsert ( push_task, (*task_key)(push_task) );
+				}
+				else {
+					MWprintf(10, "Won't insert task whose key value %f > max_task_key %f.\n",
+							 (*task_key)(push_task), max_task_key);
+				}
+				break;
+			}
+		default: 
+			{
+				MWprintf ( 10, "What the heck kinda addmode is %d?\n", addmode );
+				assert( 0 );
+			}
+		} // switch
+}
+
+void 
+MWDriver::addTasks( int n, MWTask **add_tasks )
+{
+	if ( n <= 0 ) 
+		{
+			MWprintf ( 10, "Please add a positive number of tasks!\n" );
+			RMC->exit(1);
+		}
+    
+	for ( int i = 0; i < n; i++ )
+		{
+			add_tasks[i]->number = task_counter++;
+			if ( MWworkClasses <= 1 )
+				{
+					add_tasks[i]->initGroups ( MWworkClasses );
+					add_tasks[i]->addGroup ( 0 );
+				}
+
+			pushTask ( add_tasks[i] );
+		}
+}
+
+void 
+MWDriver::addTask( MWTask *add_task )  
+{
+	add_task->number = task_counter++;
+	if ( MWworkClasses <= 1 )
+		{
+			add_task->initGroups ( MWworkClasses );
+			add_task->addGroup ( 0 );
+		}
+	pushTask ( add_task );
+}
+
+void 
+MWDriver::ckpt_addTask( MWTask *add_task )  
+{
+	pushTask ( add_task );
+}
+
+void 
+MWDriver::set_task_key_function( MWKey (*t)( MWTask * ) ) 
+{
+	if ( ( t != task_key ) && (task_key == NULL) ) {
+		sort_task_list();
+		listsorted = true;
+	} else if ( t != task_key )
+		listsorted = false;
+		
+	task_key = t;
+}
+
+int 
+MWDriver::set_task_add_mode( MWTaskAdditionMode mode )
+{
+	int errcode = 0;
+	if( mode < ADD_AT_END || mode > ADD_BY_KEY ) {
+		errcode = UNDEFINED;
+		MWprintf( 10, " Bad Add Task Mode.  Switching to ADD_AT_END\n");
+		addmode = ADD_AT_END;
+    }
+	else {
+		addmode = mode;
+	}
+	return errcode;
+}
+
+int 
+MWDriver::set_task_retrieve_mode( MWTaskRetrievalMode mode )
+{
+	int errcode = 0;
+	if( mode < GET_FROM_BEGIN || mode > GET_FROM_KEY ) {
+		errcode = UNDEFINED;
+		MWprintf( 10, " Bad Retrive Task Mode.  "
+				  "Switching to GET_FROM_BEGIN\n" );
+		getmode = GET_FROM_BEGIN;
+    }
+	else {
+		getmode = mode;
+		if( ( mode == GET_FROM_KEY ) && ( task_key == NULL ) ) {
+			MWprintf( 10, " Warning.  Call set_task_key() function before ");
+			MWprintf( 10, " retrieving task\n");
+		}
+    }
+	
+	return errcode;
+}
+
+int 
+MWDriver::set_machine_ordering_policy( MWMachineOrderingPolicy mode ) 
+{
+	int errcode = 0;
+	if( mode < NO_ORDER || mode > BY_KFLOPS ) {
+		errcode = UNDEFINED;
+		MWprintf( 10, "Bad machine ordering policy %d.  Switching to NO_ORDER\n", 
+				  (int) mode );
+		machine_ordering_policy = NO_ORDER;
+		worker_key = NULL;
+	}
+	else {
+		MWprintf( 30, "Set machine ordering policy to %d\n", (int) mode );
+		machine_ordering_policy = mode;
+		if( mode == BY_USER_BENCHMARK ) {
+			worker_key = &benchmark_result;
+		}
+		else {
+			worker_key = &kflops;
+		}
+
+	}
+	return errcode;
+}
+
+
+void 
+MWDriver::set_worker_timeout_limit( double timeout_limit, int timeout_freq ) 
+{
+	if (timeout_limit > 0)
+		{
+			worker_timeout = true;
+			worker_timeout_limit = timeout_limit;
+
+			worker_timeout_check_frequency = timeout_freq ;
+			next_worker_timeout_check = time(0) + timeout_freq ;
+
+			MWprintf( 30, "Set worker timeout limit to %lf\n", timeout_limit);
+			MWprintf( 30, "Set worker timeout frequency to %d\n", timeout_freq);    
+
+		}
+	else 
+		{
+			MWprintf(10, "Urgh, Timeout limit has to be > 0\n");
+		}
+}
+
+void MWDriver::reassign_tasks_timedout_workers()
+{
+	MWprintf ( 10, "Enter : reassign_tasks_timedout_workers()\n");
+	MWWorkerID *tempw;
+	int total = 0;
+
+	if (worker_timeout_limit > 0) 
+		{
+			double now = MWSystem::gettimeofday();
+			MWprintf( 60, "Now: %lf\n", now );
+
+			while( total < workers->number() ) 
+				{
+					total++;
+					tempw = (MWWorkerID *)workers->Remove();
+					if (tempw->currentState() == WORKING) 
+						{
+							MWprintf( 50, "Last event from %s (%08x) : %lf\n", tempw->machine_name(), 
+									  tempw->get_id1(), tempw->get_last_event() );
+
+							if ( (now - tempw->get_last_event() ) > worker_timeout_limit )
+								{
+										// this worker is timed out
+									if (tempw->runningtask)
+										{
+											int task = tempw->runningtask->number;
+
+											MWTask *rmTask = rmFromRunQ( task );
+											if ( rmTask ) 
+												{
+													MWprintf ( 10, "Worker %08x is timed-out\n",tempw->get_id1());
+													MWprintf ( 10, "Task %d rescheduled \n",rmTask->number);
+												}
+											else 
+												{
+													MWprintf ( 60, "Task not found in running list; assumed done or in todo list.\n" );
+												}
+						
+											if ( !rmTask || rmTask->taskType != MWNORMAL ) 
+												{
+													MWprintf ( 60, "No need to reassign task %d.\n", task );
+												}
+											else 
+												{
+													MWTask *rt = tempw->runningtask;
+													if ( rt != rmTask ) 
+														{
+															MWprintf ( 10, "REASSIGN: something big-time screwy.\n");
+														}
+														// We don't need to do that.
+														// tempw->runningtask = NULL;
+
+														// Now we put that task on the todo list and rematch
+														// the tasks to workers, in case any are waiting around.
+													if (!in_set(reassigned_tasks_done, rt->number)) {
+														insert_into_set(reassigned_tasks, rt->number);
+														MWprintf(60, "REASSIGN: Will assign task %d.\n", rt->number);
+														pushTask( rt );
+															// just in case...
+														rematch_tasks_to_workers ( tempw );
+													}
+												}
+										}
+								}
+						}
+					workers->Append ( tempw );
+				}
+
+/*
+  This is Jeff's code.  We go through the *running* list 
+  too to see if there is a task there that needs to be reassigned.
+  For example -- if there is a task in the running list
+  not assigned to anyone.  This can happen.  For example...
+*/		
+
+			total = 0;
+			MWTask *tempr;
+
+			while( total < running->number() ) 
+				{
+					total++;
+					tempr = (MWTask *)running->Remove();
+					if ( tempr->taskType != MWNORMAL )
+						{
+							running->Append ( tempr );
+							continue;
+						}
+
+						// Find the worker running this task.
+					bool foundworker = false;
+					int subtotal = 0;
+					MWWorkerID *tempw = NULL;
+			
+						// XXX // while( subtotal < workers->number() ) 
+					while( (foundworker == false) && (subtotal < workers->number()) ) 
+						{
+							subtotal++;
+							tempw = (MWWorkerID *)workers->Remove();
+							if( tempw->runningtask ) 
+								{
+									MWprintf(99, "worker=%08x, task=%d, worker->runningTask=%d\n", 
+											 tempw->get_id1(), tempr->number, tempw->runningtask->number);
+									if( tempw->runningtask->number == tempr->number ) 
+										{
+											foundworker = true;
+											MWprintf(99, "Found worker!\n");
+										}
+								}
+
+								// XXX Should be the bug that Steve reported - jichuan
+								// running->Append ( tempw );
+							workers->Append ( tempw );
+						}
+			
+					if( foundworker ) 
+						{
+							assert( tempw != NULL );
+							MWprintf( 60, "Worker id %08x  has task %d\n", tempw->get_id1(), 
+									  tempr->number );
+							running->Append ( tempr );
+						}
+					else
+						{
+							MWprintf( 10, "Woah!!!  Task number %08x lost his worker.  Rescheduling\n", 
+									  tempr->number );
+								// First remove him from the run queue
+							MWTask *check = rmFromRunQ( tempr->number);
+							if( check != tempr ) 
+								{
+									MWprintf( 10, "There is a HUGE logic error in the code.  Aborting\n" );
+									assert( 0 );
+								}
+							pushTask( tempr );
+							break;
+						}
+				}
+		}
+}
+
+int 
+MWDriver::print_task_keys() 
+{
+	int retcode = 0;
+	
+	if( task_key == NULL ) 
+		{
+			retcode = UNDEFINED;
+			MWprintf( 10, " No key function assigned to tasks -- Can't print\n");
+		}
+	else 
+		{
+			MWprintf( 10, "Task Keys:\n");
+			MWTask *t;
+
+				/* Won't print the keys if todo->number() too large */
+			if (todo->number() <= 10000) {
+				t = todo->First();
+				while (todo->AfterEnd() == false) {
+					t = todo->Current();
+					MWprintf(10, "   %f\t(%d)\n", (*task_key)(t), t->number);
+					todo->Next();
+				}
+			} else {
+				MWprintf(10, "Too many task keys (%d), skip the printing.\n", 
+						 todo->number());
+			}
+		}
+	return retcode;
+}
+
+int 
+MWDriver::delete_tasks_worse_than( MWKey key ) 
+{
+	if( task_key == NULL ) 
+		{
+			MWprintf( 10, " delete_task_worse_than:  no task key "
+					  "function defined!\n");
+			return UNDEFINED;
+		}
+	
+	MWTask *t = todo->First();
+
+	while( todo->AfterEnd() == false) {
+		t = todo->Current();
+		if( (*task_key)( t ) > key ) {
+			todo->RemoveCurrent();
+			delete t;
+		} else todo->Next();
+	}
+
+		//Jeff says -- DO NOT save this state!  What if the user changes the
+		//     task key?
+		/* Update max_task_key */
+#if 0
+	if (key < max_task_key)
+		max_task_key = key;
+#endif
+	return 0;
+}
+
+void 
+MWDriver::putOnRunQ( MWTask *t ) 
+{
+
+		// Here's the deal:  running points to the head of the runQ, 
+		// runningend points at the last element in the runQ.
+		// we insert tasks at the end.
+	running->Append ( t );
+}
+
+MWTask * 
+MWDriver::rmFromRunQ( int jobnum ) 
+{
+	MWTask *t;
+
+	running->First();
+	while (running->AfterEnd() == false) {
+		t = running->Current();
+		if (t->number == jobnum) {
+			running->RemoveCurrent();
+			return t;
+		} else running->Next();
+	}
+	return NULL;
+}
+
+MWWorkerID * 
+MWDriver::task_assigned( MWTask *t ) 
+{
+	MWWorkerID * w;
+	
+	workers->ToHead();
+	while (workers->AfterEnd() == false) {
+		w = workers->Current();
+		if ( (w->runningtask) && (w->runningtask->number == t->number) )
+			return w;
+		else workers->Next();
+	}
+	return NULL;
+}
+
+bool 
+MWDriver::task_in_todo_list( MWTask *t )
+{
+		// Before rescheduling a task on a TASKEXIT message, we need 
+		// to see that the task is still in the todo list
+		// Tasks NOT in the todo list have already been finished,
+		// hence they should not be reassigned and this function should
+		// return false.
+
+	MWTask * tt;
+	todo->ToHead();
+
+	while (todo->AfterEnd() == false) {
+		tt = todo->Current();
+		if (tt->number == t->number)
+			return true;
+		else todo->Next();
+	}
+	return false;
+}  
+
+int
+MWDriver::matchTask ( void *arg1, void *arg2 )
+{
+	MWTask *t1 = (MWTask *)arg1;
+	MWTask *t2 = (MWTask *)arg2;
+	if ( t1 == t2 )
+		return 1;
+	return 0;
+}
+
+void 
+MWDriver::printRunQ() 
+{
+	MWprintf ( 60, "PrintRunQ start:\n" );
+	MWTask *t = running->First();
+   	while ( running->AfterEnd() == false )
+		{
+			t = running->Current();
+			t->printself();
+			running->Next();
+		}
+	MWprintf ( 60, "PrintRunQ end.\n\n" );
+}
+
+void 
+MWDriver::addWorker( MWWorkerID *w ) 
+{
+		// put a worker on the workers list.  Add to front.
+		//  At this point, no benchmark information or machine information
+		//  is known, so it is impossible to put the new machine in its proper
+		//  place
+
+	w->initGroups ( MWworkClasses );
+	MWcurrentWorker = w;
+	act_on_starting_worker ( w );
+	if ( MWworkClasses <= 1 )
+		w->addGroup ( 0 );
+	RMC->MW_exec_class_num_workers[w->get_exec_class()]++;
+
+	workers->Append ( w );
+}
+
+
+// This could be more efficient, since we would need only insert items
+//  in order to ensure that things are sorted.  But this gives us
+//  more flexibility for later, and we will likely rewrite these classes anyway
+
+void 
+MWDriver::sort_worker_list()
+{
+	if( machine_ordering_policy == NO_ORDER || worker_key == NULL  )
+		return;
+
+	MWWorkerID *w;
+	MWList<MWWorkerID> * newList = new MWList<MWWorkerID>;
+	while ( !workers->isEmpty() )
+		{
+			w = (MWWorkerID *)workers->Remove();
+			newList->SortedInsert ( w, (*worker_key)( w ) );
+		}
+	delete workers;
+	workers = newList;
+}
+
+MWWorkerID* 
+MWDriver::lookupWorker ( int id )
+{
+	MWWorkerID * w = workers->First();
+	while (workers->AfterEnd() == false) {
+		w = workers->Current();
+		if ( (w->get_id1() == id) || (w->get_id2() == id) )
+			return w;
+		else workers->Next();
+	}
+	return NULL;
+}
+
+void
+MWDriver::call_hostaddlogic() 
+{
+		/* This is a wrapper around the lower level's hostaddlogic(), 
+		   which will return 0 as a basic OK value, and a positive number
+		   of hosts to delete if it thinks we should delete hosts.  This
+		   can happen if the user changes the target number of workers 
+		   to a lower value. */
+
+	int *num_workers = new int[RMC->get_num_exec_classes()];
+	int j, numtodelete;
+	int total = 0;
+	MWWorkerID *w; // , *wx, *wn;
+	for ( j=0 ; j < RMC->get_num_exec_classes() ; j++ ) {
+		num_workers[j] = numWorkers( j );
+	}
+	
+	numtodelete = RMC->hostaddlogic( num_workers );
+	delete [] num_workers;
+	
+	
+		/* Make sure we don't count already doomed machines: */
+	if ( numtodelete > 0 ) 
+		{
+			while ( total < workers->number() )
+				{
+					total++;
+					w = (MWWorkerID *)workers->Remove();
+					if ( w->is_doomed() ) numtodelete--;
+					workers->Append ( w );
+				}
+		}
+
+	if ( numtodelete > 0 ) 
+		{
+			MWprintf ( 40, "Deleting %d hosts.\n", numtodelete );
+			MWprintf ( 40, "Ignore the HOSTDELETE or TASKEXIT messages.\n" );
+
+				/* Walk thru list and kill idle workers. */
+			total = 0;
+			while ( total < workers->number() ) 
+				{
+					total++;
+					w = (MWWorkerID *)workers->Remove();
+					if ( numtodelete > 0 && w->isIdle() ) 
+						{
+							MWprintf ( 80, "Idle worker:\n" );
+							worker_last_rites ( w );
+							numtodelete--;
+						} 
+					else 
+						{
+							workers->Append ( w );
+						}
+				}
+			if ( numtodelete <= 0 ) return;
+				 
+				/* Now walk thru workers and remove suspended machines */
+			total = 0;
+			while ( total < workers->number() ) 
+				{
+					total++;
+					w = (MWWorkerID *)workers->Remove();
+					if ( numtodelete > 0 && w->isSusp() ) 
+						{
+							MWprintf ( 80, "Suspended worker:\n" );
+							w->printself ( 80 );
+				
+							hostPostmortem( w ); /* this really does do what we want! */
+							RMC->removeWorker( w );
+							numtodelete--;
+						} 
+					else 
+						{
+							workers->Append ( w );
+						}
+				}
+			if ( numtodelete <= 0 ) return;
+
+				/* At this point, we could do something really cool like 
+				   sort the workers based on some attributes.... */
+
+				/* Next, walk thru list and mark working workers for removal */
+			total = 0;
+			while ( total < workers->number() ) 
+				{
+					total++;
+					w = (MWWorkerID *)workers->Remove();
+					if ( numtodelete > 0 && !(w->is_doomed()) ) 
+						{
+							w->mark_for_removal();
+							MWprintf ( 40, "Host %s marked for removal.\n", 
+									   w->machine_name() );
+							numtodelete--;
+						}
+					workers->Append ( w );
+				}
+		}
+
+}
+
+int 
+MWDriver::numWorkers() 
+{
+	return workers->number();
+}
+
+int 
+MWDriver::numWorkers( int ex_cl ) 
+{
+	int count = 0;
+	int total = 0;
+	MWWorkerID *w;
+	while ( total < workers->number() ) 
+		{
+			total++;
+			w = (MWWorkerID *)workers->Remove();
+			if ( w->get_exec_class() == ex_cl ) 
+				{
+					count++;
+				}
+			workers->Append ( w );
+		}
+	return count;
+}
+
+
+int 
+MWDriver::numWorkersInState( int ThisState ) 
+{
+		// We handle the case WORKING separately such that
+		// we don't count the workers with no runningtask
+
+	int total = 0;
+	int count = 0;   
+	MWWorkerID *w;
+  
+	while ( total < workers->number() )
+		{
+			total++;
+			w = (MWWorkerID *)workers->Remove();
+			if (ThisState == WORKING)
+				{
+					if ( (w->currentState() == ThisState) && (w->runningtask != NULL) ) 
+						{
+							count++;
+						}
+				}
+			else
+				{
+					if ( w->currentState() == ThisState ) 
+						{
+							count++;
+						}
+				}
+			workers->Append ( w );
+		}
+	return count;
+}
+
+void 
+MWDriver::printWorkers() 
+{
+	MWprintf ( 10, "---- A list of Workers follows: ----------------\n" );
+
+	MWWorkerID *w = workers->First();
+
+	while ( workers->AfterEnd() == false ) 
+		{
+			w = workers->Current();
+			w->printself( 10 );
+			MWprintf( 10, "\n" );
+			workers->Next();
+		}
+
+	MWprintf ( 10, "---- End worker list --- %d workers ------------\n", workers->number() );
+}
+
+MWKey 
+MWDriver::return_best_todo_keyval()
+{
+	MWKey retval = DBL_MAX;
+
+	if( task_key == NULL ) {
+		MWprintf( 10, " return_bst_keyval:  no task key "
+				  "function defined!\n");      
+	}
+	else {
+		if ( todo->isEmpty() )
+			return retval;
+		if ( listsorted ) {
+				//XXX Jeff -- fixed the bug, if you take something off the list that has a key, 
+				//  You'd better damn well put it back with the same key (not 0.0)
+				//  but I don't know if it is the best way to remove
+				//  and put the key back on the list.  I know I didn' write it this way
+			MWTask *t = (MWTask *)todo->Remove();
+			double val = (*task_key)(t);
+			todo->Prepend(t, val);
+			return (*task_key)( t );
+		}
+		else {
+			MWTask * t = todo->First();
+			while ( todo->AfterEnd() == false ) {
+				t = todo->Current();
+				MWKey tmp = (*task_key) ( t );
+				if ( retval > tmp )
+					retval = tmp;
+				todo->Next();
+			}
+			return retval;
+		}
+	}
+	return retval;
+}
+
+MWKey MWDriver::return_best_running_keyval()
+{
+	MWKey retval = DBL_MAX;
+
+	if( task_key == NULL )
+		{
+			MWprintf( 10, " return_bst_keyval:  no task key "
+					  "function defined!\n");      
+    	}
+	else
+		{
+			if ( running->isEmpty() ) return retval;
+			MWTask * t = running->First();
+			while ( running->AfterEnd() == false )
+				{
+					t = running->Current();
+					if ( t->taskType == MWNORMAL )
+						{
+							MWKey tmp = (*task_key)( t );
+							if( tmp < retval )
+								retval = tmp;
+						}
+					running->Next();
+				}
+			return retval;
+		}
+	return retval;
+}
+
+
+
+MWWorkerID * 
+MWDriver::rmWorker ( int id ) 
+{
+        // search for a worker with the given id and remove it.
+		// The id can refer to either the primary or secondary id.
+	
+	MWWorkerID * w = workers->First();
+	while (workers->AfterEnd() == false) {
+		w = workers->Current();
+		if ( (w->get_id1() == id) || (w->get_id2() == id) ) {
+			workers->RemoveCurrent();
+			return w;
+		}
+		else workers->Next();
+	}
+	return NULL;
+}
+
+int
+MWDriver::set_checkpoint_frequency( int freq ) {
+	if ( checkpoint_time_freq != 0 ) {
+		MWprintf ( 10, "Cannot set_checkpoint_frequency while time-based "
+				   "frequency is not zero!\n" );
+		return checkpoint_frequency;
+	}
+    int old = checkpoint_frequency;
+    checkpoint_frequency = freq;
+    return old;
+}
+
+int 
+MWDriver::set_checkpoint_time ( int secs ) {
+	if ( checkpoint_frequency != 0 ) {
+		MWprintf ( 10, "Cannot set_checkpoint_time while task-based "
+				   "frequency is not zero!\n" );
+		return checkpoint_time_freq;
+	}
+	int old = checkpoint_time_freq;
+	checkpoint_time_freq = secs;
+	next_ckpt_time = time(0) + secs;
+	return old;
+}
+
+void 
+MWDriver::set_suspension_policy( MWSuspensionPolicy policy ) {
+	if ( (policy!=DEFAULT) && (policy!=REASSIGN) ) {
+		MWprintf ( 10, "Bad suspension policy %d.  Using DEFAULT.\n" );
+		suspensionPolicy = DEFAULT;
+		return;
+	}
+	suspensionPolicy = policy;
+}
+
+void
+MWDriver::checkpoint() 
+{
+    FILE *cfp;  // Checkpoint File Pointer
+		/* We're going to write the checkpoint to a temporary file, 
+		   then move the file to "ckpt_filename" */
+
+		/* We're not going to use tempnam(), because it sometimes 
+		   gives us a filename in /var/tmp, which is bad for rename() */
+
+	char *tempName = "mw_tmp_ckpt_file";
+
+    if ( ( cfp=fopen( tempName, "w" ) ) == NULL ) {
+        MWprintf ( 10, "Failed to open %s for writing! errno %d\n", 
+				   tempName, errno );
+        return;
+    }
+
+    MWprintf ( 50, "Beginning checkpoint()\n" );
+
+        // header
+    fprintf ( cfp, "MWDriver Checkpoint File.  %ld\n", time(0) );
+    
+        // some internal MWDriver state:
+    fprintf ( cfp, "%d %d %d %d\n%d %d %d %d %d %lf %d\n", task_counter, 
+			  checkpoint_frequency, checkpoint_time_freq, 
+			  num_completed_tasks,
+			  (int)addmode, (int)getmode, (int)suspensionPolicy,
+			  (int) machine_ordering_policy,
+	          worker_timeout,worker_timeout_limit, worker_timeout_check_frequency);
+
+	if ( bench_task ) {
+		fprintf ( cfp, "1 " );
+		bench_task->write_ckpt_info ( cfp );
+	} else {
+		fprintf ( cfp, "0\n" );
+	}
+
+	MWprintf ( 80, "Wrote internal MWDriver state.\n" );
+
+	RMC->write_checkpoint( cfp );
+
+	MWprintf ( 80, "Wrote RMC state.\n" );
+
+		/* Yes, I really am passing it the list of workers... */
+	stats->write_checkpoint ( cfp, workers );
+	
+	MWprintf ( 80, "Wrote the Worker stats.\n" );
+
+		// Write the user master's state:
+	write_master_state( cfp );
+
+	MWprintf ( 80, "Wrote the user master's state.\n" );
+
+		// write the number of work classes
+	fprintf ( cfp, "%d\n", MWworkClasses );
+
+	int tempnum = 0;
+	MWTask * ttt = running->First();
+	while ( running->AfterEnd() == false )
+		{
+			ttt = running->Current();
+			if ( ttt->taskType == MWNORMAL )
+				tempnum++;
+			running->Next();
+		}
+	int num_tasks = tempnum + todo->number();
+    
+		// Tasks separator:
+	fprintf ( cfp, "Tasks: %d \n", num_tasks );
+
+		/* Write ordered todo before unsorted running tasks */
+	MWTask *t;
+	
+	fprintf ( cfp, "TODO_num: %d \n", todo->number() );
+	t = todo->First();
+	while ( todo->AfterEnd() == false ) 
+		{
+			t = todo->Current();
+			fprintf ( cfp, "%d ", t->number );
+			t->write_ckpt_info( cfp );
+			t->write_group_info ( cfp );
+			todo->Next();
+		}
+
+	fprintf( cfp, "running_num: %d \n", running->number() ); 
+	t = running->First();
+	while ( running->AfterEnd() == false) 
+		{
+			t = running->Current();
+			if ( t->taskType == MWNORMAL )
+				{
+					fprintf ( cfp, "%d ", t->number );
+					t->write_ckpt_info( cfp );
+					t->write_group_info ( cfp );
+				}
+			running->Next();
+		}
+
+	MWprintf ( 80, "Wrote task list.\n" );
+
+	fclose ( cfp );
+
+		/* Now we rename our temp file to the real thing. Atomicity! */
+	if ( rename( tempName, ckpt_filename ) == -1 ) {
+		MWprintf ( 10, "rename( %s, %s ) failed! errno %d.\n", 
+				   tempName, ckpt_filename, errno );
+	}
+
+	MWprintf ( 50, "Done checkpointing.\n" );
+}
+
+void 
+MWDriver::restart_from_ckpt() 
+{
+
+	int i;
+	
+	FILE *cfp;
+	if ( ( cfp=fopen( ckpt_filename, "r" ) ) == NULL ) {
+		MWprintf ( 10, "Failed to open %s for reading! errno %d\n", 
+				   ckpt_filename, errno );
+		return;	
+	}	
+
+	char buf[128];
+	time_t then;
+	fscanf( cfp, "%s %s %s %ld", buf, buf, buf, &then );
+    
+	MWprintf ( 10, "This checkpoint made on %s\n", ctime( &then ) );
+
+	fscanf( cfp, "%d %d %d %d", &task_counter, 
+			&checkpoint_frequency, &checkpoint_time_freq,
+			&num_completed_tasks );
+
+	fscanf( cfp, "%d %d %d %d", 
+			(int*) &addmode, (int*) &getmode, (int*) &suspensionPolicy,
+			(int*) &machine_ordering_policy );
+
+	int worker_timeout_int;
+	fscanf( cfp, "%d %lf %d", &worker_timeout_int, 
+		&worker_timeout_limit, &worker_timeout_check_frequency);
+	worker_timeout_int ? worker_timeout = true : worker_timeout = false;
+
+	int hasbench = 0;
+	fscanf( cfp, "%d ", &hasbench );
+	if ( hasbench ) {
+		bench_task = gimme_a_task();
+		bench_task->read_ckpt_info( cfp );
+		MWprintf ( 10, "Got benchmark task:\n" );
+		bench_task->printself( 10 );
+	} 
+
+	MWprintf ( 10, "Read internal MW info.\n" );
+
+	RMC->read_checkpoint( cfp );
+
+	MWprintf ( 10, "Read RMC state.\n" );
+
+		// read old stats 
+	stats->read_checkpoint( cfp );
+	
+	MWprintf ( 10, "Read defunct workers' stats.\n" );
+
+	read_master_state( cfp );
+
+	MWprintf ( 10, "Read the user master's state.\n" );
+
+	fscanf ( cfp, "%d", &MWworkClasses );
+	MWworkClassWorkers = new int[MWworkClasses];
+	MWworkClassTasks = new int[MWworkClasses];
+	MWcurrentWorker = NULL;
+	for ( i = 0; i < MWworkClasses; i++ )
+		{
+			MWworkClassWorkers[i] = 0;
+			MWworkClassTasks[i] = 0;
+		}
+
+	int num_tasks;
+	fscanf ( cfp, "%s %d", buf, &num_tasks );
+
+	if ( strcmp( buf, "Tasks:" ) ) {
+		MWprintf ( 10, "Problem in reading Tasks separator. buf = %s\n", buf );
+		fclose ( cfp );
+		return;
+	}
+
+	MWTask *t;
+	
+	int num_todo; 
+	fscanf( cfp, "%s %d", buf, &num_todo);
+	if ( strcmp( buf, "TODO_num:" ) ) {
+		MWprintf ( 10, "Problem in reading TODO_num separator. buf = %s\n", buf );
+		fclose( cfp );
+		return;
+	}
+
+	if (task_key != NULL) {
+		/* Add all tasks by key, if user has set it. */
+		set_task_add_mode( ADD_BY_KEY );
+	}
+	else {
+		set_task_add_mode( ADD_AT_END );
+	}
+	
+	for ( i=0 ; i<num_todo ; i++ ) 	{
+		t = gimme_a_task();   // return a derived task class...
+		fscanf( cfp, "%d ", &(t->number) );
+		t->read_ckpt_info( cfp );
+		t->read_group_info ( cfp );
+		t->printself( 90 );
+		pushTask(t);
+	}
+
+	int num_running;
+	fscanf( cfp, "%s %d", buf, &num_running);
+	if ( strcmp( buf, "running_num:" ) ) {
+		MWprintf ( 10, "Problem in reading running_num separator. buf = %s\n", buf );
+		fclose( cfp );
+		return;
+	}
+
+	for ( i=0 ; i<num_running ; i++ ) 
+		{
+			t = gimme_a_task();   // return a derived task class...
+			fscanf( cfp, "%d ", &(t->number) );
+			t->read_ckpt_info( cfp );
+			t->read_group_info ( cfp );
+			t->printself( 90 );
+			pushTask(t);
+		}
+
+	MWprintf ( 10, "Read the task list.\n" );
+
+		// This is debugging code for Michael
+
+#if 1
+	if( task_key != NULL ) {
+		MWprintf( 10, "Sort the TODO task list...\n" );
+		sort_task_list();
+		MWprintf( 10, "Printing keys of user's task list...\n" );
+		print_task_keys();
+	}
+#endif
+	fclose( cfp );
+    
+	FILE *swapfile;
+	if ( (swapfile = fopen(todo->Name(), "r")) == NULL ) {
+		MWprintf(90, "Task_Swap:: No task swap file exists, has_task_swapped = false.\n");
+		has_task_swapped = false;
+	} else {
+		fclose(swapfile);
+	}
+	
+		/* Task_Swap testing code */
+	if (todo->Number() > MAX_IN_MEM) {
+		swap_out_todo_tasks();
+		checkpoint();
+	}
+	
+	MWprintf ( 10, "We are done restarting.\n" );
+}
+
+/* Read/write task */
+MWTask*
+MWDriver::read_mem_task(MWList<MWTask> *tasks)
+{
+	if (tasks->AfterEnd())
+		return NULL;
+
+	MWTask * t = tasks->RemoveCurrent();
+	todo->Next();
+	return t;
+}
+
+MWTask*
+MWDriver::read_file_task(FILE *f)
+{
+	char strbuf[128];
+
+	fscanf(f, "%s ", strbuf);
+	if (strcmp(strbuf, "~~Task~~")) {
+		MWprintf(10, "Problem in reading ~~Task~~ separator, buf=%s\n", strbuf);
+		return NULL;
+	}
+
+	MWTask *t = gimme_a_task();
+	fscanf(f, "%d ", &(t->number));
+	t->read_ckpt_info(f);
+	t->read_group_info(f);
+	MWprintf(90, "Read task %d\n", t->number);
+	return t;
+}
+
+void
+MWDriver::write_task(FILE *f, MWTask *t)
+{
+	fprintf(f, "%s \n", "~~Task~~");
+	fprintf(f, "%d \n", t->number);
+	t->write_ckpt_info(f);
+	t->write_group_info(f);
+	MWprintf(90, "Written task %d\n", t->number);
+}
+
+/* Remember to update (1) how to check whether we are done;
+ * (2) give each list a "name", so that they can be dumped into 
+ * a file; (3) change remove_tasks_worse_than() to update the 
+ * max_task_key value; (4) add logic to trigger the swapping */
+
+/** TODO Tasks Swapping **/
+bool 
+MWDriver::swap_out_todo_tasks(int num_in_mem, int max_in_mem, double max_key)
+{
+	char strbuf[128];
+	MWTask *mem_t = NULL, *file_t = NULL;
+	double mem_key = -DBL_MAX, file_key = -DBL_MAX;
+	FILE *swap, *new_swap;
+	int num_swapped, num_to_skip, num_file_task=0, num_total;
+	
+	if ( (task_key == NULL)||(todo->isSorted()==false) ) {
+		MWprintf(10, "Task_Swap:: No task_key func defined for the list.\n");
+		MWprintf(10, "Task_Swap:: I won't swap these tasks are not sorted.\n");
+		return false;
+	}
+
+	if (todo->number() < max_in_mem)
+		return true;
+	if (todo->number() < num_in_mem) /* just in case :=) */
+		return true;
+	
+		/* Skip the first num_in_mem tasks */
+	mem_t = todo->First();
+	for (int i=0; i<num_in_mem; i++)
+		todo->Next();
+
+	FILE *swapfile;
+	if ( (swapfile = fopen(todo->Name(), "r")) == NULL) {
+		MWprintf(10, "Task_Swap:: No existing swap file, dump memory directly into the file.\n");
+		
+			/* Create the swap file for the first time */
+		swap = Open(todo->Name(), "a");
+		if (swap == NULL) {
+			MWprintf(10, "Task_Swap:: Can't create swap file.\n");
+			return false;
+		}
+		
+			/* As will rebuild index, we ClearIndex() first */
+		todo->ClearIndex();
+		
+			/* First write the num_to_skip to 0 */
+		fprintf(swap, "num_to_skip %10d\n", 0);
+		fprintf(swap, "num_of_file_task %10d\n", todo->number()-num_in_mem);
+		
+			/* Remove tasks until we only have num_in_mem in list */
+		num_swapped = 0;
+		while ( (mem_t=read_mem_task(todo)) != NULL ) {
+			write_task(swap, mem_t);
+			delete mem_t;
+			num_swapped ++;
+		}
+		fflush(swap);
+		Close(swap);
+		
+			/* rebuild index for todo */
+		todo->BuildIndex();
+
+			/* Remember that we have tasks swapped out */
+		has_task_swapped = true;
+
+		MWprintf(10, "Task_Swap:: Done swapping, swapped out %d tasks, keep %d tasks in memory.\n",
+				 num_swapped, todo->number());
+	} else {
+		
+		MWprintf(10, "Task_Swap:: Will merge tasks in memory with those in file.\n");
+
+		fclose(swapfile);
+			/* As will rebuild index, we ClearIndex() first */
+		todo->ClearIndex();
+		
+			/* Create new temp file */
+		new_swap = Open("tmp_TODO_swap", "w");
+		if (new_swap == NULL) {
+			MWprintf(10, "Task_Swap:: Can't create tmp swap file.\n");
+			return false;
+		}
+
+		fprintf(new_swap, "num_to_skip %10d\n", 0);
+		fprintf(new_swap, "num_of_file_task %10d\n", 0);
+		
+			/* Open the swap file, read num_to_skip */ 
+		swap = Open(todo->Name(), "r");
+		if (swap == NULL) {
+			MWprintf(10, "Task_Swap:: Can't open swap file to read.\n");
+			return false;
+		}
+		
+		fscanf(swap, "%s %10d", strbuf, &num_to_skip);
+		if ( strcmp(strbuf, "num_to_skip") ) {
+			MWprintf(10, "Task_Swap:: problem in reading num_to_skip marker.\n");
+			Close(swap);
+			return false;
+		}
+
+			/* Read num_of_file_task */
+		fscanf(swap, "%s %10d", strbuf, &num_file_task);
+		if ( strcmp(strbuf, "num_of_file_task") ) {
+			MWprintf(10, "Task_Swap:: problem in reading num_of_file_task marker.\n");
+			Close(swap);
+			return false;
+		}
+
+			/* Skip tasks at the beginning */
+		for (int i=0; i<num_to_skip; i++) {
+			file_t = read_file_task(swap);
+			if (file_t != NULL)
+				delete file_t;
+		}
+
+		if ( (mem_t = read_mem_task(todo)) != NULL ) {
+			mem_key = (*task_key)(mem_t);
+		}
+
+		if ( (file_t = read_file_task(swap)) != NULL ) {
+			file_key = (*task_key)(file_t);
+			num_file_task --;
+		}
+		
+			/* Begin merging the rest of the file and the rest of the list */
+		num_total = 0;
+		while ( mem_t && file_t ) /* while both valid */ {
+			if (mem_key <= file_key) { 
+					/* dump current mem_t */
+				if (mem_key < max_task_key) {
+					write_task(new_swap, mem_t);
+					num_total ++;
+				}
+				delete mem_t;
+				if ( (mem_t = read_mem_task(todo)) != NULL ) {
+					mem_key = (*task_key)(mem_t);
+				}
+			} else { 
+					/* dump current file_t */
+				if (file_key < max_task_key) {
+					write_task(new_swap, file_t);
+					num_total ++;
+				}
+				delete file_t;
+				
+				if (num_file_task > 0) {
+					if ( (file_t = read_file_task(swap) ) != NULL ) {
+						file_key = (*task_key)(file_t);
+						num_file_task --;
+					} 
+				} else file_t = NULL;
+			}
+		}
+
+			/* dump the remaining */
+		if ((mem_t != NULL)) {
+			write_task(new_swap, mem_t);
+			num_total ++;
+			delete mem_t;
+			
+			while ( (mem_t = read_mem_task(todo)) != NULL ) {
+				mem_key = (*task_key)(mem_t);
+				if (mem_key < max_task_key) {
+					write_task(new_swap, mem_t);
+					num_total ++;
+				}
+				delete mem_t;
+			}
+		} else if (file_t != NULL) {
+			write_task(new_swap, file_t);
+			num_total ++;
+			delete file_t;
+			
+			while ( num_file_task > 0) {
+				if ( (file_t = read_file_task(swap)) != NULL ) {
+					file_key = (*task_key)(file_t);
+					if (file_key < max_task_key) {
+						write_task(new_swap, file_t);
+						num_total ++;
+					}
+					delete file_t;
+				}
+				num_file_task --;
+			}
+		} else {
+			MWprintf(10, "Task_Swap:: Write task error, either mem_t or file_t should be NULL.\n");
+		}
+		
+		MWprintf(10, " num_file_task now is %d\n", num_file_task);
+		Close(swap);
+			
+		fflush(new_swap);
+		Close(new_swap);
+
+			/* Update header info */
+		new_swap = Open("tmp_TODO_swap", "r+");
+		if (new_swap == NULL) {
+			MWprintf(10, "Task_Swap:: Can't open swap file to read.\n");
+			return false;
+		}
+		
+		fprintf(new_swap, "num_to_skip %10d\n", 0);
+		fprintf(new_swap, "num_of_file_task %10d\n", num_total);
+		fflush(new_swap);
+		Close(new_swap);
+
+			/* Swith the files */
+		char cmd[1024];
+		sprintf(cmd, "mv %s old_TODO_tasks", todo->Name());
+		if (system(cmd) < 0) {
+			MWprintf(10, "Task_Swap:: Can't rename the old swap file, errno = %d.\n", errno);
+			return false;
+		}
+
+		sprintf(cmd, "mv -f tmp_TODO_swap %s", todo->Name());
+		if (system(cmd) < 0) {
+			MWprintf(10, "Task_Swap:: Can't rename the new swap file, errno = %d.\n", errno);
+			return false;
+		}
+
+		remove("old_TODO_tasks");
+
+			/* rebuild index for todo */
+		todo->BuildIndex();
+		
+			/* Remember that we have tasks swapped out */
+		has_task_swapped = true;
+
+			/* Print some trash */
+		MWprintf(10, "Task_Swap:: Done swapping, swapped out %d tasks, keep %d tasks in memory.\n",
+				 num_total, todo->number());
+	}
+
+		/* Keep a snapshot */
+	checkpoint();
+	return true;
+}
+
+bool 
+MWDriver::swap_in_todo_tasks(int min_in_mem, int num_in_mem)
+{
+	char strbuf[128];
+	MWTask *file_t = NULL, * mem_t = NULL;
+	MWList<MWTask> * todo_new, * todo_old;
+	FILE *swap;
+	int num_swapped, num_to_skip, num_file_task = 0;
+	
+	if ( (todo->number() > num_in_mem) )
+		return true;
+	
+	FILE *swapfp;
+	if ( (swapfp = fopen(todo->Name(), "r")) == NULL) {
+		MWprintf(90, "Task_Swap:: No task swap file exists, will not swap in.\n");
+		has_task_swapped = false;
+		return true;
+	}
+	
+	fclose(swapfp);
+		/* Now need to bring more task on disk into mem */
+		/* Open the swap file, read num_to_skip */ 
+	swap = Open(todo->Name(), "r+");
+	if (swap == NULL) {
+		MWprintf(10, "Task_Swap:: Can't open swap file to read.\n");
+		return false;
+	}
+
+	fscanf(swap, "%s %10d", strbuf, &num_to_skip);
+	if ( strcmp(strbuf, "num_to_skip") ) {
+		MWprintf(10, "Task_Swap:: problem in reading num_to_skip marker.\n");
+		Close(swap);
+		return false;
+	}
+
+		/* Read num_of_file_task */
+	fscanf(swap, "%s %10d", strbuf, &num_file_task);
+	if ( strcmp(strbuf, "num_of_file_task") ) {
+		MWprintf(10, "Task_Swap:: problem in reading num_of_file_task marker.\n");
+		Close(swap);
+		return false;
+	}
+
+		/* Skip tasks at the beginning */
+	file_t = gimme_a_task();
+	if (file_t == NULL) {
+		MWprintf(10, "Task_Swap:: Can't allocate a task.\n");
+		return false;
+	}
+
+		/* Skip some tasks */
+	for (int i=0; i<num_to_skip; i++) {
+		file_t = read_file_task(swap);
+		if (file_t != NULL)
+			delete file_t;
+	}
+
+		/* Now begin read into mem */
+	todo_new = new MWList<MWTask>("TODO_tasks");
+	if (todo_new == NULL) {
+		MWprintf(10, "Task_Swap:: Can't allocate a new task list.\n");
+		Close(swap);
+		return false;
+	}
+	
+	num_swapped = (num_in_mem < num_file_task) ? num_in_mem : num_file_task;
+	for (int ii=0; ii<num_swapped; ii++) 
+		if ( (file_t = read_file_task(swap)) != NULL )
+			todo_new->SortedInsert(file_t, (*task_key)(file_t));
+	
+		/* Update header info */
+	if (num_swapped == num_file_task) { /* No task on disk then */
+		Close(swap);
+		remove(todo->Name());
+		has_task_swapped = false;
+	} else {
+		if (fseek(swap, 0L, SEEK_SET) == -1) {
+			MWprintf(10, "Task_Swap:: Can update header_info in the swap file, errno = %d.\n", errno);
+			return false;
+		}
+
+		fprintf(swap, "num_to_skip %10d\n", num_to_skip + num_swapped);
+		fprintf(swap, "num_of_file_task %10d\n", num_file_task-num_swapped);
+		fflush(swap);
+
+			/* Close new swap file and switch */
+		Close(swap);
+	}
+
+		/* Sorted insert old tasks into new todo list */
+	todo->First();
+	while ( (mem_t = read_mem_task(todo))!=NULL ) {
+		todo_new->SortedInsert(mem_t, (*task_key)(mem_t));
+	}
+
+	todo_old = todo;
+	delete todo_old;
+	todo = todo_new;
+	
+	MWprintf(10, "Task_Swap:: done swap in, moved %d tasks into memory. num_todo = %d.\n", 
+			 num_swapped, todo->Number());
+
+		/* Keep a snapshot */
+	checkpoint();
+	return true;
+}
+
+bool 
+MWDriver::is_TODO_empty()
+{
+	if (todo->number() > 0)
+		return false;
+	
+	if (has_task_swapped)
+		return false;
+
+	return true;
+}
+	
+int	/* Added as in $GAMS */
+MWDriver::sort_task_list ( )
+{
+		/* check and only sort the list when listsorted is FALSE */
+	if ( (task_key == NULL) || (listsorted) )
+		return 0;
+	
+	MWList<MWTask> * newList = new MWList<MWTask>;
+	while ( todo->number() > 0 )
+        {
+			MWTask *t = (MWTask *)todo->Remove();
+			newList->SortedInsert ( t, (*task_key)(t) );
+        }
+	delete todo; 
+        
+	todo = newList; 
+	
+		/* reset listsorted as TRUE */
+	listsorted = true;
+	return 0;
+}
+
+
+int 
+MWDriver::get_number_tasks() 
+{
+	return todo->number();
+}
+
+int MWDriver::get_number_running_tasks()
+{
+	return running->number();
+}
+
+void
+MWDriver::workClasses_set ( int num )
+{
+	if ( num < 1 )
+		{
+			MWprintf ( 10, "Use of workClasses_set with <= 1 classes not allowed\n");
+			assert ( 0 );
+		}
+	MWworkClasses = num;
+	MWworkClassWorkers = new int[MWworkClasses];
+	MWworkClassTasks = new int[MWworkClasses];
+
+	for ( int i = 0; i < MWworkClasses; i++ )
+		{
+			MWworkClassWorkers[i] = 0;
+			MWworkClassTasks[i] = 0;
+		}
+}
+
+int
+MWDriver::workClasses_get ( )
+{
+	return MWworkClasses;
+}
+
+int
+MWDriver::workClasses_getworkers ( int num )
+{
+	return MWworkClassWorkers[num];
+}
+
+int
+MWDriver::workClasses_gettasks ( int num )
+{
+	return MWworkClassTasks[num];
+}
+
+
+/* 8/28/00
+
+Qun added Jeff's idea of adding a SORTED list of tasks.
+This can greatly improve the efficiency in many applications.
+   
+XXX I haven't debugged this, and probably there needs to be more
+checking that the list is actually sorted.  
+*/
+
+/* added by Qun: for insert a list of sorted tasks */
+
+void 
+MWDriver::addSortedTasks( int n, MWTask **add_tasks )
+{
+	if ( n <= 0 ) {
+		MWprintf ( 10, "Please add a positive number of tasks!\n" );
+		RMC->exit(1);
+	}
+
+	for ( int i = 0; i < n; i++ )
+		{
+			add_tasks[i]->number = task_counter++;
+			if ( MWworkClasses <= 1 )
+				{
+					add_tasks[i]->initGroups ( MWworkClasses );
+					add_tasks[i]->addGroup ( 0 );
+				}
+			pushTask ( add_tasks[i] );
+		}
+}
+
+
+void 
+MWDriver::addTaskByKey( MWTask *add_task )  
+{
+	add_task->number = task_counter++;
+	if ( MWworkClasses <= 1 )
+		{
+			add_task->initGroups ( MWworkClasses );
+			add_task->addGroup ( 0 );
+		}
+	if ( task_key == NULL )
+		{
+			MWprintf ( 10, "ERROR!  Adding by key, but no key "
+					   "function defined!\n" );
+			assert(0);
+		}
+	todo->SortedInsert ( add_task, (*task_key)(add_task) );
+}
+
+//end the changes done  by Qun
+
+extern MWWorker *gimme_a_worker ();
+
+void
+MWDriver::ControlPanel ( )
+{
+
+#ifdef INDEPENDENT
+    MWReturn ustat = OK;
+    RMC->hostadd ();
+    master_mainloop_oneshot ( 0, 2 );
+    MWWorker *worker = gimme_a_worker();
+    worker->go( 1, NULL );
+    master_mainloop_oneshot ( 0, 2 );
+    worker->do_benchmark_cmd( );
+    ustat = master_mainloop_oneshot ( 0, 2 );
+    
+		// while ( ( (todo != NULL) || (running != NULL) ) && ( ustat == OK ) )
+    while ( ( (!todo->isEmpty()) || (!running->isEmpty()) ) && ( ustat == OK ) )
+		{
+			ustat = worker->worker_mainloop_oneshot ( );
+			ustat = master_mainloop_oneshot ( 0, 2 );
+		}
+    
+    MWprintf(71, "\n\n\n ***** Almost done ***** \n\n\n\n");
+
+		// found LEAK_SCOPE! need to deallocate worker
+    delete worker;
+#endif
+    return;
+}
+
+
+MWKey
+kflops( MWWorkerID *w )
+{
+	return (MWKey) w->KFlops;
+}
+
+MWKey
+benchmark_result( MWWorkerID *w )
+{
+	return (MWKey) w->get_bench_result();
+}
+
+// These are functions that might be useful, but I am not sure if they should
+//  be included in the final release.
+
+double 
+MWDriver::get_instant_pool_perf( ) 
+{
+	double total_perf = 0;
+	int total = 0;
+	MWWorkerID *w;
+
+	while ( total < workers->number() ) 
+		{
+			total++;
+			w = (MWWorkerID *)workers->Remove();
+			if ( (w->currentState() == WORKING) && (w->runningtask != NULL) ) 
+				{
+					total_perf += w->get_bench_result();
+				}
+			workers->Append ( w );
+		}
+	return total_perf;
+}
+
+MWTask*
+MWDriver::get_todo_head ( )
+{
+	MWTask *t = (MWTask *)todo->Remove();
+	todo->Prepend ( t );
+	return t;
+}
+
+MWWorkerID*
+MWDriver::get_workers_head ( )
+{
+	MWWorkerID *w = (MWWorkerID *)workers->Remove();
+	workers->Prepend ( w );
+	return w;
+}
+
+
+#if defined( XML_OUTPUT )
+
+void MWDriver::write_XML_status()
+{
+	ofstream xmlfile("/u/m/e/metaneos/public/html/iMW/status.xml",
+					 ios::trunc|ios::out);
+
+
+	if( ! xmlfile ) {
+		cerr << "Cannot open 'status.xml data file' file!\n";
+	}
+
+		//system("/bin/rm -f ~/public/html/iMW/status.xml");
+		//system("/bin/mv -f ./status.xml ~/public/html/iMW/");   
+
+		// system("/bin/more status.xml");
+
+	char *temp_ptr ;
+	temp_ptr = get_XML_status();
+
+	xmlfile << temp_ptr;
+	delete temp_ptr;
+
+		//  xmlfile << ends;
+
+	xmlfile.close();
+
+		//system("/bin/rm -f ~/public/html/iMW/status.xml");
+		//system("/bin/cp -f status.xml /u/m/e/metaneos/public/html/iMW/");
+		// system("/bin/cp -f status.xml ~metaneos/public/html/iMW/");
+}
+
+#include <strstream.h>
+
+char* MWDriver::get_XML_status(){
+
+	ifstream menus(xml_menus_filename);
+
+	ostrstream xmlstr;
+
+	xmlstr << "<?xml version=\"1.0\"?>" << endl;
+	xmlstr << "<?xml:stylesheet type=\"text/xsl\" href=\"menus-QAP.xsl\"?>" << endl;
+	xmlstr << "<INTERFACE TYPE=\"iMW-QAP\">" << endl;
+
+		// xmlstr << menus;
+
+	char ch;
+	while (menus.get(ch)) xmlstr.put(ch);
+
+		// menus >> xmlstr ;
+
+	xmlstr << "<MWOutput TYPE=\"QAP\">" << endl;
+
+	char *temp_ptr ;
+
+	temp_ptr = get_XML_job_information();
+
+	xmlstr << temp_ptr;
+	delete temp_ptr;
+
+	temp_ptr = get_XML_problem_description();
+
+	xmlstr << temp_ptr;
+	delete temp_ptr;
+
+	temp_ptr = get_XML_interface_remote_files();
+
+	xmlstr << temp_ptr;
+	delete temp_ptr;
+
+	temp_ptr = get_XML_resources_status();
+
+	xmlstr << temp_ptr;
+	delete temp_ptr;
+
+	temp_ptr = get_XML_results_status();
+
+	xmlstr << temp_ptr;
+	delete temp_ptr;
+
+	xmlstr << "</MWOutput>" << endl;
+	xmlstr << "</INTERFACE>" << endl;
+
+	xmlstr << ends;
+
+
+
+	menus.close();
+
+
+	return xmlstr.str();
+
+}
+
+char* MWDriver::get_XML_job_information()
+{
+
+	ifstream jobinfo(xml_jobinfo_filename);
+
+	ostrstream xmlstr;
+
+	char ch;
+	while (jobinfo.get(ch)) xmlstr.put(ch);
+
+	xmlstr << ends;
+
+	jobinfo.close();
+ 
+
+	return xmlstr.str();
+
+};
+
+char* MWDriver::get_XML_problem_description(){
+
+	ifstream pbdescrib(xml_pbdescrib_filename);
+
+	ostrstream xmlstr;
+
+	char ch;
+	while (pbdescrib.get(ch)) xmlstr.put(ch);
+
+	xmlstr << ends;
+
+	pbdescrib.close();
+
+
+	return xmlstr.str();
+
+};
+
+char* MWDriver::get_XML_interface_remote_files(){
+
+	ostrstream xmlstr;
+
+	xmlstr << "<InterfaceRemoteFiles>" << endl;
+
+		// dump here content of file
+
+	xmlstr << "</InterfaceRemoteFiles>" << endl;
+
+	xmlstr << ends;
+
+	return xmlstr.str();
+
+}
+
+
+char* MWDriver::get_XML_resources_status()
+{
+
+	int total;
+	int i;
+	ostrstream xmlstr;
+
+		// Begin XML string
+
+	xmlstr << "<ResourcesStatus>" << endl;
+
+	double average_bench;
+	double equivalent_bench;
+	double min_bench;
+	double max_bench;
+	double av_present_workers;
+	double av_nonsusp_workers;
+	double av_active_workers;
+	double equi_pool_performance;
+	double equi_run_time;
+	double parallel_performance;
+	double wall_time;
+
+	stats->get_stats(&average_bench,
+					 &equivalent_bench,
+					 &min_bench,
+					 &max_bench,
+					 &av_present_workers,
+					 &av_nonsusp_workers,
+					 &av_active_workers,
+					 &equi_pool_performance,
+					 &equi_run_time,
+					 &parallel_performance,
+					 &wall_time,
+					 workers
+					 );
+
+		// MWStats Information
+
+	xmlstr << "<MWStats>" << endl;
+
+	xmlstr << "<WallClockTime>" << wall_time << "</WallClockTime>" << endl;
+	xmlstr << "<NormalizedTotalCPU>" << equi_run_time << "</NormalizedTotalCPU>" << endl;
+	xmlstr << "<ParallelEff>" <<  parallel_performance << "</ParallelEff>" << endl;
+
+	xmlstr << "<BenchInfo>" << endl;
+	xmlstr << "<InstantPoolPerf>" << get_instant_pool_perf() << "</InstantPoolPerf>" << endl;
+	xmlstr << "<EquivalentPoolPerf>" << equi_pool_performance << "</EquivalentPoolPerf>" << endl;
+	xmlstr << "<AverageBench>" << average_bench << "</AverageBench>" << endl;
+	xmlstr << "<EquivalentBench>" << equivalent_bench << "</EquivalentBench>" << endl;
+	xmlstr << "<MinBench>" << min_bench << "</MinBench>" << endl;
+	xmlstr << "<MaxBench>" << max_bench << "</MaxBench>" << endl;
+	xmlstr << "</BenchInfo>" << endl;
+
+	xmlstr << "<AverageWorkersStats>" << endl;
+	xmlstr << "<AveragePresentWorkers>" << av_present_workers << "</AveragePresentWorkers>" << endl;
+	xmlstr << "<AverageNonSuspWorkers>" << av_nonsusp_workers << "</AverageNonSuspWorkers>" << endl;
+	xmlstr << "<AverageActiveWorkers>"  << av_nonsusp_workers << "</AverageActiveWorkers>" << endl;
+	xmlstr << "</AverageWorkersStats>" << endl;
+
+
+	xmlstr << "</MWStats>" << endl;
+
+		// Master Information
+
+	xmlstr << "<Master>" << endl;
+
+	xmlstr << "<MasterPhysicalProperties>" << endl;
+	xmlstr << "<Name>" << mach_name << "</Name>" << endl;
+		//     xmlstr << "<IPAddress>" << get_IPAddress() << "</IPAddress>" << endl;
+	xmlstr << "<OpSys>" << get_OpSys() << "</OpSys>" << endl;
+	xmlstr << "<Arch>" << get_Arch() <<"</Arch>" << endl;
+	xmlstr << "<Memory>" << get_Memory() << "</Memory>" << endl;
+	xmlstr << "<VirtualMemory>" << get_VirtualMemory() << "</VirtualMemory>" <<  endl; 
+	xmlstr << "<DiskSpace>" << get_Disk() << "</DiskSpace>" << endl;
+	xmlstr << "<KFlops>" << get_KFlops() << "</KFlops>" << endl;
+	xmlstr << "<Mips>" << get_Mips() << "</Mips>" << endl;
+	xmlstr << "<CPUs>" << get_Cpus() << "</CPUs>" << endl;
+	xmlstr << "<NWSinfos/>" << endl;
+	xmlstr << "</MasterPhysicalProperties>" << endl;
+                       
+
+
+	xmlstr << "<MasterUsageProperties>" << endl;
+	xmlstr << "<StartTime>July 1st 1999, 18:21:12s GMT</StartTime>"  << endl;
+	xmlstr << "</MasterUsageProperties>" << endl;
+
+	xmlstr << "</Master>" << endl;
+
+		// Worker Information
+
+	xmlstr << "<Workers>" << endl;
+
+	int numworkers = numWorkersInState( INITIALIZING ) +  numWorkersInState( BENCHMARKING ) + numWorkersInState( IDLE ) + numWorkersInState( WORKING ) ;
+
+	xmlstr << "<WorkersNumber>" << numworkers << "</WorkersNumber>" << endl;
+
+	xmlstr << "<WorkersStats>" << endl;
+
+	xmlstr << "<WorkersInitializing>" << numWorkersInState( INITIALIZING ) << "</WorkersInitializing>" << endl;
+	xmlstr << "<WorkersBenchMarking>" << numWorkersInState( BENCHMARKING ) << "</WorkersBenchMarking>" << endl;
+	xmlstr << "<WorkersWaiting>" << numWorkersInState( IDLE ) << "</WorkersWaiting>" << endl;
+	xmlstr << "<WorkersWorking>" << numWorkersInState( WORKING ) << "</WorkersWorking>" << endl;
+	xmlstr << "<WorkersSuspended>" << numWorkersInState( SUSPENDED ) << "</WorkersSuspended>" << endl;
+	xmlstr << "<WorkersDone>" << numWorkersInState( EXITED ) << "</WorkersDone>" << endl;
+
+	xmlstr << "</WorkersStats>" << endl;
+
+	xmlstr << "<WorkersList>" << endl;
+
+	total = 0;
+	MWWorkerID *w;
+
+	while ( total < workers->number() ) 
+		{
+			total++;
+			w = (MWWorkerID *)workers->Remove();
+
+			if ((w->currentState() != SUSPENDED) || (w->currentState() != EXITED))
+				{
+		         
+					xmlstr << "<Worker>" << endl;
+
+					xmlstr << "<WorkerPhysicalProperties>" << endl;
+
+					xmlstr << "<Name>" << w->machine_name() << "</Name>" << endl;
+						//          xmlstr << "<IPAddress>" << w->get_IPAddress() << "</IPAddress>" << endl; 
+					xmlstr << "<Status>" << MWworker_statenames[w->currentState()] << "</Status>" << endl; 
+					xmlstr << "<OpSys>" << w->OpSys << "</OpSys>" << endl; 
+					xmlstr << "<Arch>" <<  w->Arch << "</Arch>" << endl; 
+					xmlstr << "<Bandwidth>" << "N/A" << "</Bandwidth>" << endl; 
+					xmlstr << "<Latency>" << "N/A" << "</Latency>" << endl; 
+					xmlstr << "<Memory>" << w->Memory << "</Memory>" <<  endl; 
+					xmlstr << "<VirtualMemory>" << w->VirtualMemory << "</VirtualMemory>" <<  endl; 
+					xmlstr << "<DiskSpace>" << w->Disk << "</DiskSpace>" << endl; 
+					xmlstr << "<BenchResult>" << w->get_bench_result() <<"</BenchResult>" << endl;
+					xmlstr << "<KFlops>" << w->KFlops <<"</KFlops>" << endl;
+					xmlstr << "<Mips>" << w->Mips <<"</Mips>" << endl;   
+					xmlstr << "<CPUs>" << w->Cpus <<"</CPUs>" << endl;
+					xmlstr << "<NWSinfos>" << "N/A" << "</NWSinfos>" << endl; 
+
+					xmlstr << "</WorkerPhysicalProperties>" << endl;
+
+					xmlstr << "<WorkerUsageProperties>" << endl;
+
+					xmlstr << "<TotalTime>" << "N/A" << "</TotalTime>" << endl;
+					xmlstr << "<TotalWorking>" << w->get_total_working() << "</TotalWorking>" << endl;
+					xmlstr << "<TotalSuspended>" << w->get_total_suspended() << "</TotalSuspended>" << endl;
+
+					xmlstr << "</WorkerUsageProperties>" << endl;
+
+					xmlstr << "</Worker>" << endl;
+				}
+			workers->Append ( w );
+		}
+
+	xmlstr << "</WorkersList>" << endl;
+
+	xmlstr << "</Workers>" << endl;
+
+		// Global Worker Statistics
+
+	xmlstr << "<GlobalStats>" << endl;
+
+      
+
+	xmlstr << "</GlobalStats>" << endl;
+
+		// Task Pool Information
+
+
+	xmlstr << "<TaskPoolInfos>" << endl;
+
+	int nrt = get_number_running_tasks();
+	int tt = get_number_tasks();
+	int tdt = tt - nrt;
+
+	xmlstr << "<TotalTasks>" << tt << "</TotalTasks>" << endl;
+	xmlstr << "<TodoTasks>" << tdt << "</TodoTasks>" << endl;
+	xmlstr << "<RunningTasks>" << nrt << "</RunningTasks>" << endl;
+	xmlstr << "<NumberCompletedTasks>" << num_completed_tasks << "</NumberCompletedTasks>" << endl;
+		//xmlstr << "<MaxNumberTasks>" << max_number_tasks << "</MaxNumberTasks>" << endl;
+	xmlstr << "</TaskPoolInfos>" << endl;
+
+		// Memory Info
+
+		// Secondary storage info
+
+
+		// End  XML string
+
+	xmlstr << "</ResourcesStatus>" << endl;
+	xmlstr << ends ;
+
+	return xmlstr.str();
+
+}
+
+char* MWDriver::get_XML_results_status(){
+
+	ostrstream xmlstr;
+
+	xmlstr << "<ResultsStatus>" << endl;
+	xmlstr << "</ResultsStatus>" << endl;
+
+	xmlstr << ends;
+
+	return xmlstr.str();
+
+}
+
+/* The following (until the end of the file) was written by one of 
+   Jean-Pierre's students.  It isn't exactly efficient, dumping
+   a condor_status output to a file and reading from that.  I understand
+   that it does work, however.  -MEY (8-18-99) */
+
+/* UPDATE:  Note that it doesn't work for flocked machines - GGT 9/26/06 */
+
+int MWDriver::check_for_int_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return atoi(value);
+	else return NO_VAL;
+}
+
+double MWDriver::check_for_float_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return atof(value);
+	else return NO_VAL;  
+}
+
+int  MWDriver::check_for_string_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return 0;
+	else return NO_VAL;  
+}
+
+
+void MWDriver::get_machine_info()
+{
+	FILE* inputfile;
+	char filename[50];
+	char key[200];
+	char value[1300];
+	char raw_line[1500];
+	char* equal_pos;
+	int found;
+	char temp_str[256];
+
+	char zero_string[2];
+
+	memset(zero_string, 0 , sizeof(zero_string));
+
+	memset(filename, '\0', sizeof(filename));
+	memset(key, '\0', sizeof(key));
+	memset(value, '\0', sizeof(value));
+
+	strcpy(filename, "/tmp/metaneos_file2");
+
+	memset(temp_str, '\0', sizeof(temp_str));
+	sprintf(temp_str, "%s/bin/condor_status -l %s > %s", CONDOR_DIR, mach_name, filename);
+
+	if (system(temp_str) < 0)
+		{
+
+			MWprintf( 10, "Error occurred during attempt to get condor_status for %s.\n",  mach_name );
+			return;
+		}
+
+	if ((inputfile = fopen(filename, "r")) == 0)
+		{
+			MWprintf( 10, "Failed to open condor_status file!\n");
+			return;
+		}
+	else
+		{
+			MWprintf( 90, "Successfully opened condor_status file.\n");      
+		}
+
+	while (fgets(raw_line, 1500, inputfile) != 0)
+		{
+			found = 0;
+			equal_pos = strchr(raw_line, '=');
+
+			if (equal_pos != NULL)
+				{
+					strncpy(key, raw_line, equal_pos - (raw_line+1));
+					strcpy(value, equal_pos+2);
+
+					if (CondorLoadAvg == NO_VAL && !found)
+						{
+							CondorLoadAvg = check_for_float_val("CondorLoadAvg", key, value);
+							if (CondorLoadAvg != NO_VAL)
+								found = 1;
+						}
+
+					if (LoadAvg == NO_VAL && !found)
+						{
+							LoadAvg = check_for_float_val("LoadAvg", key, value);
+							if (LoadAvg != NO_VAL)
+								found = 1;
+						}
+
+					if (Memory == NO_VAL && !found)
+						{
+							Memory = check_for_int_val("Memory", key, value);
+							if (Memory != NO_VAL)
+								found = 1;
+						}
+
+					if (Cpus == NO_VAL && !found)
+						{
+							Cpus = check_for_int_val("Cpus", key, value);
+							if (Cpus != NO_VAL)
+								found = 1;
+						}
+
+					if (VirtualMemory == NO_VAL && !found)
+						{
+							VirtualMemory = check_for_int_val("VirtualMemory", key, value);
+							if (VirtualMemory != NO_VAL)
+								found = 1;
+						}
+
+					if (Disk == NO_VAL && !found)
+						{
+							Disk = check_for_int_val("Disk", key, value);
+							if (Disk != NO_VAL)
+								found = 1;
+						}
+
+					if (KFlops == NO_VAL && !found)
+						{
+							KFlops = check_for_int_val("KFlops", key, value);
+							if (KFlops != NO_VAL)
+								found = 1;
+						}
+
+					if (Mips == NO_VAL && !found)
+						{
+							Mips = check_for_int_val("Mips", key, value);
+							if (Mips != NO_VAL)
+								found = 1;
+						}
+
+	  
+					if ( (strncmp(Arch, zero_string, 1) == 0) && !found)
+						{	     
+							if (check_for_string_val("Arch", key, value) == 0){
+								strncpy( Arch, value, sizeof(Arch) );	       
+							}
+	     
+							if (strncmp(Arch, zero_string, 1) != 0)
+								found = 1;
+						}
+
+					if ( (strncmp(OpSys, zero_string, 1) == 0) && !found)
+						{	     
+							if (check_for_string_val("OpSys", key, value) == 0){
+								strncpy( OpSys, value, sizeof(OpSys) );	       
+							}
+	     
+							if (strncmp(OpSys, zero_string, 1) != 0)
+								found = 1;
+						}
+
+					if ( (strncmp(IPAddress, zero_string, 1) == 0) && !found)
+						{	     
+							if (check_for_string_val("StartdIpAddr", key, value) == 0){
+								strncpy(IPAddress , value, sizeof(IPAddress) );	       
+							}
+	     
+							if (strncmp(IPAddress, zero_string, 1) != 0)
+								found = 1;
+						}
+
+
+					memset(key, '\0', sizeof(key));
+					memset(value, '\0', sizeof(value));
+
+				}
+
+		}
+
+	MWprintf(90,"CURRENT MACHINE  : %s \n", mach_name);
+	MWprintf(90,"Architecture : %s \n", Arch);
+	MWprintf(90,"Operating System : %s \n", OpSys);
+	MWprintf(90,"IP address : %s \n", IPAddress);
+
+	MWprintf(90,"CondorLoadAvg : %f\n", CondorLoadAvg);
+	MWprintf(90,"LoadAvg : %f\n", LoadAvg);
+	MWprintf(90,"Memory : %d\n", Memory);
+	MWprintf(90,"Cpus : %d\n", Cpus);
+	MWprintf(90,"VirtualMemory : %d\n", VirtualMemory);
+	MWprintf(90,"Disk : %d\n", Disk);
+	MWprintf(90,"KFlops : %d\n", KFlops);
+	MWprintf(90,"Mips : %d\n", Mips);
+
+	fclose( inputfile );
+
+	if (remove(filename) != 0)
+		{
+			MWprintf(10,"Condor status file NOT removed!\n");
+		}
+	else
+		{
+			MWprintf(90,"Condor status file removed.\n");
+		}
+
+
+}
+#endif
+
+
+static char hostname[255];
+
+char* 	
+MWDriver::getHostName ()
+{
+    MWSystem::gethostname(hostname, 255);
+	return hostname;
+}
+
+int
+MWDriver::getNumWorkers()
+{
+	return workers->number();
+}
+
+#ifdef MEASURE
+void 
+MWDriver::_measure()
+{
+	time_t now_time = time(0);
+	if ( now_time - _measure_last_read_opt_time >= _measure_read_opt_interval ) {
+			// Need to read the option file again
+		_measure_read_options(_measure_opt_file_name);
+		_measure_last_read_opt_time = now_time;
+	} else if ( now_time - _measure_last_dump_rec_time >= _measure_dump_rec_interval ) {
+		if (_measure_num_task_Done == 0)
+			return;
+
+			// Need to dump measurement result again
+			// First collect the information
+		statsgather(workers, stats);
+			
+		_measure_master_wall_time += _measure_cur_wall_time();
+		_measure_master_cpu_time += _measure_cur_cpu_time();
+		if (_measure_master_cpu_time < 0.0001)
+			_measure_master_cpu_time = 0.0;
+		if (_measure_master_recv_cpu_time < 0.0001)
+			_measure_master_recv_cpu_time = 0.0;
+		if (_measure_master_act_on_completed_task_cpu_time < 0.0001)
+			_measure_master_act_on_completed_task_cpu_time = 0.0;
+		if (_measure_task_MP_worker_cpu_time < 0.0001)
+			_measure_task_MP_worker_cpu_time = 0.0;
+
+	    	// Dump record to file
+		_measure_dump_records();
+
+		if (_measure_use_adaptation == 1) {
+				// Adapt the number of workers when necessary
+			_measure_adapt();
+		}
+
+			// Reset the measurement numbers for the next run
+		_measure_reset();
+	}
+}
+
+void MWDriver::_measure_reset()
+{
+		// Reset the measurements for the next interval
+	MWprintf(91, "MEASURE: reset all measurement related values to default.\n");
+	_measure_num_task_Done = 0;
+	_measure_master_wall_time = 0.0 - _measure_cur_wall_time();
+	_measure_master_cpu_time = 0.0 - _measure_cur_cpu_time();
+	_measure_master_recv_time = 0.0;
+	_measure_master_recv_cpu_time = 0.0;
+	_measure_master_act_on_completed_task_time = 0.0;
+	_measure_master_act_on_completed_task_cpu_time = 0.0;
+	_measure_task_RoundTrip_time = 0.0;
+	_measure_task_MP_master_time = 0.0;
+	_measure_task_MP_worker_time = 0.0;
+	_measure_task_MP_worker_cpu_time = 0.0;
+	_measure_task_Exe_wall_time = 0.0;
+	_measure_task_Exe_cpu_time = 0.0;
+	_measure_target_num_workers = 99999;
+}
+
+void
+MWDriver::_measure_dump_header() 
+{
+		// Create the file and write the first several lines		
+	FILE *rec;
+	if ( (rec = fopen(_measure_rec_file_name, "a")) == NULL ) {
+		MWprintf(31, "MEASURE|Failed to open %s for measurement records! errno = %d\n", 
+				 _measure_rec_file_name, errno);
+	} else {
+		fprintf(rec, "Start_time = %s\n", ctime(&_measure_last_read_opt_time));
+		fprintf(rec, "NOW_TIME LastDump #Wkr #RUN #TODO #Done(sum) *M_wall(-CPU-) *M_recv(-CPU-) *W_recv(-CPU-) *M_exec(-CPU-) *W_exec(-CPU-) #MSGS\n");
+		fclose(rec);
+	}
+}
+
+void 
+MWDriver::_measure_dump_records()
+{
+	time_t now_time = time(0);
+	
+	FILE *rec;
+	if ( (rec = fopen(_measure_rec_file_name, "a")) == NULL ) {
+		MWprintf(31, "MEASURE|Failed to open %s for measurement records! errno = %d \n", _measure_rec_file_name, errno);
+		return;
+	} 
+	
+		// NOW_TIME LastDump 
+	char *now = ctime(&now_time);
+	now[19] = '\0';
+	fprintf(rec, "%s ", &now[11]);
+	char *last = ctime(&_measure_last_dump_rec_time);
+	last[19] = '\0';
+	fprintf(rec, "%s ", &last[11]);
+		// Then the numbers
+        // #Wkr #RUN #TODO #Done(sum) *M_wall(-CPU-) *M_recv(-CPU-) *W_recv(-CPU-) *M_exec(-CPU-) *W_exec(-CPU-) *T_RTrp
+	if (_measure_num_task_Done) {
+		fprintf(rec, "%3d %3d %6d %3d(%6d) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f)\n",
+				(workers->number()>999)?999:workers->number(),		// %3d #Wkr
+				(running->number()>999)?999:running->number(), 		// %3d #RUN
+				(todo->number()>999999)?999999:todo->number(), 		// %6d #TODO
+				_measure_num_task_Done,					// %3d #Done
+				(num_completed_tasks>999999)?999999:num_completed_tasks,// %6d (sum)
+			
+				_measure_master_wall_time, 				// %7.2f *M_wall
+				_measure_master_cpu_time,				// %5.1f (-CPU-)
+				_measure_master_recv_time,				// %7.2f *M_recv
+				_measure_master_recv_cpu_time,				// %5.1f (-CPU-)
+				_measure_task_MP_worker_time/_measure_num_task_Done,	// %7.2f *W_recv 
+				_measure_task_MP_worker_cpu_time/_measure_num_task_Done,// %5.1f (-CPU-)
+				_measure_master_act_on_completed_task_time, 		// %7.2f *M_exec
+				_measure_master_act_on_completed_task_cpu_time,		// %5.1f (-CPU-)
+				_measure_task_Exe_wall_time/_measure_num_task_Done, 	// %7.2f *T_exec
+				_measure_task_Exe_cpu_time/_measure_num_task_Done 	// %5.1f (-CPU-)
+					// 	_measure_task_RoundTrip_time/_measure_num_task_Done 	// %7.2f *T_RTrp
+				);
+		MWList<void> * recv_buf_list = RMC->recv_buffers();
+		if (recv_buf_list) {
+			fprintf(rec, "BUFFER: size = %4d\n", RMC->recv_buffers()->number() );
+		}
+	} else {
+		fprintf(rec, "%3d %3d %6d %3d(%6d) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f) %7.2f(%5.1f)\n",
+				(workers->number()>999)?999:workers->number(),		// %3d #Wkr
+				(running->number()>999)?999:running->number(), 		// %3d #RUN
+				(todo->number()>999999)?999999:todo->number(), 		// %6d #TODO
+				_measure_num_task_Done,					// %3d #Done
+				(num_completed_tasks>999999)?999999:num_completed_tasks,// %6d (sum)
+			
+				_measure_master_wall_time, 				// %7.2f *M_wall
+				_measure_master_cpu_time,				// %5.1f (-CPU-)
+				_measure_master_recv_time,				// %7.2f *M_recv
+				_measure_master_recv_cpu_time,				// %5.1f (-CPU-)
+				0.0,							// %7.2f *W_recv 
+				0.0,							// %5.1f (-CPU-)
+				_measure_master_act_on_completed_task_time, 		// %7.2f *M_exec
+				_measure_master_act_on_completed_task_cpu_time,		// %5.1f (-CPU-)
+				0.0,							// %7.2f *T_exec
+				0.0							// %5.1f (-CPU-)
+					// 0.0  						// %7.2f *T_RTrp
+				);
+		MWList<void> * recv_buf_list = RMC->recv_buffers();
+		if (recv_buf_list) {
+			fprintf(rec, "BUFFER: size = %4d\n", RMC->recv_buffers()->number() );
+		}
+	}
+		
+	fclose(rec);
+	_measure_last_dump_rec_time = now_time;
+
+		/*
+		  if (num_completed_tasks > 20000) {
+		  MWprintf(31, "Jichuan's hack - exit when running too long!");
+		  assert(0);
+		  exit(1);
+		  }
+		*/
+	
+}
+
+void 
+MWDriver::_measure_read_options(const char* opt_fname)
+{
+	FILE *opt;
+	if ( (opt = fopen(opt_fname, "r")) == NULL ) {
+		MWprintf (31, "MEASURE|%s not found, uses default.\n", opt_fname);
+		return;
+	}
+	
+	char str[512];
+	char *ret = NULL;
+	while (fgets(str, 512, opt)) {
+		if ((str[0] == '#')||(str[0] == ' ')) // comments
+			continue;
+		ret = strchr(str, '\n');
+		if (ret) *ret = '\0';
+		if (strstr(str, "dump_record_interval") != NULL) {
+			_measure_dump_rec_interval = atoi( &(str[strlen("dump_record_interval")+1]) );
+			MWprintf(31, "MEASURE|Setting dump_record_interval = %d\n", _measure_dump_rec_interval);
+		} else if (strstr(str, "read_option_interval") != NULL) {
+			_measure_read_opt_interval = atoi( &(str[strlen("read_option_interval")+1]) );
+			MWprintf(31, "MEASURE|Setting read_option_interval = %d\n", _measure_read_opt_interval);
+		} else if (strstr(str, "use_adaptation") != NULL) {
+			_measure_use_adaptation = 1;
+			MWprintf(21, "MEASURE|Setting use_adaptation to yes. \n");
+		}
+
+	}
+	fclose(opt);
+}
+
+void 
+MWDriver::_measure_remove_worker()
+{
+	MWWorkerID * w = _measure_current_worker;
+	MWprintf(31, "MEASURE|ADAPT|Removing worker id1 = %08x \n", w->get_id1());
+	RMC->initsend ( );
+	RMC->send ( w->get_id1(), KILL_YOURSELF );
+	worker_last_rites ( w );
+}
+
+void 
+MWDriver::_measure_adapt()
+{
+	if (_measure_num_task_Done == 0)  {
+		return;
+	}
+	
+	if (_measure_target_num_workers < workers->number()) {
+			// need to remove more workers, still adapting ...
+		_measure_remove_worker();		
+		return;
+	}
+		
+	_measure_master_wait_rate = _measure_master_recv_time/_measure_master_wall_time;
+	if (_measure_master_wait_rate  < 0.001) { // then the workers MIGHT BE WAITING
+		_measure_master_busy_times ++ ; 
+	} else if (_measure_master_wait_rate > 0.50) { // then the master is WAITING
+		_measure_master_wait_times ++;
+	}
+				
+	if (_measure_master_busy_times > workers->number()/10 ) {
+			// reduce target worker numbers
+		_measure_master_busy_times = 0;
+		
+		_measure_target_num_workers = (workers->number()>12)? workers->number()-12 : 6;
+		RMC->set_target_num_workers(_measure_target_num_workers);
+		
+		_measure_remove_worker();
+		
+		call_hostaddlogic();
+		MWprintf(31, "MEASURE|ADAPT|decrease worker number to %d\n", _measure_target_num_workers);
+	}
+	
+	if (_measure_master_wait_times > 10) {
+			// ask for more workers
+		_measure_master_wait_times = 0;
+		
+		if (RMC->get_num_exec_classes() == 0) {
+			int target = RMC->get_target_num_workers(-1);
+			if (workers->number() == target) {
+				RMC->set_target_num_workers(target + 6);
+				MWprintf(31, "MEASURE|ADAPT|increase worker number to %d\n", target+6);
+			}
+		}
+	}
+}
+#endif // MEASURE
+
+void 
+MWDriver::prepare_update(int mode)
+{
+	MWWorkerID *w = workers->First();
+	switch(mode)
+		{
+		case -2:
+			while ( workers->AfterEnd() == false )
+				{
+					if( w->currentState() != BENCHMARKING && w->currentState() != INITIALIZING )
+						{
+							w = workers->Current();
+							RMC->initsend();
+							pack_update();
+							RMC->send(w->get_id1(), UPDATE_FROM_DRIVER);
+						}
+					workers->Next();
+				}
+			break;
+		case -1:
+			RMC->initsend();
+			pack_update();
+			send_update_message();
+			break;
+		default:
+			RMC->initsend();
+			pack_update();
+			send_update_message_to(mode);
+		}
+}
+
+/* send a UPDATE_FROM_DRIVER message to MWcurrentWorker, assuming the user has 
+ * already called RMC->initsend(), and RMC->pack() for the read data. */
+int 
+MWDriver::send_update_message()
+{
+	if (MWcurrentWorker == NULL)
+		return -1;
+
+	return RMC->send(MWcurrentWorker->get_id1(), UPDATE_FROM_DRIVER);
+}
+
+/* send a UPDATE_FROM_DRIVER message to a specific worker, assuming the user has 
+ * already called RMC->initsend(), and RMC->pack() for the read data. */
+int
+MWDriver::send_update_message_to(int worker)
+{
+	return RMC->send(worker, UPDATE_FROM_DRIVER);
+}
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq c-tab-always-indent nil)
+  eval: (setq tab-width 4)
+  End:
+*/
+
+void
+MWDriver::increasePendingNum(void)
+{
+  	pthread_mutex_lock(&m_pending_mutex);
+  	m_pending_num++;
+  	pthread_mutex_unlock(&m_pending_mutex);
+}
+void
+MWDriver::decreasePendingNum(void)
+{
+  	pthread_mutex_lock(&m_pending_mutex);
+  	m_pending_num--;
+	pthread_cond_signal(&m_pending_cond);
+  	pthread_mutex_unlock(&m_pending_mutex);
+}
+
+void 
+MWDriver::getGlobalLock(void)
+{
+	pthread_mutex_lock(&global_mw_mutex);
+}
+
+void 
+MWDriver::getGlobalUnLock(void)
+{
+	pthread_mutex_unlock(&global_mw_mutex);
+}
diff --git a/MW/src/MWDriver.h b/MW/src/MWDriver.h
new file mode 100644
index 0000000..82d5574
--- /dev/null
+++ b/MW/src/MWDriver.h
@@ -0,0 +1,1274 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWDRIVER_H
+#define MWDRIVER_H
+
+#include "MWTask.h"
+#include "MWWorker.h"
+#include "MWStats.h"
+#include "MWList.h"
+#include "MW.h"
+#include <MWRMComm.h>
+#include <pthread.h>
+
+/// This is the "key" by which the task list can be managed.
+#define MWKey double
+//typedef double MWKey;
+
+/// This is if you wish to have XML output.
+//#define XML_OUTPUT
+// (Note -- it should be included in 'configure' output later)
+
+/** The ways in which tasks may be added to the list.
+*/
+enum MWTaskAdditionMode {
+  /// Tasks will be added at the end of the list
+  ADD_AT_END,
+  /// Tasks will be added at the beginning
+  ADD_AT_BEGIN,
+  /// Tasks will be added based on their key (low keys before high keys)
+  ADD_BY_KEY 
+};
+
+/** The ways in which tasks may be removed from the list.
+*/
+enum MWTaskRetrievalMode {
+  /// Task at head of list will be returned.
+  GET_FROM_BEGIN,
+  /// Task with lowest key will be retrieved
+  GET_FROM_KEY 
+};
+
+enum MWREFRESH_TYPE
+{
+	MW_ALL,
+	MW_THIS,
+	MW_NONE
+};
+
+/** The suspension policy to use - What do we do when it happens? */
+enum MWSuspensionPolicy {
+		/// Normally do nothing unless there are idle workers.
+	DEFAULT,
+		/** Always reassign the task; move it to the front of the 
+			todo list */
+	REASSIGN 
+};
+
+/** Tasks are always assigned to he first "IDLE" machine.  By ordering
+    the machine list, we can implement a number of scheduling policies.
+    Insert your own favorite policy here.
+*/
+enum MWMachineOrderingPolicy {
+
+  /// The machines are ordered simply as they become available
+  NO_ORDER,
+  
+  /** Machines are ordered by the "benchmark" result.  Larger benchmark results
+      go first, so if using time to complete a task as the benchmark, you
+      should return 1/time as the benchmark value.
+  */
+  BY_USER_BENCHMARK,
+
+  /// Machines are ordered by KFLOPS reported by Condor.
+  BY_KFLOPS
+  
+};
+
+/* TASK CLUSTERING / WORK CYCLE */
+
+/** This class is responsible for managing an application in an 
+    opportunistic environment.  The goal is to be completely fault - 
+    tolerant, dealing with all possiblities of host (worker) problems.  
+    To do this, the MWDriver class manages a set of tasks and a set 
+    of workers.  It monitors messages about hosts coming up and 
+    going down, and assigns tasks appropriately.
+
+	This class is built upon some sort of resource management and 
+	message passing lower layer.  Previously, it was built directly 
+	on top of Condor - PVM, but the interface to that has been 
+	abstracted away so that it can use any facility that provides 
+	for resource management and message passing.  See the abstract
+	MWRMComm class for details of this lower layer.  When interfacing
+	with this level, you'll have use the RMC object that's a static
+	member of the MWDriver, MWTask, and MWWorker class.  
+
+    To implement an application, a user must derive a class from this
+    base class and implement the following methods:
+
+    - get_userinfo()
+    - setup_initial_tasks()
+    - pack_worker_init_data()
+    - act_on_completed_task()
+  
+
+	For a higher level of control regarding distribution of tasks to workers, 
+	tasks and workers may be enrolled to workclasses/groups by calling the
+	following methods:
+
+	- MWWorkerID::addGroup()
+	- MWWorkerID::deleteGroup()
+	- MWTask::addGroup()
+	- MWTask::deleteGroup()
+
+	These methods can be called by an application using workclasses:
+	
+	- workClasses_set()  (Required)
+	- workClasses_get()
+	- workClasses_gettasks()
+	- workClasses_getworkers()
+
+	To enroll workers in workclasses, there are two options:
+	- act_on_starting_worker() can be implemented to enroll workers to 
+	workclasses based on MWWorkerID info at the start of execution
+	- pack_worker_init_data() can be implemented to enroll workers. When used 
+	in conjunction with refreshWorkers(), can change workclass of workers in the 	middle of execution.	
+
+    Similar application dependent methods must be implemented
+    for the "Task" of work to be done and the "Worker" who performs
+    the tasks.
+    
+    @see MWTask
+    @see MWWorker
+    @see MWRMComm
+    @author Mike Yoder, Jeff Linderoth, Jean-Pierre Goux, Sanjeev Kulkarni
+*/
+
+
+class MWDriver {
+
+	friend class MWTask;
+
+	public:
+	
+		/// Default constructor
+		MWDriver();
+	
+		/** Destructor - walks through lists of tasks & workers and
+		deletes them. */	
+		virtual ~MWDriver();
+	
+		/** This method runs the entire fault-tolerant
+		application in the condor environment.  What is *really* does
+		is call setup_master(), then master(), then printresults(), 
+		and then ends.  See the other functions	for details. 
+		*/
+		void go( int argc, char *argv[] );
+	
+		/** This version of go simply calls go(0, NULL).*/
+		void go() { go ( 0, NULL ); };
+  
+		/**
+		Prints the Results. Applications may re-implement this
+		to print their application specific results.
+		It is meant to be over-ridden.
+		*/
+		virtual void printresults();
+
+
+		/** A static instance of our Resource Management / Communication
+		class.  It's a member of this class because that way derived
+		classes can use it easily; it's static because there should
+		only be one instance EVER.  The instance of RMC in the MWTask
+		class is actually a pointer to this one... */
+		static MWRMComm * RMC;
+
+
+	protected:
+	
+		/**@name A. Pure Virtual Methods
+		These are the methods from the MWDriver class that a user 
+		{\bf must} reimplement in order to have to create an application. 
+		*/
+	
+		//@{
+		/** This function is called to read in all information
+		specific to a user's application and do any initialization on
+		this information.
+		*/
+		virtual MWReturn get_userinfo( int argc, char *argv[] )=0;
+  
+		/** This function must return a number n > 0 of pointers
+		to Tasks to "jump start" the application.
+			
+		The MWTasks pointed to should be of the task type derived
+		for your application
+		*/
+		virtual MWReturn setup_initial_tasks( int *n, MWTask ***task ) = 0;
+	
+		/** 
+		This function performs actions that happen
+		once the Driver receives notification of a completed task.  
+		You will need to cast the MWTask * to a pointer of the Task type 
+		derived for your application.  For example
+
+				\begin{verbatim}
+				My_Task *dt = dynamic_cast<My_Task *> ( t );
+				assert( dt );     
+				\end{verbatim}
+		*/
+		virtual MWReturn act_on_completed_task( MWTask * ) = 0;
+
+		/**
+			This is called once the Worker is done with the TaskContainer.
+			- Put the logic for this in MWDriver
+		*/
+		//virtual MWReturn act_on_completed_task( MWTaskContainer * ) = 0;
+
+		/**
+		This function should be implemented by the application
+		to assign the workClass number to the worker if it is doing
+		intelligent work scheduling.
+		*/
+		virtual MWReturn act_on_starting_worker ( MWWorkerID *w );
+
+
+		/**
+		A common theme of Master-Worker applications is that there is 
+		a base amount of "initial" data defining the problem, and then 
+		just incremental data defining "Tasks" to be done by the Workers.
+
+		This one packs all the user's initial data.  It is unpacked 
+		int the worker class, in unpack_init_data().
+		*/
+		virtual MWReturn pack_worker_init_data( void ) = 0;
+	
+		/**
+     This one unpacks the "initial" information sent to the driver
+     once the worker initializes. 
+     
+     Potential "initial" information that might be useful is...
+     \begin{itemize}
+     \item Information on the worker characteristics  etc...
+     \item Information on the bandwith between MWDriver and worker
+     \end{itemize}
+		   
+     These sorts of things could be useful in building some 
+     scheduling intelligence into the driver.
+     
+  */
+  virtual void unpack_worker_initinfo( MWWorkerID *w ) {};
+	
+  /**
+     OK, This one is not pure virtual either, but if you have some 
+     "driver" data that is conceptually part of the task and you wish
+     not to replicate the data in each task, you can pack it in a
+     message buffer by implementing this function.  If you do this, 
+     you must implement a matching unpack_worker_task_data()
+     function.
+  */
+	
+  virtual void pack_driver_task_data( void ) {};
+	
+        /**@name Data streaming/subtasks
+        These are the methods that must be implemented to enable data streaming/
+		subtasks.
+		- act_on_completed_subtask()
+		- MWWorker::execute_subtask
+		- MWWorker::set_num_subtask
+		- MWTask::pack_subresults
+		- MWTask::unpack_subresults
+
+		A subtask is identified by a MWTask and a subtask id. The subtask id 
+		starts at 0 and ends at n-1 subtasks.
+
+		When subtasks are enabled, the Master sends the task to the Worker as 
+	 	usual. But instead of calling execute_task once, execute_subtask is
+		called once per subtask id (starting at 0). At the end of each call, the
+		result will be returned to the Master. After all subtasks have completed,
+		the Master is notified that the Task has completed.	
+        */
+
+		/**
+   		This function performs an action that happens once the 
+		Driver receives notification of a completed subtask. 
+   		*/
+        virtual MWReturn act_on_completed_subtask(MWTask *) { return ABORT; }
+  //@}
+	
+	
+  /**@name B. Task List Management
+		   
+     These functions are to manage the list of Tasks.  MW provides
+     default useful functionality for managing the list of tasks.
+		   
+  */
+	
+  //@{
+
+  /// Set number of workclasses
+  void workClasses_set ( int num );
+
+  /// Get the number of workclasses
+  int workClasses_get ( );
+
+  /// Stop the worker working on this task container and send it a new task container. This should only be called in act_on_completed_task(MWTask*)
+  int stop_work();
+
+  /// get number of workers in the specified work class
+  int workClasses_getworkers ( int num );
+  /// get number of tasks in the specified work class
+  int workClasses_gettasks ( int num );
+  /// Pack new init data for all workers in group i
+  int refreshWorkers ( int i, MWREFRESH_TYPE );
+
+	
+  /// Add a task to the list
+  void addTask( MWTask * );
+	
+  /** Add a bunch of tasks to the list.  You do this by making
+      an array of pointers to MWTasks and giving that array to 
+      this function.  The MWDriver will take over memory 
+      management for the MWTasks, but not for the array of 
+      pointers, so don't forget to delete [] it! */
+  void addTasks( int, MWTask ** );
+
+  /** This will add a list of tasks that are sorted by key.  Efficiency can 
+      be greatly improved by using this function */  
+  void addSortedTasks( int n, MWTask **add_tasks );
+
+private:
+  /// This is a helper function for addSortedTasks().
+  void addTaskByKey( MWTask *add_task );
+
+public:
+  /// Sets the function that MWDriver users to get the "key" for a task
+  void set_task_key_function( MWKey (*)( MWTask * ) );
+	
+  /// Set the mode you wish for task addition.
+  int set_task_add_mode( MWTaskAdditionMode );
+	
+  /// Set the mode you wish for task retrieval.  
+  int set_task_retrieve_mode( MWTaskRetrievalMode );
+	
+  /// This sorts the task list by the key that is set
+  int sort_task_list( void );
+	
+  /** This deletes all tasks in the task list with a key worse than 
+      the one specified */
+  int delete_tasks_worse_than( MWKey );
+	
+  /// returns the number of tasks on the todo list.
+  int get_number_tasks();
+
+  int getNumWorkers ( );
+	
+  /// returns the number of running tasks.
+  int get_number_running_tasks();
+
+  /// (Mostly for debugging) -- Prints the task keys in the todo list
+  int print_task_keys( void );
+
+
+  //@}
+  void reassignSuspendedTask ( MWList<MWTask> * running, MWWorkerID * w );
+  void reassignIdleTask ( MWList<MWWorkerID> * workers, MWWorkerID * w );
+  int matchTask ( void *arg1, void *arg2 );
+  MWWorkerID* numberworker ( void *arg1, void *arg2 );
+
+	
+  /** @name C. Worker Policy Management */
+  //@{
+  /** Set the policy to use when suspending.  Currently 
+      this can be either DEFAULT or REASSIGN */
+  void set_suspension_policy( MWSuspensionPolicy );
+
+  ///   Sets the machine ordering policy.
+  int set_machine_ordering_policy( MWMachineOrderingPolicy );
+
+  //@}
+
+  /** @name.  task timeout policy.  
+
+      MW provides a mechanism for performing tasks on workers that are 
+      potentially "lost".  If the RMComm fails to notify MW of a worker
+      going away in a timely fashion, the state of the computing platform
+      and MW's vision of its state may become out of synch.  In order to
+      make sure that all tasks are done in a timely fashion, the user may set
+      a time limit after which a task running on a "lost" worker 
+      may be rescheduled.
+   */
+
+  //@{
+
+private:	
+
+  /** If false : workers never timeout and can potentially work forever on a task
+      If true : workers time out after worker_timeout_limit seconds */	
+  bool worker_timeout;
+
+  /** Limit of seconds after which workers are considered time out and 
+      tasks are re-assigned */
+  double worker_timeout_limit;
+
+  /** frequency at which we check if there are timed out workers */
+  int worker_timeout_check_frequency;
+
+  /** based on the time out frequency, next timeout check time*/
+  int next_worker_timeout_check;
+
+  /** Go through the list of timed out WORKING workers and reschedule tasks */
+  void reassign_tasks_timedout_workers();
+
+public:
+
+  /** Sets the timeout_limit and turn worker_timeout to 1 */
+  void set_worker_timeout_limit(double timeout_limit, int timeout_frequency);
+
+  //@}
+
+
+  /**@name D. Event Handling Methods
+		   
+     In the case that the user wants to take specific actions
+     when notified of processors going away, these methods
+     may be reimplemented.  Care must be taken when
+     reimplementing these, or else things may get messed up.
+     
+     Probably a better solution in the long run is to provide 
+     users hooks into these functions or something. 
+		   
+     Basic default functionality that updates the known
+     status of our virtual machine is provided. 
+		   
+  */
+	
+  //@{
+	
+  /** Here, we get back the benchmarking
+      results, which tell us something about the worker we've got.
+      Also, we could get some sort of error back from the worker
+      at this stage, in which case we remove it. */
+
+  virtual MWReturn handle_benchmark( MWWorkerID *w );
+
+  /** This is what gets called when a host goes away.  We figure out
+      who died, remove that worker from our records, remove its task
+      from the running queue (if it was running one) and put that
+      task back on the todo list. */
+	
+  virtual void handle_hostdel();
+	
+  /** Implements a suspension policy.  Currently either DEFAULT or
+      REASSIGN, depending on how suspensionPolicy is set. */
+  virtual void handle_hostsuspend();
+	
+  /** Here's where you go when a host gets resumed.  Usually, 
+      you do nothing...but it's nice to know...*/
+  virtual void handle_hostresume();
+  
+  /** We do basically the same thing as handle_hostdel().  One might 
+      {\em think} that we could restart something on that host; 
+      in practice, however -- especially with the Condor-PVM RMComm
+      implementation -- it means that the host has gone down, too.
+      We put that host's task back on the todo list.
+  */
+  virtual void handle_taskexit();
+
+  /** Routine to handle when the communication layer says that a
+      checksum error happened. If the underlying Communitor
+      gives a reliably reliable communication then this messge
+      need not be generated. But for some Communicators like
+      MW-File we may need some thing like this.
+  */
+  virtual void handle_checksum ();
+
+  //@}
+	
+  /** @name E. Checkpoint Handling Functions
+			
+      These are logical checkpoint handling functions.  They are
+      virtual, and are *entirely* application-specific.  In them, the
+      user must save the "state" of the application to permanent
+      storage (disk).  To do this, you need to:
+			
+      \begin{itemize}
+      \item Implement the methods write_master_state() and
+      read_master_state() in your derived MWDriver app.
+      \item Implement the methods write_ckpt_info() and 
+      read_ckpt_info() in your derived MWTask class.
+      \end{itemize}
+			
+      Then MWDriver does the rest for you.  When checkpoint() is
+      called (see below) it opens up a known filename for writing.
+      It passes the file pointer of that file to write_master_state(), 
+      which dumps the "state" of the master to that fp.  Here 
+      "sate" includes all the variables, info, etc of YOUR
+      CLASS THAT WAS DERIVED FROM MWDRIVER.  All state in
+      MWDriver.C is taken care of (there's not much).  Next, 
+      checkpoint will walk down the running queue and the todo
+      queue and call each member's write_ckpt_info().  
+      
+      Upon restart, MWDriver will detect the presence of the 
+      checkpoint file and restart from it.  It calls 
+      read_master_state(), which is the inverse of 
+      write_master_state().  Then, for each task in the 
+      checkpoint file, it creates a new MWTask, calls 
+      read_ckpt_info() on it, and adds it to the todo queue.
+			
+      We start from there and proceed as normal.
+			
+      One can set the "frequency" that checkpoint files will be 
+      written (using set_checkpoint_frequency()).  The default
+      frequency is zero - no checkpointing.  When the frequency is
+      set to n, every nth time that act_on_completed_task gets 
+      called, we checkpoint immediately afterwards.  If your
+      application involves "work steps", you probably will want to 
+      leave the frequency at zero and call checkpoint yourself
+      at the end of a work step.
+			
+  */
+  //@{
+	
+  /** This function writes the current state of the job to disk.  
+      See the section header to see how it does this.
+      @see MWTask
+  */
+  void checkpoint();
+	
+  
+  /** This function does the inverse of checkpoint.  
+      It opens the checkpoint file, calls read_master_state(), 
+      then, for each task class in the file, creates a MWTask, 
+      calls read_ckpt_info on it, and adds that class to the
+      todo list. */
+  void restart_from_ckpt();
+	
+	
+  /** This function sets the frequency with with checkpoints are
+      done.  It returns the former frequency value.  The default
+      frequency is zero (no checkpoints).  If the frequency is n, 
+      then a checkpoint will occur after the nth call to 
+      act_on_completed_task().  A good place to set this is in
+      get_userinfo().
+      @param freq The frequency to set checkpoints to.
+      @return The former frequency value.
+  */
+
+  int set_checkpoint_frequency( int freq );
+	
+  /** Set a time-based frequency for checkpoints.  The time units
+      are in seconds.  A value of 0 "turns off" time-based 
+      checkpointing.  Time-based checkpointing cannot be "turned 
+      on" unless the checkpoint_frequency is set to 0.  A good
+      place to do this is in get_userinfo().
+      @param secs Checkpoint every "secs" seconds
+      @return The former time frequency value.
+  */
+  int set_checkpoint_time( int secs );
+	
+  /** Here you write out all 'state' of the driver to fp.
+      @param fp A file pointer that has been opened for writing. */
+  virtual void write_master_state( FILE *fp ) {};
+	
+  /** Here, you read in the 'state' of the driver from fp.  Note
+      that this is the reverse of write_master_state().
+      @param fp A file pointer that has been opened for reading. */
+  virtual void read_master_state( FILE *fp ) {};
+
+  
+  /** Swap the unused part of the (sorted and indexed) TODO list 
+      onto disk (file name: TODO_tasks.id), so that the TODO tasks
+      with smaller key values are kept in memory, and others are kept
+      in a file. When there are too many tasks in memory, we swap most
+      of them out; when there are too few tasks in memory, we swap in
+      more. The MW application will be done only when all TODO tasks 
+      are done. When checkpointing, it only saves TODO tasks in memory, 
+      and the pointers (the file name) to the swap file. 
+      
+      To help swapping in tasks, we will record the number of tasks
+      swapped in at the beginning of the file, and skip then when read 
+      to swap file. The num_to_skip is initially set to 0.
+      
+      The swap file for TODO tasks is fully-sorted, and looks like:
+      
+        num_to_skip
+	trash_task1
+	trash_task2
+	...
+	...
+	task1
+	task2
+	...
+	...
+  	task[num_tasks]
+   **/
+   
+  /** When swapping out, we walk through the sorted TODO list, keep the first
+      num_in_mem tasks in memory (copy into a newly created list). For the 
+      rest of the list, merge it in order with existing tasks in the file 
+      TODO_tasks, and write them into a newly created swap file. Tasks
+      in swap file whose key values are larger than max_key are removed. When 
+      done, delete the old TODO list and swap file, switch to the new ones.
+      
+      If the old TODO list is not too large (<max_in_mem), won't swap out.
+      Return value indicates whether the swapping is successful or not. 
+   **/
+
+int MIN_IN_MEM;	   /* == 256            */
+int NUM_IN_MEM_LO; /* == MIN_IN_MEM*8   */
+int NUM_IN_MEM_HI; /* == MIN_IN_MEM*100 */
+int MAX_IN_MEM;    /* == MIN_IN_MEM*800 */
+  
+public:
+  bool swap_out_todo_tasks(int num_in_mem = 2048, 
+		  int max_in_mem = 204800, 
+		  double max_key = DBL_MAX);
+
+  /** When swapping in, we first read first num_in_mem (or all tasks if not so
+      many tasks in swap file) tasks from the swap file, create tasks and 
+      append to a newly created list. Then we sorted insert the existing tasks 
+      in memory into the new list. When done, switch the list and file.
+
+      If the old TODO list is not too small (>num_in_mem), won't swap in.
+      Return value indicates whether the swapping is successful or not. 
+   **/
+  bool swap_in_todo_tasks(int min_in_mem = 256, 
+		  int num_in_mem = 25600);
+
+  /** See whether we still have TODO tasks */
+  bool is_TODO_empty();
+
+  /* Read and write tasks */
+  MWTask * read_mem_task(MWList<MWTask> *tasks);
+  MWTask * read_file_task(FILE *f);
+  void write_task(FILE *f, MWTask *t);
+
+private:
+  bool has_task_swapped;  /* inited as false */
+  double max_task_key; 	  /* inited as -DBL_MAX, 
+			     tasks with larger key values should be removed */
+  
+public:
+  /** It's really annoying that the user has to do this, but
+      they do.  The thing is, we have to make a new task of the
+      user's derived type when we read in the checkpoint file.
+      
+      If your application coredumps when trying to restart from
+      a checkpoint, it might be becasue you haven't implemented this function.
+
+      \begin{verbatim}
+      MWTask* gimme_a_task() {
+      return new <your derived task class>;
+      }
+      \end{verbatim}
+  */
+  virtual MWTask *gimme_a_task() = 0;
+  //@}
+
+  /**   @name Benchmarking
+	We now have a user-defined benchmarking phase.  
+	The user can "register" a task that is sent to each worker upon startup.
+	This way, the user knows which machines are fastest, and MW can perform
+	can automatic "normalization" of the equivalent CPU time.
+  */
+  //@{
+
+  /** register the task that will be used for benchmarking. */
+  void register_benchmark_task( MWTask *t ) { bench_task = t; };
+
+  /** get the benchmark task */
+  MWTask * get_benchmark_task() { return bench_task; };
+
+  //@}
+
+private:
+	
+  /** @name Main Internal Handling Routines */
+  //@{
+  
+  /** This method is called before master_mainloop() is.  It does 
+      some setup, including calling the get_userinfo() and 
+      create_initial_tasks() methods.  It then figures out how 
+      many machines it has and starts worker processes on them.
+      @param argc The argc from the command line
+      @param argv The argv from the command line
+      @return This is the from the user's get_userinfo() routine.
+      If get_userinfo() returns OK, then the return value is from 
+      the user's setup_initial_tasks() function.
+  */
+
+  MWReturn master_setup( int argc, char *argv[] );  
+	
+  /** This is the main controlling routine of the master.  It sits
+      in a loop that accepts a message and then (in a big switch 
+      statement) calls routines to deal with that message.  This loop
+      ends when there are no jobs on either the running or todo queues.
+      It is probably best to see the switch staement yourself to see
+      which routines are called when. */
+
+  MWReturn master_mainloop();      
+	
+  /**
+     unpacks the initial worker information, and sends the
+     application startup information (by calling pure virtual
+     {\tt pack_worker_init_data()}
+     
+     The return value is taken as the return value from the user's 
+     {\tt pack_worker_init_data()} function.
+     
+  */
+
+  MWReturn worker_init( MWWorkerID *w );
+	
+  /** 
+      This routine sets up the list of initial tasks to do on the 
+      todo list.  In calls the pure virtual function 
+      {\tt setup_initial_tasks()}.
+      @return Is taken from the return value of
+      {\tt setup_initial_tasks()}.
+  */
+  MWReturn create_initial_tasks();  
+	
+  /**
+     Act on a "completed task" message from a worker.
+     Calls pure virtual function {\tt act_on_completed_task()}.
+     @return Is from the return value of {\tt act_on_completed_task()}.
+  */
+  MWReturn handle_worker_results( MWWorkerID *w );
+
+	
+  /** We grab the next task off the todo list, make and send a work
+      message, and send it to a worker.  That worker is marked as 
+      "working" and has its runningtask pointer set to that task.  The
+      worker pointer in the task is set to that worker.  The task
+      is then placed on the running queue. */
+  void send_task_to_worker( MWWorkerID *w );
+
+  //by jae
+  void lockSendTaskToWorker( MWWorkerID *w ); 
+	
+  /**  After each result message is processed, we try to match up
+       tasks with workers.  (New tasks might have been added to the list
+       during processing of a message).  Don't send a task to
+       "nosend", since he just reported in.
+  */
+  void rematch_tasks_to_workers( MWWorkerID *nosend );
+	
+  /** A wrapper around the lower level's hostaddlogic.  Handles
+      things like counting machines and deleting surplus */
+  void call_hostaddlogic();
+
+  /// Kill all the workers
+  void kill_workers();
+	
+  /** This is called in both handle_hostdelete and handle_taskexit.
+      It removes the host from our records and cleans up 
+      relevent pointers with the task it's running. */
+ 
+ void hostPostmortem ( MWWorkerID *w );
+
+
+
+  /** The control panel that controls the execution of the
+      independent mode. */
+  void ControlPanel ( );	
+
+  MWReturn master_mainloop_oneshot ( int buf_id, int sending_host);
+
+  int outstanding_spawn;
+  
+  //@}
+	
+  /**@name Internal Task List Routines 
+		   
+     These methods and data are responsible for managing the 
+     list of tasks to be done
+  */
+	
+  //@{
+  
+  /// This puts a (generally failed) task at the beginning of the list
+  void pushTask( MWTask * );
+	
+  /// Get a Task.  
+  MWTask *getNextTask( MWGroup *grp );
+	
+  /// This puts a task at the end of the running list
+  void putOnRunQ( MWTask *t );
+	
+  /// Removes a task from the queue of things to run
+  MWTask * rmFromRunQ ( int jobnum );
+	
+  /// Print the tasks in the list of tasks to do
+  void printRunQ();
+	
+  /** Add one task to the todo list; do NOT set the 'number' of
+      the task - useful in restarting from a checkpoint */
+  void ckpt_addTask( MWTask * );
+	
+  /// returns the worker this task is assigned to, NULL if none.
+  MWWorkerID * task_assigned( MWTask *t );
+	
+  /// Returns true if "t" is still in the todo list
+  bool task_in_todo_list( MWTask *t );
+	
+  /** A pointer to a (user written) function that takes an MWTask
+      and returns the "key" for this task.  The user is allowed to 
+      change the "key" by simply changing the function
+  */
+protected:
+  MWKey (*task_key)( MWTask * );
+
+	  void give_work ( MWWorkerID *w, MWTask *t );
+
+private:
+	
+  /// Where should tasks be added to the list?
+  MWTaskAdditionMode addmode;
+	
+  /// Where should tasks by retrived from the list
+  MWTaskRetrievalMode getmode;
+
+  /** A pointer to the function that returns the "key" by which machines are ranked.
+      Right now, we offer only some (hopefully useful) default functions that are 
+      set through the machine_ordering_policy
+   */
+
+  MWKey (*worker_key)( MWWorkerID * );
+	
+
+  MWMachineOrderingPolicy machine_ordering_policy;
+
+  /** MWDriver keeps a unique identifier for each task -- 
+      here's the counter */
+  int task_counter;
+	
+  /// Is the list sorted by the current key function
+  bool listsorted;
+	
+  /// The head of the list of tasks to do
+  MWList<MWTask> * todo;
+
+public:
+  /// This is Jeff's nasty addition so that he can get access
+  ///  to the tasks on the master
+  MWTask *get_todo_head();
+
+  //by jae
+  void increasePendingNum(void);
+  void decreasePendingNum(void);
+  int getPendingNum(void) { return m_pending_num; }
+
+  void getGlobalLock(void);
+  void getGlobalUnLock(void);
+
+private:
+	//by jae
+  int m_pending_num;
+  pthread_mutex_t m_pending_mutex;
+  pthread_cond_t m_pending_cond;
+	
+  /// The head of the list of tasks that are actually running
+  MWList<MWTask> * running;
+
+  /// The reassigned task list
+  MWList<int> * reassigned_tasks;
+  /// The reassigned and done task list
+  MWList<int> * reassigned_tasks_done;
+  /// All running tasks are reassigned_done
+  bool normal_tasks_all_done;
+
+  /// Insert a task with an id of tid into a int* list
+  inline void insert_into_set(MWList<int> * list, int tid) {
+	  int i, num = list->number();
+	  int *t;
+	  bool found = false;
+	  
+	  for (i=0; i<num; i++) {
+		t = (int*)list->Remove();
+		if (*t==tid)
+			found = true;
+		list->Append(t);
+	  }
+	  if (!found) {
+	  	  t = new int;
+		  *t = tid;
+		  list->Append(t);
+	  }
+  }
+  /// See if a task is in a given int* list
+  inline bool in_set(MWList<int> * list, int tid) {
+	  int i, num = list->number();
+	  int *t;
+	  
+	  for (i=0; i<num; i++) {
+		t = (int*)list->Remove();
+		list->Append(t);
+		if (*t==tid) 
+			return true;
+	  }
+	  return false;
+  } 
+  //@}
+  
+  /**@name Worker management methods
+		   
+     These methods act on the list of workers
+     (or specifically) ID's of workers, that the
+     driver knows about.
+     
+  */
+	
+  //@{
+	
+  /// Adds a worker to the list of avaiable workers
+  void addWorker ( MWWorkerID *w );
+  
+  /// Looks up information about a worker given its task ID
+  MWWorkerID * lookupWorker( int tid );
+	
+  /// Removes a worker from the list of available workers
+  MWWorkerID * rmWorker ( int tid );
+
+  /// This function removes worker from the list, removes it and deletes
+  /// the structure.
+  void worker_last_rites ( MWWorkerID *w );
+
+public:	
+  /// Prints the available workers
+  void printWorkers();
+
+  /** Another terrible addition so that Jeff can print out the worker list
+      in his own format */
+  MWWorkerID *get_workers_head();
+
+private:
+
+  /// The head of the list of workers.
+  MWList<MWWorkerID> * workers;
+
+  /// Here's where we store what should happen on a suspension...
+  MWSuspensionPolicy suspensionPolicy;
+
+  /// Based on the ordering policy, place w in the worker list appropriately
+  void sort_worker_list();
+public:
+  /// Counts the existing workers
+  int numWorkers();
+	
+  /// Counts the number of workers in the given arch class
+  int numWorkers( int arch );
+
+  /// Counts the number of workers in the given state
+  int numWorkersInState( int ThisState );
+
+  /// Returns the value (only) of the best key in the Todo list 
+  MWKey return_best_todo_keyval( void );
+
+  /// Returns the best value (only) of the best key in the Running list.
+  MWKey return_best_running_keyval( void );  
+
+private:
+	
+  //@}
+	
+  /** @name Checkpoint internal helpers... */
+  //@{
+
+  /** How often to checkpoint?  Task frequency based. */
+  int checkpoint_frequency;
+	
+  /** How often to checkpoint?  Time based. */
+  int checkpoint_time_freq;
+  /** Time to do next checkpoint...valid when using time-based 
+      checkpointing. */
+
+  long next_ckpt_time;
+	
+  /** The number of tasks acted upon up to now.  Used with 
+      checkpoint_frequency */
+  //int num_completed_tasks;
+	
+  /** The benchmark task. */
+  MWTask *bench_task;
+	
+  /** The name of the checkpoint file */
+  const char *ckpt_filename; // JGS
+  
+  /** When submitting multiple jobs from the same directory, the checkpoint files all the 
+   *  the same name if we use the fixed ckpt_filename. So we made some changes:
+   *  (1) Allow the user set their checkpoint file name by calling 
+   *  		set_ckpt_filename(const char*) before finishing get_user_info()
+   *  (2) If the user doesn't specify the ckpt_filename, then use
+   *  		$(master_exec_name)-ckpt.$(Process)
+   *  (3) When reading checkpoints during execution, MW will just read the file. When the
+   *      application restarts, it will find the file with the same name as user specified,
+   *      or as the default name (choose the first one when there are multiple files). 
+   */
+  // char *ckpt_filename;
+  
+	
+  //@}
+
+  /** The instance of the stats class that takes workers and later
+      prints out relevant stats... */
+  // Changed into MWStatistics * to make insure happy (then I can new and delete it).
+  MWStatistics* stats;
+
+  /// This returns the sum of the bench results for the currently working machines
+
+  double get_instant_pool_perf();
+
+  /// This returns the hostname
+  char *getHostName ();
+  
+
+
+#if defined( XML_OUTPUT )
+  
+  /**@name XML and Status Methods.
+
+     This function is called by the CORBA layer to get the
+     XML status of the MWDriver.
+  */
+
+  //@{
+
+public:
+  ///
+  void  write_XML_status();
+
+
+  /**
+     If you want to display information about status of some
+     results variables of your solver, you have to dump a string in
+     ASCII, HTML or XML format out of the following method. 
+     The iMW interface will be in charge of displaying this information
+     on the user's browser.
+   */
+
+  virtual char* get_XML_results_status(void );
+
+private:
+
+  ///
+  char* get_XML_status();
+
+  ///
+  char* get_XML_job_information();
+
+  ///
+  char* get_XML_problem_description();
+
+  ///
+  char* get_XML_interface_remote_files();
+  
+  ///
+  char* get_XML_resources_status();
+
+  ///
+  const char *xml_filename; // JGS
+
+  ///
+  const char *xml_menus_filename;
+
+  ///
+  const char *xml_jobinfo_filename;
+
+  ///
+  const char *xml_pbdescrib_filename;
+
+  /// Set the current machine information
+  void get_machine_info();
+
+  /// Returns a pointer to the machine's Arch
+  char *get_Arch(){ return Arch; }
+  
+  /// Returns a pointer to the machine's OpSys
+  char *get_OpSys(){ return OpSys; }
+
+  /// Returns a pointer to the machine's IPAddress
+  char *get_IPAddress(){ return IPAddress; }
+
+  ///
+  double get_CondorLoadAvg(){ return CondorLoadAvg; }
+
+  ///
+  double get_LoadAvg(){ return LoadAvg; }
+
+  ///
+  int get_Memory(){return Memory;}
+
+  ///
+  int get_Cpus(){return Cpus;}
+
+  ///
+  int get_VirtualMemory(){return VirtualMemory;}
+
+  ///
+  int get_Disk(){return Disk;}
+
+  ///
+  int get_KFlops(){return KFlops;}
+
+  ///
+  int get_Mips(){return Mips;}
+
+  ///
+  char Arch[64];
+
+  ///
+  char OpSys[64];
+
+  ///
+  char IPAddress[64];
+
+  ///
+  double CondorLoadAvg;
+
+  ///
+  double LoadAvg;
+
+  ///
+  int Memory;
+
+  ///
+  int Cpus;
+
+  ///
+  int VirtualMemory;
+
+  ///
+  int Disk;
+
+  ///
+  int KFlops;
+
+  ///
+  int Mips;
+
+  /// Utility functions used by get_machine info
+  int check_for_int_val(char* name, char* key, char* value);
+  double check_for_float_val(char* name, char* key, char* value);
+  int check_for_string_val(char* name, char* key, char* value);
+
+#endif
+
+  /// The name of the machine the worker is running on.
+  char mach_name[64];
+
+  /// for measuring network connectivity
+  double defaultTimeInterval;
+  int defaultIterations;
+  int defaultPortNo;
+
+#ifdef MEASURE
+  // Gather performance measurement information at runtime
+public:
+  // read/write measurement files
+  void _measure_read_options(const char* opt_fname);
+  void _measure_dump_header();
+  void _measure_dump_records();
+private:
+  // Do the measurement
+  void _measure();
+  // Reset the numbers
+  void _measure_reset();
+
+private:
+  // Names for the measurement option and record files
+  // We want to make the record file unique across different runs, so better
+  //  add the ProcID part. But how to get the $(Cluster).$(Process) part? 
+  //  Here is Peter's method: use _ProcID_$(Cluster).$(Process) in the 
+  //  argument line in the master's submit file, and Condor will substitute 
+  //  them into the real ProcID before it executes the master executable, 
+  //  so that I can read this from argv. 
+  // Suggestion from Peter: don't make this with fixed argc position.
+  char _measure_opt_file_name[_POSIX_PATH_MAX]; 	// = "_measure_opt";
+  char _measure_rec_fname_prefix[_POSIX_PATH_MAX]; 	//  = "_measure_rec";
+  char _measure_ProcID_prefix[_POSIX_PATH_MAX]; 	//  = "_ProcID.";
+  char _measure_rec_file_name[_POSIX_PATH_MAX];
+  
+  // Time intervals to read options and dump measurement record (append)
+  int  _measure_read_opt_interval; 	//  = 300;
+  int  _measure_dump_rec_interval; 	//  = 120;
+  time_t  _measure_last_read_opt_time;
+  time_t  _measure_last_dump_rec_time;
+  
+  // Recent queue statistics
+  // int  _measure_num_worker;		// = workers->number();
+  // int  _measure_num_task_TODO;	// = todo->number();
+  int  _measure_num_task_Done;
+  
+  // Recent master performance
+  double _measure_master_recv_time;	// time used for mainloop's recv()
+  double _measure_master_recv_cpu_time;	// CPU time used for mainloop's recv()
+  double _measure_master_wall_time;	// time elapsed
+  double _measure_master_cpu_time;	// CPU time (both user and system)
+  double _measure_master_act_on_completed_task_time;	// Time in user code
+  double _measure_master_act_on_completed_task_cpu_time;// CPU time in user code
+
+  // Performance of recent finished tasks
+  double _measure_task_RoundTrip_time;	// time from sending task to deleting it
+  double _measure_task_MP_master_time;	// time used when master packing/sending 
+  double _measure_task_MP_worker_time;	// time used when worker unpacking/recving
+  double _measure_task_MP_worker_cpu_time; // CPU time used when worker unpacking/recving
+  double _measure_task_Exe_wall_time;	// time elapsed when worker executing task
+  double _measure_task_Exe_cpu_time;	// CPU time when worker executing task
+
+  // Below are adaptation logic 
+  int _measure_use_adaptation;
+  // To keep track of the master and worker utilization
+  double _measure_master_wait_rate;
+  int _measure_master_busy_times;
+  int _measure_master_wait_times;
+  MWWorkerID *_measure_current_worker;
+  int _measure_target_num_workers;
+  
+  // Adapt the number of workers when necessary: 
+  //  assumes that it's called in the mainloop (can access w that just returns a RESULT)
+  //  also assumes that it can access the most recent measurement numbers
+  void _measure_adapt(); 
+  void _measure_remove_worker();
+#endif
+
+public:
+	/* Send an asynchronous UPDATE_FROM_DRIVER message to the worker
+		-2 to send to all workers
+		-1 to send to current worker
+		>0 to send to a specific worker
+		User should override pack_update if some data needs to be sent with update.
+	*/
+	void prepare_update(int mode);
+
+	/* user packs update data here. Used in conjunction with prepare_update */
+	virtual void pack_update(){};	
+
+	/* user tells Driver to send a DRIVER_UPDATE message to the current worker 
+	 * from who a task result or async message has been send */
+	int send_update_message();
+
+	/* user tells Driver to send a DRIVER_UPDATE message to a specific worker */
+	int send_update_message_to(int worker);
+};
+
+///  This is the function allowing the workers to be sorted by KFlops
+MWKey kflops( MWWorkerID * );
+
+/// This is the function allowing the workers to be sorted by benchmarkresult
+MWKey benchmark_result( MWWorkerID * );
+
+#endif
+
+
diff --git a/MW/src/MWGroup.C b/MW/src/MWGroup.C
new file mode 100644
index 0000000..2909bc7
--- /dev/null
+++ b/MW/src/MWGroup.C
@@ -0,0 +1,99 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#include "MWGroup.h"
+
+MWGroup::MWGroup ( int grps )
+{
+	maxGroups = grps;
+	group = new bool[maxGroups];
+	for ( int i = 0; i < maxGroups; i++ )
+		group[i] = FALSE;
+}
+
+MWGroup::~MWGroup ( )
+{
+	delete []group;
+}
+
+void
+MWGroup::join ( int num )
+{
+	if ( num >= 0 && num < maxGroups )
+		group[num] = TRUE;
+}
+
+void
+MWGroup::leave ( int num )
+{
+	if ( num >= 0 && num < maxGroups )
+		group[num] = FALSE;
+}
+
+bool
+MWGroup::belong ( int num )
+{
+	if ( num >= 0 && num < maxGroups )
+		return group[num];
+
+	return FALSE;
+}
+
+bool
+MWGroup::doesOverlap ( MWGroup *grp )
+{
+	for ( int i = 0; i < maxGroups; i++ )
+	{
+		if ( belong ( i ) && grp->belong ( i ) )
+			return TRUE;
+	}
+	return FALSE;
+}
+
+void
+MWGroup::write_checkpoint ( FILE *fp )
+{
+	int num = 0;
+	int i;
+	for ( i = 0; i < maxGroups; i++ )
+		if ( belong ( i ) ) num++;
+	fprintf ( fp, "%d ", num );
+
+	for ( i = 0; i < maxGroups; i++ )
+		if ( belong ( i ) )
+			fprintf ( fp, "%d ", i );
+	fprintf ( fp, "\n" );
+}
+
+void
+MWGroup::read_checkpoint ( FILE *fp )
+{
+	int i, temp;
+	int gp;
+	fscanf ( fp, "%d ", &temp );
+	for ( i = 0; i < temp; i++ )
+	{
+		fscanf ( fp, "%d ", &gp );
+		join ( gp );
+	}
+}
diff --git a/MW/src/MWGroup.h b/MW/src/MWGroup.h
new file mode 100644
index 0000000..0a1ef84
--- /dev/null
+++ b/MW/src/MWGroup.h
@@ -0,0 +1,49 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWGROUP_H
+#define MWGROUP_H
+
+#include "MW.h"
+
+/** This is a simple class to keep track of what workclass/group a
+	task or worker belongs to. It is not called directly by the application.
+*/
+
+class MWGroup
+{
+	private:
+		bool *group;
+		int maxGroups;
+
+	public:
+		MWGroup ( int grp );
+		~MWGroup ( );
+		void join ( int num );
+		void leave ( int num );
+		bool belong ( int num );
+		bool doesOverlap ( MWGroup *grp );
+		void write_checkpoint ( FILE *fp );
+		void read_checkpoint ( FILE *fp );
+};
+#endif /*MWGROUP_H*/
diff --git a/MW/src/MWList.C b/MW/src/MWList.C
new file mode 100644
index 0000000..9598cd3
--- /dev/null
+++ b/MW/src/MWList.C
@@ -0,0 +1,873 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/**************************************************************************
+ *  Implementation of MWListElement, MWIndex, MWIndexList, MWList         *
+ **************************************************************************/ 
+
+#include "MWList.h"
+
+#if 0
+
+/** Implementation of MWListElement<ObjType> **/
+
+template <class ObjType>
+MWListElement<ObjType>::MWListElement(ObjType *itemPtr, double sortKey)
+{
+	obj= itemPtr;
+	key = sortKey;
+	next = this; 
+	prev = this;
+}
+	
+template <class ObjType>
+MWListElement<ObjType>::~MWListElement()
+{
+	/* Nothing */
+}
+	
+/** Implementation of MWIndex<ObjType> **/
+template <class ObjType>
+MWIndex<ObjType>::MWIndex<ObjType>()
+{
+	/* Nothing */
+}
+
+template <class ObjType>
+MWIndex<ObjType>::~MWIndex<ObjType>()
+{
+	/* Nothing */
+}
+
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndex<ObjType>::Split()
+{
+	int i;
+
+	if (this->num<2)
+		return NULL;
+	
+	MWListElement<ObjType> * current = this->first->prev;
+
+	/* Walk through the list until we meet the half point */
+	for (i=0; i<num/2; i++)
+		current = current->next;
+	
+	/* Create a new index for the second half */
+	MWIndex<ObjType> * i2 = new MWIndex<ObjType>;
+	if (i2 == NULL)
+		return NULL;
+
+	i2->num = num - i;
+	i2->first = current->next;
+	i2->lower = current->key; /* must not leave space between boundaries */
+	i2->last = this->last;
+	i2->upper = this->upper;
+	
+	/* Update the current index */
+	this->num = num/2;
+	this->last = current;
+	this->upper = current->key;
+
+	/* return the new index, which should be inserted into index list */
+	return i2;
+}
+
+/* split an index into many smaller ones whose sizes <= bucket_size */
+template <class ObjType>
+void
+MWIndex<ObjType>::SplitTo(MWIndexList<ObjType>* ilist, int bucket_size)
+{
+	if (num < bucket_size)
+		return;
+	else {
+		ilist->Split(this);
+		this->SplitTo(ilist, bucket_size);
+		this->next->SplitTo(ilist, bucket_size);
+	}
+}
+
+/* Balance the current index with the next index, either split or merge, 
+ * to make small buckets together, and cut large buckets into halves. 
+ * Return ptr to new index (current when splitting or next when merging) */
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndex<ObjType>::BalanceNext(MWIndexList<ObjType>* ilist, int bucket_size)
+{
+	/* Need to split */
+	if (this->num > bucket_size) {
+		MWIndex<ObjType> * next = this->next;
+		this->SplitTo(ilist, bucket_size+1);
+		return next;
+	}
+
+	/* Already the end of index list */
+	if (this->next == ilist->dummy)
+		return this->next;
+
+	/* Need to merget */
+	MWIndex<ObjType>* next_ind = this->next;
+	if (this->num + next_ind->num < bucket_size+1) {
+		return ilist->Merge(this);
+	} else {  
+		/* Nothing to be changed */
+		return this->next;
+	}
+}
+
+/** Implementation of MWIndexList<ObjType> **/
+template <class ObjType>
+MWIndexList<ObjType>::MWIndexList()
+{
+	dummy = new MWIndex<ObjType>();
+	if (dummy == NULL) {
+		MWprintf(10, "MWList::Can't initialize the list during object construction.\n");
+		return;
+	}
+	dummy->num = 0;
+	dummy->next = dummy;
+	dummy->prev = dummy;
+	dummy->lower = -DBL_MAX;
+	dummy->upper = DBL_MAX;
+	dummy->first = NULL;
+	dummy->last = NULL;
+
+	num = 0;
+}
+
+template <class ObjType>
+MWIndexList<ObjType>::~MWIndexList()
+{
+	MWIndex<ObjType>* ptr = dummy;
+	
+	while (num !=0) {
+		ptr = ptr->next;
+		delete ptr;
+		num --;
+	}
+	delete dummy;
+
+	MWprintf(10, "MWIndexList destructed.\n");
+}
+
+/* Build index for the list, split index whose number >= bucket_size,
+ * and merge adjacent index whose number < 0.25 * bucket_size */
+template <class ObjType>
+void 
+MWIndexList<ObjType>::BuildIndex(MWList<ObjType>* list, int bucket_size)
+{ 
+	MWprintf(10, "MWIndexList::BuildIndex()\n");
+
+	if (list->Number() < BUCKET_SIZE/2) {
+		MWprintf(10, "MWIndexList:: \
+			Will not build index when the list is still short.\n");
+		return;
+	}
+	
+	if (num == 0) { /* create index */
+		list->Sort();
+		
+		/* create the first index for the whole list */
+		MWIndex<ObjType> * ind = new MWIndex<ObjType>;
+		ind->num = list->Number();
+		ind->upper = DBL_MAX;
+		ind->lower = -DBL_MAX;
+		ind->first = list->dummy->next;
+		ind->last= list->dummy->prev;
+
+		/* Insert into index list */
+		dummy->next = ind;
+		ind->next = dummy;
+		dummy->prev = ind;
+		ind->prev = dummy;
+
+		num ++;
+		
+		/* split into small enough buckets */
+		ind->SplitTo(this, bucket_size);
+		
+	} else { 
+		/* balance index items */
+		MWIndex<ObjType> * ind = dummy->next;
+		
+		while ( (ind != this->dummy) && (ind != NULL) ) {
+			ind = ind->BalanceNext(this, bucket_size);
+		}
+	}
+}
+
+template <class ObjType>
+void
+MWIndexList<ObjType>::Split(MWIndex<ObjType>* index)
+{ 
+	MWIndex<ObjType> * another = index->Split();
+	index->next->prev = another;
+	another->next = index->next;
+	index->next = another;
+	another->prev = index;
+
+	num ++;
+}
+	
+template <class ObjType>
+MWIndex<ObjType>* 
+MWIndexList<ObjType>::IndexFor(double key)
+{
+	MWIndex<ObjType> * ptr = dummy;
+	for (int i=0; i<num; i++) {
+		ptr = ptr->next;
+		if ( (ptr->upper >= key) && (ptr->lower <= key) )
+			return ptr;
+	}
+	return NULL;
+}
+
+/* Merge two index, and delete any empty index */
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndexList<ObjType>::Merge(MWIndex<ObjType> * i1)
+{
+	if (num == 1) {/* Can't merge */
+		if (i1->num == 0) { /* Delete i1 then */
+			dummy->next = dummy->prev = dummy;
+			num = 0;
+			delete i1;
+			return NULL;
+		}
+	}
+	
+	if (i1->next != dummy) {
+		/* need to merge with it's next */
+	       	MWIndex<ObjType> * next_ind = i1->next;
+	       	i1->num = i1->num + next_ind->num;
+	       	i1->last = next_ind->last;
+	       	i1->upper = next_ind->upper;
+
+		/* remove the item from the list */
+	       	next_ind->next->prev = i1;
+	       	i1->next = next_ind->next;
+	       	delete next_ind;
+	       	num --;
+	}
+
+	return i1;
+}
+
+template <class ObjType>
+void
+MWIndexList<ObjType>::Display()
+{
+	MWIndex<ObjType> * ind = dummy;
+	int total = 0;
+	for (int i=0; i<num; i++) {
+		ind = ind->next;
+		if (ind == NULL) {
+			MWprintf(10, "MWList:: Bad problem, index list broken.\n");
+		}
+			
+		total += ind->num;
+		if (ind->num > 0) {
+			MWprintf(10, "[%d] num=%4d lower=%12.2f\tupper=%12.2f\tfirst=%12.2f\tlast=%12.2f\n", 
+				i, ind->num, ind->lower, ind->upper, ind->first->key, ind->last->key);
+		}
+	}
+	MWprintf(10, "Total num = %d.\n", total);
+}
+
+/** Implementation of MWList<ObjType> **/
+
+/* The empty list contains a dummy element which has a null ptr 
+ * to an object. dummy->next will be the first obj, dummy->prev 
+ * will be the last obj when the list is not empty. */
+template <class ObjType>
+MWList<ObjType>::MWList()
+{
+	dummy = new MWListElement<ObjType>(NULL, -DBL_MAX);
+	if (dummy == NULL) {
+		MWprintf(10, "MWList::Can't initialize the list during object construction.\n");
+		return;
+	}
+	dummy->next = dummy;
+	dummy->prev = dummy;
+	
+	current = dummy;
+	num = 0;
+
+	/* Indexing */
+	sorted = false;
+	index = NULL;
+}
+
+template <class ObjType>
+MWList<ObjType>::~MWList()
+{ 
+	if (num == 0)
+		return;
+	current = dummy->next;
+	while (RemoveCurrent() != NULL); // delete all the list elements
+	delete dummy;
+}
+
+template <class ObjType>
+bool
+MWList<ObjType>::IsEmpty() 
+{
+       return (num == 0);
+}
+
+template <class ObjType>
+int
+MWList<ObjType>::Number()
+{
+	return num;
+}
+
+template <class ObjType>
+ObjType*
+MWList<ObjType>::First()
+{
+	if (num == 0)
+		return NULL;
+	
+	current = dummy->next;
+	return current->obj;
+}
+
+template <class ObjType>
+ObjType*
+MWList<ObjType>::Last()
+{
+	if (num == 0)
+		return NULL;
+	
+	current = dummy->prev;
+	return current->obj;
+}
+
+template <class ObjType>
+bool 
+MWList<ObjType>::BeforeHead()
+{
+	return (current == dummy);
+}
+
+template <class ObjType>
+bool 
+MWList<ObjType>::AfterEnd()
+{
+	return (current == dummy);
+}
+
+template <class ObjType>
+void
+MWList<ObjType>::ToHead()
+{
+	current = dummy->next;
+}
+
+template <class ObjType>
+void
+MWList<ObjType>::ToEnd()
+{
+	current = dummy->prev;
+}
+
+/* Return the current object, unless currently at head or end */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Current()
+{
+	if (num==0)
+		return NULL;
+	
+	if (current == dummy)
+		return NULL;
+
+	return current->obj;
+}
+
+/* Return the position, can be used to remove a particular element */
+template <class ObjType>
+MWListElement<ObjType> *
+MWList<ObjType>::CurPosition()
+{
+	return current;
+}
+
+/* Advance the current ptr, and return the new obj that current pointed to */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Next()
+{
+	current = current->next;
+	if (current== dummy)
+		return NULL;
+	else return current->obj;
+}
+
+/* Retreat the current ptr, and return the new obj that current pointed to */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Prev()
+{
+	current = current->prev;
+	if (current->prev == dummy)
+		return NULL;
+	else return current->obj;
+}
+
+/* Remove an element from the list */
+template <class ObjType>
+void 
+MWList<ObjType>::Remove(MWListElement<ObjType> * item)
+{
+	if ((item == dummy)||(num == 0)) {
+		MWprintf(10, "MWList::Can't remove the current element from empty list.\n");
+		return;
+	}
+	
+	/* Update index */
+	if (index != NULL) {
+	       	MWIndex<ObjType> * ind = index->IndexFor(item->key);
+	       	if (ind->num == 1)
+		       	index->Merge(ind);
+
+		if (ind->num > 1) {
+		       	if (item == ind->last) 
+				ind->last = item->prev; 
+			if (item == ind->first)
+			       	ind->first = item->next;
+	       	} else {
+		       	ind->first = ind->last = NULL;
+	       	}
+
+		ind->num --;
+	}
+	
+	/* Remove the item */
+	item->prev->next = item->next;
+	item->next->prev = item->prev;
+	delete item;
+	num --;
+	
+	if ((num == 0))
+		ClearIndex();
+}
+
+/* Remove the current element, and return the obj it points to. 
+ * The current pointer will become the previous element, or if removing
+ * the first element, the dummy position */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::RemoveCurrent()
+{
+	if (num == 0) {
+		MWprintf(10, "MWList::Can't remove any element from empty list.\n");
+		return NULL;
+	}
+	
+	ObjType * newObj = current->obj;
+	current = current->prev;
+	Remove(current->next);
+	return newObj;
+}
+
+/* Rewind to head position, remove the first element, 
+ * and return the object it points to. - to keep compatible with the old API*/
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Remove()
+{
+	if (num == 0) {
+		MWprintf(10, "MWList::Can't remove any element from empty list.\n");
+		return NULL;
+	}
+	
+	ObjType * newObj = dummy->next->obj;
+	Remove(dummy->next);
+	current = dummy;
+	return newObj;
+}
+
+/* Pop the first element from the list */
+template <class ObjType>
+ObjType*
+MWList<ObjType>::Pop()
+{
+	return Remove();
+}
+
+/* Append an object at the end of the list */
+template <class ObjType>
+MWListElement<ObjType>*
+MWList<ObjType>::Append(ObjType *obj)
+{
+	MWListElement<ObjType> * item = new MWListElement<ObjType>(obj, 0.0);
+	
+	if (item == NULL) 
+		return NULL;
+	
+	dummy->prev->next = item;
+	item->prev = dummy->prev;
+	dummy->prev = item;
+	item->next = dummy;
+	current = item;
+	num ++;
+
+	if (num == 1)
+		sorted = true;
+
+	if (sorted)  { /* Update sorted */
+		if ( (num>1) && (dummy->prev->prev->key > 0.0) ) {
+			sorted = false;
+			if (index != NULL) 
+				ClearIndex();
+		} else if (index != NULL) { /* Update index */
+		       	MWIndex<ObjType> * ind = index->IndexFor(0.0);
+		       	if (ind->num == 1)
+			       	index->Merge(ind);
+
+			if (ind->num > 1) {
+			       	if (item == ind->last) 
+					ind->last = item->prev; 
+				if (item == ind->first)
+				       	ind->first = item->next;
+		       	} else {
+			       	ind->first = ind->last = NULL;
+		       	}
+
+			ind->num --;
+		}
+	}
+	
+	return item;
+}
+
+/* Prepend an object at the head of the list */
+template <class ObjType>
+MWListElement<ObjType>*
+MWList<ObjType>::Prepend(ObjType *obj)
+{
+	MWListElement<ObjType> * item = new MWListElement<ObjType>(obj, 0.0);
+	
+	if (item == NULL) 
+		return NULL;
+	
+	dummy->next->prev = item;
+	item->next = dummy->next;
+	dummy->next = item;
+	item->prev = dummy;
+	current = item;
+	num ++;
+
+	if (num == 1)
+		sorted = true;
+
+	if (sorted) { /* Update sorted */
+		if ( (num>1) && (dummy->next->next->key < 0.0) ) {
+			sorted = false;
+			MWprintf(10, "MWList becomes not sorted.\n");
+			if (index != NULL)
+				ClearIndex();
+		} else if (index != NULL) { /* Update index */
+		       	MWIndex<ObjType> * ind = index->IndexFor(0.0);
+		       	if (ind->num == 1)
+			       	index->Merge(ind);
+
+			if (ind->num > 1) {
+			       	if (item == ind->last) 
+					ind->last = item->prev; 
+				if (item == ind->first)
+				       	ind->first = item->next;
+		       	} else {
+			       	ind->first = ind->last = NULL;
+		       	}
+
+			ind->num --;
+		}
+	}
+
+	return item;
+}
+
+template <class ObjType>
+void 
+MWList<ObjType>::Display()
+{
+	MWprintf(80, "Number = %d\n", num);
+#if 0
+	MWListElement<ObjType> *p;
+	
+	MWprintf(80, "<< -- \n");
+       	p = dummy->next;
+	while (p!=dummy){
+		MWprintf(80, "  %f\t", p->key);
+		p->obj->Display();
+		p = p->next;
+	}
+	MWprintf(80, "-- >>\n");
+#endif
+}
+
+/* Add an object into the list in a sorted order */
+template <class ObjType>
+void 
+MWList<ObjType>::SortedInsert(ObjType *obj, double key)
+{
+	MWListElement<ObjType> * ptr;
+
+	if ( (sorted == false) && (num > 0) ) {
+		MWprintf(10, "MWList::SortedInsert into unsorted list.\n");
+		exit(1);
+	}
+		
+	if (index != NULL) { /* indexed */
+		IndexedInsert(obj, key);
+		return;
+	} 
+
+	/* If not indexed */
+	if (num == 0) {
+		MWListElement<ObjType>* ele = new MWListElement<ObjType>(obj, key);
+		dummy->next = dummy->prev = ele;
+		ele->next = ele->prev = dummy;
+		num ++;
+		sorted = true;
+	} else { 
+		/* walk through the list to find a place to insert */
+		ptr = dummy->next;
+		while ( (ptr != dummy) && (key > ptr->key) ) 
+				ptr = ptr->next;
+		
+		MWListElement<ObjType> * item = 
+			new MWListElement<ObjType>(obj, key);
+		/* Insert before ptr */
+		ptr->prev->next = item;
+		item->prev = ptr->prev;
+		item->next = ptr; 
+		ptr->prev = item;
+		num ++;
+
+		/* Build index when there are already many elements */
+		if ( (num > BUCKET_SIZE) && (index == NULL) )
+			this->BuildIndex();
+	}
+}
+
+/* Delete the first item with given key from the sorted list */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::SortedRemove(double key)
+{
+	MWListElement<ObjType> * ptr;
+
+	if ( (sorted == false) && (num > 0) ) {
+		MWprintf(10, "MWList::SortedRemove from unsorted list.\n");
+		return NULL;
+	}
+		
+	if (index != NULL) /* indexed */
+		return IndexedRemove(key);
+
+	/* If not indexed */
+	if (num == 0) {
+		return NULL;
+	} else { 
+		/* walk through the list to find the element with given key */
+		ptr = dummy->next;
+		while ( (ptr != dummy) && (key > ptr->key) ) 
+				ptr = ptr->next;
+		
+		if ( (key < ptr->key) || (ptr == dummy) ) /* not found */
+			return NULL;
+		
+		/* delete ptr*/
+		ObjType * obj = ptr->obj;
+		
+		ptr->prev->next = ptr->next;
+		ptr->next->prev = ptr->prev;
+		delete ptr;
+		num --;
+
+		return obj;
+	}
+}
+
+/* With the help of index, add an object into an ordered list */
+template <class ObjType>
+void 
+MWList<ObjType>::IndexedInsert(ObjType *obj, double key)
+{  
+	static int newly_inserted = 0;
+
+	MWIndex<ObjType> * ind = index->IndexFor(key);
+	if (ind == NULL) {
+		MWprintf(10, "MWList::IndexedInsert() can't find an index for key = %f.\n", key);
+		return;
+	}
+       	/* walk through the list to find a place to insert */
+       	MWListElement<ObjType>* ptr = ind->first;
+       	while ( (ptr != dummy) && (key > ptr->key) ) 
+		ptr = ptr->next;
+
+	MWListElement<ObjType> * item = 
+		new MWListElement<ObjType>(obj, key);
+	
+       	/* Insert before ptr */
+       	ptr->prev->next = item;
+       	item->prev = ptr->prev;
+       	item->next = ptr; 
+	ptr->prev = item;
+	ind->num ++;
+       	num ++;
+	
+	/* Need to update the index */
+	if (ptr == ind->last->next) 
+		ind->last = item;
+	if (ptr == ind->first) 
+		ind->first = item;
+
+	/* Balance */
+	newly_inserted ++;
+	
+	if (newly_inserted > BUCKET_SIZE) {
+		BuildIndex();
+		newly_inserted = 0;
+	}
+
+}
+
+/* With the help of index, add an object into an ordered list */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::IndexedRemove(double key)
+{  
+	static int newly_removed = 0;
+	
+	if (num == 0) 
+		return NULL;
+	
+	MWIndex<ObjType> * ind = index->IndexFor(key);
+	if (ind == NULL) {
+		MWprintf(10, "MWList::IndexedRemove() can't find an index.\n");
+		return NULL;
+	}
+	
+	/* walk through the list to find the element with given key */
+       	MWListElement<ObjType> * ptr = ind->first;
+       	while ( (ptr != dummy) && (key > ptr->key) ) 
+		ptr = ptr->next;
+
+	if ( (key < ptr->key) || (ptr == dummy) ) /* not found */
+	       	return NULL;
+
+	/* Need to update the index */
+	if (ind->num == 1)
+		index->Merge(ind);
+	
+	if (ind->num > 1) {
+		if (ptr == ind->last) 
+			ind->last = ptr->prev; 
+		if (ptr == ind->first)
+		       	ind->first = ptr->next;
+	} else {
+		ind->first = ind->last = NULL;
+	}
+	
+	/* delete ptr*/
+       	ObjType * obj = ptr->obj;
+	ptr->prev->next = ptr->next;
+       	ptr->next->prev = ptr->prev;
+       	delete ptr;
+	ind->num --;
+       	num --;
+
+	/* Balance */
+	if (num == 0) 
+		ClearIndex(); 
+	else {
+		newly_removed ++;
+		if (newly_removed > BUCKET_SIZE) {
+			BuildIndex();
+			newly_removed = 0;
+		}
+	}
+	
+	return obj;
+}
+
+/* Sort the list */
+template <class ObjType>
+void 
+MWList<ObjType>::Sort()
+{
+	if (sorted == true)
+		return;
+
+	MWList<ObjType> * list = new MWList<ObjType>;
+	ObjType * obj;
+	double key;
+	
+	int inserted = 0;
+	while (num > 0) {
+		obj = dummy->next->obj;
+		key = dummy->next->key;
+		list->SortedInsert(obj, key);
+		Remove(dummy->next);
+		inserted ++;
+
+		/* Use index to accelerate insertion */
+		if ( (index == NULL)&&(inserted > BUCKET_SIZE/2) ) {
+			list->BuildIndex();
+			inserted = 0;
+		}
+	}
+
+	sorted = true;
+}
+
+/* Build index */
+template <class ObjType>
+void 
+MWList<ObjType>::BuildIndex()
+{  
+	if (index == NULL) 
+		index = new MWIndexList<ObjType>;
+
+	index->BuildIndex(this);
+	index->Display();
+}
+
+/* Build index */
+template <class ObjType>
+void 
+MWList<ObjType>::ClearIndex()
+{  
+	if (index == NULL) 
+		return;
+
+	delete index;
+	index = NULL;
+}
+
+#endif
diff --git a/MW/src/MWList.h b/MW/src/MWList.h
new file mode 100644
index 0000000..1d8f77a
--- /dev/null
+++ b/MW/src/MWList.h
@@ -0,0 +1,1088 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* MWList.h: rewrite to make MWListElement and MWList into template classes.
+ */ 
+
+#ifndef MWLIST_H
+#define MWLIST_H
+#include <stdio.h>
+#include <string.h>
+#include <float.h>
+#include "MW.h"
+
+#define BUCKET_SIZE 4096
+
+/* MWListElement defines the <key, item> pair for actual data.
+ * The key is used as priority, item is the ptr to actual object. */
+template <class ObjType> class MWList;
+template <class ObjType> class MWIndex;
+template <class ObjType> class MWIndexList;
+
+template <class ObjType> 
+class MWListElement 
+{
+friend class MWList<ObjType>;
+friend class MWIndex<ObjType>;
+friend class MWIndexList<ObjType>;
+
+public:
+	MWListElement(ObjType *itemPtr = NULL, double key = 0.0);
+	~MWListElement();
+	
+private:
+	MWListElement<ObjType>	*next;
+	MWListElement<ObjType>	*prev;
+	ObjType *obj;
+	double key;
+};
+
+/* MWIndex defines an index into MWList */
+template <class ObjType>
+class MWIndex
+{
+friend class MWList<ObjType>;
+friend class MWIndexList<ObjType>;
+
+public:
+	MWIndex();
+	~MWIndex();
+
+	/* split the index into two halves, create a new index to the 
+	 * second half and returns the ptr to the new index */
+	MWIndex<ObjType>* Split(); 
+	void SplitTo(MWIndexList<ObjType>* ilist, int bucket_size);
+
+	/* Split the index, or merge it with the next index to make
+	 * the index involved have their size close to bucket_size.
+	 * Return value: 
+	 *  * if splitted, then return the ptr to newly created index;
+	 *  * if merged, then return the ptr to merged index; 
+	 *  * if not changed, then return the ptr to the next index. */
+	MWIndex<ObjType>* BalanceNext(MWIndexList<ObjType>* ilist, int bucket_size);
+	
+private:
+	/* How many elements are included by this index */
+	int num;
+	
+	/* bounds and boundary ptr to the actual elements */
+	double upper;
+	double lower;
+	MWListElement<ObjType> * first;
+	MWListElement<ObjType> * last;
+
+	/* ptr to other index */
+	MWIndex<ObjType> * next;
+	MWIndex<ObjType> * prev;
+};
+
+/* MWIndexList defines a list of index for a list */
+template <class ObjType>
+class MWIndexList
+{
+friend class MWList<ObjType>;
+friend class MWIndex<ObjType>;
+
+public:
+	MWIndexList();
+	~MWIndexList();
+
+	/* Build index for the list, split index whose number >= bucket_size,
+	 * and merge adjacent index whose number < 0.25 * bucket_size */
+	void BuildIndex(MWList<ObjType>* list, int bucket_size = BUCKET_SIZE);
+	
+	/* Split an index and insert the new index into the list */
+	void Split(MWIndex<ObjType>* index);
+
+	/* Search for the index for key */
+	MWIndex<ObjType>* IndexFor(double key);
+
+	/* Merge an index with its neibough */
+	MWIndex<ObjType>* Merge(MWIndex<ObjType>* i1);
+
+	/* Remove an empty index */
+	bool  RemoveEmptyIndex(MWIndex<ObjType> * ind);
+
+	void Display();
+	
+private:
+	/* number of index in the list */
+	int num;
+	MWIndex<ObjType> * dummy;
+};
+
+/* MWList defines a list of items */
+template <class ObjType>
+class MWList 
+{
+friend class MWIndexList<ObjType>;
+
+public:
+	MWList(char * name = "dummy_list");
+	virtual ~MWList();
+
+	/* Query */
+	inline char* Name() { return name; }; 
+	inline bool isSorted() { return sorted; };
+	inline int number() { return num; };
+	inline bool isEmpty() { return num == 0; };
+	int Number();	// number of elements in the list
+	bool IsEmpty(); // is the list empty? 
+
+	ObjType * First();
+	ObjType * Last();
+
+	/* Scans */
+	bool BeforeHead();
+	bool AfterEnd();
+
+	void ToHead();
+	void ToEnd();
+	
+	ObjType * Current(); /* return the current object */
+	MWListElement<ObjType> * CurPosition();
+	ObjType * Next();    /* advance ptr, return the next object */
+	ObjType * Prev();    /* backup prt, return the prev object */
+
+	/* Removal */
+	ObjType * Pop();
+	/* Rewind, and take item off the front of the list*/
+	ObjType * Remove();	    
+	
+	/* Take the given item off the list */
+	void Remove(MWListElement<ObjType>* item);
+	/* remove the current object from the list */
+	ObjType * RemoveCurrent(); 
+
+	MWListElement<ObjType>* Append(ObjType *item, double key = 0.0); /* Put item at the end of the list */
+	MWListElement<ObjType>* Prepend(ObjType *obj, double key = 0.0); /* Put item at the head of the list */
+		
+	/* Put item into list by order */
+	void SortedInsert(ObjType *item, double key);
+
+	/* Remove first item with key value from list */
+	ObjType* SortedRemove(double key); 
+
+	/* Sort and Indexing */
+	void Sort();
+	void BuildIndex();
+	void ClearIndex();
+
+	/* Debug, display */
+	void Display();
+
+	private:
+		int num;
+		char *name;
+		MWListElement<ObjType> *dummy;
+		MWListElement<ObjType> *current;
+
+		/* indexing */
+		bool sorted;	/* true after calling Sort() */
+		MWIndexList<ObjType> * index; /* indexed if not NULL */
+
+		/* Indexed insertion */
+		void IndexedInsert(ObjType *item, double key);
+		/* Indexed removal */
+		ObjType * IndexedRemove(double key);
+};
+
+/**************************************************************************
+ *  Implementation of MWListElement, MWIndex, MWIndexList, MWList         *
+ **************************************************************************/ 
+
+/** Implementation of MWListElement<ObjType> **/
+
+template <class ObjType>
+MWListElement<ObjType>::MWListElement(ObjType *itemPtr, double sortKey)
+{
+	obj= itemPtr;
+	key = sortKey;
+	next = this; 
+	prev = this;
+}
+	
+template <class ObjType>
+MWListElement<ObjType>::~MWListElement()
+{
+	/* Nothing */
+}
+	
+/** Implementation of MWIndex<ObjType> **/
+template <class ObjType>
+MWIndex<ObjType>::MWIndex()
+{
+	/* Nothing */
+}
+
+template <class ObjType>
+MWIndex<ObjType>::~MWIndex()
+{
+	/* Nothing */
+}
+
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndex<ObjType>::Split()
+{
+	int i;
+
+	if (this->num<2)
+		return NULL;
+	
+	MWListElement<ObjType> * current = this->first->prev;
+
+	/* Walk through the list until we meet the half point */
+	for (i=0; i<num/2; i++)
+		current = current->next;
+	
+	/* Create a new index for the second half */
+	MWIndex<ObjType> * i2 = new MWIndex<ObjType>;
+	if (i2 == NULL)
+		return NULL;
+
+	i2->num = num - i;
+	i2->first = current->next;
+	i2->lower = current->key; /* must not leave space between boundaries */
+	i2->last = this->last;
+	i2->upper = this->upper;
+	
+	/* Update the current index */
+	this->num = num/2;
+	this->last = current;
+	this->upper = current->key;
+
+	/* return the new index, which should be inserted into index list */
+	return i2;
+}
+
+/* split an index into many smaller ones whose sizes <= bucket_size */
+template <class ObjType>
+void
+MWIndex<ObjType>::SplitTo(MWIndexList<ObjType>* ilist, int bucket_size)
+{
+	if (num < bucket_size)
+		return;
+	
+	ilist->Split(this);
+	MWIndex<ObjType> * next = this->next;
+	
+	this->SplitTo(ilist, bucket_size);
+	next->SplitTo(ilist, bucket_size);
+}
+
+/* Balance the current index with the next index, either split or merge, 
+ * to make small buckets together, and cut large buckets into halves. 
+ * Return ptr to new index (current when splitting or next when merging) */
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndex<ObjType>::BalanceNext(MWIndexList<ObjType>* ilist, int bucket_size)
+{
+	/* Need to split */
+	if (this->num > bucket_size) {
+		MWIndex<ObjType> * next = this->next;
+		this->SplitTo(ilist, bucket_size+1);
+		return next;
+	}
+
+	/* Already the end of index list */
+	if (this->next == ilist->dummy)
+		return this->next;
+
+	/* Need to merget */
+	MWIndex<ObjType>* next_ind = this->next;
+	if (this->num + next_ind->num < bucket_size+1) {
+		return ilist->Merge(this);
+	} else {  
+		/* Nothing to be changed */
+		return this->next;
+	}
+}
+
+/** Implementation of MWIndexList<ObjType> **/
+template <class ObjType>
+MWIndexList<ObjType>::MWIndexList()
+{
+	dummy = new MWIndex<ObjType>();
+	if (dummy == NULL) {
+		MWprintf(10, "MWList::Can't initialize the list during object construction.\n");
+		return;
+	}
+	dummy->num = 0;
+	dummy->next = dummy;
+	dummy->prev = dummy;
+	dummy->lower = -DBL_MAX;
+	dummy->upper = DBL_MAX;
+	dummy->first = NULL;
+	dummy->last = NULL;
+
+	num = 0;
+}
+
+template <class ObjType>
+MWIndexList<ObjType>::~MWIndexList()
+{
+	MWIndex<ObjType>* ptr = dummy;
+	
+	while (num !=0) {
+		ptr = ptr->next;
+		delete ptr;
+		num --;
+	}
+	delete dummy;
+
+	MWprintf(10, "MWIndexList destructed.\n");
+}
+
+/* Build index for the list, split index whose number >= bucket_size,
+ * and merge adjacent index whose number < 0.25 * bucket_size */
+template <class ObjType>
+void 
+MWIndexList<ObjType>::BuildIndex(MWList<ObjType>* list, int bucket_size)
+{ 
+	MWprintf(10, "MWIndexList::BuildIndex()\n");
+
+	if (list->Number() < BUCKET_SIZE/2) {
+		MWprintf(10, "MWIndexList:: \
+			Will not build index when the list is still short.\n");
+		return;
+	}
+	
+	if (num == 0) { /* create index */
+		list->Sort();
+		
+		/* create the first index for the whole list */
+		MWIndex<ObjType> * ind = new MWIndex<ObjType>;
+		ind->num = list->Number();
+		ind->upper = DBL_MAX;
+		ind->lower = -DBL_MAX;
+		ind->first = list->dummy->next;
+		ind->last= list->dummy->prev;
+
+		/* Insert into index list */
+		dummy->next = ind;
+		ind->next = dummy;
+		dummy->prev = ind;
+		ind->prev = dummy;
+
+		num ++;
+		
+		/* split into small enough buckets */
+		ind->SplitTo(this, bucket_size);
+		
+	} else { 
+		/* balance index items */
+		MWIndex<ObjType> * ind = dummy->next;
+		
+		while ( (ind != this->dummy) && (ind != NULL) ) {
+			ind = ind->BalanceNext(this, bucket_size);
+		}
+	}
+}
+
+template <class ObjType>
+void
+MWIndexList<ObjType>::Split(MWIndex<ObjType>* index)
+{ 
+	MWIndex<ObjType> * another = index->Split();
+	index->next->prev = another;
+	another->next = index->next;
+	index->next = another;
+	another->prev = index;
+
+	num ++;
+}
+	
+template <class ObjType>
+MWIndex<ObjType>* 
+MWIndexList<ObjType>::IndexFor(double key)
+{
+	MWIndex<ObjType> * ptr = dummy;
+	for (int i=0; i<num; i++) {
+		ptr = ptr->next;
+		if ( (ptr->upper >= key) && (ptr->lower <= key) )
+			return ptr;
+	}
+	return NULL;
+}
+
+/* Merge two index, and delete any empty index */
+template <class ObjType>
+MWIndex<ObjType>*
+MWIndexList<ObjType>::Merge(MWIndex<ObjType> * i1)
+{
+	if (num == 1) {/* Can't merge */
+		if (i1->num == 0) { /* Delete i1 then */
+			dummy->next = dummy->prev = dummy;
+			num = 0;
+			delete i1;
+			return NULL;
+		}
+	}
+	
+       	MWIndex<ObjType> * next_ind = i1->next;
+	while ((i1->next->num == 0) && (i1->next != dummy)) {
+		/* clear empty index until the first non empty index */
+		next_ind = i1->next;
+		i1->next = next_ind->next;
+		delete next_ind;
+		num --;
+	}
+		
+	next_ind = i1->next;
+	if (i1->next != dummy) {
+		/* need to merge with it's next */
+	       	i1->num = i1->num + next_ind->num;
+	       	i1->last = next_ind->last;
+	       	i1->upper = next_ind->upper;
+
+		/* remove the item from the list */
+	       	next_ind->next->prev = i1;
+	       	i1->next = next_ind->next;
+	       	delete next_ind;
+	       	num --;
+	}
+
+	return i1;
+}
+
+/* Merge two index, and delete any empty index */
+template <class ObjType>
+bool
+MWIndexList<ObjType>::RemoveEmptyIndex(MWIndex<ObjType> * ind)
+{
+	if (num > 1) {
+	       	if (ind->next != dummy) {
+		       	/* Merge with ind->next */
+		       	ind->next->prev = ind->prev;
+		       	ind->prev->next = ind->next;
+		       	ind->next->lower = ind->lower;
+	       	} else if (ind->prev != dummy) {
+		       	/* Merge with ind->prev */
+		       	ind->prev->next = ind->next;
+		       	ind->next->prev = ind->prev;
+		       	ind->prev->upper = ind->upper;
+		} 
+		num --;
+		return false;
+	} else {
+		num = 0;
+		return true; /* should ClearIndex() */
+	}
+}
+
+template <class ObjType>
+void
+MWIndexList<ObjType>::Display()
+{
+	MWIndex<ObjType> * ind = dummy;
+	int total = 0;
+	for (int i=0; i<num; i++) {
+		ind = ind->next;
+		if (ind == NULL) {
+			MWprintf(10, "MWList:: Bad problem, index list broken.\n");
+		}
+			
+		total += ind->num;
+		if (ind->num > 0) {
+			if (ind->first == NULL) 
+				MWprintf(10, "MWList:: Bad error, ind->first == NULL");
+			else if (ind->last == NULL) 
+				MWprintf(10, "MWList:: Bad error, ind->last == NULL");
+			else MWprintf(10, "[%d] num=%4d lower=%12.2f\tupper=%12.2f\tfirst=%12.2f\tlast=%12.2f\n", 
+				i, ind->num, ind->lower, ind->upper, ind->first->key, ind->last->key);
+		}
+	}
+	MWprintf(10, "Total num = %d.\n", total);
+}
+
+/** Implementation of MWList<ObjType> **/
+
+/* The empty list contains a dummy element which has a null ptr 
+ * to an object. dummy->next will be the first obj, dummy->prev 
+ * will be the last obj when the list is not empty. */
+template <class ObjType>
+MWList<ObjType>::MWList(char *name)
+{
+	dummy = new MWListElement<ObjType>(NULL, -DBL_MAX);
+	if (dummy == NULL) {
+		MWprintf(10, "MWList::Can't initialize the list during object construction.\n");
+		return;
+	}
+	dummy->next = dummy;
+	dummy->prev = dummy;
+	
+	current = dummy;
+	num = 0;
+
+	/* Indexing */
+	sorted = false;
+	index = NULL;
+
+	this->name = (char*)malloc(strlen(name)+1);
+	if (this->name == NULL) {
+		MWprintf(10, "MWList::Can't initialize the list name during construction.\n");
+		return;
+	} else {
+		strcpy(this->name, name);
+	}
+}
+
+template <class ObjType>
+MWList<ObjType>::~MWList()
+{ 
+	if (num == 0)
+		return;
+	current = dummy->next;
+	while (RemoveCurrent() != NULL); // delete all the list elements
+	delete dummy;
+}
+
+template <class ObjType>
+bool
+MWList<ObjType>::IsEmpty() 
+{
+       return (num == 0);
+}
+
+template <class ObjType>
+int
+MWList<ObjType>::Number()
+{
+	return num;
+}
+
+template <class ObjType>
+ObjType*
+MWList<ObjType>::First()
+{
+	if (num == 0)
+		return NULL;
+	
+	current = dummy->next;
+	return current->obj;
+}
+
+template <class ObjType>
+ObjType*
+MWList<ObjType>::Last()
+{
+	if (num == 0)
+		return NULL;
+	
+	current = dummy->prev;
+	return current->obj;
+}
+
+template <class ObjType>
+bool 
+MWList<ObjType>::BeforeHead()
+{
+	return (current == dummy);
+}
+
+template <class ObjType>
+bool 
+MWList<ObjType>::AfterEnd()
+{
+	return (current == dummy);
+}
+
+template <class ObjType>
+void
+MWList<ObjType>::ToHead()
+{
+	current = dummy->next;
+}
+
+template <class ObjType>
+void
+MWList<ObjType>::ToEnd()
+{
+	current = dummy->prev;
+}
+
+/* Return the current object, unless currently at head or end */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Current()
+{
+	if (num==0)
+		return NULL;
+	
+	if (current == dummy)
+		return NULL;
+
+	return current->obj;
+}
+
+/* Return the position, can be used to remove a particular element */
+template <class ObjType>
+MWListElement<ObjType> *
+MWList<ObjType>::CurPosition()
+{
+	return current;
+}
+
+/* Advance the current ptr, and return the new obj that current pointed to */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Next()
+{
+	current = current->next;
+	if (current== dummy)
+		return NULL;
+	else return current->obj;
+}
+
+/* Retreat the current ptr, and return the new obj that current pointed to */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Prev()
+{
+	current = current->prev;
+	if (current->prev == dummy)
+		return NULL;
+	else return current->obj;
+}
+
+/* Remove an element from the list */
+template <class ObjType>
+void 
+MWList<ObjType>::Remove(MWListElement<ObjType> * item)
+{
+	if ((item == dummy)||(num == 0)) {
+		MWprintf(10, "MWList::Can't remove the current element from empty list.\n");
+		return;
+	}
+	
+	/* Update index */
+	if (index != NULL) {
+	       	MWIndex<ObjType> * ind = index->IndexFor(item->key);
+
+		if (ind->num > 1) {
+		       	if (item == ind->last) 
+				ind->last = item->prev; 
+			if (item == ind->first)
+			       	ind->first = item->next;
+			ind->num --;
+	       	} else { 
+			/* ind will become empty after removal */
+			if (index->RemoveEmptyIndex(ind))
+				ClearIndex();
+	       	}
+	}
+	
+	/* Remove the item */
+	if (item->key != 0.0)
+		MWprintf(70, "MWList remove %f.\n", item->key);
+	
+	item->prev->next = item->next;
+	item->next->prev = item->prev;
+	delete item;
+	num --;
+}
+
+/* Remove the current element, and return the obj it points to. 
+ * The current pointer will become the previous element, or if removing
+ * the first element, the dummy position */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::RemoveCurrent()
+{
+	if (num == 0) {
+		MWprintf(10, "MWList::Can't remove any element from empty list.\n");
+		return NULL;
+	}
+	
+	ObjType * newObj = current->obj;
+	current = current->prev;
+	Remove(current->next);
+	return newObj;
+}
+
+/* Rewind to head position, remove the first element, 
+ * and return the object it points to. - to keep compatible with the old API*/
+template <class ObjType>
+ObjType *
+MWList<ObjType>::Remove()
+{
+	if (num == 0) {
+		MWprintf(10, "MWList::Can't remove any element from empty list.\n");
+		return NULL;
+	}
+	
+	ObjType * newObj = dummy->next->obj;
+	Remove(dummy->next);
+	current = dummy;
+	return newObj;
+}
+
+/* Pop the first element from the list */
+template <class ObjType>
+ObjType*
+MWList<ObjType>::Pop()
+{
+	return Remove();
+}
+
+/* Append an object at the end of the list */
+template <class ObjType>
+MWListElement<ObjType>*
+MWList<ObjType>::Append(ObjType *obj, double key)
+{
+	MWListElement<ObjType> * item = new MWListElement<ObjType>(obj, key);
+	
+	if (item == NULL) 
+		return NULL;
+	
+	dummy->prev->next = item;
+	item->prev = dummy->prev;
+	dummy->prev = item;
+	item->next = dummy;
+	current = item;
+	num ++;
+
+	if (num == 1)
+		sorted = true;
+
+	if (sorted)  { /* Update sorted */
+		if ( (num>1) && (dummy->prev->prev->key > key) ) {
+			sorted = false;
+			if (index != NULL) 
+				ClearIndex();
+		} else if ( (index != NULL) && (index->num>0) ) { 
+				/* Update index */
+			       	MWIndex<ObjType> * ind = index->dummy->prev;
+				/* ind is the last index entry */
+				ind->last = item;
+				ind->num ++;
+		}
+	}
+	
+	return item;
+}
+
+/* Prepend an object at the head of the list */
+template <class ObjType>
+MWListElement<ObjType>*
+MWList<ObjType>::Prepend(ObjType *obj, double key)
+{
+	MWListElement<ObjType> * item = new MWListElement<ObjType>(obj, key);
+	
+	if (item == NULL) 
+		return NULL;
+	
+	dummy->next->prev = item;
+	item->next = dummy->next;
+	dummy->next = item;
+	item->prev = dummy;
+	current = item;
+	num ++;
+
+	if (num == 1)
+		sorted = true;
+
+	if (sorted) { /* Update sorted */
+		if ( (num>1) && (dummy->next->next->key < key) ) {
+			sorted = false;
+			if (index != NULL)
+				ClearIndex();
+		} else if ( (index != NULL) && (index->num > 0)  ) { 
+			/* Update index */
+		       	MWIndex<ObjType> * ind = index->dummy->next;
+			/* ind is the first index entry */
+			ind->first = item;
+			ind->num ++;
+		}
+	}
+
+	return item;
+}
+
+template <class ObjType>
+void 
+MWList<ObjType>::Display()
+{
+	MWprintf(80, "Number = %d\n", num);
+#if 0
+	MWListElement<ObjType> *p;
+	
+	MWprintf(80, "<< -- \n");
+       	p = dummy->next;
+	while (p!=dummy){
+		MWprintf(80, "  %f\t", p->key);
+		p->obj->Display();
+		p = p->next;
+	}
+	MWprintf(80, "-- >>\n");
+#endif
+}
+
+/* Add an object into the list in a sorted order */
+template <class ObjType>
+void 
+MWList<ObjType>::SortedInsert(ObjType *obj, double key)
+{
+	MWListElement<ObjType> * ptr;
+
+	if ( (sorted == false) && (num > 0) ) {
+		MWprintf(10, "MWList::SortedInsert into unsorted list.\n");
+		exit(1);
+	}
+		
+	if (index != NULL) { /* indexed */
+		IndexedInsert(obj, key);
+		return;
+	} 
+
+	/* If not indexed */
+	if (num == 0) {
+		MWListElement<ObjType>* ele = new MWListElement<ObjType>(obj, key);
+		dummy->next = dummy->prev = ele;
+		ele->next = ele->prev = dummy;
+		num ++;
+		sorted = true;
+	} else { 
+		/* walk through the list to find a place to insert */
+		ptr = dummy->next;
+		while ( (ptr != dummy) && (key > ptr->key) ) 
+				ptr = ptr->next;
+		
+		MWListElement<ObjType> * item = 
+			new MWListElement<ObjType>(obj, key);
+		
+		/* Insert before ptr */
+		// MWprintf(10, "MWList insert %f\n", item->key);
+		ptr->prev->next = item;
+		item->prev = ptr->prev;
+		item->next = ptr; 
+		ptr->prev = item;
+		num ++;
+
+		/* Build index when there are already many elements */
+		if ( (num > BUCKET_SIZE) && (index == NULL) )
+			this->BuildIndex();
+	}
+}
+
+/* Delete the first item with given key from the sorted list */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::SortedRemove(double key)
+{
+	MWListElement<ObjType> * ptr;
+
+	if ( (sorted == false) && (num > 0) ) {
+		MWprintf(10, "MWList::SortedRemove from unsorted list.\n");
+		return NULL;
+	}
+		
+	if (index != NULL) /* indexed */
+		return IndexedRemove(key);
+
+	/* If not indexed */
+	if (num == 0) {
+		return NULL;
+	} else { 
+		/* walk through the list to find the element with given key */
+		ptr = dummy->next;
+		while ( (ptr != dummy) && (key > ptr->key) ) 
+				ptr = ptr->next;
+		
+		if ( (key < ptr->key) || (ptr == dummy) ) /* not found */
+			return NULL;
+		
+		/* delete ptr*/
+		ObjType * obj = ptr->obj;
+		
+		ptr->prev->next = ptr->next;
+		ptr->next->prev = ptr->prev;
+		delete ptr;
+		num --;
+
+		return obj;
+	}
+}
+
+/* With the help of index, add an object into an ordered list */
+template <class ObjType>
+void 
+MWList<ObjType>::IndexedInsert(ObjType *obj, double key)
+{  
+	static int newly_inserted = 0;
+
+	MWIndex<ObjType> * ind = index->IndexFor(key);
+	if (ind == NULL) {
+		MWprintf(10, "MWList::IndexedInsert() can't find an index for key = %f.\n", key);
+		return;
+	}
+       	/* walk through the list to find a place to insert */
+       	MWListElement<ObjType>* ptr = ind->first;
+       	while ( (ptr != dummy) && (key > ptr->key) ) 
+		ptr = ptr->next;
+
+	MWListElement<ObjType> * item = 
+		new MWListElement<ObjType>(obj, key);
+	
+       	/* Insert before ptr */
+	// MWprintf(10, "MWList insert %f\n", item->key);
+       	ptr->prev->next = item;
+       	item->prev = ptr->prev;
+       	item->next = ptr; 
+	ptr->prev = item;
+	ind->num ++;
+       	num ++;
+	
+	/* Need to update the index */
+	if (ptr == ind->last->next) 
+		ind->last = item;
+	if (ptr == ind->first) 
+		ind->first = item;
+
+	/* Balance */
+	newly_inserted ++;
+	
+	if (newly_inserted > BUCKET_SIZE) {
+		BuildIndex();
+		newly_inserted = 0;
+	}
+
+}
+
+/* With the help of index, add an object into an ordered list */
+template <class ObjType>
+ObjType *
+MWList<ObjType>::IndexedRemove(double key)
+{  
+	static int newly_removed = 0;
+	
+	if (num == 0) 
+		return NULL;
+	
+	MWIndex<ObjType> * ind = index->IndexFor(key);
+	if (ind == NULL) {
+		MWprintf(10, "MWList::IndexedRemove() can't find an index.\n");
+		return NULL;
+	}
+	
+	/* walk through the list to find the element with given key */
+       	MWListElement<ObjType> * ptr = ind->first;
+       	while ( (ptr != dummy) && (key > ptr->key) ) 
+		ptr = ptr->next;
+
+	if ( (key < ptr->key) || (ptr == dummy) ) /* not found */
+	       	return NULL;
+
+	/* Need to update the index */
+	if (ind->num > 1) {
+		if (ptr == ind->last) 
+			ind->last = ptr->prev; 
+		if (ptr == ind->first)
+		       	ind->first = ptr->next;
+		ind->num --;
+       	} else { 
+		/* ind will become empty after removal */
+	       	if (index->RemoveEmptyIndex(ind))
+		       	ClearIndex();
+	}
+	
+	/* delete ptr*/
+       	ObjType * obj = ptr->obj;
+	// MWprintf(70, "MWList remove %f\n", ptr->key);
+	ptr->prev->next = ptr->next;
+       	ptr->next->prev = ptr->prev;
+       	delete ptr;
+       	num --;
+
+	/* Balance */
+	if (index != NULL) {
+		newly_removed ++;
+		if (newly_removed > BUCKET_SIZE) {
+			BuildIndex();
+			newly_removed = 0;
+		}
+	}
+	
+	return obj;
+}
+
+/* Sort the list */
+template <class ObjType>
+void 
+MWList<ObjType>::Sort()
+{
+	if (sorted == true)
+		return;
+
+	MWList<ObjType> * list = new MWList<ObjType>;
+	ObjType * obj;
+	double key;
+	
+	int inserted = 0;
+	while (num > 0) {
+		obj = dummy->next->obj;
+		key = dummy->next->key;
+		list->SortedInsert(obj, key);
+		Remove(dummy->next);
+		inserted ++;
+
+		/* Use index to accelerate insertion */
+		if ( (index == NULL)&&(inserted > BUCKET_SIZE/2) ) {
+			list->BuildIndex();
+			inserted = 0;
+		}
+	}
+
+	sorted = true;
+}
+
+/* Build index */
+template <class ObjType>
+void 
+MWList<ObjType>::BuildIndex()
+{  
+	if (num < BUCKET_SIZE/2) {
+		MWprintf(10, "MWIndexList:: Will not build index when the list is still short.\n");
+		return;
+	}
+	
+	if (index == NULL) 
+		index = new MWIndexList<ObjType>;
+
+	index->BuildIndex(this);
+	index->Display();
+}
+
+/* Build index */
+template <class ObjType>
+void 
+MWList<ObjType>::ClearIndex()
+{  
+	if (index == NULL) 
+		return;
+
+	delete index;
+	index = NULL;
+}
+
+#endif // MWLIST_H
diff --git a/MW/src/MWMasterMain.C b/MW/src/MWMasterMain.C
new file mode 100644
index 0000000..56db4e6
--- /dev/null
+++ b/MW/src/MWMasterMain.C
@@ -0,0 +1,43 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* 
+ *	This is the master's main function. The whole starts from this point
+ *	This was done on 2/2/00 to make MW pure Object Oriented.
+ *
+ *	Author:
+ *		Sanjeev. R. Kulkarni
+ */
+
+
+
+#include <stdio.h>
+#include "MWDriver.h"
+
+extern MWDriver* gimme_the_master();
+
+int main ( int argc, char *argv[] )
+{
+	MWDriver *driver;
+	driver = gimme_the_master ( );
+	driver->go ( argc, argv );
+}
diff --git a/MW/src/MWStats.C b/MW/src/MWStats.C
new file mode 100644
index 0000000..0740bda
--- /dev/null
+++ b/MW/src/MWStats.C
@@ -0,0 +1,539 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* stats.C
+
+   Implementation of Statistics class
+*/
+
+#include "MWStats.h"
+#include "MWSystem.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+extern int num_completed_tasks;
+
+MWStatistics::MWStatistics() {
+
+	uptimes = new double[MW_MAX_WORKERS];
+	workingtimes = new double[MW_MAX_WORKERS];
+	susptimes = new double[MW_MAX_WORKERS];
+	cputimes = new double[MW_MAX_WORKERS];
+
+	workingtimesnorm  = new double[MW_MAX_WORKERS];
+
+	sumbenchmark = new double[MW_MAX_WORKERS];
+	numbenchmark = new int[MW_MAX_WORKERS];
+
+	max_task_result = max_bench_result = 0.0;
+	min_task_result = min_bench_result = DBL_MAX;
+
+	for ( int i=0 ; i<MW_MAX_WORKERS ; i++ ) {
+		uptimes[i] = workingtimes[i] = susptimes[i] = cputimes[i] = 0.0;
+		workingtimesnorm[i] = sumbenchmark[i] = 0.0;
+		numbenchmark[i] = 0;
+	}
+
+    duration = 0;
+		// start in the constructor...
+	starttime = MWSystem::gettimeofday();
+	previoustime = 0.0;
+}
+
+
+MWStatistics::~MWStatistics() {
+    
+	delete [] uptimes;
+	delete [] workingtimes;
+	delete [] susptimes;
+	delete [] cputimes;
+
+	delete [] sumbenchmark;
+	delete [] numbenchmark;
+	delete [] workingtimesnorm;
+}
+
+void MWStatistics::write_checkpoint( FILE *cfp, MWList<MWWorkerID> *worlist ) 
+{
+  /* write out stats for each worker Vid.  This is a pain in 
+     my ass.  We have to find the maximum Vid in the system;
+     in both the old stats and the running workers.  Then, for
+     each Vid, we have to sum the old stats + the new running
+     worker stats, and write them out one at a time.... */
+
+  MWWorkerID *wkr;  // My eternal temporary workerID...
+  int sn_workers = get_max_vid();  // stats now says max is...
+  int run_workers=0;
+
+  	wkr = worlist->First();
+	while ( worlist->AfterEnd() == false ) 
+	{
+		wkr = worlist->Current();
+		if ( wkr->get_vid() > run_workers ) 
+		{
+			run_workers = wkr->get_vid();
+		}
+		worlist->Next();
+	}
+  run_workers++;   // there are this many running
+
+  int max = 0;  // get the max of the two...
+  if ( run_workers > sn_workers ) {
+    max = run_workers;
+  } else {
+    max = sn_workers;
+  }
+  
+  MWprintf ( 10, "In checkpointing -- sn: %d, run:%d, max:%d\n", sn_workers, run_workers, max );
+
+  double *u  = new double[max];
+  double *w  = new double[max];
+  double *s  = new double[max];
+  double *c  = new double[max];
+  double *wn  = new double[max];
+  double *sb = new double[max];	
+  int    *nb = new int[max];
+
+  int i;
+  for ( i=0 ; i<max ; i++ ) {
+    u[i] = uptimes[i];
+    w[i] = workingtimes[i];
+    s[i] = susptimes[i];
+    c[i] = cputimes[i];
+    wn[i] = workingtimesnorm[i];
+    sb[i] = sumbenchmark[i];
+    nb[i] = numbenchmark[i];
+  }
+
+  double up, wo, su, cp,  tn, sumb;
+  int numb;
+  
+  	wkr = worlist->First();
+	while ( worlist->AfterEnd() == false ) 
+	{
+		wkr = worlist->Current();
+		wkr->ckpt_stats( &up, &wo, &su, &cp,  &tn, &sumb, &numb );
+		u[wkr->get_vid()] += up;
+		w[wkr->get_vid()] += wo;
+		s[wkr->get_vid()] += su;
+		c[wkr->get_vid()] += cp;
+		wn[wkr->get_vid()] += tn;
+		sb[wkr->get_vid()] += sumb;
+		nb[wkr->get_vid()] += numb;
+    
+		worlist->Next();
+	}
+
+	double now = MWSystem::gettimeofday();
+  
+  fprintf ( cfp, "%d %15.5f\n", max, ((now-starttime)+previoustime) );
+  for ( i=0 ; i<max ; i++ ) {
+    //		MWprintf ( 10, "%15.5f %15.5f %15.5f %15.5f\n", 
+    //				   u[i], w[i], s[i], c[i] );
+    fprintf ( cfp, "%15.5f %15.5f %15.5f %15.5f %15.5f %15.5f %d\n", 
+	      u[i], w[i], s[i], c[i] , wn[i], sb[i], nb[i]);
+  }
+
+  fprintf ( cfp, "%15.5f %15.5f\n", max_bench_result, min_bench_result);
+  fprintf ( cfp, "%15.5f %15.5f\n", max_task_result, min_task_result);
+
+  delete [] u;
+  delete [] w;
+  delete [] s;
+  delete [] c;	
+  delete [] wn;
+  delete [] sb;
+  delete [] nb;;
+
+
+}
+
+
+//This is the good one
+void MWStatistics::read_checkpoint( FILE *cfp ) {
+	
+	int n=0;
+	int i;
+	fscanf ( cfp, "%d %lf", &n, &previoustime );
+	MWprintf ( 10, "num stats to read: %d prev: %f\n", n, previoustime );
+	for ( i=0 ; i<n ; i++ ) {
+
+		fscanf ( cfp, "%lf %lf %lf %lf %lf %lf %d", 
+			 &uptimes[i],
+			 &workingtimes[i], 
+			 &susptimes[i],
+			 &cputimes[i], 
+			 &workingtimesnorm[i],
+			 &sumbenchmark[i],
+			 &numbenchmark[i]);
+
+		MWprintf ( 10, "%d %15.5f %15.5f %15.5f %15.5f %15.5f %15.5f %d\n", 
+			   i,
+			   uptimes[i], 
+			   workingtimes[i], 
+			   susptimes[i], 
+			   cputimes[i],
+			   workingtimesnorm[i],
+			   sumbenchmark[i],
+			   numbenchmark[i]);
+	}
+
+	fscanf ( cfp, "%lf %lf", &max_bench_result, &min_bench_result);
+	fscanf ( cfp, "%lf %lf", &max_task_result, &min_task_result);
+}
+
+
+
+
+void MWStatistics::gather( MWWorkerID *w )
+{
+    if ( w == NULL ) {
+        MWprintf ( 10, "Tried to gather NULL worker!\n" );
+        return;
+    }
+
+	// MWprintf ( 80, "Gathering: worker vid %d\n", w->get_vid() );
+
+	//JTL 8/25/00
+	// We need to update the total time to include this time,
+	// because now we can call gather() without calling ended()
+
+	//  This is starting top get a bit kludgy, but the main
+	//  sticking point is that we don't want the "kill workers"
+	//  time in our efficiency numbers.
+
+	double now = MWSystem::gettimeofday();
+	
+	if( w->start_time > 1.0 ) {
+	  w->total_time = now - w->start_time;
+	}
+	
+	uptimes[w->get_vid()] += w->total_time;
+	workingtimes[w->get_vid()] += w->total_working;
+	susptimes[w->get_vid()] += w->total_suspended;	
+	cputimes[w->get_vid()] += w->cpu_while_working;
+
+	workingtimesnorm[w->get_vid()] += (w->normalized_cpu_working_time);
+
+	sumbenchmark[w->get_vid()] += (w->sum_benchmark);
+	numbenchmark[w->get_vid()] += (w->num_benchmark);
+
+
+	// Jeff resets all these to 0 -- so we can call gather 
+	//  more than once without affecting the stats validity
+
+	w->total_time = 0.0;
+	w->total_working = 0.0;
+	w->total_suspended = 0.0;
+	w->cpu_while_working = 0.0;
+	w->normalized_cpu_working_time = 0.0;
+	w->sum_benchmark = 0.0;
+	w->num_benchmark = 0;
+	w->start_time = now;
+	
+	
+		/* we don't delete w here.  That's done in RMC->removeWorker() */
+}
+
+void MWStatistics::makestats() {
+	//jae - we don't want to print the stat out
+	return;
+
+	int i;
+	int numWorkers = get_max_vid();
+	double sumuptimes = 0.0;
+	double sumworking = 0.0;
+	double sumcpu = 0.0;
+	double sumsusp = 0.0;
+
+	double sumworknorm = 0.0;
+
+	double sum_sum_benchmark = 0.0;
+	int    sum_num_benchmark = 0;
+
+    MWprintf ( 0, "**** Statistics ****\n" );
+
+	MWprintf ( 20, "Dumping raw stats:\n" );
+	MWprintf ( 20, "Vid    Uptimes     Working     CpuUsage   Susptime\n" );
+	for ( i=0 ; i<numWorkers ; i++ ) {
+		if ( uptimes[i] > 34560000 ) { /* 400 days! */
+			MWprintf ( 0, "Found odd uptime[%d] = %12.4f\n", i, uptimes[i] );
+			uptimes[i] = 0;
+		}
+		
+		MWprintf ( 20, "%3d  %10.4f  %10.4f  %10.4f %10.4f %10.4f %10.4f %d \n",
+			   i, 
+			   uptimes[i], 
+			   workingtimes[i], 
+			   cputimes[i], 
+			   susptimes[i], 
+			   workingtimesnorm[i], 
+			   sumbenchmark[i], 
+			   numbenchmark[i] );
+
+
+		sumuptimes += uptimes[i];
+		sumworking += workingtimes[i];
+		sumcpu += cputimes[i];
+		sumsusp += susptimes[i];
+		sumworknorm  += workingtimesnorm[i];
+		sum_sum_benchmark += sumbenchmark[i];
+		sum_num_benchmark += numbenchmark[i];
+
+	}
+	
+        // find duration of this run (+= in case of checkpoint)
+	double now = MWSystem::gettimeofday();
+    duration = now - starttime;
+	duration += previoustime;  // so it's sum over all checkpointed work
+
+	MWprintf ( 0, "\n" );
+    MWprintf ( 0, "Number of (different) workers:            %d\n", 
+			   numWorkers);
+
+ 	MWprintf ( 0, "Number of completed tasks:                %d\n", 
+			   num_completed_tasks);
+
+    
+    MWprintf ( 0, "Wall clock time for this job:             %10.4f\n", 
+			   duration );
+
+	MWprintf ( 0, "Total time workers were alive (up):       %10.4f\n", 
+			   sumuptimes );
+		//JTL -- This is a confusing statistic -- should just use CPU time
+		//MWprintf ( 0, "Total wall clock time of workers:         %10.4f\n", 
+		//sumworking );
+	MWprintf ( 0, "Total cpu time used by all workers:       %10.4f\n", 
+			   sumcpu );
+	MWprintf ( 0, "Total time workers were suspended:        %10.4f\n", 
+			   sumsusp );
+
+	double average_bench = ( sum_sum_benchmark / sum_num_benchmark );
+	double equivalent_bench = ( sumworknorm / sumcpu );
+
+
+	MWprintf (0, "Average       benchmark   factor    :      %10.4f\n", average_bench);
+	MWprintf (0, "Equivalent    benchmark   factor    :      %10.4f\n", equivalent_bench);
+	MWprintf (0, "Minimum       benchmark   factor    :      %10.4f\n", min_bench_result);
+	MWprintf (0, "Maximum       benchmark   factor    :      %10.4f\n\n", max_bench_result);
+	MWprintf (0, "Minimum       task cpu time         :      %10.4f\n", min_task_result);
+	MWprintf (0, "Maximum       task cpu time         :      %10.4f\n\n", max_task_result);
+
+	double av_present_workers = ( sumuptimes / duration ) ;
+	double av_nonsusp_workers = ( ( sumuptimes - sumsusp) / duration ) ;
+	double av_active_workers  = ( ( sumcpu ) / duration ) ;
+
+	MWprintf (0, "Average Number Present Workers      :      %10.4f\n", av_present_workers);
+	MWprintf (0, "Average Number NonSuspended Workers :      %10.4f\n", av_nonsusp_workers);
+	MWprintf (0, "Average Number Active Workers       :      %10.4f\n", av_active_workers);
+
+	double equi_pool_performance = ( equivalent_bench * av_active_workers );
+	double equi_run_time = ( sumworknorm );
+	double parallel_performance  = (( sumworking ) / ( sumuptimes - sumsusp)) ;
+
+	MWprintf (0, "Equivalent Pool Performance         :      %10.4f\n", equi_pool_performance);
+	MWprintf (0, "Equivalent Run Time                 :      %10.4f\n\n", equi_run_time);
+
+	MWprintf (0, "Overall Parallel Performance        :      %10.4f\n", parallel_performance);
+		// JTL -- I don't know why we would print this...
+		//MWprintf (0, "Total Number of benchmark tasks     :      %10d\n\n",  sum_num_benchmark);
+	
+
+    double uptime_mean = mean( uptimes, numWorkers );
+    double uptime_var  = var ( uptimes, numWorkers, uptime_mean );
+    double wktime_mean = mean( workingtimes, numWorkers );
+    double wktime_var  = var ( workingtimes, numWorkers, wktime_mean );
+	double cputime_mean= mean( cputimes, numWorkers );
+	double cputime_var = var ( cputimes, numWorkers, cputime_mean );
+    double sptime_mean = mean( susptimes, numWorkers );
+    double sptime_var  = var ( susptimes, numWorkers, sptime_mean );
+
+    MWprintf ( 0,"Mean & Var. uptime for the workers:       %10.4f\t%10.4f\n",
+             uptime_mean, uptime_var );
+    MWprintf ( 0,"Mean & Var. working time for the worker:  %10.4f\t%10.4f\n",
+             wktime_mean, wktime_var );
+    MWprintf ( 0,"Mean & Var. cpu time for the workers:     %10.4f\t%10.4f\n",
+             cputime_mean, cputime_var );
+    MWprintf ( 0,"Mean & Var. susp. time for the workers:   %10.4f\t%10.4f\n",
+             sptime_mean, sptime_var );
+
+}
+
+
+void MWStatistics::get_stats(double *average_bench,
+			     double *equivalent_bench,
+			     double *min_bench,
+			     double *max_bench,
+			     double *av_present_workers,
+			     double *av_nonsusp_workers,
+			     double *av_active_workers,
+			     double *equi_pool_performance,
+			     double *equi_run_time,
+			     double *parallel_performance,
+			     double *wall_time,
+			     MWList<MWWorkerID> *wrlist
+			     )
+{
+
+  int i;
+  int numWorkers = get_max_vid();
+  double sumuptimes = 0.0;
+  double sumworking = 0.0;
+  double sumcpu = 0.0;
+  double sumsusp = 0.0;
+  double sumworknorm = 0.0;
+  
+  double sum_sum_benchmark = 0.0;
+  int    sum_num_benchmark = 0;
+
+  for ( i=0 ; i<numWorkers ; i++ ) {
+    if ( uptimes[i] > 34560000 ) { /* 400 days! */
+      MWprintf ( 20, "Found odd uptime[%d] = %12.4f\n", i, uptimes[i] );
+      uptimes[i] = 0;
+    }
+
+    sumuptimes += uptimes[i];
+    sumworking += workingtimes[i];
+    sumsusp += susptimes[i];
+    sumcpu += cputimes[i];
+    sumworknorm  += workingtimesnorm[i];
+    sum_sum_benchmark += sumbenchmark[i];
+    sum_num_benchmark += numbenchmark[i];
+
+  }
+
+  // find duration of this run (+= in case of checkpoint)
+  double now = MWSystem::gettimeofday();
+  duration = now - starttime;
+  duration += previoustime;  // so it's sum over all checkpointed work
+
+  MWWorkerID *tempw = wrlist->First();
+	while( wrlist->AfterEnd() == false ) 
+	{
+		tempw = wrlist->Current();
+		if( tempw->start_time > 0.1 )
+			sumuptimes += now - tempw->start_time;
+
+		sumworking += tempw->total_working;
+		sumsusp += tempw->total_suspended;	
+		sumcpu += tempw->cpu_while_working;
+
+		sumworknorm += (tempw->normalized_cpu_working_time);
+
+		sum_sum_benchmark += (tempw->sum_benchmark);
+		sum_num_benchmark += (tempw->num_benchmark);
+
+
+		MWprintf(10, "Stats, id: %d\t%lf, %lf, %lf, %lf, %lf, %lf, %d\n",
+			     tempw->id1, sumuptimes, sumworking, sumsusp, sumcpu, sumworknorm, 
+	   		  sum_sum_benchmark, sum_num_benchmark );
+
+		wrlist->Next();
+	}
+	
+  *wall_time = duration;
+
+  *average_bench = ( sum_sum_benchmark / sum_num_benchmark );
+  *equivalent_bench = ( sumworknorm / sumcpu );
+  *min_bench = min_bench_result;
+  *max_bench = max_bench_result;
+  
+  *av_present_workers = ( sumuptimes / duration ) ;
+  *av_nonsusp_workers = ( ( sumuptimes - sumsusp ) / duration ) ;
+  *av_active_workers  = ( ( sumcpu ) / duration ) ;
+
+  *equi_pool_performance = ( *equivalent_bench * *av_active_workers );
+  *equi_run_time = ( sumworknorm );
+  *parallel_performance  = (( sumworking ) / ( sumuptimes - sumsusp)) ;
+
+    // Commented out so that no complain about unused variables. 
+    /*
+    double uptime_mean = mean( uptimes, numWorkers );
+    double uptime_var  = var ( uptimes, numWorkers, uptime_mean );
+    double wktime_mean = mean( workingtimes, numWorkers );
+    double wktime_var  = var ( workingtimes, numWorkers, wktime_mean );
+    double cputime_mean= mean( cputimes, numWorkers );
+    double cputime_var = var ( cputimes, numWorkers, cputime_mean );
+    double sptime_mean = mean( susptimes, numWorkers );
+    double sptime_var  = var ( susptimes, numWorkers, sptime_mean );
+    */
+}
+
+void MWStatistics::update_best_bench_results ( double bres ) {
+
+  MWprintf(10,"bench = %lf\n", bres);
+
+  if (bres > max_bench_result){
+    max_bench_result = bres;
+  }
+
+  if (bres < min_bench_result){
+    min_bench_result = bres;
+  }
+
+}
+
+void MWStatistics::update_best_task_results(double cpu_time) {
+  if (cpu_time > max_task_result){
+    max_task_result = cpu_time;
+  }
+
+  if ( cpu_time < min_task_result){
+    min_task_result =  cpu_time;
+  }
+}
+
+
+double MWStatistics::mean( double *array, int length ) {
+    double sum=0;
+    for ( int i=0 ; i<length ; i++ ) {
+        sum += array[i];
+    }
+    sum /= length;
+    return sum;
+}
+
+double MWStatistics::var( double *array, int length, double mean ) {
+	double ret=0;
+	double diff=0;
+	for ( int i=0 ; i<length ; i++ ) {
+		diff = array[i] - mean;
+		ret += ( diff * diff );
+	}
+	if( length > 1 )
+		ret /= length-1;
+	return ret;
+}
+
+int MWStatistics::get_max_vid() {
+
+  int n = -1;
+  for ( int i=0 ; i<MW_MAX_WORKERS ; i++ ) {
+    if ( uptimes[i] > 0.0 ) {
+      n = i;
+    }
+  }
+  n++;
+  return n;
+}
diff --git a/MW/src/MWStats.h b/MW/src/MWStats.h
new file mode 100644
index 0000000..4cbd701
--- /dev/null
+++ b/MW/src/MWStats.h
@@ -0,0 +1,153 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* stats.h
+
+   Header file for statistics class.
+*/
+
+#ifndef STATISTICS_H
+#define STATISTICS_H
+
+#include "MWWorkerID.h"
+#include "MW.h"
+#include "MWList.h"
+
+/** This class serves as a holder for worker classes before they go to die.
+    It holds the workers until a makestats() call is made, at which
+    point it generates some statistics, given the workers.  
+*/
+class MWStatistics {
+
+ public:
+    /// Default constructor
+    MWStatistics();
+    /// Destructor...
+    ~MWStatistics();
+
+  /** Literally, take the stats from this worker and store 
+      them in the stats class.  This is done when the worker
+      dies and during a checkpoint.
+  */
+    void gather ( MWWorkerID * );
+
+  /** This method is called at the end of a run.  It prints out some
+      statistical information on that run.
+  */
+    void makestats();
+
+  /** This function is just like makestats(), except it return the relative
+      statistics information to the caller. 
+  */
+  void get_stats(double *average_bench,
+		 double *equivalent_bench,
+		 double *min_bench,
+		 double *max_bench,
+		 double *av_present_workers,
+		 double *av_nonsusp_workers,
+		 double *av_active_workers,
+		 double *equi_pool_performance,
+		 double *equi_run_time,
+		 double *parallel_performance,
+		 double *wall_time,
+		 MWList<MWWorkerID> *workerlist );
+
+ /** Everytime we get a new bench factor, we update the max and min ones if necessary */
+  void update_best_bench_results( double bres ); 
+
+  /** Each time a task finishes, we call this method, to record the 
+    * best of times, the worst of times.
+    */
+  void update_best_task_results(double cpu_time);
+  /** We find that we should save stats across checkpoints.  Here
+      we're given the ckpt FILE* and the list of running workers.
+      Basically, we write out the sum of the old stats we've got
+      plus the stats of the running workers. */
+  void write_checkpoint( FILE *cfp, MWList<MWWorkerID> *wlist );
+  
+  /** Read in stats information across the checkpoint */
+  void read_checkpoint( FILE *cfp );
+
+ private:
+
+  double duration;
+  double starttime;
+  double previoustime; // the total run time of the checkpoints before...
+
+  /// Array of times that the workerIDs have been "up"
+  double *uptimes;
+  /// Array of times that the workerIDs have been working
+  double *workingtimes;
+  /// Array of times holding the CPU times of the workerIDs
+  double *cputimes;
+  /// Array of times that the workerIDs have been suspended
+  double *susptimes;
+
+  /**@name Normalized Statistics.  MW computes "normalized" statistics
+     about the runs performance based on the relative speed of the machines
+     that the user obtained during the course of the run.
+  */
+     
+     
+  //@{
+
+  double *workingtimesnorm; // the total working time normalized by benchmark factor
+
+  /** Min benchmark result -- the "slowest" machine we ever had. */
+  double max_bench_result;
+
+  /** Max benchmark result -- the "faster" machine we ever had. */
+  double min_bench_result;
+
+  /** Min task result -- the "slowest" machine we ever had. */
+  double max_task_result;
+
+  /** Max benchmark result -- the "faster" machine we ever had. */
+  double min_task_result;
+
+  /// The sum of benchmark factors for this vid
+  double *sumbenchmark;     
+  /// The number of benchmar factors for this vid
+  int *numbenchmark;        
+
+  //@}
+
+  /// Computes the mean of an array of number.
+  double mean ( double *array, int length );
+
+  /** Computes the variance of an array of numbers (given the mean, 
+      to avoid "double processing" the list -- which you don't need
+      to do anyway, but Mike wrote this function).
+  */
+  double var ( double *array, int length, double mean );
+
+  /** What is the maximum "virtuid ID" that we ever assigned to a worker.
+      This amounts to asking how many workers did we ever have in ALL states
+      at any one time during the course of the run.
+  */
+  int get_max_vid();
+
+};
+
+#endif
+
+
diff --git a/MW/src/MWSystem.h b/MW/src/MWSystem.h
new file mode 100644
index 0000000..312341d
--- /dev/null
+++ b/MW/src/MWSystem.h
@@ -0,0 +1,15 @@
+
+// This class implements all functionality outside of ANSI C/C++
+// All the ifdefery should be located here, and every class
+// above this should either call into MWSystem, or use
+// portable, ANSI code.
+
+class MWSystem {
+ public:
+	static int getpid();
+	static void gethostname(char *, int);
+	static double gettimeofday();
+	static double getcputime();
+	static void sleep(int);
+	static void mkdir(char *);
+};
diff --git a/MW/src/MWTask.C b/MW/src/MWTask.C
new file mode 100644
index 0000000..04a067c
--- /dev/null
+++ b/MW/src/MWTask.C
@@ -0,0 +1,129 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* MWTask.C
+
+   The implementation of the MWTask class
+
+*/
+
+#include "MWTask.h"
+#include "MWDriver.h"
+#include <stdio.h>
+
+extern int MWworkClasses;
+extern int *MWworkClassTasks;
+
+MWTask::MWTask() {
+	number = -1;
+	numsubtask = -1;
+	worker = NULL;
+	taskType = MWNORMAL;
+	group = new MWGroup ( MWworkClasses );
+}
+
+MWTask::~MWTask() {
+  if ( worker )
+    if ( worker->runningtask )
+      worker->runningtask = NULL;
+
+  delete group;
+}
+
+void MWTask::printself( int level ) 
+{    
+	MWprintf ( level, "  Task %d\n", number);
+}
+
+void
+MWTask::initGroups ( int num )
+{
+	// found LEAK_ASSIGN (group probably already allocated!)
+	// group = new MWGroup ( num );
+	if (group != NULL)
+		delete group;
+	group = new MWGroup( num );
+}
+
+void
+MWTask::addGroup ( int num )
+{
+	if ( doesBelong ( num ) )
+		return;
+	MWworkClassTasks[num]++;
+	group->join ( num );
+}
+
+void
+MWTask::deleteGroup ( int num )
+{
+	if ( !doesBelong ( num ) )
+		return;
+	MWworkClassTasks[num]--;
+	group->leave ( num );
+}
+
+bool
+MWTask::doesBelong ( int num )
+{
+	return group->belong ( num );
+}
+
+MWGroup*
+MWTask::getGroup ( )
+{
+	return group;
+}
+
+void
+MWTask::write_group_info ( FILE *fp )
+{
+	group->write_checkpoint ( fp );
+}
+
+void
+MWTask::read_group_info ( FILE *fp )
+{
+	// found LEAK_ASSIGN (group probably already allocated!)
+        // group = new MWGroup ( num );
+	if (group != NULL)
+		delete group;
+	group = new MWGroup ( MWworkClasses );
+	group->read_checkpoint ( fp );
+	for ( int i = 0; i < MWworkClasses; i++ )
+	{
+		if ( doesBelong ( i ) )
+			addGroup ( i );
+	}
+}
+
+void 
+MWTask::completedTask(double wall_time, double cpu_time)
+{
+	worker->runningtask = NULL;
+	worker->completedtask( wall_time, cpu_time);
+	worker = NULL;
+
+	for ( int tempi = 0; tempi < MWworkClasses; tempi++ ) {
+		deleteGroup ( tempi );
+	}
+}
diff --git a/MW/src/MWTask.h b/MW/src/MWTask.h
new file mode 100644
index 0000000..2d093c9
--- /dev/null
+++ b/MW/src/MWTask.h
@@ -0,0 +1,191 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWTASK_H
+#define MWTASK_H
+
+#include "MW.h"
+#include "MWWorkerID.h"
+#include "MWGroup.h"
+#include <MWRMComm.h>
+#include <stdio.h>
+
+//I'm moving this into MW.h so that task container can compile
+//typedef enum { MWNORMAL, MWNWS, MWNUMTASKTYPES } MWTaskType;
+
+/** 
+    This the class that represents a unit of work. 
+
+    The task consits of two main components.  The "work" to be done,
+    and the "result" of the completed task.
+    In order to create an application, the user must specify methods
+    for packing and unpacking both the "work" and "result" portions
+    of the task.
+    The user is not responsible for initializing the send
+    or for packing the task's number    
+
+    When the task is being serviced by a worker, it contains a link
+    to the ID of that instance of the worker.
+
+
+    @see MWDriver
+    @see MWWorker
+    @author Mike Yoder, modified by Jeff Linderoth and Jean-Pierre Goux
+*/
+
+class MWTask
+{
+ public:   
+
+  /// Default constructor
+  MWTask();
+  
+  /// Default Destructor
+  virtual ~MWTask();
+
+  /// The task's number
+  int number;
+int randomstop;
+int numsubtask;
+  /// The task's type.
+  MWTaskType taskType;
+
+	  /** @name Time and usage data */
+	  //@{
+	  /** The time (wall clock) that it takes to run the 'execute_task'
+		  function on the worker's side. */
+  double working_time;
+	  /** The amount of user+system time taken by this task, measured
+		  from start to finish of the 'execute_task' function. */
+  double cpu_time;
+
+	  //@}
+
+	  /**@name Packing and Unpacking 
+
+		 The user must pack and unpack the contents of the class
+		 so that it can be sent to the worker and back.  These 
+		 functions will make RMC->pack() and RMC->unpack() calls.
+   */
+  //@{
+
+  /// Pack the work portion of the task
+  virtual void pack_work( void ) = 0;
+
+  /// Unpack the work portion of the task
+  virtual void unpack_work( void ) = 0;
+
+  /// Pack the result portion of the task
+  virtual void pack_results( void ) = 0;
+  
+  /// Unpack the result portion of the task
+  virtual void unpack_results( void ) = 0;
+
+  /// Pack the subresult portion of the task
+  virtual void pack_subresults( int ) {}
+  
+  /// Unpack the subresult portion of the task
+  virtual void unpack_subresults( int ) {}
+
+
+  /// Dump this task to the screen
+  virtual void printself( int level = 60 );
+
+	  //@}
+
+  /**@name Checkpointing Utilities
+
+     These two functions are used when checkpointing.  Simply put, 
+     they write/read the state of the task to this file pointer 
+     provided. */
+
+      //@{
+
+      /** Write the state of this task out to a FILE* */
+  virtual void write_ckpt_info( FILE *fp ) {};
+      /** Read the state of this task from a FILE* (overwriting
+          any existing state */
+  virtual void read_ckpt_info( FILE *fp ) {};
+
+  void write_group_info ( FILE *fp );
+
+  void read_group_info ( FILE *fp );
+
+
+      //@}
+
+  void initGroups ( int num );
+  /// add task to a workclass/group	
+  void addGroup ( int num );
+  /// remove a task from a workclass/group
+  void deleteGroup ( int num );
+  bool doesBelong ( int num );
+  MWGroup *getGroup ( );
+
+
+  /**@name List management 
+
+     The task also has pointers that aid for managing the list
+     of tasks to be done
+   */
+
+  //@{
+  /// A pointer to the worker ID executing this task (NULL if none)
+  MWWorkerID *worker;
+
+  /*
+  /// A pointer to the next task in the list (NULL if none)
+  MWTask *next;
+  */
+  //@}
+
+  MWGroup *group;
+
+  static MWRMComm * RMC;
+
+	//by jae
+	void completedTask(double wall_time, double cpu_time);
+
+#ifdef MEASURE
+public:
+  // double _measure_start_time;	// the time called give_task
+  // double _measure_MP_master_time;	// master send_data + recv_result
+  double _measure_MP_worker_time;	// worker recv_data + send_result
+  double _measure_MP_worker_cpu_time;	// CPU time (worker recv_data + send_result)
+  // double _measure_Exe_wall_time;	// worker execute_task wall time = working_time
+  // double _measure_Exe_cpu_time;	// worker execute_task CPU time = cpu_time
+  // double _measure_Life_time;   	// from creation to deletion
+#endif // MEASURE
+  
+};
+
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/MW/src/MWTaskContainer.C b/MW/src/MWTaskContainer.C
new file mode 100644
index 0000000..0c2d1a3
--- /dev/null
+++ b/MW/src/MWTaskContainer.C
@@ -0,0 +1,157 @@
+#include "MWTaskContainer.h"
+#include "MWDriver.h"
+MWDriver* gimme_the_master();
+// Constructor and Destructor
+MWTaskContainer::MWTaskContainer()
+{
+	taskType = MWNORMAL;
+	RMC = MWTask::RMC;
+	tasks = new MWList<MWTask>("");
+}
+
+MWTaskContainer::~MWTaskContainer()
+{
+	delete tasks;
+}
+
+// Task related
+void 
+MWTaskContainer::pack_work()
+{
+//	int numtasks = tasks->Number();
+
+//	RMC->pack(&numtasks, 1, 1); //this is done in MWWorker.C
+//MWprintf(10,"MWTaskContainer::pack_work\n");
+    MWTask * t = tasks->First();
+    while ( tasks->AfterEnd() == false ) {
+        t = tasks->Current();
+		RMC->pack(&(t->number),1,1);
+        t->pack_work();
+        tasks->Next();
+    }
+}
+
+void 
+MWTaskContainer::unpack_work()
+{
+//MWDriver *driver = gimme_the_master();
+//driver->gimme_a_task();
+//MWprintf(10,"MWTaskContainer::unpack_work");
+    MWTask * t = tasks->First();
+    while ( tasks->AfterEnd() == false ) {
+        t = tasks->Current();
+		RMC->unpack(&(t->number),1,1);
+        t->unpack_work();
+        tasks->Next();
+    }
+}
+
+void
+MWTaskContainer::pack_subresults(int tasknum)
+{
+}
+
+void
+MWTaskContainer::unpack_subresults(int tasknum)
+{
+}
+
+int
+MWTaskContainer::FirstNum()
+{
+	MWTask *t;
+
+	tasks->First();
+	t = tasks->Current();
+	return t->number;
+}
+
+int 
+MWTaskContainer::LastNum()
+{
+	MWTask *t;
+
+    tasks->Last();
+    t = tasks->Current();
+    return t->number;
+}
+
+int
+MWTaskContainer::Number()
+{
+	return tasks->Number();
+}
+
+void 
+MWTaskContainer::pack_results()
+{
+		//int results = tasks->Number();
+
+    //RMC->pack(&results, 1, 1);
+	MWTask * t = tasks->First();
+    while ( tasks->AfterEnd() == false ) {
+        t = tasks->Current();
+        t->pack_results();
+        tasks->Next();
+    }
+}
+
+void 
+MWTaskContainer::unpack_results()
+{
+		//int results;
+
+    //RMC->unpack(&results, 1, 1);
+    MWTask * t = tasks->First();
+    while ( tasks->AfterEnd() == false ) {
+        t = tasks->Current();
+        t->unpack_results();
+        tasks->Next();
+    }
+}
+
+//List related
+void 
+MWTaskContainer::addTask(MWTask *t)
+{
+    tasks->Append(t);
+
+}
+
+void
+MWTaskContainer::removeAll()
+{
+	while(tasks->Remove() != NULL){};
+}
+
+
+MWTask* 
+MWTaskContainer::First()
+{
+	return tasks->First();
+}
+
+bool 
+MWTaskContainer::AfterEnd()
+{
+	return tasks->AfterEnd();
+}
+
+MWTask* 
+MWTaskContainer::Current()
+{
+	return tasks->Current();
+}
+
+MWTask* 
+MWTaskContainer::Next()
+{
+	return tasks->Next();
+}
+
+void 
+MWTaskContainer::printself( int level )
+{
+    MWprintf ( level, "  Task container from task number %d to %d\n", FirstNum(), LastNum());
+}
+
diff --git a/MW/src/MWTaskContainer.h b/MW/src/MWTaskContainer.h
new file mode 100644
index 0000000..0974170
--- /dev/null
+++ b/MW/src/MWTaskContainer.h
@@ -0,0 +1,112 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWTASKCONTAINER_H
+#define MWTASKCONTAINER_H
+
+#include "MW.h"
+#include "MWList.h"
+#include "MWTask.h"
+//#include <MWRMComm.h> MWTask.h already had this header
+
+//forward declarations necessary for compilation
+class MWTask;
+class MWWorkerID;
+//enum MWTaskType;
+
+/**
+	MWTaskContainer allows MWDriver to send multiple tasks to a single worker.
+	The exact number of tasks is hardcoded in send_task_to_worker() in 
+	MWDriver.C
+	The worker then works on each task and sends an update to MWDriver upon the 
+	completion of each task; act_on_completed_subtask(MWTask*) is called.
+	When all tasks are done, the results of all the tasks are sent back to 
+	MWDriver and act_on_completed_task(MWTask*) is called for each completed 
+	task. 
+	MWDriver then sends a new MWTaskContainer to the Worker.
+
+	The following functions in this class have to be defined in a derived class:
+	- pack_work()
+	- unpack_work()
+	- pack_subresults()
+	- unpack_subresults()
+	- pack_results()
+	- unpack_results()
+
+	The following functions in MWDriver.C have to be defined:
+	- MWDriver::act_on_completed_subtask(MWTask*)
+	
+	Notes:	
+	- None of the functions in MWTask are called directly by MW. They are now
+	called by MWTaskContainer.
+*/
+class MWTaskContainer
+{
+public:
+	MWTaskType taskType;
+	int number; // have to define numbering system for task containers, let's make it the number of the first task for now
+	MWList<MWTask> *tasks;
+	MWWorkerID *worker;
+	MWRMComm *RMC; //pointer to RMC instance in MWTask.h
+
+	MWTaskContainer();
+	virtual ~MWTaskContainer();
+	void addTask(MWTask *t);
+	void removeAll();
+	MWTask* First();
+	bool AfterEnd();
+	MWTask* Current();
+	MWTask* Next();
+
+	/// Pack all the tasks in this container
+	virtual void pack_work();
+
+	/// Unpack all the tasks in this container
+	virtual void unpack_work();
+
+	/// Pack all the results in this container
+	virtual void pack_results();
+
+	/// Unpack all the results in this container
+	virtual void unpack_results();
+
+	/// Called by MWWorker at the completion of each task(not task container). This could be left empty if we only want to let MWDriver know that a task was completed
+	virtual void pack_subresults(int tasknum);
+
+	/// Called by MWDriver at the completion of each task. @param tasknum number of the task that was completed
+	virtual void unpack_subresults(int tasknum);
+
+	virtual void printself(int level);
+
+	int FirstNum();
+
+	int LastNum();
+
+	/// Number of tasks in this task container
+	int Number();
+
+private:
+	double Side;
+};
+
+#endif
diff --git a/MW/src/MWUnixSystem.C b/MW/src/MWUnixSystem.C
new file mode 100644
index 0000000..ffd3098
--- /dev/null
+++ b/MW/src/MWUnixSystem.C
@@ -0,0 +1,52 @@
+
+#include "MWSystem.h"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <fcntl.h>
+
+#include <sys/resource.h> // getrusage
+#include <sys/time.h> // gettimeofday
+
+int
+MWSystem::getpid() {
+	return ::getpid();
+}
+
+void
+MWSystem::gethostname(char *h, int len) {
+	::gethostname(h, len);
+}
+
+double 
+timeval_to_double( struct timeval t )
+{
+	return (double) t.tv_sec + ( (double) t.tv_usec * (double) 1e-6 );
+}
+
+double
+MWSystem::gettimeofday() {
+	struct timeval t;
+	::gettimeofday(&t, NULL);
+	return timeval_to_double(t);
+}
+
+double
+MWSystem::getcputime() {
+	struct rusage rt;
+	::getrusage ( RUSAGE_SELF, &rt );
+	double d =  timeval_to_double ( rt.ru_utime ) + timeval_to_double ( rt.ru_stime );
+	::getrusage ( RUSAGE_CHILDREN, &rt );
+	return d +  timeval_to_double ( rt.ru_utime ) + timeval_to_double ( rt.ru_stime );
+}
+
+void
+MWSystem::sleep(int t) {
+	::sleep(t);
+}
+
+void
+MWSystem::mkdir(char *c) {
+	::mkdir(c, 0755);
+}
diff --git a/MW/src/MWWinSystem.C b/MW/src/MWWinSystem.C
new file mode 100644
index 0000000..d69512f
--- /dev/null
+++ b/MW/src/MWWinSystem.C
@@ -0,0 +1,47 @@
+#include "MWSystem.h"
+
+#include <windows.h>
+#include <stdio.h>
+#include <direct.h>
+
+int
+MWSystem::getpid() {
+  return GetCurrentProcessId();
+}
+
+static bool initialized = false;
+
+void
+MWSystem::gethostname(char *h, int len) {
+  if (!initialized) {
+    WSAData wsaData;
+    if (WSAStartup(MAKEWORD(1, 1), &wsaData) !=0) {
+      printf("Can't WSAStartup\n");
+      exit(-1);
+    };
+    initialized = true;
+  }
+  
+  ::gethostname(h, len);
+  return;
+}
+
+double
+MWSystem::gettimeofday() {
+  return 0.0;
+}
+
+double
+MWSystem::getcputime() {
+     return 0.0;
+}
+
+void
+MWSystem::sleep(int time) {
+  ::Sleep(time * 1000);
+}
+
+void
+MWSystem::mkdir(char *filename) {
+  ::mkdir(filename);
+}
diff --git a/MW/src/MWWorker.C b/MW/src/MWWorker.C
new file mode 100644
index 0000000..7c97706
--- /dev/null
+++ b/MW/src/MWWorker.C
@@ -0,0 +1,541 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MW.h"
+#include "MWWorker.h"
+#include "MWSystem.h"
+#include "RMComm/MWRMComm.h"
+
+MWWorker::MWWorker() 
+{
+	master = UNDEFINED;
+	workingTask = 0; // This must be initialized by subclass
+}
+
+MWWorker::~MWWorker() 
+{
+}
+
+double
+MWWorker::benchmark(MWTask *t)
+{
+    if (!t) return 1.0;
+        
+    double begTime = MWSystem::gettimeofday();
+    execute_task( t );
+    double endTime = MWSystem::gettimeofday();
+    return 1.0/(endTime-begTime);
+
+}
+
+void MWWorker::go( int argc, char *argv[] ) 
+{
+	MWprintf ( 10, "About to call setup\n");
+
+	if (workingTask == 0) {
+		MWprintf( 1, "Fatal Error - Worker did not set field workingTask to valid value\n");
+		exit(-1);
+	}
+
+	RMC->setup( argc, argv, &workerid, &master );
+	MWprintf ( 10, "Worker %x started.\n", workerid );
+	
+	 greet_master();
+#ifndef INDEPENDENT
+	worker_mainloop();
+#endif
+}
+
+MWReturn MWWorker::greet_master() {
+	MWSystem::gethostname ( mach_name, 64 );
+
+	MWprintf ( 10, "Worker started on machine %s.\npid = %d\n", mach_name, MWSystem::getpid() );
+	
+		/* Pack and send to the master all these information
+		   concerning the host and the worker specificities  */
+	RMC->initsend();
+	RMC->pack( mach_name );
+	pack_worker_initinfo();
+	
+	int status = RMC->send( master, INIT );
+	MWprintf ( 10, "Sent the master %x an INIT message.\n", master );
+	
+	if ( status < 0 ) {
+		MWprintf ( 10, "Had a problem sending my name to master.  Exiting.\n");
+		RMC->exit(1);
+	}
+
+	
+#ifdef INDEPENDENT
+    return OK;
+#else
+    return do_benchmark_cmd();
+#endif
+}
+
+MWReturn MWWorker::do_benchmark_cmd ( )
+{
+	int status;
+	int len, tag, tid;
+	
+	// wait for the setup info from the master 
+	int buf_id = RMC->recv( master, -1 );  
+	if( buf_id < 0 ) {
+		MWprintf ( 10, "Had a problem receiving INIT_REPLY.  Exiting.\n" );
+		RMC->exit( INIT_REPLY_FAILURE );
+	}
+	status = RMC->bufinfo ( buf_id, &len, &tag, &tid );
+	MWprintf ( 10, "Got Something from the master in reply to INIT %d\n", tag);
+	
+	MWReturn ustat = OK;
+		// unpack initial data to set up the worker state
+
+	switch ( tag )
+	{
+		case INIT_REPLY:
+		{
+
+			if ( RMC->unpack ( master_mach_name ) != 0 )
+			{
+				int err = -1;
+				MWprintf ( 10, "Error unpacking master hostname. \n");
+				RMC->initsend ( );
+				RMC->pack ( &err, 1 );
+				RMC->send ( master, BENCH_RESULTS );
+				return ustat;
+			}
+
+			if ( (ustat = unpack_init_data()) != OK ) {
+				int err = -1;
+				MWprintf ( 10, "Error unpacking initial data.\n" );
+				RMC->initsend();
+				RMC->pack( &err, 1 );
+				RMC->send( master, BENCH_RESULTS );
+				return ustat;
+			}
+
+			int bench_tf = FALSE;
+			RMC->unpack( &bench_tf, 1 );
+
+			if ( bench_tf ) {
+				MWprintf ( 10, "Recvd INIT_REPLY, now benchmarking.\n" );
+				workingTask->unpack_work();
+				double bench_result = benchmark( workingTask );
+
+				MWprintf ( 40, "Benchmark completed....%f\n", bench_result );
+				int zero = 0;
+				RMC->initsend();
+				RMC->pack( &zero, 1 );  // zero means that unpack_init_data is OK.
+				RMC->pack( &bench_result, 1 );
+			} else {
+				MWprintf ( 10, "Recvd INIT_REPLY, no benchmark.\n" );
+				double z = 0.0;
+				int zero = 0;
+				RMC->initsend();
+				RMC->pack( &zero, 1 );  // zero means that unpack_init_data is OK.
+				RMC->pack( &z, 1 );
+			}
+			MWprintf ( 10, "Worker Sending BENCH_RESULTS\n");
+			RMC->send( master, BENCH_RESULTS );
+
+			return ustat;
+			break;
+		}
+
+		case CHECKSUM_ERROR:
+		{
+			MWprintf ( 10, "Got a checksum error\n");
+			RMC->exit( CHECKSUM_ERROR_EXIT );
+		}
+	}
+	return OK;
+}
+
+
+void MWWorker::worker_mainloop() {
+	
+	for (;;) {
+      worker_mainloop_oneshot();
+    }
+}
+		
+MWReturn MWWorker::worker_mainloop_oneshot () 
+{
+	int status = 0, len = 0, tag = 0, tid = 0;
+    double wall_time = 0.0;
+    double cpu_time = 0.0;
+	
+	int curSubTask = 0;
+
+#ifdef MEASURE
+		double _recv_start_time = _measure_cur_wall_time();
+		double _recv_start_cpu_time = _measure_cur_cpu_time();
+#endif // MEASURE	
+	
+		// get message from master. block if task done
+        int buf_id;
+		buf_id = RMC->recv ( master, -1 );
+		if( buf_id < 0 ) {
+		  MWprintf( 10, "Could not receive message from master, ret = %d.  Exiting\n", buf_id );
+		  RMC->exit( buf_id );
+		}
+
+#ifdef MEASURE
+		double _task_recv_time = _measure_cur_wall_time() - _recv_start_time;
+		double _task_recv_cpu_time = _measure_cur_cpu_time() - _recv_start_cpu_time;
+#endif // MEASURE
+
+		status = -2; len = -2; tag = -2; tid = -2;		
+		status = RMC->bufinfo ( buf_id, &len, &tag, &tid );
+
+		switch ( tag ) {
+			
+		case RE_INIT: {   /* This can happen:  the lower level can tell us 
+							 that the master has gone down and come back 
+							 up, and we hve to re-initialize ourself. */
+			greet_master();
+            do_benchmark_cmd();
+			break;
+		}
+
+		case REFRESH:
+		{
+			unpack_init_data ( );
+			break;
+		}
+
+		case DO_THIS_WORK: {
+			MWprintf(51,"received DO_THIS_WORK signal\n");
+/*
+time_t now = time(0);
+while(time(0)-now<30){}	
+*/
+			int num = UNDEFINED;
+			MWTaskType thisTaskType;
+			//moved out of switch statement
+			//double wall_time = 0.0;
+			//double cpu_time = 0.0;
+			int tstat;
+			int mytemp;
+
+			MWTask *curTask = NULL;
+			
+			tstat = RMC->unpack ( &mytemp, 1, 1);
+
+			if ( tstat != 0 )
+			{
+				MWprintf ( 10, "Error: The receive buffer not unpacked on %d\n",
+					mach_name );
+				fflush ( stdout );
+				RMC->exit ( UNPACK_FAILURE );
+			}
+			thisTaskType = (MWTaskType)mytemp;
+
+			switch ( thisTaskType )
+			{
+				case MWNORMAL:
+				  //curTask = workingTaskContainer->Current();
+					break;
+				case MWNWS:
+#ifndef NWSENABLED
+/*
+					MWprintf(31, "Got a MWNWS task. \n");
+					controlTask = getNWSTask ( );
+					curTask = controlTask;
+*/
+#endif
+					break;
+					
+				default:
+					MWprintf(30, "MWWorker::worker_mainloop_ind() - other task type\n");
+			}
+			curTask = workingTask;
+
+			curTask->taskType = thisTaskType;
+			tstat = RMC->unpack( &num, 1, 1 );
+			if( tstat != 0 ) {
+			  MWprintf( 10, "Error.  The receive buffer not unpacked on %s\n", 
+				    mach_name );
+			  fflush( stdout );
+			  RMC->exit( UNPACK_FAILURE );
+			}
+			curTask->number = num; 
+
+			unpack_driver_task_data();
+			curTask->unpack_work();
+			
+			MWprintf(51,"Finished unpacking work, now executing...\n");			
+			/* Set our stopwatch.  :-) */
+			wall_time = - MWSystem::gettimeofday();
+			cpu_time = - MWSystem::getcputime();
+		      
+				/* do it! */
+			switch ( thisTaskType )
+			{
+				case MWNORMAL:
+						execute_task(curTask);
+						// Record times for it...
+                		wall_time += MWSystem::gettimeofday();
+                		cpu_time +=  MWSystem::getcputime();
+/*
+				      RMC->initsend();
+				      RMC->pack( &(curTask->number), 1, 1 );   
+
+						  // GGT Not sure what to do here..
+
+					  RMC->pack(&curSubTask, 1, 1);
+				      curTask->pack_subresults(curSubTask);
+					  
+				      status = RMC->send(master, SUBRESULTS);
+				      if ( status < 0 ){
+					MWprintf ( 10, "Bummer!  Could not send SUBresults of task %d\n", num );
+					MWprintf( 10, "Exiting worker!" );
+					RMC->exit( FAIL_MASTER_SEND );
+				      }
+*/
+            // if all subtasks done, do task and send RESULT message to master
+            // worker then goes back into blocking recv. This gets called if there is only 1 task in the container
+			{
+                // Record times for it...
+            	//wall_time += MWSystem::getcputime();
+            	//cpu_time += MWSystem::gettimeofday();
+
+                RMC->initsend();
+				RMC->pack( &num, 1, 1);
+#ifdef MEASURE
+                RMC->pack(&_task_recv_time, 1, 1);
+                RMC->pack(&_task_recv_cpu_time, 1, 1);
+#endif // END MEASURE
+                RMC->pack( &wall_time, 1, 1 );
+                RMC->pack( &cpu_time, 1, 1 );
+                curTask->pack_results();
+                status = RMC->send(master, RESULTS);
+                MWprintf(51,"sent result\n");
+			}
+
+				      break;
+				case MWNWS:
+#ifndef NWSENABLED
+/*
+					curTask->printself ( 10 );
+					execute_nws ( curTask );
+					curTask->printself ( 10 );
+*/
+#endif
+					break;
+				default:
+					MWprintf ( 10, "Unidentified %d \n", thisTaskType);
+					exit(1);
+			}
+
+/*
+			if(curTask->numsubtask == -1) // partial results disabled
+			{	
+				// Record times for it... 
+			wall_time += _measure_cur_wall_time();
+			cpu_time += _measure_cur_cpu_time();
+
+				// Now send... 
+			RMC->initsend();
+			//RMC->pack( &num, 1, 1 );
+#ifdef MEASURE
+			RMC->pack(&_task_recv_time, 1, 1);
+			RMC->pack(&_task_recv_cpu_time, 1, 1);
+#endif // END MEASURE
+			RMC->pack( &wall_time, 1, 1 );
+			RMC->pack( &cpu_time, 1, 1 );
+			curTask->pack_results();
+			
+			status = RMC->send(master, RESULTS);
+
+			if ( status < 0 ){
+			  MWprintf ( 10, "Bummer!  Could not send results of task %d\n", num ); 
+			  MWprintf( 10, "Exiting worker!" ); 
+			  RMC->exit( FAIL_MASTER_SEND );
+			}
+                        
+		
+			MWprintf ( 40, "%s sent results of job %d.\n", 
+					   mach_name, curTask->number );
+			}
+*/
+			switch ( thisTaskType )
+			{
+				case MWNORMAL:
+					break;
+				case MWNWS:
+#ifndef NWSENABLED
+					delete curTask;
+					controlTask = NULL;
+#endif
+					break;
+
+				default:
+					MWprintf(30, "MWWorker::worker_mainloop_ind() - other task type\n");
+			}
+			break;
+			
+		}
+        case NO_MESSAGE:{
+            MWTask *curTask = workingTask;
+			int num = curTask->number;
+
+            /* Set our stopwatch. again  :-) */
+            wall_time -= MWSystem::gettimeofday();
+            cpu_time -= MWSystem::getcputime();
+	
+			execute_task(curTask);
+
+			// Record times for it...
+			wall_time += MWSystem::gettimeofday();
+			cpu_time += MWSystem::getcputime();
+
+            curSubTask++;
+
+            if(curSubTask==curTask->numsubtask)
+            {   MWprintf(50,"sending result\n");
+                curSubTask = 0;
+                execute_task( curTask );
+                RMC->initsend();
+                RMC->pack( &num, 1, 1 );
+                #ifdef MEASURE
+                    RMC->pack(&_task_recv_time, 1, 1);
+                    RMC->pack(&_task_recv_cpu_time, 1, 1);
+                #endif // END MEASURE
+                RMC->pack( &wall_time, 1, 1 );
+                RMC->pack( &cpu_time, 1, 1 );
+                curTask->pack_results();
+                status = RMC->send(master, RESULTS);
+                MWprintf(50,"sent result\n");
+            }  
+
+            break;
+		}
+		case UPDATE_FROM_DRIVER:
+		{
+			MWprintf(51,"Received update while not working on task\n");
+			break;
+		}       
+		case STOP_WORK: {
+// GGT This shouldn't happen anymore -- ignore it
+
+// 		  int tasknum;
+// 		  RMC->unpack(&tasknum, 1, 1);
+// 		  // stop our current task only if the signal is for current task (not a previous one) and task is still running
+// 		  if(tasknum == curTask->number)
+// 		    {
+// 		      //curSubTask = 0;
+// 		      //execute_task( workingTaskContainer );
+// 		      RMC->initsend();
+// 		      RMC->pack( &workingTaskContainer->number, 1, 1 );
+// #ifdef MEASURE
+// 		      RMC->pack(&_task_recv_time, 1, 1);
+// 		      RMC->pack(&_task_recv_cpu_time, 1, 1);
+// #endif // END MEASURE
+// 		      RMC->pack( &wall_time, 1, 1 );
+// 		      RMC->pack( &cpu_time, 1, 1 );
+// 		      workingTaskContainer->pack_results();
+// 		      status = RMC->send(master, RESULTS);
+// 		      MWprintf(50,"sent result\n");
+//		    }
+
+		  break;
+		}
+		case KILL_YOURSELF: {
+			suicide();
+		}
+		case CHECKSUM_ERROR:
+		{
+			MWprintf ( 10, "Got a checksum error\n");
+			RMC->exit( CHECKSUM_ERROR_EXIT );
+		}
+		default: {
+			MWprintf ( 10, "Received strange command %d.\n", tag );
+			RMC->exit( UNKNOWN_COMMAND );
+		}
+		} // switch
+
+	return OK;
+
+}
+
+/* We've received orders to kill ourself; we're not needed anymore.
+   Fall on own sword. */
+
+void MWWorker::suicide () 
+{   
+	MWprintf ( 10, "\"Goodbye, cruel world...\" says %s\n", mach_name );
+	
+	RMC->exit(0);
+}
+
+
+/* For steering */
+int 
+MWWorker::send_update_message()
+{
+	return RMC->send(master, UPDATE_FROM_WORKER);	
+}
+
+void
+MWWorker::check_update_message()
+{
+	int bid = 0 ;
+	int info, len, tag, sending_host;
+
+	RMC->nrecv(-1, UPDATE_FROM_DRIVER);
+	info = RMC->bufinfo(bid, &len, &tag, &sending_host);
+	if (tag == UPDATE_FROM_DRIVER)
+	{
+		unpack_update();
+	}
+	else if(tag != NO_MESSAGE)
+		MWprintf(10, "check_update_message: \
+			got a message which is not UPDATE_FROM_DRIVER.\n");
+/* moving recv_all functionality into recv
+	MWList<void> * recv_buf_list = RMC->recv_buffers();
+	
+	RMC->recv_all(-1, UPDATE_FROM_DRIVER);
+       	len = recv_buf_list->number();
+	recv_buf_list->First();	
+	while (recv_buf_list->AfterEnd() == false) {
+		bid = (int*)recv_buf_list->Current();
+		info = RMC->bufinfo(*bid, &len, &tag, &sending_host);
+		if (tag != UPDATE_FROM_DRIVER) {
+			MWprintf(10, "check_update_message: \
+				got a message which is not UPDATE_FROM_DRIVER.\n");
+			recv_buf_list->Remove();
+		}
+		recv_buf_list->Next();
+	}
+	return RMC->recv_buffers()->number();
+*/
+}
+// Local Variables:
+// mode: c++
+// eval: (c-set-style "K&R")
+// eval: (setq fill-column 79)
+// eval: (setq c-basic-offset 2)
+// eval: (setq tab-width 4)
+// eval: (c-set-offset 'arglist-close 0)
+// eval: (setq indent-tabs-mode nil)
+// End:
diff --git a/MW/src/MWWorker.h b/MW/src/MWWorker.h
new file mode 100644
index 0000000..f4eab90
--- /dev/null
+++ b/MW/src/MWWorker.h
@@ -0,0 +1,190 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWWORKER_H
+#define MWWORKER_H
+
+#include <stdlib.h>
+#include <string.h>
+#include "MWTask.h"
+
+/**  This is the worker class that performs the tasks in the
+    opportunistic condor environment.  It is an oppressed worker class
+    in that in simply executes the tasks given to it and reports the
+    results back to the master.  {\tt :-)}
+
+    Capitalist stooges who wish to create an application
+    must derive a class from this class, and implement the following
+    two methods
+
+    \begin{itemize}
+    \item unpack_init_data()
+    \item execute_task()
+    \end{itemize}
+
+    @see MWDriver
+    @see MWWorker
+    @author Mike Yoder, modified by Jeff Linderoth and Jean-Pierre Goux */
+
+class MWWorker
+{
+
+public:
+    
+  /// Default constructor
+  MWWorker();  
+
+  /// Default Destructor
+  virtual ~MWWorker();
+
+  /// Giddyap!
+  void go( int argc, char *argv[] );
+
+  MWReturn do_benchmark_cmd( );
+
+  MWReturn worker_mainloop_oneshot ();
+
+
+	  /// Our RM / Comm class.  Used here only for communication.
+  static MWRMComm * RMC;
+
+ protected:
+
+  /// The task ID of the master - used for sending messages.
+  int master;
+
+  /// The task instance that a worker will use for packing/unpacking 
+  /// information from the master
+  MWTask *workingTask;
+  MWTask *controlTask;
+
+  /// The name of the machine the worker is running on.
+  char mach_name[64];
+
+  /// The name of the master machine.
+  char master_mach_name[64];
+
+  /** 
+      Here we might in the future pack some useful information about
+      the specific machine on which we're running.  Right now,
+      all workers are equal, and we pass only the hostname.
+
+      There must be a "matching" unpack_worker_initinfo() in
+      the MWDriver class.
+  */
+  virtual void pack_worker_initinfo() {};
+
+
+//virtual MWTask* gimme_a_task() { return ((MWTask *) 0xdeadbeef); }
+
+  /**
+     This unpacks the initial data that is sent to the worker
+     once the master knows that he has started.
+
+     There must be a "matching" pack_worker_init_data() in
+     the MWDriver class derived for your application.
+     
+   */
+  virtual MWReturn unpack_init_data() = 0;
+
+  /** This function performs the actions that happen
+      once the Worker finds out there is a task to do.
+      You will need to cast the MWTask * to a pointer of the Task type
+      derived for your application.  For example
+
+      \begin{verbatim}
+      Task_Fib *dt = dynamic_cast<Task_Fib *> ( t );
+      assert( dt );     
+      \end{verbatim}    
+
+   */
+  virtual void execute_task( MWTask * ) = 0;
+
+  /**
+     This function performs the action that happens once the worker
+	 receives a subtask. Subtask id starts at 0 and ends at n-1 subtasks.
+	
+	Deprecated - changing subtask model for container of tasks model
+   */
+  //virtual void execute_subtask(MWTask *, int) {}
+
+  /**
+     The number of subtasks per worker is defined here.
+	 If this function is not implemented, then data streaming/subtasks
+	 is turned off and Master-Worker executes normally.
+
+	    Deprecated - changing subtask model for container of tasks model
+   */
+  //virtual void set_num_subtask(int *) {}
+
+  /** Run a benchmark, given an MWTASK.  The default implementation 
+   *  is to call \begin{verbatim} execute_task(t) \end{verbatim}
+   *  and return 1.0/(Task Time) as a benchmark of how fast the machine
+   *  is
+   */
+  virtual double benchmark ( MWTask *t );
+
+  /**
+    If you have some driver data that you would like to use on the
+    worker in order to execute the task, you should unpack it here.
+   */
+  virtual void unpack_driver_task_data( void ) {};
+  
+  /**
+     This is run before the worker_mainloop().  It prints a message 
+     that the worker has been spawned, sends the master an INIT
+     message, and awaits a reply from the master, upon which 
+     it calls  unpack_init_data().
+    
+  */
+  MWReturn greet_master(); 
+
+  /**
+     This sits in a loop in which it asks for work from the master
+     and does the work.  Maybe we should name this class GradStudent.
+     {\tt :-)}
+   */
+  void worker_mainloop();
+
+  /// Die!!!!!!
+  void suicide();
+
+  private:
+
+public:
+    /* send a update message to the master, without stopping current execution
+	 * assume that the user has already called RMC->initsend, and RMC->pack */
+  	int send_update_message();
+
+	/* Non-blocking check for DRIVER_UPDATE message, calls unpack_update */
+	void check_update_message();
+
+	/* Unpack data sent by send_update in master. Defined by user and called by check_update_message */
+	virtual void unpack_update(){};
+
+	int workerid; // id of worker.
+
+};
+
+#endif
+
+
diff --git a/MW/src/MWWorkerID.C b/MW/src/MWWorkerID.C
new file mode 100644
index 0000000..353cabd
--- /dev/null
+++ b/MW/src/MWWorkerID.C
@@ -0,0 +1,659 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* MWWorkerID.C
+*/
+#include "MW.h"
+#include "MWWorkerID.h"
+#include "MWTask.h"
+#include "MWSystem.h"
+
+#include <memory.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+
+
+int *MWWorkerID::vids = new int[MW_MAX_WORKERS];  
+int MWWorkerID::vids_inited = 0;
+
+char *MWWorkerID::ulv_filename = "/tmp/mw-ulv";
+FILE *MWWorkerID::lfp = NULL;
+extern int *MWworkClassWorkers;
+extern int MWworkClasses;
+
+/** This static array is used to hold strings that represent the
+    MWworker_states.  They are handy for printing out a worker - now
+    you'll see "WORKING" instead of "2" in printself().
+    @see MWworker_states */
+
+const char *MWworker_statenames[] = {
+    "INITIALIZING", 
+    "IDLE", 
+    "BENCHMARKING/INITIAL DATA HANDLING",
+    "WORKING", 
+    "SUSPENDED",
+    "EXITED"
+};
+
+
+void 
+MWWorkerID::init_vids() {
+	if (vids_inited == 0) {
+		for ( int i = 0; i < MW_MAX_WORKERS; i++ )
+			vids[i] = 0;
+		vids_inited = 1;
+	}
+}
+
+MWWorkerID::MWWorkerID() 
+{
+    init_vids();
+    memset ( mach_name, 0, 64 ); 
+
+    id1 = -1;
+    id2 = -1;
+	virtual_id = -1;
+	doomed = FALSE;
+	// We use a negative number to signify that no benchmark has been set
+	bench_result = -1.0;
+
+    runningtask = NULL;
+	/*
+    next = NULL;
+	*/
+
+    state = INITIALIZING;
+    isBenchMark = FALSE;
+    isBenchMarkAvailable = FALSE;
+
+	total_suspended = 0.0;
+	total_working = 0.0;
+	start_time = 0.0;
+	total_time = 0.0;
+	last_event = 0.0;
+	cpu_while_working = 0.0;
+
+
+	normalized_cpu_working_time = 0.0;
+	sum_benchmark = 0.0;
+	num_benchmark = 0;
+
+	
+    CondorLoadAvg = NO_VAL;
+    LoadAvg = NO_VAL;
+    Memory = NO_VAL;
+    Cpus = NO_VAL;
+    VirtualMemory = NO_VAL;
+    Disk = NO_VAL;
+    KFlops = NO_VAL;
+    Mips = NO_VAL;
+
+    memset(OpSys, 0, sizeof(OpSys)); 
+    memset(Arch, 0 , sizeof(Arch)); 
+
+	set_vid ( get_next_vid() );
+    double currentTime = MWSystem::gettimeofday();
+    networkLatency = 0.0;
+    networkLatency_lastMeasuredTime = currentTime;
+
+	group = NULL;
+	executable_name = NULL;
+}
+
+MWWorkerID::~MWWorkerID()
+{
+	delete group;
+}
+
+
+enum MWworker_states MWWorkerID::currentState()
+{
+	return state;
+}
+
+void MWWorkerID::printself( int level ) 
+{
+
+    MWprintf ( level, "id1: %d id2: %d, vid: %d, name: \"%s\"\n",
+			   id1, id2, virtual_id, mach_name ? mach_name : "" );
+    MWprintf ( level, "Memory: %d, KFlops: %d, Mips: %d\n", Memory, KFlops, Mips );
+    MWprintf ( level, "arch: \"%d\" state: %s\n", 
+			   arch, MWworker_statenames[state] );
+	
+    if ( runningtask != NULL ) {
+        MWprintf ( level, " -> Running task: " );
+        runningtask->printself( level );
+    }
+    else 
+        MWprintf ( level, " -> There's no task on this worker.\n" );
+    
+    /* Print Here other Worker specific Info */    
+    
+}    
+
+void MWWorkerID::set_machine_name( char *name ) {
+    strncpy( mach_name, name, 64 );
+}
+
+char * MWWorkerID::machine_name() {
+    return mach_name;
+}
+
+void MWWorkerID::started() {
+        // this is called when a worker first starts up.
+	if( state != INITIALIZING && state != BENCHMARKING ) {
+		MWprintf( 10, "Danger Will Robinson!  started() worker whose "
+				  "state != INITIALIZING && state != BENCHMARKING\n" );
+		printself(10);
+    }
+    
+    // The following line is commented out because the state should be INITIALIZING !? - jichuan
+    // state = IDLE;
+
+    //XXX Jeff's hack.  To get parallel efficiency "right" on
+    //  MWfiles (with worker timeouts), we don't want to count
+    //  the machines that just sit there in INITIALIZING state
+    //  until they time out.  Thus, we do not start the counter here, but
+    //  only when we send a benchmark.
+
+    lprintf ( virtual_id, start_time, "Started on host %s\n", mach_name );
+}
+
+
+void MWWorkerID::benchmark() 
+{
+	// this is called when a worker is sent the benchmark task
+	if ( state != INITIALIZING )
+	{
+		MWprintf( 10, "Danger Will Robinson! benchmarking a worker "
+				"state != INITIALIZING\n" );
+		printself(10);
+	}
+	state = BENCHMARKING;
+	isBenchMark = TRUE;
+
+}
+
+void MWWorkerID::benchmarkOver()
+{
+	if ( state != BENCHMARKING )
+	{
+		MWprintf( 10, "Danger Will Robinson! benchmarking over of "
+				" a worker whose state != BENCHMARKING\n" );
+		printself(10);
+	}
+	isBenchMark = FALSE;
+
+    //XXX Jeff's hack.  To get parallel efficiency "right" on
+    //  MWfiles (with worker timeouts), we don't want to count
+    //  the machines that just sit there in INITIALIZING state
+    //  until they time out.  Thus, we start the counter here
+
+	start_time = MWSystem::gettimeofday();
+	state = IDLE;
+
+}
+
+void MWWorkerID::gottask( int tasknum ) {
+        // called when we begin a task.
+	state = WORKING;
+	last_event = MWSystem::gettimeofday();
+
+	lprintf ( virtual_id, last_event, "Assigned task %d\n", tasknum );
+}
+
+void MWWorkerID::completedtask( double wall_time, double cpu_time ) {
+        // called when the master is told that we finished this task.
+    	state = IDLE;
+		last_event = MWSystem::gettimeofday();
+
+	total_working += wall_time;
+	cpu_while_working += cpu_time;
+
+	if (isBenchMarkAvailable){
+	  if ( (cpu_time * bench_result) < -1.0e-6 ) {
+	        MWprintf ( 10, "PROBLEM !!! cpu_time = %lf ; bench = %lf\n", cpu_time, bench_result);
+	  } else {
+	  	normalized_cpu_working_time += cpu_time * bench_result;
+	  }
+	}
+	
+	lprintf ( virtual_id, last_event, "Completed task. (tot: %12.4f)\n"
+		  "\tWall time: %12.4f\n"
+		  "\tCpu time:  %12.4f\n",
+		  total_working, wall_time, cpu_time );
+
+}
+
+void MWWorkerID::suspended() {
+        // Called when this worker has a task and gets suspended.
+	last_event = MWSystem::gettimeofday();
+    state = SUSPENDED;
+
+	lprintf ( virtual_id, last_event, "Suspend.\n" );
+}
+
+void MWWorkerID::resumed() {
+
+	double now = MWSystem::gettimeofday();
+
+  // called when we resume and have a task.
+  if ( state != SUSPENDED ) {
+    MWprintf ( 10, "Got resume while not suspended!\n" );
+  }
+  else
+    {
+	if ( runningtask ) {
+		total_suspended += now - last_event;
+		state = WORKING;
+	} else if ( isBenchMark == TRUE ) {
+		state = BENCHMARKING;
+	} else {
+		state = IDLE;
+	}
+
+    }
+  last_event = now;
+
+  lprintf ( virtual_id, now, "Resume.\n" );
+}
+
+void MWWorkerID::set_bench_result( double bres )
+{
+  if( bres < 1.0e-8 ) {
+    MWprintf( 10, "Benchmark result must be a *positive* number\nSetting to 0\n" );
+    bench_result = 0.0;
+  }
+  else {
+    bench_result = bres;
+    sum_benchmark += bres;
+    num_benchmark++;
+
+    isBenchMarkAvailable = TRUE;
+  }
+}
+
+void MWWorkerID::ended() {
+        // called when the master is aware of the worker's death.
+	double now = MWSystem::gettimeofday();
+
+	if ( state == WORKING ) { 
+/* We don't want to do this!  If we're here, it means that we're running
+   a task, but we're done - therefore whatever we were doing wasn't
+   important and we shouldn't count it towards our work.  (It's not
+   part of "GoodPut", in other words.) */
+//		total_working += now - last_event; 
+	} else if ( state == SUSPENDED ) {
+/* But what the heck, we'll count suspended */
+		total_suspended += now - last_event;
+	}
+	state = EXITED;
+
+
+	if( start_time > 1.0 ) {
+	  total_time = now - start_time;
+	}
+	else {
+	  total_time = 0.0;
+	}
+
+	lprintf ( virtual_id, now, "Finished.\n" );
+
+	release_vid ( get_vid() );
+
+	if ( group )
+	{
+		for ( int i = 0; i < MWworkClasses; i++ )
+			if ( doesBelong ( i ) )
+				deleteGroup ( i );
+
+	}
+}
+
+void MWWorkerID::ckpt_stats( double *up, 
+			     double *working, 
+			     double *susp, 
+			     double *cpu, 
+			     double *norm, 
+			     double *s_bench, 
+			     int *n_bench ) {
+
+		// print duration, total_working, total_suspended 
+
+	double now = MWSystem::gettimeofday();
+
+	if ( start_time > 1.0 ) { 
+		*up = now - start_time;  
+	} else {
+		*up = 0.0;   // possible if not yet started().
+	}
+
+	*working = total_working;
+	*susp = total_suspended;
+	*cpu = cpu_while_working;
+	*norm = normalized_cpu_working_time;
+
+	*s_bench = sum_benchmark;
+	*n_bench = num_benchmark;
+
+/* Don't do any of this - only count goodput... 
+	if ( state == WORKING ) {
+		*work += now - last_event;
+		*cpu += now - last_event;  // punt... 
+	} else if ( state == SUSPENDED ) {
+		*susp += now - last_event; // we can lose some cpu time here.  Oops. 
+	}
+*/
+}
+
+
+
+/* get the lowest vid from 'vids' */
+int
+MWWorkerID::get_next_vid() {
+	int i;
+	for ( i=0 ; i< MW_MAX_WORKERS ; i++ ) {
+		if ( MWWorkerID::vids[i] == 0 ) {
+			MWWorkerID::vids[i] = 1;
+			return i;
+		}
+	}
+	MWprintf ( 10, "ERROR: Ran out of virtual IDs in MWWorkerID!\n" );
+	return -1;
+}
+
+/* Set virtual id */
+void 
+MWWorkerID::set_vid( int i ) { 
+	virtual_id = i; 
+}
+
+/* Returns a virtual id to the pool */
+void 
+MWWorkerID::release_vid( int vid ) { 
+	MWWorkerID::vids[vid] = 0; 
+}	
+
+void
+MWWorkerID::lprintf ( int vid, double now, char *fmt, ... ) {
+
+		/* let's return now so we don't inflict this code on others. */
+	return;
+
+	if ( !lfp ) {
+		if ( (lfp=fopen( ulv_filename, "w" )) == NULL ) {
+			MWprintf ( 10, "Failed to open %s in MWWorkerID::lprintf, "
+					   "errno %d\n", ulv_filename, errno );
+			return;
+		} else {
+			fprintf ( lfp, "#MW\n" );
+		}
+	}
+
+	fprintf ( lfp, "(%03d) ", vid );
+
+	struct tm	*tm;
+	time_t time = (time_t) now;
+	tm = localtime( (time_t *)&time );
+	fprintf( lfp, "%d/%d %02d:%02d:%02d.%03d ",
+			 tm->tm_mon + 1, tm->tm_mday,
+			 tm->tm_hour, tm->tm_min, tm->tm_sec, 
+			 ((int)(((double) ((double) now -((int) now ))) * 1000))
+	);
+
+	va_list ap;
+	va_start( ap, fmt );
+	vfprintf( lfp, fmt, ap );
+	va_end( ap );
+
+	if ( fmt[strlen(fmt)-1] == '\n' ) {
+		fprintf ( lfp, "...\n" );
+	} else {
+		fprintf ( lfp, "\n...\n" );
+	}
+
+	fflush ( lfp );
+}
+
+/* The following (until the end of the file) was written by one of 
+   Jean-Pierre's students.  It isn't exactly efficient, dumping
+   a condor_status output to a file and reading from that.  I understand
+   that it does work, however.  -MEY (8-18-99) */
+
+int MWWorkerID::check_for_int_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return atoi(value);
+	else return NO_VAL;
+}
+
+double MWWorkerID::check_for_float_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return atof(value);
+	else return NO_VAL;  
+}
+
+int  MWWorkerID::check_for_string_val(char* name, char* key, char* value) {
+	if (strcmp(name, key) == 0)
+		return 0;
+	else return NO_VAL;  
+}
+
+void MWWorkerID::get_machine_info() {
+
+	FILE* inputfile;
+	char key[200];
+	char value[1300];
+	char raw_line[1500];
+	char* equal_pos;
+	int found;
+	char temp_str[256];
+	
+	char zero_string[2];
+	
+#ifdef INDEPENDENT
+		return;
+#endif
+
+	memset(zero_string, 0 , sizeof(zero_string));
+	
+	memset(key, '\0', sizeof(key));
+	memset(value, '\0', sizeof(value));
+
+	// This is a terrible kludge, but I'd rather do this in a script.
+	// We're going to move this into the RMC class anyway, so it's 
+	//  not so bad to fake it for now.
+
+	const bool jeff_hack = false;;
+
+	if( jeff_hack ) {
+	// note to jeff_hack: change this script to output to stdout, not filename
+	  sprintf( temp_str, "./create_condor_status_file %s", mach_name /*, filename */);
+	}
+	else {
+	  
+	  memset(temp_str, '\0', sizeof(temp_str));
+	  sprintf(temp_str, "%s/bin/condor_status -l %s", 
+		  CONDOR_DIR, mach_name);
+	}
+
+	
+#ifdef WINDOWS
+	return;
+
+#else
+	if (( inputfile = popen(temp_str, "r")) == 0) {
+	  MWprintf( 10, "Error occurred during attempt to get "
+		    "condor_status for %s.\n",  mach_name );
+	  return;
+	}
+	
+	while (fgets(raw_line, 1500, inputfile) != 0) {
+		found = 0;
+		equal_pos = strchr(raw_line, '=');
+		
+		if (equal_pos != NULL) {
+			strncpy(key, raw_line, equal_pos - (raw_line+1));
+			strcpy(value, equal_pos+2);
+			
+			if (CondorLoadAvg == NO_VAL && !found) {
+				CondorLoadAvg = check_for_float_val("CondorLoadAvg", 
+													key, value);
+				if (CondorLoadAvg != NO_VAL)
+					found = 1;
+			}
+			
+			if (LoadAvg == NO_VAL && !found) {
+				LoadAvg = check_for_float_val("LoadAvg", key, value);
+				if (LoadAvg != NO_VAL)
+					found = 1;
+			}
+			
+			if (Memory == NO_VAL && !found) {
+				Memory = check_for_int_val("Memory", key, value);
+				if (Memory != NO_VAL)
+					found = 1;
+			}
+			
+			if (Cpus == NO_VAL && !found) {
+				Cpus = check_for_int_val("Cpus", key, value);
+				if (Cpus != NO_VAL)
+					found = 1;
+			}
+			
+			if (VirtualMemory == NO_VAL && !found) {
+				VirtualMemory = check_for_int_val("VirtualMemory", key, value);
+				if (VirtualMemory != NO_VAL)
+					found = 1;
+			}
+			
+			if (Disk == NO_VAL && !found) {
+				Disk = check_for_int_val("Disk", key, value);
+				if (Disk != NO_VAL)
+					found = 1;
+			}
+
+			if (KFlops == NO_VAL && !found) {
+				KFlops = check_for_int_val("KFlops", key, value);
+				if (KFlops != NO_VAL)
+					found = 1;
+			}
+
+			if (Mips == NO_VAL && !found) {
+				Mips = check_for_int_val("Mips", key, value);
+				if (Mips != NO_VAL)
+					found = 1;
+			}
+
+			if ( (strncmp(Arch, zero_string, 1) == 0) && !found) {	     
+				if (check_for_string_val("Arch", key, value) == 0){
+					strncpy( Arch, value, strlen(value)-1 );
+				}
+				
+				if (strncmp(Arch, zero_string, 1) != 0)
+					found = 1;
+			}
+			
+			if ( (strncmp(OpSys, zero_string, 1) == 0) && !found) {	     
+				if (check_for_string_val("OpSys", key, value) == 0){
+					strncpy( OpSys, value, strlen(value)-1 );
+				}
+				
+				if (strncmp(OpSys, zero_string, 1) != 0)
+					found = 1;
+			}
+
+			memset(key, '\0', sizeof(key));
+			memset(value, '\0', sizeof(value));
+			
+		}
+		
+    }
+
+    pclose ( inputfile);
+	
+	MWprintf(90,"CURRENT MACHINE  : %s \n", mach_name);
+	MWprintf(90,"Architecture : %s \n", Arch);
+	MWprintf(90,"Operating System : %s \n", OpSys);
+	
+	MWprintf(90,"CondorLoadAvg : %f\n", CondorLoadAvg);
+	MWprintf(90,"LoadAvg : %f\n", LoadAvg);
+	MWprintf(90,"Memory : %d\n", Memory);
+	MWprintf(90,"Cpus : %d\n", Cpus);
+	MWprintf(90,"VirtualMemory : %d\n", VirtualMemory);
+	MWprintf(90,"Disk : %d\n", Disk);
+	MWprintf(90,"KFlops : %d\n", KFlops);
+	MWprintf(90,"Mips : %d\n", Mips);
+#endif
+}
+
+void
+MWWorkerID::setNetworkConnectivity ( double latency )
+{
+	networkLatency_lastMeasuredTime = MWSystem::gettimeofday();
+	networkLatency = latency;
+	MWprintf ( 10, "The network latency is %f\n", networkLatency);
+}
+
+double
+MWWorkerID::getNetworkConnectivity ( double &retVal )
+{
+	retVal = networkLatency_lastMeasuredTime;
+	return networkLatency;
+}
+
+void
+MWWorkerID::initGroups ( int num )
+{
+	group = new MWGroup ( num );
+}
+
+void
+MWWorkerID::addGroup ( int num )
+{
+	MWworkClassWorkers[num]++;
+	group->join ( num );
+    return;
+}
+
+void
+MWWorkerID::deleteGroup ( int num )
+{
+	MWworkClassWorkers[num]--;
+	group->leave ( num );
+    return;
+}
+
+bool
+MWWorkerID::doesBelong ( int num )
+{
+	return group->belong ( num );
+}
+
+MWGroup*
+MWWorkerID::getGroup ( )
+{
+	return group;
+}
diff --git a/MW/src/MWWorkerID.h b/MW/src/MWWorkerID.h
new file mode 100644
index 0000000..4795fc2
--- /dev/null
+++ b/MW/src/MWWorkerID.h
@@ -0,0 +1,395 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWWORKERID_H
+#define MWWORKERID_H
+#include "MW.h"
+#include "MWGroup.h"
+#include <string.h>
+
+#define NO_VAL -1
+
+/// A forward reference; needed to define the MWWorkerID class.
+class MWTask;
+
+/**
+   This is a list of the states in which a worker can be.
+ */
+enum MWworker_states { 
+    /// Some initialization; not ready for work
+    INITIALIZING, 
+    /// Waiting for the master to send work
+    IDLE, 
+    /// Benchmarking, or doing application initialization on the initial data
+    BENCHMARKING,
+    /// Working actively on its task
+    WORKING, 
+    /// The machine has been suspended
+    SUSPENDED,
+    /// This worker has finished life.
+    EXITED
+};
+
+/** This array is used to hold strings that represent the
+    MWworker_states.  They are handy for printing out a worker - now
+    you'll see "WORKING" instead of "2" in printself().
+    @see MWworker_states */
+extern const char* MWworker_statenames[];
+
+
+/**
+   This class keeps an identification of the worker application
+   useful for the driver class.  It also keeps statistical information
+   that is useful to the stats class.  This information will be used at
+   the end of a run.
+ */
+class MWWorkerID  {
+
+        // allow access to worker's data...makes my life easier.
+    friend class MWStatistics;
+
+public:
+
+    /// Default constructor
+    MWWorkerID();
+    
+    /// Default destructor
+    virtual ~MWWorkerID();
+    
+		/// Return primary id of this worker
+	int get_id1() { return id1; };
+
+		/// Return secondard id of this worker
+	int get_id2() { return id2; };
+
+		/** Return the virtual id.  This is an int starting at zero and
+			increasing by one with each worker.  When a worker dies, this
+			number can be reused by a worker that joins us. */
+	int get_vid() { return virtual_id; };
+
+	/// Set primary id
+	void set_id1( int i ) { id1 = i; };
+
+	/// Set secondary id
+	void set_id2( int i ) { id2 = i; };
+
+    /// Set the machine's name
+    void set_machine_name( char * );
+
+    /// Get the current machine information
+    void get_machine_info();
+
+    /// Returns a pointer to the machine's name
+    char *machine_name();
+    
+	/// Set this worker's arch class
+	void set_arch ( int a ) { arch = a; };
+
+	/// Get this worker's arch class
+	int get_arch() { return arch; };
+
+	/// Sets the exec_class
+	void set_exec_class ( int num ) { exec_class = num; };
+
+	/// Gets the exec_class
+	int get_exec_class ( ) { return exec_class; };
+
+	/// Sets the executable
+	void set_executable ( char *exec ) { executable_name = exec; };
+
+	/// returns the executable name
+	char* get_executable ( ) { return executable_name; };
+
+		/// Mark this worker so that when the task completes it will exit
+	void mark_for_removal() { doomed = TRUE; };
+
+		/// returns TRUE if mark_for_removal was called previously
+	int is_doomed() { return doomed; };
+
+		/// 
+	void set_bench_result( double bres );
+
+		///
+	double get_bench_result() { return bench_result; };
+
+		/// 
+	double getNetworkConnectivity ( double &t );
+	void setNetworkConnectivity ( double );
+
+
+    /// The task running on this worker.  NULL if there isn't one.
+    MWTask *runningtask;
+    
+	/*
+    /// The next worker ID in the list of available workers.  NULL otherwise
+    MWWorkerID *next;
+	*/
+
+	/// The state of the worker.
+	enum MWworker_states currentState();
+
+	/// Set the state of the worker
+	void setState ( MWworker_states st ) { state = st; };
+    
+		/** Print out a description of this worker.
+			@param level The debug level to use */
+    virtual void printself( int level = 40 ); 
+
+    /**@name Statistics Collection Calls
+
+       These methods are called when events happen to workers.
+    */
+
+    //@{
+
+        /// Returns true if this worker is idle.
+    bool isIdle() { return (state==IDLE); }
+
+        /// Returns true if this worker is suspended.
+    bool isSusp() { return (state==SUSPENDED); }
+
+    /** This should be called when the master becomes aware of the 
+        existence of this worker. */
+    void started();
+    /// Called when the worker is doing the benchmarking task
+    void benchmark();
+    /// Called when the worker has done the benchmarking task
+    void benchmarkOver();
+    /// Called when this worker gets a task.
+    void gottask( int tasknum );
+    /// Called when this worker just finished the task it was working on.
+    void completedtask( double wall_time = 0.0, double cpu_time = 0.0 );
+    /// Called when the worker becomes suspended
+    void suspended();
+    /// Called when the worker resumes.
+    void resumed();
+    /// Send flowers...this is called when the worker dies.
+    void ended();
+
+    //@}
+
+	void initGroups ( int num );
+	/// Add worker to a workclass/group
+	void addGroup ( int num );
+	/// Remove worker from a workclass/group
+	void deleteGroup ( int num );
+	bool doesBelong ( int num );
+	MWGroup *getGroup ( );
+
+    /**@name Checkpointing Call
+
+	   Yes, each instance of a MWWorkerID needs to be able to checkpoint
+	   itself.  Why?  It has to store statistics information on itself.
+	   It never has to read them in, though, because stats that we write
+	   out here wind up being read in by the stats class when we restart.
+    */
+
+    //@{
+
+		/// Return the relevant stats info for this worker.
+
+	void ckpt_stats( double *up, 
+			 double *working, 
+			 double *susp, 
+			 double *cpu, 
+			 double *norm, 
+			 double* s_bench, 
+			 int* n_bench );
+
+	//@}
+	
+		/** @name Worker Information
+			This is now collected from condor_status.  It's the work of 
+			one of JP's students... 
+			
+			Note that this Arch is different from arch.  This one is 
+			what condor claims its arch is to the outside world. 
+		*/
+		//@{
+
+  ///
+    char Arch[64];
+
+  ///
+    char OpSys[64];
+
+  ///
+    double CondorLoadAvg;
+
+  ///
+    double LoadAvg;
+
+  ///
+    int Memory;
+
+  ///
+    int Cpus;
+
+  ///
+    int VirtualMemory;
+
+  ///
+    int Disk;
+
+  ///
+    int KFlops;
+
+  ///
+    int Mips;
+
+
+  ///
+    double get_total_time(){ return total_time;};
+  ///
+    double get_last_event(){return  last_event;};
+  ///
+    double get_total_suspended(){return total_suspended;};
+  ///
+    double get_total_working(){return total_working;};
+
+ private:
+
+    int check_for_int_val(char* name, char* key, char* value);
+    double check_for_float_val(char* name, char* key, char* value);
+    int check_for_string_val(char* name, char* key, char* value);
+
+		//@}
+
+		/** @name Private Data... */
+		//@{
+	
+		/// The machine name of the worker
+    char mach_name[64];
+	
+		/// A "primary" identifier of this machine.  (Was pvmd_tid)
+    int id1;
+    
+		/// A "secondary" identifier of this machine.  (Was user_tid)
+    int id2;
+    
+		/** A "virtual" number for this worker.  Assigned starting at 
+			0 and working upwards by one.  Also, when a worker dies, 
+			this number can get taken over by another worker */
+	int virtual_id;
+
+		/// This worker's arch class
+	int arch;   // (should be just a 0, 1, 2, etc...)
+
+	/// This is the exec_class
+	int exec_class;
+
+	/// This is the executable_name
+	char *executable_name;
+
+		/// TRUE if marked for removal, FALSE otherwise	
+	int doomed;  
+
+		/// The results of the benchmarking process.
+	double bench_result;
+
+		/// The state of this worker.
+    enum MWworker_states state;
+
+		/** @name Time information 
+		    Note that all time information is really stored as a double.
+		    We use gettimeofday() internally, and convert the result to 
+		    a double.  That way, we don't have to mess around with the
+		    struct timeval... */
+		//@{
+		/// The time that this worker started.
+	double start_time;
+	
+		/// The total time that this worker ran for.
+	double total_time;
+
+		/// The time of the last 'event'.
+	double last_event;
+	
+		/// The time spent in the suspended state
+	double total_suspended;
+
+		/// The time spent working
+	double total_working;
+
+		/// The cpu usage while working
+	double cpu_while_working;
+
+                /// The benchmarked (weighted) cpu working time
+        double benchmarked_cpu_working_time;
+
+               /// The benchmarked (normalized) cpu working time
+	double normalized_cpu_working_time;
+
+               /// The sum of the benchmark values for that vid
+        double sum_benchmark;
+
+               /// The number of the benchmark values for that vid
+        int num_benchmark;
+  
+
+		//@}
+		//@}
+
+	bool isBenchMark;
+	bool isBenchMarkAvailable;
+
+	/** @name Virtual Id Helpers */
+	//@{
+	/// vids[i] is 1 if virtual id i is taken, 0 if not.
+	static int *vids; 
+
+	// So here is the fix to MWStats bugs: I moved the vids[MW_MAX_WORKERS] init logic 
+	// into the init_vids() function. 
+	static int vids_inited;
+	void init_vids();
+	
+	/// Set virtual id
+	void set_vid( int i );
+	
+	/// Returns the lowest available virtual id; also sets it as used.
+	int get_next_vid();
+	
+	/// Returns a virtual id to the pool
+	void release_vid( int vid );
+	//@}
+
+	/** @name A Special Printf
+		Used to make output for John Bent's ulv program... */
+	
+	//@{
+	/** The log printf - use it to print ONE log event.  It will 
+		automagically add the "..." delimiter for you. */
+	void lprintf ( int vid, double now, char *fmt, ... );
+	/// The name of the ulv log file
+	static char *ulv_filename;
+	/// The log file fp.
+	static FILE *lfp;
+	//@}
+
+	/// Variables regarding the nw bandwidth.
+	double networkLatency;
+	double networkLatency_lastMeasuredTime;
+	MWGroup *group;
+};
+
+
+#endif
diff --git a/MW/src/MWWorkerMain.C b/MW/src/MWWorkerMain.C
new file mode 100644
index 0000000..b41a242
--- /dev/null
+++ b/MW/src/MWWorkerMain.C
@@ -0,0 +1,42 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* 
+ *	This is the master's main function. The whole starts from this point
+ *	This was done on 2/2/00 to make MW pure Object Oriented.
+ *
+ *	Author:
+ *		Sanjeev. R. Kulkarni
+ */
+
+
+
+#include <stdio.h>
+#include "MWWorker.h"
+extern MWWorker* gimme_a_worker();
+
+int main ( int argc, char *argv[] )
+{
+	MWWorker *worker;
+	worker = gimme_a_worker ( );
+	worker->go ( argc, argv );
+}
diff --git a/MW/src/MWprintf.C b/MW/src/MWprintf.C
new file mode 100644
index 0000000..fbc0d5a
--- /dev/null
+++ b/MW/src/MWprintf.C
@@ -0,0 +1,106 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* MWprintf.C - The place for the MWPrintf stuff. */
+
+#include "MW.h"
+#include <stdarg.h>
+#include <time.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef WINDOWS
+#include <sys/time.h>
+#endif
+
+int MWprintf_level = 50;
+static int fopen_count = 0;
+
+FILE* Open ( char *filename, char *mode )
+{
+    FILE *fp;
+
+    fp = fopen ( filename, mode );
+    if ( fp ) { 
+      fopen_count++;
+    }
+    else{
+      //MWprintf ( 10, "Could not open file %s as errno is %d\n", filename, errno );
+    }
+    return fp;
+}
+
+void Close ( FILE *fp )
+{
+    int retval;
+	fflush(fp);
+    retval = fclose ( fp );
+    if ( retval != 0 )
+    	MWprintf ( 10, "Could not close the file %x as errno is %d\n", fp, errno );
+    else
+    	fopen_count--;
+}
+
+int 
+get_MWprintf_level () {
+   return MWprintf_level;
+}
+
+
+int set_MWprintf_level ( int level ) {
+	int foo = MWprintf_level;
+	if ( (level<0) || (level>99) ) {
+		MWprintf( 10, "Bad arg \"%d\" in set_MWprintf_level().\n", level );
+	} else {
+		MWprintf_level = level;
+	}
+	return foo;
+}
+
+void MWprintf ( int level, char *fmt, ... ) {
+
+	static int printTime = TRUE;
+
+	if ( level > MWprintf_level ) {
+		return;
+	}
+
+#ifndef WINDOWS
+	if ( printTime ) {
+		struct timeval tv;
+		::gettimeofday(&tv, NULL);
+		struct tm *t = localtime(&tv.tv_sec);
+		printf( "%d:%02d:%02d.%03d ",  t->tm_hour, t->tm_min, t->tm_sec, (int) (tv.tv_usec / 1000));
+	}
+#endif
+
+	va_list ap;
+	va_start( ap, fmt );
+	vprintf( fmt, ap );
+	va_end( ap );
+	fflush( stdout );
+
+	if ( fmt[strlen(fmt)-1] == '\n' ) 
+		printTime = TRUE;
+	else
+		printTime = FALSE;
+}
diff --git a/MW/src/MWprintf.h b/MW/src/MWprintf.h
new file mode 100644
index 0000000..5e2cef7
--- /dev/null
+++ b/MW/src/MWprintf.h
@@ -0,0 +1,82 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/* MWprintf.h
+
+   A definition of the MWprintf functions
+
+*/
+
+#ifndef MWPRINTF_H
+#define MWPRINTF_H
+
+#include <stdio.h>
+
+	/** @name MWPrintf
+		This functions control the amount of printed information
+		in the MWDriver.  This is controlled through "levels", where
+		a level of 0 is the most important and 99 is the least 
+		important.  You can set the debug level to only print 
+		levels n and below.
+
+		Yes, this *is* a global function.  However, everyone needs 
+		to use it, and making it a static member of MWDriver would 
+		mean that you'd have to type MWDriver::MWprintf(), which
+		would get downright annoying.
+		
+		Other suggestions would be welcome.
+
+		Here's a proposed layout of how the numbers should work:
+		\begin{itemize}
+		\item 10 : Big errors, major events
+		\item 20 : Statistics at the end, user results
+		\item 30 : User-defined results, info, etc
+		\item 40 : Hosts up/down, other minor events
+		\item 50 : Checkpointing information
+		\item 60 : Sending/Receiving work
+		\item 70 : Misc messges...
+		\item 80 : Pointers!
+		\item 90 : Even more pointers, debugging info, etc
+		\end{itemize}
+
+		Remember, you've got 9 levels in between each of these, so
+		feel free to be creative....
+	*/
+
+	//@{
+
+	/** A regular printf, with debugging level. */
+void MWprintf ( int level, char *fmt, ... );
+
+/** Get the debug level for  the MWprintf function. */
+int get_MWprintf_level();
+
+	/** Set the debug level for the MWprintf function.  The default
+		upon startup is 50.
+		@return The old level */
+int set_MWprintf_level( int level );
+	//@}
+
+FILE* Open ( char*, char* );
+void Close ( FILE* );
+
+#endif
diff --git a/MW/src/Makefile.in b/MW/src/Makefile.in
new file mode 100644
index 0000000..444b5ad
--- /dev/null
+++ b/MW/src/Makefile.in
@@ -0,0 +1,171 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+ENABLE_MWINDEPENDENT = @ENABLE_MWINDEPENDENT@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# Subdirectories
+SUBDIRS = RMComm MWControlTasks BlackBox
+
+###  Libraries to be built, and dependent source files
+# If ENDABLE_INDEPENDENT is yes (you can do that by configure --with-independent). 
+# It seems we must build two sets of object file/lib for the normal configuration and --with-independent (otherwise 
+# the class definition included in different obj files are different (some are larget with independent - realized
+# this after PAINFUL debugging. Thanks for Peter's intuition!)
+# Here the safest way is to build libMW_indp.a and libMWutil_indp.a (although it currently doesn't include MWDriver.h 
+#  or MWWorker.h), also the libNWS_indp.a, libMWRMComm_lib.a and the libMWRC_indp.a (the actual RMC implementation).
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+LIBRARIES = libMW.a libMWutil.a libMW_indp.a libMWutil_indp.a
+else 
+LIBRARIES = libMW.a libMWutil.a
+endif
+
+libMW_a_SOURCES = MW.C MWDriver.C MWTask.C MWTaskContainer.C MWWorkerID.C MWWorker.C MWStats.C MWprintf.C MWGroup.C MWUnixSystem.C
+libMW_a_OBJECTS =  MW.o MWDriver.o MWTask.o MWTaskContainer.o MWWorkerID.o MWWorker.o MWStats.o MWprintf.o MWGroup.o MWUnixSystem.o
+libMWutil_a_SOURCES = MWList.C
+libMWutil_a_OBJECTS =  MWList.o
+
+libMW_indp_a_OBJECTS = MWInd.o MWDriverInd.o MWWorkerInd.o MWWorkerIDInd.o MWTaskInd.o MWTaskContainerInd.o MWStatsInd.o MWprintfInd.o MWGroupInd.o MWUnixSystem.o
+libMWutil_indp_a_OBJECTS = MWListInd.o 
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+INCLUDES = -I. -IRMComm -IMW-File -IMW-CondorPVM -IMW-Socket -IMWControlTasks $(MISC_DEFN) $(MEASURE_DEFN)
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+INDP_CXXCOMPILE = $(CXXCOMPILE) -DINDEPENDENT
+
+INCLUDEFILES = MW.h MWDriver.h\
+	MWGroup.h MWList.h MWStats.h MWSystem.h MWTask.h  MWTaskContainer.h MWWorker.h MWWorkerID.h MWprintf.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+libMW.a: $(libMW_a_OBJECTS) $(libMW_a_DEPENDENCIES)
+	-rm -f libMW.a
+	$(AR) cru libMW.a $(libMW_a_OBJECTS) $(libMW_a_LIBADD)
+	$(RANLIB) libMW.a
+	cp libMW.a $(MW_LIBDIR)
+
+libMWutil.a: $(libMWutil_a_OBJECTS) $(libMWutil_a_DEPENDENCIES)
+	-rm -f libMWutil.a
+	$(AR) cru libMWutil.a $(libMWutil_a_OBJECTS) $(libMWutil_a_LIBADD)
+	$(RANLIB) libMWutil.a
+	cp libMWutil.a $(MW_LIBDIR)
+
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+libMW_indp.a: $(libMW_indp_a_OBJECTS)
+	-rm -f libMW_indp.a
+	$(AR) cru libMW_indp.a $(libMW_indp_a_OBJECTS)
+	$(RANLIB) libMW_indp.a
+	cp libMW_indp.a $(MW_LIBDIR)
+libMWutil_indp.a: $(libMWutil_indp_a_OBJECTS)
+	-rm -f libMWutil_indp.a
+	$(AR) cru libMWutil_indp.a $(libMWutil_indp_a_OBJECTS)
+	$(RANLIB) libMWutil_indp.a
+	cp libMWutil_indp.a $(MW_LIBDIR)
+MWInd.o:MW.C
+	$(INDP_CXXCOMPILE) -o MWInd.o -c MW.C
+MWDriverInd.o:MWDriver.C
+	$(INDP_CXXCOMPILE) -o MWDriverInd.o -c MWDriver.C
+MWWorkerInd.o:MWWorker.C
+	$(INDP_CXXCOMPILE) -o MWWorkerInd.o -c MWWorker.C
+MWTaskInd.o:MWTask.C
+	$(INDP_CXXCOMPILE) -o MWTaskInd.o -c MWTask.C
+MWTaskContainerInd.o:MWTaskContainer.C
+	$(INDP_CXXCOMPILE) -o MWTaskContainerInd.o -c MWTaskContainer.C
+MWWorkerIDInd.o:MWWorkerID.C
+	$(INDP_CXXCOMPILE) -o MWWorkerIDInd.o -c MWWorkerID.C
+MWStatsInd.o:MWStats.C
+	$(INDP_CXXCOMPILE) -o MWStatsInd.o -c MWStats.C
+MWprintfInd.o:MWprintf.C
+	$(INDP_CXXCOMPILE) -o MWprintfInd.o -c MWprintf.C
+MWGroupInd.o:MWGroup.C
+	$(INDP_CXXCOMPILE) -o MWGroupInd.o -c MWGroup.C
+MWListInd.o:MWList.C
+	$(INDP_CXXCOMPILE) -o MWListInd.o -c MWList.C
+endif
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+
+install: $(LIBRARIES) $(INCLUDEFILES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check: 
+
+clean: 
+	-rm -f *.o *.a *core
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean: 
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a core
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C b/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C
new file mode 100644
index 0000000..b14c005
--- /dev/null
+++ b/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C
@@ -0,0 +1,1290 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWCondorPvmRC.h"
+#include <MW.h>
+#include <MWDriver.h>
+#include <MWTask.h>
+#include <MWWorker.h>
+
+#ifdef PVM_MASTER
+MWRMComm * MWDriver::RMC = new MWPvmRC;
+MWRMComm * MWTask::RMC = MWDriver::RMC;
+MWRMComm * MWWorker::RMC = NULL;
+#else
+MWRMComm * MWWorker::RMC = new MWPvmRC;
+MWRMComm * MWTask::RMC = MWWorker::RMC;
+MWRMComm * MWDriver::RMC = NULL;
+#endif
+
+extern int *MW_exec_class_num_workers;
+
+MWPvmRC::MWPvmRC ( )
+{ 
+	hostadd_reqs = NULL;
+	is_master = FALSE;   // assume the worst...
+	submit_list = new MWList<void>;
+}
+
+MWPvmRC::~MWPvmRC ( )
+{
+	if ( hostadd_reqs )
+	{
+		for ( int i = 0; i < exec_classes; i++ )
+			delete [] hostadd_reqs[i];
+		delete [] hostadd_reqs;
+	}
+	if ( submit_list )
+	{
+		while ( submit_list->number() > 0 )
+			delete ((int *)submit_list->Remove());
+		delete submit_list;
+	}
+	
+	if (recv_buf_list) {
+		while ( recv_buf_list->number() > 0 )
+			delete ((int *)recv_buf_list->Remove());
+		delete recv_buf_list;
+	}
+}
+
+/* Implementation of comm / rm class for pvm. */
+void 
+MWPvmRC::exit( int exitval ) 
+{
+	MWprintf ( 50, "Before pvm_exit\n" );
+	pvm_catchout( 0 );
+	pvm_exit();
+	MWprintf ( 50, "After pvm_exit\n" );
+	::exit(exitval);
+}
+
+int  
+MWPvmRC::setup( int argc, char *argv[], int *id, int *master_id ) 
+{
+	
+	MWprintf ( 10, "In MWPvmRC::setup()\n");
+
+	*id = pvm_mytid();
+	MWprintf(10, "MyPid is %d(%x)\n", *id, *id );
+
+	// BUFFER - init the recv_buf_list
+	recv_buf_list = new MWList<void>;
+	
+	if ( ( *master_id = pvm_parent() ) == PvmNoParent ) {
+	   	MWprintf ( 40, "I have no parent, therefore I'm the master.\n" );
+	   	is_master = TRUE;
+	   	*master_id = 0;
+   	} else {
+	   	is_master = FALSE;
+		return 0;
+	}
+    
+	pvm_catchout( stderr );
+		/* We tell PVM to tell us when hosts are added.  We will be sent
+		   a message with tag HOSTADD.  The -1 turns the notification on.
+		*/
+	pvm_notify ( PvmHostAdd, HOSTADD, -1, NULL );
+
+	return 0;
+}
+
+int 
+MWPvmRC::config( int *nhosts, int *narches, MWWorkerID ***workers ) 
+{
+	if ( !is_master ) {
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+
+	struct pvmhostinfo *hi= NULL;
+	int r;
+	
+	MWprintf ( 70, "In MWPvmRC::config()\n" );
+
+	if ( *workers ) {
+		MWprintf ( 10, "workers should be NULL when called.\n" );
+		return -1;
+	}
+
+	if ( (r = pvm_config ( nhosts, narches, &hi ) ) < 0 ) {
+		MWprintf ( 10, "Return value of %d from pvm_config!\n", r );
+		return -1;
+	}
+	
+	(*workers) = new MWWorkerID*[*nhosts];
+	for ( int i=0 ; i<*nhosts ; i++ ) {
+		(*workers)[i] = new MWWorkerID;
+		(*workers)[i]->set_arch ( atoi ( hi[i].hi_arch ) );
+			/* Do domething creative with speed later! */
+	}
+
+	return 0;
+} 
+
+int
+MWPvmRC::start_worker ( MWWorkerID *w ) 
+{
+	struct condorpvm_submit_element *elem = NULL;
+	// int ex_cl;
+	int retval;
+
+	if ( !is_master ) 
+	{
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+
+	MWprintf ( 50, "In MWPvmRC::start_worker()\n" );
+	if ( !w ) 
+	{
+		MWprintf ( 10, "w cannot be NULL!\n" );
+		return -1;
+	}
+
+		/* First, we will unpack some goodies that pvm gave us: */
+    int val;
+    char name[64], arch[64];
+    int status, dsig;
+
+		/* The following is packed by the multishadow along with the 
+		   HOSTADD message.  We unpack it here to put into the MWWorkerID */
+    unpack ( &val, 1, 1 );
+    unpack ( name );
+    unpack ( arch );
+    unpack ( &status, 1, 1 );
+    unpack ( &dsig, 1, 1 );  // new in 3.4.1
+    val &= PVM_MASK;   // remove that annoying high bit
+    MWprintf ( 40, "Received a host: " );
+    MWprintf ( 40, "Host %x added (%s), arch: %s, status:%d\n", 
+			   val, name, arch, status );
+
+	w->set_arch( atoi(arch) );
+//	w->set_machine_name( name );
+	elem = find_exec_class ( atoi(arch) );
+	if ( !elem )
+	{
+		MWprintf ( 10, "Strange!! No pending request found for arch %d\n", atoi(arch) );
+		w->set_id1(-1);
+		return -1;
+	}
+	else
+	{
+		w->set_exec_class ( elem->exec_class );
+		w->set_executable ( elem->exec );
+		retval = do_spawn( w );
+	}
+
+		/* We can do this now because the request will go down regardless
+		   of whether or not the spawn succeeds... */
+	hostadd_reqs[elem->exec_class][w->get_arch()]--;
+	delete elem;
+	return retval;
+}
+
+int
+MWPvmRC::init_beginning_workers( int *nworkers, MWWorkerID ***workers ) 
+{
+	if ( !is_master ) 
+	{
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+
+	int i, j, narches;
+	MWprintf ( 50, "In MWPvmRC::init_beginning_workers\n" );
+
+		/* config allocates memory for workers */
+	if ( config( nworkers, &narches, workers ) < 0 ) 
+	{
+		return -1;
+	}
+	
+		/* num_arches is a member of MWCommRC */
+	if ( (num_arches != -1) && (num_arches != narches) ) 
+	{
+			/* We were told by someone that we had the wrong number of 
+			   arch classes.  Complain here. */
+		MWprintf ( 10, "num_arches was set to %d, pvm just told us %d!\n", 
+				   num_arches, narches );
+		return -1;
+	}
+	num_arches = narches;
+
+    MWprintf ( 40, "Number of hosts at start: %d.\n", *nworkers );
+    MWprintf ( 40, "Number of arch. classes:  %d.\n", num_arches );
+
+	hostadd_reqs = new int*[exec_classes];
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		hostadd_reqs[i] = new int[num_arches];
+		for ( j = 0 ; j < num_arches ; j++ ) 
+		{
+			hostadd_reqs[i][j] = 0;
+		}
+	}
+
+	for ( i=0 ; i<(*nworkers) ; i++ ) 
+	{
+		do_spawn( (*workers)[i] );
+	}
+	
+	return 0;
+}
+
+int
+MWPvmRC::restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg )
+{
+	return init_beginning_workers ( nworkers, workers );
+}
+
+int
+MWPvmRC::do_spawn ( MWWorkerID *w ) 
+{
+	int spawned_tid;
+	int exec_class;
+	char arch[4];
+	char *exec;
+	int archnum = w->get_arch();
+	sprintf ( arch, "%d", archnum );
+	int i;
+
+	if ( w->get_executable() == NULL )
+	{
+		int tempi[exec_classes];
+
+		for ( i = 0; i < exec_classes; i++ )
+		{
+			tempi[i] = 0;
+		}
+
+		for ( i = 0; i < num_executables; i++ )
+		{
+			if ( worker_executables[i]->arch_class == w->get_arch() )
+			tempi[worker_executables[i]->exec_class] = 1;
+		}
+	
+		exec_class = choose_exec_class ( tempi );
+		if ( exec_class < 0 )
+		{
+			MWprintf ( 10, "ERROR!! No suitable exec_class chosen for arch_class %d\n", w->get_arch() );
+			return -1;
+		}
+		exec = find_executable ( exec_class, w->get_arch() );
+		w->set_executable ( exec );
+		w->set_exec_class ( exec_class );
+	}
+	else
+	{
+		exec_class = w->get_exec_class();
+		exec = w->get_executable();
+	}
+
+	MWprintf ( 40, "About to call pvm_spawn (%s)...\n", exec );
+	
+#if ! defined( STANDALONE )
+    int status = pvm_spawn( exec, NULL, 2, arch, 1, &spawned_tid );
+#else    
+    int status = pvm_spawn( exec, NULL, 1, "wheel", 1, &spawned_tid );
+#endif
+	
+	if ( status == 1 ) 
+	{
+        MWprintf ( 40, "Success spawning as tid %x.\n", spawned_tid );
+		w->set_id1( ( spawned_tid & PVM_MASK ) );
+		w->set_id2( ( pvm_tidtohost( spawned_tid ) & PVM_MASK ) );
+		setup_notifies ( spawned_tid );
+		return spawned_tid;
+	}
+	else
+	{
+        MWprintf ( 40, "Huh? Error: status:%d, tid:%d\n", 
+				   status, spawned_tid );
+		MWprintf ( 40, "There was a problem spawning on %x.\n", w->get_id1() );
+
+			/* We make sure that id2 is -1, signifying error! */
+		// w->set_id1( -1 );	// FIXME ??? Isn't it set_id2(-1) ?
+		w->set_id2(-1);
+		return -1;
+    }
+}
+
+int
+MWPvmRC::removeWorker ( MWWorkerID *w ) 
+{
+	char *machine = w->machine_name();
+	int info;
+	MWprintf ( 70, "Removing worker %s.\n", machine );
+	int retval = pvm_delhosts( &machine, 1, &info );
+	MWprintf(31, "pvm_delhosts returned %d and infos[0] = %d\n", retval, info);
+	if ( retval < 0 ) {
+		MWprintf ( 10, "pvm_delhosts returns an error of %d!\n", retval );
+	} 
+	if ( info < 0 ) {
+		MWprintf ( 10, "pvm_delhosts of %s has error %d.\n", machine, info );
+	}
+	delete w;
+	return retval;
+}
+
+int
+MWPvmRC::hostaddlogic( int *num_workers ) 
+{
+		/* This awfully complex function determines the conditions 
+		   under which it being called, and then calls pvm_addhosts()
+		   asking for the correct number of hosts.
+		   
+		   - num_workers - an array of size num_arches that contains 
+		      the number of workers in each arch class.
+		   - hostadd_reqs: The number of outstanding HOSTADDs out there
+		   - target_num_workers: Set by the user...
+		*/
+
+		/* If we're in STANDALONE mode, we never ask for hosts,
+		   so we basically ignore this whole function: */
+#if !defined (STANDALONE)
+
+	if ( !hostadd_reqs ) {
+			/* if this doesn't exist yet, we won't do anything */
+		return 0;
+	}
+
+		/* number of hosts to ask for at a time. The idea is that we'll
+		   have double this outstanding at a time - and this amounts 
+		   to 12 for 1, 2, or 3 arch classes. */
+
+	// Jeff changed this -- we always ask for six extra for each arch class...
+	int HOSTINC = hostinc_;
+	
+
+	int i, j;
+	int *sorted_order = new int[exec_classes];
+	sort_exec_class_ratio ( sorted_order );
+	int *howmany = new int[num_arches];  // how many to ask for
+	int *current_reqs_arches = new int[num_arches];
+	int *current_reqs_execs = new int[num_arches];
+	int *num_execs = new int[exec_classes];
+	// int total_workers = 0;
+	// int total_reqs = 0;
+	// int total_howmany = 0;
+	
+	
+	// DEBUGGING
+	struct pvmhostinfo *hostp;
+	int info, k, nhost, narch;
+
+	MWprintf ( 60, "hal: target: %d.\n", target_num_workers );
+
+	for ( i = 0; i < num_arches; i++ )
+	{
+		current_reqs_arches[i] = 0;
+		howmany[i] = 0;
+		for ( j = 0; j < exec_classes; j++ )
+		{
+			current_reqs_arches[i] += hostadd_reqs[j][i];
+		}
+	}
+
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		current_reqs_execs[i] = 0;
+		num_execs[i] = 0;
+		for ( j = 0; j < num_arches; j++ )
+		{
+			current_reqs_execs[i] += hostadd_reqs[i][j];
+		}
+	}
+
+	for ( i = 0; i < num_executables; i++ )
+	{
+		num_execs[ worker_executables[i]->exec_class ]++;
+	}
+
+	for ( i = 0 ; i < exec_classes ; i++ ) 
+	{
+		MWprintf ( 60, "hal: %d workers in class %d\n", num_workers[i], i );
+		MWprintf ( 60, "   -- outstanding reqs: %d\n", current_reqs_arches[i] );
+		int cur = sorted_order[i];
+		int req;
+
+		// DEBUGGING
+
+	        info = pvm_config( &nhost, &narch, &hostp );
+		if (info!=0)
+			MWprintf(31, "DEBUG: pvm_config() failed, returns %d.\n", info);
+		else {
+			MWprintf(31, "DEBUG: pvm_config() returned, nhost = %d.\n", nhost);
+			if ( (exec_classes == 1) && (nhost > MW_exec_class_num_workers[cur]) ) {
+				MWprintf(81, "DEBUG: CondorPvm and MW thinks differently about the number of workers.\n");
+				MWprintf(81, "DEBUG: nhost(MW) = %d, nhost(CondorPvm) = %d. Below is the worker list: \n", 
+					        MW_exec_class_num_workers[cur], nhost);
+				for (k = 0; k < nhost; k++)
+					MWprintf(91, "HOST_NAME = %s\n", hostp[k].hi_name);
+			}
+		}
+		
+		
+		if ( MW_exec_class_num_workers[cur] + current_reqs_execs[cur] >= exec_class_target_num_workers[cur] ) continue;
+		if ( current_reqs_execs[cur] > num_execs[cur] * HOSTINC ) continue;
+		if ( exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + current_reqs_execs[cur] ) > 2 * HOSTINC )
+			req = 2 * HOSTINC;
+		else
+			req = exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + current_reqs_execs[cur] );
+
+		for ( j = 0; j < num_arches; j++ )
+		{
+			int given;
+			char *temp;
+			if ( !(temp = exists_executable ( cur, j )) ) continue;
+			if ( current_reqs_arches[j] > HOSTINC ) continue;
+			if ( current_reqs_arches[j] + req > 2 * HOSTINC )
+			{
+				given = 2 * HOSTINC - current_reqs_arches[j];
+			}
+			else
+			{
+				given = req;
+			}
+
+			req -= given;
+			current_reqs_execs[cur] += given;
+			hostadd_reqs[cur][j] += given;
+			current_reqs_arches[j] += given;
+			howmany[j] += given;
+
+			for ( int k = 0; k < given; k++ )
+			{
+				struct condorpvm_submit_element *news = new struct condorpvm_submit_element;
+				news->arch_class = j;
+				news->exec_class = cur;
+				news->exec = temp;
+				submit_list->Append ( (void *)news );
+			}
+		}
+	}
+
+	/* We're FINALLY ready to do the deed! */
+	for ( i = 0 ; i < num_arches ; i++ ) 
+	{
+		if ( howmany[i] > 0 ) 
+			ask_for_host( howmany[i], i );
+	}
+
+	delete [] howmany;
+	delete [] current_reqs_execs;
+	delete [] current_reqs_arches;
+	delete [] sorted_order;
+
+#endif /* ifndef STANDALONE */
+	return 0;
+}
+
+int
+MWPvmRC::setup_notifies ( int task_tid ) 
+{
+		/* Takes a *task* tid, and sets up all notifies at once. */
+
+	MWprintf ( 40, "Setting up notifies for tid %x.\n", task_tid );
+	int pvmd_tid = pvm_tidtohost( task_tid );
+	
+    pvm_notify ( PvmHostDelete, HOSTDELETE, 1, &pvmd_tid );
+	pvm_notify ( PvmTaskExit, TASKEXIT, 1, &task_tid );
+#if !defined( STANDALONE )
+    pvm_notify ( PvmHostSuspend, HOSTSUSPEND, 1, &pvmd_tid );
+	pvm_notify ( PvmHostResume,  HOSTRESUME, 1, &pvmd_tid );
+#endif
+
+	return 0;
+}
+
+int 
+MWPvmRC::ask_for_host( int howmany, int arch ) 
+{
+	int status;
+	MWprintf ( 10, "Asking for %d host(s) with arch %d\n", howmany, arch );
+	
+	char **arches = new char*[howmany];
+	for ( int i=0 ; i<howmany ; i++ ) {
+		arches[i] = new char[4];
+		sprintf( arches[i], "%d", arch );
+	}
+	int *infos = new int[howmany];
+	
+	status = pvm_addhosts ( arches, howmany, infos );
+	
+	for ( int j=0 ; j<howmany ; j++ ) {
+		delete [] arches[j];
+	}
+	delete [] arches;
+	delete [] infos;
+
+	if ( status < 0 ) {
+		MWprintf ( 10, "pvm_addhosts returns %d, may not be able to "
+				   "aquire requested resources...\n", status );
+	} else {
+		MWprintf ( 90, "pvm_addhosts called with status = %d\n", status );
+	}
+    
+	return status; // JGS
+}	
+
+struct condorpvm_submit_element*
+MWPvmRC::find_exec_class ( int arch )
+{
+	struct condorpvm_submit_element *elem;
+       
+	elem = (struct condorpvm_submit_element *)submit_list->First();
+	while ( submit_list->AfterEnd() == false )
+	{
+		elem = (struct condorpvm_submit_element *)submit_list->Current();
+		if ( elem->arch_class == arch ) {
+			submit_list->RemoveCurrent();
+			return elem;
+		}
+		else submit_list->Next ();
+	}
+	return NULL;
+}
+
+int
+MWPvmRC::choose_exec_class ( int *tempi )
+{
+	for ( int i = 0; i < exec_classes; i++ )
+	{
+		if ( tempi[i] == 1 )
+			return i;
+	}
+	return -1;
+}
+
+char*
+MWPvmRC::find_executable ( int ex_cl, int ar_cl )
+{
+	for ( int i = 0; i < num_executables; i++ )
+	{
+		if ( worker_executables[i]->arch_class == ar_cl && 
+				worker_executables[i]->exec_class == ex_cl )
+			return worker_executables[i]->executable_name;
+	}
+	return NULL;
+}
+
+void
+MWPvmRC::sort_exec_class_ratio ( int *temp )
+{
+	int i, j;
+	double ii, jj;
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		temp[i] = i;
+	}
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		for ( j = i + 1; j < exec_classes; j++ )
+		{
+			ii = ((double)MW_exec_class_num_workers[temp[i]]) / exec_class_target_num_workers[temp[i]];
+			jj = ((double)MW_exec_class_num_workers[temp[j]]) / exec_class_target_num_workers[temp[j]];
+			if ( jj > ii )
+			{
+				int temp = j;
+				j = i;
+				i = temp;
+			}
+		}
+	}
+	return;
+}
+
+char*
+MWPvmRC::exists_executable ( int ex_cl, int ar_cl )
+{
+	for ( int i = 0; i < num_executables; i++ )
+	{
+		if ( worker_executables[i]->arch_class == ar_cl &&
+				worker_executables[i]->exec_class == ex_cl )
+			return worker_executables[i]->executable_name;
+	}
+	return NULL;
+}
+
+void 
+MWPvmRC::conf() {
+
+    int num_curr_hosts, num_curr_arch;
+
+    struct pvmhostinfo *hi;
+
+        // Foolish pvm_config allocs its own memory...
+    pvm_config ( &num_curr_hosts, &num_curr_arch, &hi );
+
+    MWprintf ( 40, "* Pvm says that there are %d machines and %d arches.\n", 
+             num_curr_hosts, num_curr_arch );
+    
+    MWprintf ( 40, "* These machines have the following configurations:\n" );
+    MWprintf ( 40, "* tid\t\tname\t\t\tarch\tspeed\n" );
+    MWprintf ( 40, "* ---\t\t----\t\t\t----\t-----\n" );
+
+    for ( int i=0 ; i<num_curr_hosts ; i++ ) {
+        MWprintf ( 40, "* %x\t%s\t%s\t%d\n", hi[i].hi_tid, hi[i].hi_name, 
+                 hi[i].hi_arch, hi[i].hi_speed );
+    }
+
+    MWprintf ( 40, "\n" );
+}
+
+int
+MWPvmRC::initsend ( int encoding ) 
+{
+	return pvm_initsend ( encoding ); 
+}
+
+
+int
+MWPvmRC::send ( int to_whom, int msgtag ) 
+{
+	return pvm_send ( to_whom, msgtag );
+}
+
+int
+MWPvmRC::nrecv( int from_whom, int msgtag)
+{
+    if ( (!is_master) )
+        return pvm_nrecv( from_whom, msgtag );
+
+    int *tmp;
+    int *buf_id = NULL;
+
+    if ( !(recv_buf_list->IsEmpty()) ) {
+        /* Assume that the first message in the list is already processed */
+        tmp = (int*) recv_buf_list->Remove();
+        MWprintf(91, "Deleted buffer %d\n", *tmp);
+        freebuf(*tmp);
+    }
+
+    if (recv_buf_list->IsEmpty()) {
+        buf_id = new int;
+        (*buf_id) = pvm_recv ( from_whom, msgtag );
+        if ( buf_id > 0 )  /* attach the buf_id  */
+            recv_buf_list->Append((void*)buf_id);
+    } else {
+        buf_id = (int*)recv_buf_list->First();
+    }
+
+    return *buf_id;
+}
+
+/* old blocking recv() */
+int
+MWPvmRC::recv ( int from_whom, int msgtag ) 
+{
+	recv_all(-1, -1);	
+	int *buf_id = NULL;
+
+	if (recv_buf_list == NULL || recv_buf_list->number()==0)
+	{
+	int *tmp;
+	
+	if ( !(recv_buf_list->IsEmpty()) ) {
+		/* Assume that the first message in the list is already processed */
+		tmp = (int*) recv_buf_list->Remove();
+		MWprintf(91, "Deleted buffer %d\n", *tmp);
+        freebuf(*tmp);
+	}
+	
+	if (recv_buf_list->IsEmpty()) {
+		buf_id = new int;
+		(*buf_id) = pvm_recv ( from_whom, msgtag );
+		if ( buf_id > 0 )  /* attach the buf_id  */
+			recv_buf_list->Append((void*)buf_id);
+	} else {
+		buf_id = (int*)recv_buf_list->First();
+	}
+	}
+	else
+	{
+		int* bid =  (int*) recv_buf_list->Remove();
+		buf_id = bid;
+		recv_buf_list->Prepend(bid);
+	}
+
+	return *buf_id;
+}
+
+/* BUFFER: returns the new buf_id if success, -1 otherwise. */
+int 
+MWPvmRC::next_buf()
+{
+	int setr_ret;
+	int *bid1, *bid2;
+
+	MWprintf(91, "BUFFER: Entered MWPvmRC::next_buf()\n");
+
+	if ( recv_buf_list->number()<2 )
+		return -1;
+	
+	bid1 = (int*) recv_buf_list->Remove();
+	bid2 = (int*) recv_buf_list->Remove();
+
+	if (bid2) {
+		setr_ret = pvm_setrbuf(*bid2);
+		while ( setr_ret == PvmBadParam || setr_ret == PvmNoSuchBuf ) {
+			MWprintf(91, "BUFFER: pvm_setrbuf() failed, can't move to the next buffer. Pvm returns %d.\n", setr_ret);
+				
+			freebuf(*bid1);
+			delete bid1;
+			bid1 = bid2;
+			bid2 = (int*) recv_buf_list->Remove();
+			
+			if (bid2)
+				setr_ret = pvm_setrbuf(*bid2);
+			else {
+				MWprintf(91, "BUFFER: In MWPvmRC::next_buf(), the next buffer points to NULL.\n");
+				return -1;
+			}
+		}
+
+		// Prepend the current active buffer
+		recv_buf_list->Prepend(bid2);
+	}
+
+	return (*bid2);
+}
+
+/* BUFFER: returns 1 if switched, returns 0 if no need to switch */
+int 
+MWPvmRC::switch_buf_back()
+{
+	int *buf_id;
+	
+	// if the newly received buffer is the only buffer in recv_buf_list, then return.
+	if (recv_buf_list->number()<1)
+		return 0;
+	
+	// otherwise, need to set the active buffer back to the head buffer of recv_buf_list
+	buf_id = (int*) recv_buf_list->Remove();
+	
+	int setr_ret = pvm_setrbuf(*buf_id);
+	if (setr_ret == PvmBadParam || setr_ret == PvmNoSuchBuf)
+		MWprintf(61, "BUFFER: Can't set active receive buffer to %d.\n", *buf_id);
+	else MWprintf(91, "BUFFER: Set active receive buffer back from %d to %d.\n", setr_ret, *buf_id);
+	recv_buf_list->Prepend(buf_id);
+
+	return 1;
+}
+
+/* BUFFER: receive from pvm and pack into the buffer list */
+int	
+MWPvmRC::recv_all( int from_whom, int msgtag )
+{
+	int *buf_id = new int[1];
+	int *tmp, len = 0;
+	
+	if ( !(recv_buf_list->IsEmpty()) ) {
+		/* Assume that the first message in the list is already processed */
+		tmp = (int*) recv_buf_list->Remove();
+		MWprintf(91, "Deleted buffer %d\n", *tmp);
+        freebuf(*tmp);
+	}
+	
+	(*buf_id) = pvm_nrecv( from_whom, msgtag );
+	
+	if ( *buf_id <= 0 ) {
+		MWprintf(91, "BUFFER: recv_all() got nothing, Pvm returns %d.\n", *buf_id);
+		if (recv_buf_list->number()) 
+			switch_buf_back();
+		return *buf_id;
+	}
+
+	while ( *buf_id > 0 ) {
+		MWprintf(91, "BUFFER: got a new buffer %d.\n", *buf_id);
+		recv_buf_list->Append(buf_id);
+		buf_id = new int [1];
+		len ++;
+		
+		pvm_setrbuf(0);
+		(*buf_id) = pvm_nrecv( from_whom, msgtag );
+	}
+	delete buf_id;
+
+	MWprintf(31, "BUFFER: recv_all() got %d new messages, recv_buf_list length is %d.\n", len, recv_buf_list->number());
+
+	// Return the number of newly received buffers
+	return (switch_buf_back()) ? len : 1;
+}
+
+/* BUFFER: pvm_setrbuf wrapper */
+int
+MWPvmRC::setrbuf( int bid )
+{
+	return pvm_setrbuf( bid );
+}
+
+// BUFFER: pvm_freebuf wrapper */
+int 
+MWPvmRC::freebuf( int bid )
+{
+	int ret = pvm_freebuf( bid );
+	
+	if ( ret == PvmNoSuchBuf || ret == PvmBadParam )
+		MWprintf(61, "BUFFER: pvm_freebuf(%d) failed, returns %d.\n", bid, ret);
+	
+	return ret;
+}
+
+/* BUFFER: pvm_bufinfo wrapper */
+int
+MWPvmRC::bufinfo ( int buf_id, int *len, int *tag, int *from ) 
+{
+	if ( buf_id == 0 ) // might want to check if 0 is a valid id
+    {
+        *tag = NO_MESSAGE;
+        return 0;
+    }
+
+	int retval = pvm_bufinfo ( buf_id, len, tag, from );
+	/* to clear out the annoying high bit! */
+	*from &= PVM_MASK;
+	return retval;
+}
+
+// BUFFER
+MWList<void>*
+MWPvmRC::recv_buffers() 
+{
+	return recv_buf_list;
+}
+
+void
+MWPvmRC::who ( int *wh )
+{
+	unpack ( wh, 1, 1 );
+	*wh &= PVM_MASK;
+}
+
+int
+MWPvmRC::pack ( const char *bytes,         int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride;
+	return pvm_pkbyte ( const_cast<char *>(bytes), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const float *f,            int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(float);
+	return pvm_pkfloat ( const_cast<float *>(f), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const double *d,           int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(double);
+	return pvm_pkdouble ( const_cast<double *>(d), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const int *i,              int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(int);
+	return pvm_pkint ( const_cast<int *>(i), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const unsigned int *ui,    int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(unsigned int);
+	return pvm_pkuint ( const_cast<unsigned int *>(ui), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const short *sh,           int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(short);
+	return pvm_pkshort ( const_cast<short *>(sh), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const unsigned short *ush, int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(unsigned short);
+	return pvm_pkushort ( const_cast<unsigned short *>(ush), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const long *l,             int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(long);
+	return pvm_pklong ( const_cast<long *>(l), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const unsigned long *ul,   int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride * sizeof(unsigned long);
+	return pvm_pkulong ( const_cast<unsigned long *>(ul), nitem, stride );
+}
+
+int
+MWPvmRC::pack ( const char *str ) 
+{
+	bytes_packed_ += strlen(str);
+	return pvm_pkstr ( const_cast<char *>(str) );
+}
+
+// BUFFER	
+int
+MWPvmRC::unpack ( char *bytes,         int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkbyte ( bytes, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkbyte ( bytes, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(char);
+				return 0;
+			}
+		} else return setr_ret;
+
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( float *f,            int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkfloat ( f, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkfloat ( f, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(float);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( double *d,           int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkdouble ( d, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkdouble ( d, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(double);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( int *i,              int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkint ( i, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkint ( i, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(int);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( unsigned int *ui,    int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkuint( ui, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkuint ( ui, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(unsigned int);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( short *sh,           int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkshort ( sh, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkshort ( sh, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(short);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( unsigned short *ush, int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkushort ( ush, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkushort ( ush, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(unsigned short);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( long *l,             int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upklong ( l, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upklong ( l, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(long);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( unsigned long *ul,   int nitem, int stride ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkulong ( ul, nitem, stride );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkulong ( ul, nitem, stride );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += nitem / stride * sizeof(unsigned long);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int
+MWPvmRC::unpack ( char *str ) 
+{
+	int ret, setr_ret;
+	
+	// receive from the current active buffer
+	ret = pvm_upkstr ( str );
+	
+	if ( ret==0 ) // Success!
+		return 0;
+	
+	if ( recv_buf_list == NULL )
+	       return ret;
+	
+	if ( ( ret == PvmNoData ) && (recv_buf_list->number()>=2) ) {
+		setr_ret = next_buf();
+		
+		if (setr_ret!=-1) { // Switch to the next valid buffer succeeded!
+			ret = pvm_upkstr ( str );
+				
+			if ( ret!=0 ) {
+				MWprintf(61, "BUFFER: The first two buffers returns PvmNoData, the second can't be unpacked %d.\n", ret);
+				return ret;
+			} else {
+				bytes_unpacked_ += strlen(str);
+				return 0;
+			}
+		} else return setr_ret;
+	} else  return ret;
+}
+
+int 
+MWPvmRC::read_RMstate ( FILE *fp = NULL )
+{
+    // No Pvm specific functions
+    return 0;
+}
+
+
+int 
+MWPvmRC::write_RMstate ( FILE *fp = NULL )
+{
+    // No Pvm specific functions
+    return 0;
+}
+
+#ifdef NWSENABLED
+typedef int (*callBackFcnDefn)(void* arg, int status);
+void setRestartFunction ( 
+				callBackFcnDefn /*cbRestart*/, 
+				void* 			/*cbRestartArg*/, 
+				callBackFcnDefn /*cbCkpt*/, 
+				void* 			/*cbCkptArg*/ )
+{
+}
+
+#endif
diff --git a/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h b/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h
new file mode 100644
index 0000000..91e8941
--- /dev/null
+++ b/MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h
@@ -0,0 +1,287 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWPVMRC_H
+#define MWPVMRC_H
+
+#include "../MWRMComm.h"
+#include "MWList.h"
+extern "C" {
+#include "pvm3.h"
+}
+
+/// A mask for getting rid of that annoying high set bit.
+#define PVM_MASK 0x7fffffff
+
+struct condorpvm_submit_element
+{
+	int arch_class;
+	int exec_class;
+	char *exec;
+};
+
+/** 
+	A Resource Management and Communication class that uses PVM 
+	for underlying support of inter-process communication and 
+	resource management.
+
+	We *could* do cool things here...like keep track of amount of
+	data sent, to whom, etc.  We could also MWprintf ( 99, "..." )
+	everything that gets sent for heaps and heaps of debugging.
+
+*/
+
+class MWPvmRC : public MWRMComm 
+{
+
+	public:
+
+		/// Constructor...
+		MWPvmRC();
+
+		/// Destructor...
+		~MWPvmRC();
+
+		/** @name A. Resource Management Routines
+
+			Here we implement the pure virtual functions found in 
+			ur parent class, MWRMComm.
+		*/
+		//@{
+
+		/** Shut down.  Calls pvm_exit(), then ::exit(exitval). */
+		void exit( int exitval );
+
+		/** Initialization.  Does pvm_catchout(), pvm_parent(), 
+			and pvm_notifies(). */
+		int setup( int argc, char *argv[], int *my_id, int *master_id );
+
+		/** Does a pvm_config, and stuffs the returned hostinfo
+		    struct information into a lot of MWWorkerID's.  See
+		    the parent class for return details.  */
+		int config( int *nhosts, int *narches, MWWorkerID ***workers );
+
+		/** Basically do a pvm_spawn.  We also put some information
+			into w upon return.
+			@return The tid spawned.  Negative number on error.
+		*/
+		int start_worker ( MWWorkerID *w );
+	
+		/** Start up the workers that are given to us at the beginning. 
+			See base class comments for more details.
+			@param nworkers The number of workers at start
+			@param workers A pointer to an array of pointers to 
+			       MWWorkerID classes.  This call will new() memory 
+				   for the MWWorkerIDs.  Also, if (*w)[n]->id2 is
+				   -1, that means that the spawn failed for 
+				   worker number n.
+		*/
+		int init_beginning_workers ( int *nworkers, MWWorkerID ***workers );
+
+		/** Called at the time of restart */
+		int restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg );
+
+		/** Remove a worker.  Basically, call pvm_delhosts(). */
+		int removeWorker( MWWorkerID *w );
+
+		/** Read some state. A null function */
+		int read_RMstate ( FILE *fp );
+
+		/** Write some state. A null function */
+		int write_RMstate ( FILE *fp );
+
+		//@}
+
+	private:
+		/** @name Other Functions to be implemented */
+
+		//@{
+
+		/** Figure out wether or not to ask for hosts, and how many... 
+			@param num_workers An array of size num_arches that contains
+			the number of workers in each arch class.
+		 */
+		int hostaddlogic( int *num_workers );
+
+		/** Do the pvm_spawn and associated stuff */
+		int do_spawn( MWWorkerID *w );
+
+		/** Set up the proper notifies for a task & host tid */
+		int setup_notifies ( int task_tid );
+
+		/** This function says to pvm: "I would like another machine, 
+			please".
+			@param howmany The number of machines to request
+			@param archnum The arch class number to ask for. */
+		int ask_for_host( int howmany, int archnum );
+
+		/** Shows the pvm virtual machine according to pvm.  Used
+			for debugging purposes; not normally called. */
+		void conf();
+	
+		/** Helper for hostaddlogic().  Returns the index of the min
+			element in array, which is of length len */
+		int min ( int *array, int len );
+
+		/** The number of outstanding requests for a particular 
+			arch. */
+		//int *hostadd_reqs;
+
+		/** The requests per exec_classes */
+		int **hostadd_reqs;
+
+		MWList<void> * submit_list;
+
+		//@}
+
+		/** Am I the master process or not? */
+		int is_master;
+
+	public:
+
+
+		/** @name C. Communication Routines
+			
+			These are essentially thin wrappers of PVM calls.
+		*/
+		//@{
+
+		///
+		int initsend ( int encoding = PvmDataDefault);
+
+		///
+		int send ( int to_whom, int msgtag );
+
+		///
+		int recv ( int from_whom, int msgtag );
+
+        /// non-blocking version of receive
+        int nrecv (int fromWhom, int msgtag);
+
+		/** Provide info on the message just received */
+		int bufinfo ( int buf_id, int *len, int *tag, int *from );
+
+		/** Tells the affected party */
+		void who ( int *id );
+
+		/// Pack some bytes
+		int pack ( const char *bytes,         int nitem, int stride = 1 );
+
+		/// float
+		int pack ( const float *f,            int nitem, int stride = 1 );
+
+		/// double
+		int pack ( const double *d,           int nitem, int stride = 1 );
+
+		/// int
+		int pack ( const int *i,              int nitem, int stride = 1 );
+
+		/// unsigned int
+		int pack ( const unsigned int *ui,    int nitem, int stride = 1 );
+
+		/// short
+		int pack ( const short *sh,           int nitem, int stride = 1 );
+
+		/// unsigned short
+		int pack ( const unsigned short *ush, int nitem, int stride = 1 );
+
+		/// long
+		int pack ( const long *l,             int nitem, int stride = 1 );
+
+		/// unsigned long
+		int pack ( const unsigned long *ul,   int nitem, int stride = 1 );
+
+		/// Pack a NULL-terminated string
+		int pack ( const char *str );
+	
+		/// Unpack some bytes
+		int unpack ( char *bytes,         int nitem, int stride = 1 );
+
+		/// float
+		int unpack ( float *f,            int nitem, int stride = 1 );
+
+		/// double
+		int unpack ( double *d,           int nitem, int stride = 1 );
+
+		/// int
+		int unpack ( int *i,              int nitem, int stride = 1 );
+
+		/// unsigned int
+		int unpack ( unsigned int *ui,    int nitem, int stride = 1 );
+
+		/// short
+		int unpack ( short *sh,           int nitem, int stride = 1 );
+
+		/// unsigned short
+		int unpack ( unsigned short *ush, int nitem, int stride = 1 );
+
+		/// long
+		int unpack ( long *l,             int nitem, int stride = 1 );
+
+		/// unsigned long
+		int unpack ( unsigned long *ul,   int nitem, int stride = 1 );
+
+		/// Unpack a NULL-terminated string
+		int unpack ( char *str );
+
+		//@}
+
+	private:
+		/** @name C. Some Misc Helper functions
+		*/
+
+		//@{
+
+		/** Find a suitable executable_class for a particular arch_class.
+		This function is useful to pick up the executable */
+		struct condorpvm_submit_element* find_exec_class ( int arch );
+
+		/** In the beginning, find a exec_class to an already
+		acquired arch_class */
+		int choose_exec_class ( int *tempi );
+
+		/** Find the appropriate executable name that belongs to exec_class ex_cl and
+		arch_class ar_cl */
+		char* find_executable ( int ex_cl, int ar_cl );
+
+		/** Sort the array temp based on the ratio of current/desired
+		number of workers of each exec_class */
+		void sort_exec_class_ratio ( int *temp );
+
+		/** Find if there is an executable that belongs to exec_class ex_cl and
+		arch_class ar_cl and if it exists return the executable name */
+		char* exists_executable ( int ex_cl, int ar_cl );
+
+		/** The non-blocking recv functions */
+	public:
+		int	recv_all( int from_whom, int msgtag );	// returns the number of new buffers
+		int 	setrbuf(int bid);		// switch the active receive buffer
+							// return the old active buf_id
+		int	freebuf(int bid);		// free the receive buffer.
+		MWList<void>* recv_buffers();			// return the recv_buf_list
+		int 	next_buf();			// advance the active buffer to the next valid buffer 
+							// in the recv_buf_list.
+		int 	switch_buf_back();		// Switch the active receive buffer to the buffer
+							// on the head of the recv_buf_list;
+};
+
+#endif
diff --git a/MW/src/RMComm/MW-CondorPVM/Makefile.in b/MW/src/RMComm/MW-CondorPVM/Makefile.in
new file mode 100644
index 0000000..4cd5d5d
--- /dev/null
+++ b/MW/src/RMComm/MW-CondorPVM/Makefile.in
@@ -0,0 +1,140 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS = 
+
+# Libraries to be built, and dependent source files
+LIBRARIES = libMWcondorpvmmaster.a libMWcondorpvmworker.a
+libNWcondorpvmmaster_a_SOURCES = MWCondorPvmRCM.ii
+libMWcondorpvmmaster_a_LIBADD = MWCondorPvmRCM.o
+libMWcondorpvmmaster_a_DEPENDENCIES =  MWCondorPvmRCM.o
+libMWcondorpvmmaster_a_OBJECTS =
+
+libMWcondorpvmworker_a_SOURCES = MWCondorPvmRCW.o
+libMWcondorpvmworker_a_LIBADD = MWCondorPvmRCW.o
+libMWcondorpvmworker_a_DEPENDENCIES =  MWCondorPvmRCW.o
+libMWcondorpvmworker_a_OBJECTS =
+
+INCLUDES = -I. -I.. -I../.. -I$(PVM_ROOT)/include $(MEASURE_DEFN)
+INCLUDEFILES = MWCondorPvmRC.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+
+libMWcondorpvmmaster.a: $(libMWcondorpvmmaster_a_OBJECTS) $(libMWcondorpvmmaster_a_DEPENDENCIES)
+	-rm -f libMWcondorpvmmaster.a
+	$(AR) cru libMWcondorpvmmaster.a $(libMWcondorpvmmaster_a_OBJECTS) $(libMWcondorpvmmaster_a_LIBADD)
+	$(RANLIB) libMWcondorpvmmaster.a
+	cp libMWcondorpvmmaster.a $(MW_LIBDIR) 
+
+libMWcondorpvmworker.a: $(libMWcondorpvmworker_a_OBJECTS) $(libMWcondorpvmworker_a_DEPENDENCIES)
+	-rm -f libMWcondorpvmworker.a
+	$(AR) cru libMWcondorpvmworker.a $(libMWcondorpvmworker_a_OBJECTS) $(libMWcondorpvmworker_a_LIBADD)
+	$(RANLIB) libMWcondorpvmworker.a
+	cp libMWcondorpvmworker.a $(MW_LIBDIR) 
+
+MWCondorPvmRCM.ii:MWCondorPvmRC.C
+	$(CXX) -E $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DPVM_MASTER MWCondorPvmRC.C > MWCondorPvmRCM.ii
+
+MWCondorPvmRCM.o:MWCondorPvmRCM.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DPVM_MASTER MWCondorPvmRCM.ii
+
+MWCondorPvmRCW.ii:MWCondorPvmRC.C
+	$(CXX) -E $(DEFS) $(MISC_DEFN) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWCondorPvmRC.C > MWCondorPvmRCW.ii
+
+MWCondorPvmRCW.o:MWCondorPvmRCW.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWCondorPvmRCW.ii
+
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/MW/src/RMComm/MW-File/MWFileError.h b/MW/src/RMComm/MW-File/MWFileError.h
new file mode 100644
index 0000000..e74a191
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileError.h
@@ -0,0 +1,35 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWFILEERROR_H
+#define MWFILEERROR_H
+
+#define HALF_WORK_WAIT_FILE	200
+
+#define HALF_MASTER_WAIT_FILE	201
+
+#define INIT_FILE_PROBLEM	202
+
+#define NEGNUMEXEC		203
+
+#endif
diff --git a/MW/src/RMComm/MW-File/MWFileRC.C b/MW/src/RMComm/MW-File/MWFileRC.C
new file mode 100644
index 0000000..8273bf1
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileRC.C
@@ -0,0 +1,2992 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWFileTypes.h"
+#include "MWFileSend.h"
+#include "MWFileRC.h"
+#include "MWFileRCSymbol.h"
+#include "MWFileError.h"
+
+#include <assert.h>
+#include <time.h>
+
+#ifdef FILE_MASTER
+#include <user_log.c++.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+
+#include <MWSystem.h>
+#include <MWDriver.h>
+#include <MWWorkerID.h>
+#include <MWTask.h>
+#include <MWWorker.h>
+
+#ifdef USE_CHIRP
+#include "chirp_client.h"
+#endif
+
+extern int *MW_exec_class_num_workers;
+
+// These static declarations are now necessary in the RMComm implementation
+#ifdef FILE_MASTER
+MWRMComm * MWDriver::RMC = new MWFileRC( TRUE, 0 );
+MWRMComm * MWTask::RMC = MWDriver::RMC;
+MWRMComm * MWWorker::RMC = NULL;
+#else
+MWRMComm * MWWorker::RMC = new MWFileRC ( FALSE, 0 );
+MWRMComm * MWTask::RMC = MWWorker::RMC;
+MWRMComm * MWDriver::RMC = NULL;
+#endif
+
+/// We need to do something better with this
+const int want_checkpointing = 0;
+
+/** If target_num_hosts is larger than this, we cut it back, since
+    we need to allocate arrays of reasonable size.
+*/
+const int REAL_TARGET_NUM_WORKERS = 2048;
+
+///
+const unsigned int SLEEP_DELAY = 5;
+
+int workerEvents[FileNumEvents] = { HOSTDELETE, HOSTADD, HOSTDELETE, HOSTSUSPEND, HOSTRESUME, CHECKSUM_ERROR };
+
+int min( int *arr, int len ) 
+{
+                // return index of min element in array of length len.
+    int min = 0;
+    for ( int i=1 ; i<len ; i++ ) 
+    {
+        if ( arr[i] < arr[min] ) 
+	{
+             min = i;
+        }
+    }
+    return min;
+}
+
+/* // To make gcc -Wall happy
+static void Truncate ( char *file )
+{
+    if ( truncate ( file, 0 ) != 0 );
+    	//MWprintf ( 10, "Could not truncate file %s. Errno is %d\n", file, errno );
+}
+*/
+
+static void HardDeleteFile ( char *file )
+{
+	if ( !file ) return;
+	remove(file);
+}
+
+MWFileRC::MWFileRC ( bool val, int id )
+{
+	isMaster = val;
+	FileRCID = id;
+	sendList = NULL;
+	recvList = NULL;
+}
+
+void
+MWFileRC::exit ( int retval )
+{
+
+#ifndef FILE_MASTER
+    ::exit( retval );
+#else
+
+//    struct stat statbuf;
+//    char cmd[_POSIX_PATH_MAX];
+
+    for ( int i = 0; i < target_num_workers; i++ )
+    {
+	if ( &fileWorkers[i] && fileWorkers[i].state != FILE_FREE )
+	    killWorker ( i );
+    }
+
+#if 1
+    // Jeff doesn't want to remove the directories for now...
+
+    /* We have to unlink the directories */
+ /*   
+	if ( stat ( output_directory, &statbuf ) == 0 )
+    {
+    	strcpy ( cmd, "/bin/rm -rf " );
+    	strcat ( cmd, output_directory );
+    	if ( system ( cmd ) < 0 )
+	    MWprintf ( 10, "Cannot unlink %s directory\n", output_directory );
+    }
+
+    if ( stat ( input_directory, &statbuf ) == 0 )
+    {
+    	strcpy ( cmd, "/bin/rm -rf " );
+    	strcat ( cmd, input_directory );
+    	if ( system ( cmd ) < 0 )
+	    MWprintf ( 10, "Cannot unlink %s directory\n", input_directory );
+    }
+
+    if ( stat ( control_directory, &statbuf ) == 0 )
+    {
+    	strcpy ( cmd, "/bin/rm -rf " );
+    	strcat ( cmd, control_directory );
+	if ( system ( cmd ) < 0 ) 
+	    MWprintf ( 10, "Cannot unlink %s directory\n", control_directory );
+    }
+*/
+#endif
+
+    ::exit( retval );
+#endif
+}
+
+
+int
+MWFileRC::setup( int argc, char *argv[], int *mytid, int *master_tid )
+{
+    SIMUL_SEND = 100;
+    worker_timeout = 80*60;
+
+    if ( isMaster == TRUE )
+    {
+
+	strcpy ( output_directory, "worker_output" );
+	strcpy ( input_directory, "worker_input" );
+	strcpy ( control_directory, "submit_files" );
+	strcpy ( moment_worker_file, "moment_worker_file" );
+	cyclePosition = 0;
+	turnNo = 0;
+	*mytid = FileRCID;
+	*master_tid = FileRCID;
+	CHECKLOG_FREQ = 100;
+	subId = 0;
+	hostadd_reqs = NULL;
+
+	MWSystem::mkdir ( output_directory);
+	MWSystem::mkdir ( input_directory);
+    MWSystem::mkdir ( control_directory);
+    }
+    else
+    {
+#ifdef USE_CHIRP
+	strcpy ( output_directory, "worker_output" );
+	strcpy ( input_directory, "worker_input" );
+	strcpy ( control_directory, "submit_files" );
+	strcpy ( moment_worker_file, "moment_worker_file" );
+	
+	MWSystem::mkdir( output_directory);
+	MWSystem::mkdir( input_directory);
+	MWSystem::mkdir( control_directory);
+#endif
+
+	// Slave FileRC instance. Only now the argc and argv make any sense
+	FileRCID = atoi ( argv[1] );
+	expected_number = atoi ( argv[2] );
+	master_expected_number = atoi(argv[3] );
+	strcpy ( output_directory, argv[4] );
+	strcpy ( input_directory, argv[5] );
+		strcpy ( control_directory, "submit_files" );
+		*master_tid = atoi ( argv[6] );
+		*mytid = FileRCID;
+		}
+
+		sendList = recvList = NULL;
+		return 0;
+	}
+
+
+	//---------------------------------------------------------------------
+	// MWFileRC::init_beginning_workers():
+	//	Called every time a master gets up either at the init time or 
+	// aftermath a brutal crash. It is here that we do a resuscicate and
+	// fill our worker lists.
+	// We start off by generating all the needed workers.
+	//---------------------------------------------------------------------
+	int
+	MWFileRC::init_beginning_workers ( int *nworkers, MWWorkerID ***workers )
+	{
+		int j = 0;
+		int i;
+
+		*nworkers = j;
+
+		if ( !hostadd_reqs )
+		{
+			// It is not restarting from checkpoint
+			MWprintf ( 10, "In MWFileRC::init_beginning_workers()\n");
+			hostadd_reqs = new int[exec_classes];
+		
+			for ( i = 0 ; i < exec_classes ; i++ ) 
+			{
+				hostadd_reqs[i] = 0;
+			}
+
+			fileWorkers = new struct FileWorker[target_num_workers];
+
+			if ( !fileWorkers )
+			{
+				MWprintf ( 10, "Cannot allocate memory\n");
+				return -1;
+			}
+			for ( i = 0; i < target_num_workers; i++ )
+			{
+				fileWorkers[i].state = FILE_FREE;
+				fileWorkers[i].served = -1;
+				fileWorkers[i].event_no = 0;
+				fileWorkers[i].id = -1;
+				fileWorkers[i].counter = 0;
+				fileWorkers[i].worker_counter = 0;
+				fileWorkers[i].arch = -1;
+				fileWorkers[i].condorID = -1;
+				fileWorkers[i].condorprocID = -1;
+			}
+		}
+
+		if ( j == 0 ) return 0;
+
+		return 0;
+	}
+
+int
+MWFileRC::restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg )
+{
+	int j = 0;
+	int i;
+	FILE *temp;
+	char worker_waitfile[_POSIX_PATH_MAX];
+	char master_waitfile[_POSIX_PATH_MAX];
+
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		if ( fileWorkers[i].state == FILE_RUNNING || fileWorkers[i].state == FILE_SUSPENDED || 
+					fileWorkers[i].state == FILE_RESUMED || fileWorkers[i].state == FILE_EXECUTE )
+		{
+			j++;
+		}
+	}
+
+	*nworkers = j;
+	if ( j == 0 ) return 0;
+
+	(*workers) = new MWWorkerID*[j];
+
+	j = 0;
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		if ( fileWorkers[i].state == FILE_RUNNING || fileWorkers[i].state == FILE_SUSPENDED || 
+					fileWorkers[i].state == FILE_RESUMED || fileWorkers[i].state == FILE_EXECUTE )
+		{
+			(*workers)[j] = new MWWorkerID;
+			(*workers)[j]->set_id1 ( fileWorkers[i].id );
+			(*workers)[j]->set_id2 ( fileWorkers[i].id );
+			(*workers)[j]->set_exec_class ( fileWorkers[i].exec_class );
+			j++;
+
+			sprintf ( worker_waitfile, "./%s/worker_waitfile.%d", input_directory, fileWorkers[i].id );
+			sprintf ( master_waitfile, "./%s/master_waitfile.%d", output_directory, fileWorkers[i].id );
+			temp = Open ( worker_waitfile, "a" );
+			if ( temp == NULL )
+			{
+				MWprintf ( 10, "Oops couldn't open the worker_waitfile for syncing\n");
+				continue;
+			}
+			fprintf( temp, "%c %d %c", SYNC, fileWorkers[i].worker_counter + SIMUL_SEND, ESYNC );
+			fileWorkers[i].worker_counter += SIMUL_SEND;
+			fflush( temp );
+			Close( temp );
+
+			initsend ( );
+			send ( i, msg );
+			fileWorkers[i].counter = 0;
+			fileWorkers[i].worker_counter = 0;
+			HardDeleteFile ( master_waitfile );
+		}
+	}
+	MWprintf (10, "Created in init %d workers\n", j );
+
+	return 0;
+}
+
+
+	//---------------------------------------------------------------------------
+	// MWFileRC::start_worker ()
+	//	In responce to a HOSTADD message. You know in whomRecv who has started.
+	//---------------------------------------------------------------------------
+	int
+	MWFileRC::start_worker ( MWWorkerID *w )
+	{
+		if ( !w )
+		{
+			MWprintf ( 10, "WorkerID w cannot be null in start_worker\n");
+			return -1;
+		}
+
+		w->set_id1 ( fileWorkers[whomRecv].id );
+		w->set_id2 ( fileWorkers[whomRecv].id );
+		w->set_arch ( fileWorkers[whomRecv].arch );
+		w->set_exec_class ( fileWorkers[whomRecv].exec_class );
+
+		hostadd_reqs[fileWorkers[whomRecv].exec_class]--; 
+		return 0;
+	}
+
+	int MWFileRC::removeWorker ( MWWorkerID *w )
+	{
+		if ( !w ) 
+		{
+		MWprintf (10, "Worker ID cannot be NULL in removeWorker\n" );
+		return -1;
+		}
+
+		char buf[_POSIX_PATH_MAX];
+
+		int condorID = fileWorkers[w->get_id1()].condorID;
+		int procID = fileWorkers[w->get_id1()].condorprocID;
+		MWprintf ( 10, "Removing workers %d.%d of %d\n", condorID, procID, w->get_id1() );
+		sprintf ( buf, "%s/bin/condor_rm %d.%d", CONDOR_DIR, condorID, procID );
+
+		if ( system ( buf ) < 0 )
+		{
+			MWprintf ( 10, "Could not condor_rm the worker\n" );
+		}
+
+		if ( fileWorkers[w->get_id1()].state == FILE_SUBMITTED )
+		{
+	//		submitted_num_workers--;
+
+			hostadd_reqs[w->get_exec_class()]--;
+	/*
+		//XXX HOSTADDDEBUG
+		MWprintf( 20, "Subtracting from %d hostadd_reqs.  Value %d\n", w->get_arch(),
+			  hostadd_reqs[w->get_arch()] );
+			for ( int i = 0; i < 2 * HOSTINC; i++ )
+				if ( hostaddind_reqs[w->get_arch()][i] == w->get_id1() ) hostaddind_reqs[w->get_arch()][i] = -1;
+	*/
+		}
+	/*
+		else
+			current_num_workers--;
+	*/
+		fileWorkers[w->get_id1()].state = FILE_FREE;
+		write_RMstate ( NULL );
+		return 0;
+	}
+
+
+//---------------------------------------------------------------------
+// MWFileRC::do_spawn(  int workerid ):
+//	Spawns the worker.
+//---------------------------------------------------------------------
+int
+MWFileRC::do_spawn ( int nWorkers, int ex_cl )
+{
+	int cID = -1;
+	int i;
+	int ids[nWorkers];
+	char sub_file[_POSIX_PATH_MAX];
+	char exe[_POSIX_PATH_MAX];
+	char logfile[_POSIX_PATH_MAX];
+	char master_waitfile[_POSIX_PATH_MAX], worker_waitfile[_POSIX_PATH_MAX];
+	FILE *ptr;
+	char temp[_POSIX_PATH_MAX];
+	char requirements[num_executables * _POSIX_PATH_MAX];
+
+	if ( nWorkers <= 0 ) return 0;
+
+	sprintf( sub_file, "%s/submit_file.%d", control_directory, subId++ );
+	sprintf( exe, "%s/bin/condor_submit %s", CONDOR_DIR, sub_file );
+
+	FILE *f = Open( sub_file, "w" );
+	if ( f == NULL )
+	{
+		MWprintf ( 10, "Couldn't open the submitfile for writing\n");
+		return -1;
+	}
+    	
+	int index = 0;
+	for ( i = 0; i < target_num_workers && index < nWorkers; i++ ) 
+	{
+		if ( fileWorkers[i].state == FILE_FREE ) 
+		{
+			ids[index++] = i;
+		}
+	}
+
+	if ( index < nWorkers ) 
+	{
+		MWprintf ( 10, "In MW-File hostaddlogic asking for more workers than target_num_workers\n");
+		MWprintf ( 10, "Had asked %d workers but I am adding only %d\n", nWorkers, index );
+		nWorkers = index;
+	}
+
+#ifdef USE_CHIRP
+	fprintf ( f, "Universe = Vanilla\n");
+	fprintf( f, "+WantIOProxy=True\n");
+	fprintf( f, "should_transfer_files = Yes\n"); // These two just needed to move to the execute dir
+	fprintf( f, "when_to_transfer_output = ON_EXIT\n");
+#else
+	fprintf ( f, "Universe = Standard\n");
+#endif
+	fprintf( f, "Executable = mw_exec%d.$$(Opsys).$$(Arch)\n", ex_cl );
+
+	bool tempfirst = TRUE;
+	for ( i = 0; i < num_executables; i++ )
+	{
+		if ( worker_executables[i]->exec_class == ex_cl )
+		{
+			if ( tempfirst == TRUE )
+			{
+				sprintf ( requirements, "( ( %s ) ", arch_class_attributes[worker_executables[i]->arch_class] );
+				tempfirst = FALSE;
+			}
+			else
+			{
+				sprintf ( requirements, "%s || ( %s ) ", requirements, arch_class_attributes[worker_executables[i]->arch_class] );
+			}
+		}
+	}
+	strcat ( requirements, " )" );
+	for ( i = 0; i < nWorkers; i++ ) 
+	{
+		sprintf( logfile, "%s/log_file.%d", control_directory, ids[i] );
+		sprintf( master_waitfile, "./%s/master_waitfile.%d", 
+							output_directory, ids[i] );
+		sprintf( worker_waitfile, "./%s/worker_waitfile.%d", 
+							input_directory, ids[i] );
+    
+		fprintf( f, "arguments = %d %d %d %s %s -1\n", ids[i], 0, 0,
+							output_directory, input_directory ); 
+		fprintf( f, "log = %s/log_file.%d\n", control_directory, ids[i] );
+
+		fprintf( f, "Output = %s/output_file.%d.$(Cluster).$(Process)\n", control_directory, ids[i] );
+		fprintf( f, "Error = %s/error_file.%d.$(Cluster).$(Process)\n", control_directory, ids[i] );
+
+		fprintf( f, "Requirements = %s\n ", requirements );
+		fprintf ( f, "getenv = True\n" );
+
+		// Jeff changed this
+
+		FILE *userf = Open( "worker_attributes", "r" );
+		if( userf == NULL ) 
+		{
+			MWprintf( 10, "No worker_attributes file, assuming Condor defaults\n" );
+		}
+		else 
+		{
+			int c;
+			while( ( c = getc( userf ) ) != EOF ) 
+			{
+				putc( c, f );
+			}
+			Close( userf );
+		}
+
+		fprintf( f, "Queue\n" );
+    
+		HardDeleteFile( logfile );
+		HardDeleteFile( master_waitfile );
+		HardDeleteFile( worker_waitfile );
+
+	}
+	Close( f );
+
+	MWprintf (10, "About to call condor_submit %s\n", exe);
+	if ( (ptr = popen(exe, "r") ) != NULL ) 
+	{
+		while ( fscanf(ptr, "%s", temp ) >= 0 ) 
+		{
+
+			if ( strcmp ( temp, "cluster" ) == 0 ) 
+			{
+
+				// This is for Jeff's debugging with JP
+				//MWprintf( 10, "Got cluster\n" );
+
+				fscanf( ptr, "%s", temp );
+
+				// This is for Jeff's debugging with JP
+				//MWprintf( 10, "Read %s from the pipe.\n", temp );
+	
+				cID = atoi ( temp );
+				pclose(ptr);
+				ptr = NULL;
+				MWprintf ( 10, "Spawned to cluster %d\n", cID );
+				break;
+			}
+		}
+		if ( ptr ) pclose ( ptr ); 
+		for ( i = 0; i < nWorkers; i++ ) 
+		{
+			int tempp = ids[i];
+			fileWorkers[tempp].condorID = cID;
+			fileWorkers[tempp].condorprocID = i;
+			fileWorkers[tempp].arch = -1;
+			fileWorkers[tempp].counter = 0;
+			fileWorkers[tempp].worker_counter = 0;
+			fileWorkers[tempp].id = tempp;
+			fileWorkers[tempp].state = FILE_SUBMITTED;
+			fileWorkers[tempp].event_no = 1;
+			fileWorkers[tempp].exec_class = ex_cl;
+/*
+			for ( int j = 0; j < 2 * HOSTINC; j++ ) {
+				if ( hostaddind_reqs[archid][j] == -1 ) { 
+				hostaddind_reqs[archid][j] = tempp; 
+				break; 
+				}
+			}
+*/
+		}
+	}
+	else 
+	{
+		MWprintf ( 10, "Couldn't popen in FileRC\n");
+		return -1;
+	}
+
+	write_RMstate ( NULL );
+	return nWorkers;
+}
+
+int
+MWFileRC::initsend ( int useless )
+{
+	/* This prepares for a series of packs before we do the actual send */
+	if ( !sendList )
+		sendList = new MWList<void> ;
+
+	while ( sendList->number() > 0 )
+	{
+		struct FileSendBuffer *buf = (struct FileSendBuffer *)sendList->Remove();
+		delete buf;
+	}
+
+	checksum = 0;
+	return 0;
+}
+
+void
+MWFileRC::who ( int *wh )
+{
+	unpack ( wh, 1, 1 );
+}
+
+
+//---------------------------------------------------------------------------
+//
+// 
+//---------------------------------------------------------------------------
+int
+MWFileRC::send ( int to_whom, int msgtag )
+{
+	char filename[_POSIX_PATH_MAX];
+	char control_file[_POSIX_PATH_MAX];
+	FILE *fp;
+	if ( isMaster == TRUE )
+	{
+		// In the master mode 
+		sprintf ( filename, "%s/worker_input.%d.%d", input_directory, to_whom,
+					fileWorkers[to_whom].worker_counter );
+		sprintf ( control_file, "%s/worker_waitfile.%d", input_directory, 
+					to_whom );
+	}
+	else
+	{
+		// We are sending something to the master. So to_whom actually has
+		// no meaning.
+		sprintf ( filename, "%s/worker_output.%d.%d", output_directory,
+					FileRCID, master_expected_number );
+		sprintf ( control_file, "%s/master_waitfile.%d", output_directory,
+					FileRCID );
+	}
+
+	fp = Open ( filename, "w" );
+	if ( fp == NULL )
+	{
+		MWprintf ( 10, "Couldn't open file %s for writing work.  Bailing out!\n", filename );
+
+		assert( filename && 0 );
+		return -1;
+	}
+
+	fprintf ( fp, "%d %lld ", msgtag, checksum );
+
+	while ( sendList->IsEmpty() != TRUE )
+	{
+		struct FileSendBuffer *buf = ( struct FileSendBuffer *)sendList->Remove();
+		switch ( buf->type )
+		{
+			case INT:
+				fprintf ( fp, "%d %d ", INT, *(int *)buf->data );
+				break;
+			case CHAR:
+				fprintf ( fp, "%d %c ", CHAR, *(char *)buf->data );
+				break;
+			case LONG:
+				fprintf ( fp, "%d %ld ", LONG, *(long *)buf->data );
+				break;
+			case FLOAT:
+				fprintf ( fp, "%d %f ", FLOAT, *(float *)buf->data );
+				break;
+			case DOUBLE:
+				fprintf ( fp, "%d %f ", DOUBLE, *(double*)buf->data );
+				break;
+			case UNSIGNED_INT:
+				fprintf ( fp, "%d %o ", UNSIGNED_INT, *(unsigned int *)buf->data );
+				break;
+			case SHORT:
+				fprintf ( fp, "%d %hd ", SHORT, *(short *)buf->data );
+				break;
+			case UNSIGNED_SHORT:
+				fprintf ( fp, "%d %ho ", UNSIGNED_SHORT, *(unsigned short *)buf->data );
+				break;
+			case UNSIGNED_LONG:
+				fprintf ( fp, "%d %lo ", UNSIGNED_LONG, *(unsigned long *)buf->data );
+				break;
+			case STRING:
+				fprintf ( fp, "%d %d %s ", STRING, buf->size - 1, 
+						(char *)buf->data );
+				break;
+			default:
+				MWprintf ( 10, "Couldnot decipher a data type while sending\n");
+				MWprintf ( 10, "Got %d\n", buf->type );
+				Close ( fp );
+				return -1;
+		}
+
+		delete buf;
+	}
+
+	fflush ( fp );
+	Close ( fp );
+
+	if ( isMaster || ( !isMaster && master_expected_number == 0 ) )
+	{
+		fp = Open ( control_file, "a" );
+	}
+	else
+	{
+		// You are a slave and expected_number is not zero.
+		fp = Open ( control_file, "a" );
+		if (fp == NULL)
+		{
+			MWprintf ( 10, "In slave my %s doesn't exist\n");
+			HardDeleteFile ( filename );
+			return 0;
+		}
+	}
+	if ( fp == NULL )
+	{
+		MWprintf ( 10, "Could not open the waitfile %s.  Send will fail!\n", control_file );
+
+		assert( control_file && 0 );
+		return -1;
+	}
+
+	if ( isMaster == TRUE )
+	{
+		fprintf ( fp, "%d %c", fileWorkers[to_whom].worker_counter, OK );
+		fileWorkers[to_whom].worker_counter++;
+	}
+	else
+	{
+		fprintf ( fp, "%d %c",  master_expected_number, OK );
+		master_expected_number++;
+	}
+	fflush ( fp );
+	Close ( fp );
+
+#ifdef USE_CHIRP
+	if (!isMaster) {
+		sendFileToMaster(filename);
+		sendFileToMaster(control_file);
+	}
+#endif
+	return 0;
+}
+
+
+int
+MWFileRC::recv ( int from_whom, int msgtag )
+{
+	if ( !recvList )
+		recvList = new MWList<void> ;
+	while ( recvList->number() > 0 )
+	{
+		struct FileSendBuffer *buf = (struct FileSendBuffer *)recvList->Remove();
+		delete buf;
+	}
+
+	if ( isMaster == TRUE )
+		return master_recv ( from_whom, msgtag );
+	else
+		return worker_recv ( from_whom, msgtag );
+}
+
+int
+MWFileRC::nrecv ( int from_whom, int msgtag )
+{
+  if ( !recvList )
+    recvList = new MWList<void> ;
+   
+  while ( recvList->number() > 0 )
+    {
+      struct FileSendBuffer *buf = (struct FileSendBuffer *)recvList->Remove();
+      delete buf;
+    }
+
+    //from_whom has no meaning as it is invariably from the master.
+    static time_t last_comm = time(0);
+    int calculated_number = 0;
+    char c;
+    char filename[_POSIX_PATH_MAX];
+    FILE *op = NULL;
+    bool toFlush = FALSE;
+    time_t starttime;
+    time_t waitedtime;
+    starttime = waitedtime = time(0);
+
+    sprintf ( filename, "%s/worker_waitfile.%d", input_directory, FileRCID );
+    op = Open ( filename, "r" );
+    while ( 1 )
+      {
+      waitedtime = time(0);
+      /*
+      if(waitedtime - starttime > SLEEP_DELAY*2)
+      {
+        Close(op);
+        msgTag = NO_MESSAGE;
+    return 0;
+      }
+      */
+    if ( worker_timeout > 0 && last_comm + worker_timeout < time(0) )
+      {
+        MWprintf ( 10, "Worker Timed out\n");
+        if ( op ) Close ( op );
+        return WORKER_TIMEOUT;
+      }
+    if ( !op )
+      {
+        MWSystem::sleep( SLEEP_DELAY );
+        op = Open ( filename, "r" );
+        //MWprintf(10,"Cannot open file, try again\n");
+        continue;
+      }
+    if ( fscanf( op, "%c", &c ) < 0 )
+      {// end of file, return from non-blocking receive
+            Close(op);
+            msgTag = NO_MESSAGE;
+        return 0;
+      /*
+        Close( op );
+        sleep( SLEEP_DELAY );
+        op = Open ( filename, "r" );
+        MWprintf(10,"opened file no data, try again\n"); // wenhan
+        continue;
+        */
+      }
+    if ( c == OK )
+      {
+        if ( calculated_number != expected_number )
+          {
+        if ( calculated_number > expected_number )
+          {
+            MWprintf(10, "Fault in master resuscicate logic,exiting\n");
+            Close ( op );
+            return UNABLE_TO_WAKE;
+          }
+        calculated_number = 0;
+        continue;
+          }
+             else
+        {
+                MWprintf ( 10, "Got the work in slave %d\n", expected_number );
+                expected_number++;
+                Close(op);
+                whomRecv = 0;
+                last_comm = time(0);
+                int hh = handle_work( msgtag );
+                if ( toFlush )
+                  {
+                expected_number = 0;
+                master_expected_number = 0;
+                HardDeleteFile ( filename );
+                toFlush = FALSE;
+                  }
+                return hh;
+              }
+      }
+    else if ( c == ' ' )
+      {
+      }
+    else if ( c == SYNC)
+      {
+        // Master wants it to ignore some things.
+        calculated_number = 0;
+      }
+    else if ( c == ESYNC )
+      {
+        expected_number = calculated_number;
+        calculated_number = 0;
+        toFlush = TRUE;
+      }
+    else if ( isdigit ( c ) )
+      {
+        calculated_number = calculated_number * 10 + c - '0';
+      }
+                else
+          {
+            Close ( op );
+            return WAITFILE_PROTOCOL_ERROR;
+          }
+      }
+}
+
+
+int MWFileRC::master_recv ( int from_whom, int msgtag )
+{
+	// msgtag has no meaning as we have to recv all sorts of control info.
+    int i;
+    bool change = FALSE;
+    while ( 1 )
+    {
+    	if ( turnNo == CHECKLOG_FREQ )
+    	{
+	    CheckLogFilesRunning();
+	    turnNo = 0;
+    	}
+    	for ( i = cyclePosition; i < target_num_workers; i++ )
+    	{
+	    cyclePosition++;
+	    switch ( fileWorkers[i].state )
+	    {
+	    	case FILE_RUNNING:
+		    change = IsComplete ( i );
+		    if ( change == TRUE )
+		    {
+    			MWprintf ( 10, "Master received something from worker %d\n", i );
+			return handle_finished_worker ( i );
+	    }
+		    break;
+
+		case FILE_EXECUTE:
+		    if ( fileWorkers[i].served != FILE_RUNNING )
+		    {
+    		    	MWprintf ( 10, "Master found that worker is Started %d\n", i );
+		    	return handle_executing_worker (i );
+		    }
+		    break;
+
+	    	case FILE_KILLED:
+		    if ( fileWorkers[i].served != FILE_KILLED )
+		    {
+		    	MWprintf ( 10, "Master found that worker was Killed %d\n", i);
+		    	return handle_killed_worker(i);
+		    }
+		    break;
+		
+		case FILE_SUSPENDED:
+		    if ( fileWorkers[i].served != FILE_SUSPENDED )
+		    {
+		    	MWprintf ( 10, "Master found that worker was Suspended %d \n", i);
+		    	return handle_suspended_worker(i);
+		    }
+		    break;
+
+		case FILE_RESUMED:
+		    if ( fileWorkers[i].served != FILE_RESUMED )
+		    {
+		    	MWprintf ( 10, "Master found that worker was Resumed %d\n", i);
+		    	return handle_resumed_worker(i);
+		    }
+		    break;
+
+		case FILE_TRANSIT:
+		    if ( fileWorkers[i].served != FILE_TRANSIT )
+		    {
+		    	MWprintf ( 10, "Master found that worker transited %d \n", i );
+			return handle_transited_worker(i);
+		    }
+
+		default:
+		    break;
+	    }
+
+	}
+
+	cyclePosition = 0;
+	turnNo++;
+    }
+}
+
+
+int
+MWFileRC::worker_recv ( int from_whom, int msgtag )
+{
+	//from_whom has no meaning as it is invariably from the master.
+	static time_t last_comm = time(0);
+	int calculated_number = 0;
+	char c;
+	char filename[_POSIX_PATH_MAX];
+	FILE *op = NULL;
+	bool toFlush = FALSE;
+
+
+	sprintf ( filename, "%s/worker_waitfile.%d", input_directory, FileRCID );
+#ifdef USE_CHIRP
+	getFileFromMaster(filename);
+#endif
+	op = Open ( filename, "r" );
+	while ( 1 )
+	{
+		if ( worker_timeout > 0 && last_comm + worker_timeout < time(0) )
+		{
+			MWprintf ( 10, "Worker Timed out\n");
+			if ( op ) Close ( op );
+			return WORKER_TIMEOUT;
+		}
+		if ( !op )
+		{
+			MWSystem::sleep( SLEEP_DELAY );
+#ifdef USE_CHIRP
+			getFileFromMaster(filename);
+#endif
+			op = Open ( filename, "r" );
+			continue;
+		}
+		if ( fscanf( op, "%c", &c ) < 0 )
+		{
+			Close( op );
+			MWSystem::sleep( SLEEP_DELAY );
+#ifdef USE_CHIRP
+			getFileFromMaster(filename);
+#endif
+			op = Open ( filename, "r" );
+			continue;
+		}
+		if ( c == OK )
+		{
+			if ( calculated_number != expected_number )
+			{
+				if ( calculated_number > expected_number )
+				{
+					MWprintf(10, "Fault in master resuscicate logic,exiting\n");
+					Close ( op );
+					return UNABLE_TO_WAKE;
+				}
+				calculated_number = 0;
+				continue;
+			}
+			else
+			{
+				MWprintf ( 10, "Got the work in slave %d\n", expected_number );
+				expected_number++;
+				Close(op);
+				whomRecv = 0;
+				last_comm = time(0);
+				int hh = handle_work( msgtag );
+				if ( toFlush )
+				{
+					expected_number = 0;
+					master_expected_number = 0;
+					HardDeleteFile ( filename );
+					toFlush = FALSE;
+				}
+				return hh;
+			}
+		}
+		else if ( c == ' ' )
+		{
+		}
+		else if ( c == SYNC)
+		{
+			// Master wants it to ignore some things.
+			calculated_number = 0;
+		}
+		else if ( c == ESYNC )
+		{
+			expected_number = calculated_number;
+			calculated_number = 0;
+			toFlush = TRUE;
+		}
+		else if ( isdigit ( c ) )
+		{
+			calculated_number = calculated_number * 10 + c - '0';
+		}
+		else
+		{
+			Close ( op );
+			return WAITFILE_PROTOCOL_ERROR;
+		}
+	}
+}
+
+
+int
+MWFileRC::pack ( const char *bytes, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&bytes[i * stride], CHAR, sizeof(char) );
+	sendList->Append ( (void *)buf );
+	checksum += CHAR;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const float *f, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(f[i * stride]), FLOAT, sizeof(float));
+	sendList->Append ( (void *)buf );
+	checksum += FLOAT;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const double *d, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(d[i * stride]), DOUBLE, sizeof(double) );
+	sendList->Append ( (void *)buf );
+	checksum += DOUBLE;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const int *j, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+    
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(j[i * stride]), INT, sizeof(int) );
+	sendList->Append ( (void *)buf );
+	checksum += INT;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const unsigned int *ui, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = new FileSendBuffer ( (void *)&(ui[i * stride]), UNSIGNED_INT, sizeof(unsigned int) );
+	sendList->Append ( (void *)buf );
+	checksum += UNSIGNED_INT;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const short *sh, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(sh[i * stride]), SHORT, sizeof(short) );
+	sendList->Append ( (void *)buf );
+	checksum += SHORT;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const unsigned short *ush, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(ush[i * stride]), UNSIGNED_SHORT,
+				sizeof(unsigned short) );
+	sendList->Append ( (void *)buf );
+	checksum += UNSIGNED_SHORT;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const long *l, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(l[i * stride]), LONG, sizeof(long) );
+	sendList->Append ( (void *)buf );
+	checksum += LONG;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const unsigned long *ul, int nitem, int stride )
+{
+    int i;
+
+    if ( nitem < 0 ) return -1;
+    if ( nitem == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    for ( i = 0; i < nitem; i++ )
+    {
+	FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)&(ul[i * stride]), UNSIGNED_LONG, 
+						sizeof(unsigned long) );
+	sendList->Append ( (void *)buf );
+	checksum += UNSIGNED_LONG;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::pack ( const char *str )
+{
+    if ( str == NULL ) return -1;
+    if ( strlen(str) == 0 ) return 0;
+
+    if ( sendList == NULL )
+    {
+	MWprintf ( 10, "Didn't do an init send before packing something\n");
+	return -1;
+    }
+
+    FileSendBuffer *buf = 
+		new FileSendBuffer ( (void *)str, STRING, 
+					strlen(str) + 1 );
+    sendList->Append ( (void *)buf );
+    checksum += STRING;
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( char *bytes, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return 0;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != CHAR )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &bytes[i * stride], buf->data, sizeof(char) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( float *f, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != FLOAT )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &f[i * stride], buf->data, sizeof(float) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( double *d, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != DOUBLE )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &d[i * stride], buf->data, sizeof(double) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( int *j, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != INT )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+	memcpy ( &j[i * stride], buf->data, sizeof(int) );
+	delete buf;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( unsigned int *ui, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != UNSIGNED_INT )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &ui[i * stride], buf->data, sizeof(unsigned int) );
+	
+	delete buf;
+    }
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( short *sh, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != SHORT )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &sh[i * stride], buf->data, sizeof(short) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+int
+MWFileRC::unpack ( unsigned short *ush, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != UNSIGNED_SHORT )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &ush[i * stride], buf->data, sizeof(unsigned short) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( long *l, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != LONG )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &l[i * stride], buf->data, sizeof(long) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( unsigned long *ul, int nitems, int stride )
+{
+    int i;
+
+    if ( nitems <= 0 ) return -1;
+
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    for ( i = 0; i < nitems; i++ )
+    {
+	FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+	if ( buf == NULL || buf->type != UNSIGNED_LONG )
+	{
+	    MWprintf ( 20, "Recieve buffer contained something else \n");
+	    recvList->Prepend ( (void *)buf );
+	    return -1;
+	}
+
+	memcpy ( &ul[i * stride], buf->data, sizeof(unsigned long) );
+	
+	delete buf;
+    }
+
+    return 0;
+}
+
+
+int
+MWFileRC::unpack ( char *str )
+{
+    if ( recvList == NULL || recvList->IsEmpty ( ) == TRUE )
+    {
+	MWprintf ( 10, "Trying to unpack before receiving \n" );
+	return -1;
+    }
+
+    FileSendBuffer *buf = (FileSendBuffer *)recvList->Remove();
+    if ( buf == NULL || buf->type != STRING )
+    {
+    	MWprintf ( 20, "Recieve buffer contained something else %d\n", buf->type);
+    	recvList->Prepend ( (void *)buf );
+    	return -1;
+    }
+
+    memcpy ( str, buf->data, sizeof(char) * buf->size );
+
+    delete buf;
+
+    return 0;
+}
+
+
+bool 
+MWFileRC::IsComplete ( int i )
+{
+    char c;
+    char f_name[_POSIX_PATH_MAX];
+
+    int number_calculated = 0;
+    int num = fileWorkers[i].counter;
+
+    sprintf( f_name, "./%s/master_waitfile.%d", output_directory, i );
+
+    FILE *fp = Open ( f_name, "r" );
+    if ( fp == NULL )
+    {
+	return FALSE;
+    }
+
+    while ( fscanf(fp, "%c", &c ) > 0 )
+    {
+	if ( c == OK )
+	{
+	    if ( number_calculated == num )
+	    {
+		Close(fp);
+		return TRUE;
+	    }
+	    else
+		number_calculated = 0;
+	}
+	else if ( c == WRONGINITFILE )
+	{
+		// The process found a wrong init file.
+		// It probably has killed itself. Thus do nothing.
+	}
+	else if ( c == SYNC )
+	{
+	    number_calculated = 0;
+	}
+	else if ( isdigit(c) > 0 )
+	{
+	    number_calculated = number_calculated * 10 + c - '0';
+	}
+    }
+
+    Close(fp);
+    return FALSE;               
+}
+
+
+int
+MWFileRC::handle_finished_worker ( int i )
+{
+    FILE *fp;
+    char filename[_POSIX_PATH_MAX];
+    int typeno;
+
+    fileWorkers[i].served = FILE_RUNNING;
+    sprintf ( filename, "%s/worker_output.%d.%d", output_directory, fileWorkers[i].id, fileWorkers[i].counter );   
+    fp = Open ( filename, "r" );
+    if ( fp == NULL )
+    {
+	MWprintf ( 10, "Couldn't open the worker output file %s for reading: Errno is %d\n", filename, errno );
+	return -1;
+    }
+    fscanf ( fp, "%d %lld ", &msgTag, &checksum );
+
+    while ( fscanf ( fp, "%d ", &typeno ) >= 0 )
+    {
+	FileSendBuffer *buf;
+
+	switch ( typeno )
+	{
+	    case INT:
+		int it1;
+		fscanf ( fp, "%d ", &it1 );
+		buf = new FileSendBuffer ( (void *)&it1, INT, sizeof(int) );
+		if (buf == NULL)
+			MWprintf(30, "MWDEBUG: FileSendBuffer construction failed\n");
+		recvList->Append ( (void *)buf );
+		checksum -= INT;
+		break;
+
+	    case CHAR:
+		char it2;
+		fscanf ( fp, "%c ", &it2 );
+		buf = new FileSendBuffer ( (void *)&it2, CHAR, sizeof(char) );
+		recvList->Append ( (void *)buf );
+		checksum -= CHAR;
+		break;
+
+	    case LONG:
+		long it3;
+		fscanf ( fp, "%ld ", &it3 );
+		buf = new FileSendBuffer ( (void *)&it3, LONG, sizeof(long) );
+		recvList->Append ( (void *)buf );
+		checksum -= LONG;
+		break;
+
+	    case FLOAT:
+		float it4;
+		fscanf ( fp, "%f ", &it4 );
+		buf = new FileSendBuffer ( (void *)&it4, FLOAT, sizeof(float) );
+		recvList->Append ( (void *)buf );
+		checksum -= FLOAT;
+		break;
+
+	    case DOUBLE:
+		double it5;
+		fscanf ( fp, "%lf ", &it5 );
+		buf = new FileSendBuffer ( (void *)&it5, DOUBLE, sizeof(double));
+		if (buf == NULL)
+			MWprintf(30, "MWDEBUG: FileSendBuffer construction failed\n");
+		recvList->Append ( (void *)buf );
+		checksum -= DOUBLE;
+		break;
+
+	    case UNSIGNED_INT:
+		unsigned int it6;
+		fscanf ( fp, "%o ", &it6 );
+		buf = new FileSendBuffer ( (void *)&it6, UNSIGNED_INT, 
+						sizeof(unsigned int));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_INT;
+		break;
+
+	    case SHORT:
+		short it7;
+		fscanf ( fp, "%hd ", &it7 );
+		buf = new FileSendBuffer ( (void *)&it7, SHORT, sizeof(short));
+		recvList->Append ( (void *)buf );
+		checksum -= SHORT;
+		break;
+
+	    case UNSIGNED_SHORT:
+		unsigned short it8;
+		fscanf ( fp, "%ho ", &it8 );
+		buf = new FileSendBuffer ( (void *)&it8, UNSIGNED_SHORT, 
+						sizeof(unsigned short));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_SHORT;
+		break;
+
+	    case UNSIGNED_LONG:
+		unsigned long it9;
+		fscanf ( fp, "%lo ", &it9 );
+		buf = new FileSendBuffer ( (void *)&it9, UNSIGNED_LONG, 
+						sizeof(unsigned long));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_LONG;
+		break;
+
+	    case STRING:
+		{
+		int sz, z;
+		fscanf ( fp, "%d ", &sz );
+		char *it10 = new char[sz+1];
+		for ( z = 0; z < sz; z++ )
+		    fscanf ( fp, "%c", &it10[z] );
+		it10[z] = '\0';
+		buf = new FileSendBuffer ( (void *)it10, STRING, 
+					strlen(it10) + 1);
+		recvList->Append ( (void *)buf );
+		delete []it10;
+		checksum -= STRING;
+		break;
+		}
+
+	    default:
+		MWprintf (10, "Couldn't decipher the data type in receiving\n");
+		MWprintf (10, "Got %d\n", typeno );
+		Close ( fp );
+		return -1;
+		break;
+	}
+    }
+    if ( checksum != 0 )
+    {
+    	// Problem 
+	MWprintf ( 10, "The checksum is not zero in recv\n");
+	while ( recvList->IsEmpty() != TRUE )
+	{
+		FileSendBuffer *buff = (FileSendBuffer *)recvList->Remove();
+		delete buff;
+	}
+
+	FileSendBuffer *newbuf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+	recvList->Append ( (void *)newbuf );
+
+	msgTag = workerEvents[FileChecksumError];
+    }
+    
+    whomRecv = i;
+    Close ( fp );
+    fileWorkers[i].counter++;
+    HardDeleteFile ( filename );
+    return 0;
+}
+
+
+int
+MWFileRC::bufinfo ( int buf_id, int *len, int *tag, int *sending_host )
+{
+    *sending_host = whomRecv;
+    *tag = msgTag;
+    *sending_host = whomRecv;
+    return 0;
+}
+
+int
+MWFileRC::handle_killed_worker ( int i )
+{
+	// We got the info that a worker has been killed.
+	// Inform the upper layer that the worker has disappeared.
+    fileWorkers[i].served = FILE_KILLED;
+
+    FileSendBuffer *buf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+    recvList->Append ( (void *)buf );
+
+    whomRecv = i;
+    msgTag = workerEvents[FileTaskExit];
+
+    // Jeff debugging 
+    MWprintf( 10, "State of killed worker was %d\n",  fileWorkers[i].state );
+
+    if ( fileWorkers[i].state == FILE_SUBMITTED )
+    {
+
+      //XXX HOSTADDDEBUG
+
+    	hostadd_reqs[fileWorkers[i].exec_class]--;
+/*
+	MWprintf( 20, "Substracting from %d hostadd_reqs.  Value %d\n", fileWorkers[i].arch,
+		  hostadd_reqs[fileWorkers[i].arch] );
+
+	submitted_num_workers--;
+    	for ( int j = 0; j < 2 * HOSTINC; j++ )
+    	    if ( hostaddind_reqs[fileWorkers[i].arch][j] == i ) hostaddind_reqs[fileWorkers[i].arch][j] = -1;
+*/
+    }
+/*
+    else
+    	current_num_workers--;
+*/
+
+    fileWorkers[i].state = FILE_FREE;
+    return 0;
+}
+
+int
+MWFileRC::handle_transited_worker ( int i )
+{
+    // int j;
+
+    MWprintf( 10, "Transit event was from worker %d, whose previous state was %d\n", 
+	      i,  fileWorkers[whomRecv].served );
+
+    fileWorkers[i].served = FILE_TRANSIT;
+    FileSendBuffer *buf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+    recvList->Append ( (void *)buf );
+
+    whomRecv = i;
+    msgTag = workerEvents[FileTaskExit];
+
+    if ( fileWorkers[i].state == FILE_SUBMITTED )
+    {
+    	MWprintf ( 10, "How can a transit event happen when I am in submit state\n");
+		hostadd_reqs[fileWorkers[i].exec_class]--;
+    }
+
+	char exe[_POSIX_PATH_MAX];
+	sprintf ( exe, "%s/bin/condor_rm %d.%d", CONDOR_DIR, fileWorkers[i].condorID, fileWorkers[i].condorprocID );
+	system ( exe );
+	fileWorkers[i].state = FILE_FREE;
+
+    return 0;
+}
+
+
+int
+MWFileRC::handle_suspended_worker ( int i )
+{
+	// We got the info from the log file that the worker has been suspended.
+	// Inform the upper layer that this is the case.
+	// No need to change the state of fileWorkers as that has been
+	// modified by the CheckLogFiles.
+
+    fileWorkers[i].served = FILE_SUSPENDED;
+    FileSendBuffer *buf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+    recvList->Append ( (void *)buf );
+
+    whomRecv = i;
+    msgTag = workerEvents[FileTaskSuspend];
+
+    return 0;
+}
+
+
+
+int
+MWFileRC::handle_resumed_worker ( int i )
+{
+	// We got the info from the log file that the worker has been resumed.
+	// Inform the upper layer that this is the case.
+	// No need to change the state of fileWorkers as that has been
+	// modified by the CheckLogFiles.
+
+    fileWorkers[i].state = FILE_RUNNING;
+    fileWorkers[i].served = FILE_RESUMED;
+    FileSendBuffer *buf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+    recvList->Append ( (void *)buf );
+
+    whomRecv = i;
+    msgTag = workerEvents[FileTaskResume];
+
+    return 0;
+}
+
+int
+MWFileRC::handle_executing_worker ( int i )
+{
+    // We got the info that the worker i started executin.
+
+    if ( !(&fileWorkers[i]) )
+    {
+	MWprintf( 10, "How can the corresponding entry in execute worker be null\n");
+	return -1;
+    }
+
+    fileWorkers[i].served = FILE_EXECUTE;
+    fileWorkers[i].state = FILE_RUNNING;
+    FileSendBuffer *buf = new FileSendBuffer ( &fileWorkers[i].id, INT,
+				sizeof(int) );
+    recvList->Append ( (void *)buf );
+
+    whomRecv = fileWorkers[i].id;
+    msgTag = workerEvents[FileHostAdd];
+
+    return 0;
+}
+
+
+int
+MWFileRC::handle_work ( int msgtag )
+{
+	// Called by the worker recv. 
+	// Read the worker_input file and prepare the recvList.
+    FILE *fp;
+    char filename[_POSIX_PATH_MAX];
+    int typeno;
+
+    sprintf ( filename, "%s/worker_input.%d.%d", input_directory, FileRCID,
+				expected_number - 1 );   
+#ifdef USE_CHIRP
+	getFileFromMaster(filename);
+#endif
+    fp = Open ( filename, "r" );
+    if ( fp == NULL )
+    {
+	MWprintf ( 10, "Couldn't open the worker input file %s for reading: errno = %d\n", filename, errno );
+	return CANNOT_OPEN_INPUT_FILE;
+    }
+
+    if ( fscanf ( fp, "%d %lld ", &msgTag, &checksum ) <= 0 ) 
+    {
+    	Close ( fp );
+    	return SCANF_ERROR_ON_INPUT_FILE;
+    }
+
+    if ( msgtag != -1 && msgTag != msgtag ) 
+    {
+	MWprintf( 10, "FileRC wrong message sequence got %d \n", msgTag);
+	Close ( fp );
+	return MESSAGE_SEQUENCE_ERROR;
+    }
+
+    while ( fscanf ( fp, "%d ", &typeno ) > 0 )
+    {
+	FileSendBuffer *buf;
+
+	switch ( typeno )
+	{
+	    case INT:
+		int it1;
+		fscanf ( fp, "%d ", &it1 );
+		buf = new FileSendBuffer ( (void *)&it1, INT, sizeof(int) );
+		recvList->Append ( (void *)buf );
+		checksum -= INT;
+		break;
+
+	    case CHAR:
+		char it2;
+		fscanf ( fp, "%c ", &it2 );
+		buf = new FileSendBuffer ( (void *)&it2, CHAR, sizeof(char) );
+		recvList->Append ( (void *)buf );
+		checksum -= CHAR;
+		break;
+
+	    case LONG:
+		long it3;
+		fscanf ( fp, "%ld ", &it3 );
+		buf = new FileSendBuffer ( (void *)&it3, LONG, sizeof(long) );
+		recvList->Append ( (void *)buf );
+		checksum -= LONG;
+		break;
+
+	    case FLOAT:
+		float it4;
+		fscanf ( fp, "%f ", &it4 );
+		buf = new FileSendBuffer ( (void *)&it4, FLOAT, sizeof(float) );
+		recvList->Append ( (void *)buf );
+		checksum -= FLOAT;
+		break;
+
+	    case DOUBLE:
+		double it5;
+		fscanf ( fp, "%lf ", &it5 );
+		buf = new FileSendBuffer ( (void *)&it5, DOUBLE, sizeof(double));
+		recvList->Append ( (void *)buf );
+		checksum -= DOUBLE;
+		break;
+
+	    case UNSIGNED_INT:
+		unsigned int it6;
+		fscanf ( fp, "%o ", &it6 );
+		buf = new FileSendBuffer ( (void *)&it6, UNSIGNED_INT, 
+						sizeof(unsigned int));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_INT;
+		break;
+
+	    case SHORT:
+		short it7;
+		fscanf ( fp, "%hd ", &it7 );
+		buf = new FileSendBuffer ( (void *)&it7, SHORT, sizeof(short));
+		recvList->Append ( (void *)buf );
+		checksum -= SHORT;
+		break;
+
+	    case UNSIGNED_SHORT:
+		unsigned short it8;
+		fscanf ( fp, "%ho ", &it8 );
+		buf = new FileSendBuffer ( (void *)&it8, UNSIGNED_SHORT, 
+						sizeof(unsigned short));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_SHORT;
+		break;
+
+	    case UNSIGNED_LONG:
+		unsigned long it9;
+		fscanf ( fp, "%lo ", &it9 );
+		buf = new FileSendBuffer ( (void *)&it9, UNSIGNED_LONG, 
+						sizeof(unsigned long));
+		recvList->Append ( (void *)buf );
+		checksum -= UNSIGNED_LONG;
+		break;
+
+	    case STRING:
+		{
+		int sz;
+		fscanf ( fp, "%d ", &sz );
+		char *it10 = new char[sz + 1];
+		it10[sz] = '\0';
+		for ( int z = 0; z < sz; z++ )
+		    fscanf ( fp, "%c", &it10[z] );
+		buf = new FileSendBuffer ( (void *)it10, STRING, 
+					strlen(it10) + 1);
+		recvList->Append ( (void *)buf );
+		delete []it10;
+		checksum -= STRING;
+		break;
+		}
+
+	    default:
+		MWprintf (10, "Couldn't decipher the data type in receiving\n");
+		MWprintf (10, "Got %d\n", typeno );
+		Close ( fp );
+		return UNKNOWN_DATA_TYPE;
+	}
+    }
+    if ( checksum != 0 )
+    {
+    	// Problem 
+	MWprintf ( 10, "The checksum is not zero in recv\n");
+	while ( recvList->IsEmpty() != TRUE )
+	{
+		FileSendBuffer *buff = (FileSendBuffer *)recvList->Remove();
+		delete buff;
+	}
+
+	FileSendBuffer *newbuf = new FileSendBuffer ( &FileRCID, INT,
+				sizeof(int) );
+	recvList->Append ( (void *)newbuf );
+
+	msgTag = CHECKSUM_ERROR;
+    }
+    
+    Close ( fp );
+    HardDeleteFile ( filename );
+    return 0;
+}
+
+
+//---------------------------------------------------------------------------
+// 	MWFileRC::CheckLogFiles():
+//	Sophisticated check log function which never fails to detect any event
+// in the log.
+//---------------------------------------------------------------------------
+void 
+MWFileRC::CheckLogFilesRunning ( )
+{
+#ifdef FILE_MASTER
+    int i;
+    char f_name[_POSIX_PATH_MAX];
+
+    for ( i = 0; i < target_num_workers; i++ ) {
+				//Discuss about this thing.
+			if ( fileWorkers[i].state == FILE_FREE ) continue;
+			int num_event = 0;
+
+			ReadUserLog log;
+			ULogEvent *event;
+			ULogEventOutcome outcome;
+
+			sprintf( f_name, "%s/log_file.%d", control_directory, i );
+
+			FILE *f;
+			if ( (f = fopen( f_name, "r" )) == NULL )
+				{
+					fileWorkers[i].state = FILE_IDLE;
+					fileWorkers[i].event_no = 0;
+					continue;
+				}
+            fclose(f);
+
+			log.initialize ( f_name );
+
+				// Skip over events we've seen before.
+			while( (outcome = log.readEvent(event)) == ULOG_OK)	{
+				num_event++;
+				if ( num_event >= fileWorkers[i].event_no)	{
+					break;
+				}
+				delete event;
+			}
+
+				// If we hit EOF in this userlog, no new events
+			if (outcome != ULOG_OK) {
+				delete event;
+				continue; 
+			}
+
+				// Make sure this event belongs to this job
+			while ( event->cluster != fileWorkers[i].condorID || event->proc != fileWorkers[i].condorprocID )	{
+					MWprintf ( 10, "How can an event belonging to a different cluster be printed here\n");
+					num_event++;
+					fileWorkers[i].event_no++;
+					delete event;
+					outcome = log.readEvent(event);
+					if (outcome != ULOG_OK) {
+						break;
+					}
+			}
+
+			if (outcome != ULOG_OK) {
+				delete event;
+				continue;
+			}
+
+			switch (event->eventNumber) {
+
+				case ULOG_JOB_ABORTED:	
+				case ULOG_JOB_TERMINATED:
+				case ULOG_EXECUTABLE_ERROR:
+					{
+						fileWorkers[i].state = FILE_KILLED;
+						break;
+					}
+
+				case ULOG_SHADOW_EXCEPTION:
+					{
+						fileWorkers[i].state = FILE_TRANSIT;
+						break;
+					}
+				case ULOG_CHECKPOINTED:
+					{
+							//fileWorkers[i].state = FILE_SUSPENDED;
+						break;
+					}
+				case ULOG_SUBMIT:
+					{
+						MWprintf ( 10, "Got a submit event\n"); 
+						fileWorkers[i].state = FILE_SUBMITTED;
+						break;
+					}
+				case ULOG_JOB_EVICTED:
+					{
+						if ( want_checkpointing == 1 )
+							{      
+								JobEvictedEvent *evictEvent = (JobEvictedEvent *)event;
+					
+								if ( evictEvent->checkpointed == TRUE ) 
+									{
+										fileWorkers[i].state = FILE_SUSPENDED;
+										MWprintf ( 10, "Got an evict with checkpoint event from %d\n",i );
+									}
+								else 
+									{
+										fileWorkers[i].state = FILE_TRANSIT;
+									}
+							}
+						else
+							{
+								fileWorkers[i].state = FILE_TRANSIT;
+							}
+
+						break;
+					}	
+				case ULOG_EXECUTE:
+					{
+						if ( fileWorkers[i].state == FILE_SUSPENDED )
+							{
+								MWprintf (10,"In LogFiles gotResumed after suspend %d\n",i);
+								fileWorkers[i].state = FILE_RESUMED;
+							}
+						else if ( fileWorkers[i].state == FILE_SUBMITTED )
+							fileWorkers[i].state = FILE_EXECUTE;
+						else {
+							MWprintf ( 10, "Unexpected state transition to execute from %d in submitfile %s\n", fileWorkers[i].state, f_name );
+							MWprintf ( 10, "Forcing this worker to TRANSIT state\n");
+							fileWorkers[i].state = FILE_TRANSIT;
+						}
+						break;
+					}
+
+				default:
+					{
+						fileWorkers[i].event_no++;
+						break;
+					}
+			}
+			fileWorkers[i].event_no++;
+			delete event;
+	}
+#endif
+}
+
+
+//---------------------------------------------------------------------------
+// MWFileRC::CheckFilesResuscicate ():
+//	Called when recovering from a crash.
+//---------------------------------------------------------------------------
+void 
+MWFileRC::CheckLogFilesResuscicate ( char *f_name, struct FileWorker &fw )
+{
+#ifdef FILE_MASTER
+
+	ReadUserLog log;
+	ULogEvent *event;
+	ULogEventOutcome outcome;
+
+	FILE *f;
+	if ( (f = fopen ( f_name, "r" )) == NULL )
+	{
+		fw.state = FILE_FREE;
+		fw.event_no = 0;
+		return;
+	}
+	fclose(f);
+
+	log.initialize ( f_name );
+
+	outcome = log.readEvent( event );
+	for ( ;  outcome == ULOG_OK ;outcome = log.readEvent( event ) )
+	{
+		if ( event->eventNumber == ULOG_JOB_ABORTED )
+		{
+			fw.state = FILE_KILLED;
+			fw.event_no++;
+			delete event;
+			return;
+		}
+		else if ( event->eventNumber == ULOG_SHADOW_EXCEPTION )
+		{
+			char exe[128];
+			sprintf ( exe, "%s/bin/condor_rm %d.%d", CONDOR_DIR, fw.condorID, fw.condorprocID);
+			system ( exe );
+			fw.state = FILE_KILLED;
+			fw.event_no++;
+			delete event;
+			return;
+		}
+		else if ( event->eventNumber == ULOG_JOB_TERMINATED )
+		{
+			fw.state = FILE_KILLED;
+			fw.event_no++;
+			delete event;
+			return;
+		}
+		else if ( event->eventNumber == ULOG_EXECUTABLE_ERROR )
+		{
+			fw.state = FILE_KILLED;
+			fw.event_no++;
+			delete event;
+			return;
+		}
+		else if ( event->eventNumber == ULOG_CHECKPOINTED )
+		{
+			fw.event_no++;
+			delete event;
+		}
+		else if ( event->eventNumber == ULOG_SUBMIT )
+		{
+			fw.state = FILE_SUBMITTED;
+			fw.event_no++;
+			delete event;
+		}
+		else if ( event->eventNumber == ULOG_JOB_EVICTED )
+		{
+			if ( want_checkpointing == 1 )
+	   		{
+				JobEvictedEvent *evictEvent = (JobEvictedEvent *)event;
+				if ( evictEvent->checkpointed == TRUE ) 
+				{
+					fw.state = FILE_SUSPENDED;
+					fw.event_no++;
+					delete event;
+				}
+				else 
+				{
+					char exe[128];
+					sprintf ( exe, "%s/bin/condor_rm %d.%d", CONDOR_DIR, fw.condorID,
+										fw.condorprocID);
+					system ( exe );
+					fw.state = FILE_KILLED;
+					delete event;
+					break;
+				}
+			}
+			else 	      
+			{
+				char exe[128];
+				sprintf ( exe, "%s/bin/condor_rm %d.%d", CONDOR_DIR, fw.condorID,
+									fw.condorprocID);
+				system ( exe );
+				fw.state = FILE_KILLED;
+				fw.event_no++;
+				delete event;
+			}
+		}
+		else if ( event->eventNumber == ULOG_EXECUTE )
+		{
+			fw.state = FILE_RUNNING;
+			fw.event_no++;
+			delete event;
+		}
+		else
+		{
+			fw.event_no++;
+			delete event;
+		}
+	}
+
+	if ( fw.state == FILE_KILLED )
+	{
+		fw.state = FILE_FREE;
+	}
+
+#endif
+}
+
+
+//---------------------------------------------------------------------------
+// MWFileRC::resuscicate ( )
+// Sanjeev : This is THE function of the whole program. It is this routine that
+// gives MWFileRC that robustness that one can only dream right now.
+// The real Sanjeev : Robustness? You must be Just kidding!!
+//---------------------------------------------------------------------------
+void
+MWFileRC::resuscicate ()
+{
+	int  i;
+	char c[2]; c[1] = '\0';
+	char worker_state_file[_POSIX_PATH_MAX];
+	char master_waitfile[_POSIX_PATH_MAX], worker_waitfile[_POSIX_PATH_MAX];
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		if ( fileWorkers[i].id < 0 ) continue;
+
+		sprintf ( worker_state_file, "%s/log_file.%d", control_directory, fileWorkers[i].id );
+		sprintf ( master_waitfile, "./%s/master_waitfile.%d", output_directory, fileWorkers[i].id );
+		sprintf ( worker_waitfile, "./%s/worker_waitfile.%d", input_directory, fileWorkers[i].id );
+
+		fileWorkers[i].worker_counter = GetWorkerCounter ( worker_waitfile );
+		fileWorkers[i].counter = GetCounter ( master_waitfile );
+		MWprintf ( 10, "The counters of %d are %d and %d and %d\n", i, fileWorkers[i].counter, 
+										fileWorkers[i].worker_counter, fileWorkers[i].condorID );
+
+		CheckLogFilesResuscicate( worker_state_file, fileWorkers[i] );
+	}
+}
+
+//---------------------------------------------------------------------------
+//Master::GetCondorId():
+//      Read the open log file and get the condor cluster of the log file.
+//---------------------------------------------------------------------------
+void
+MWFileRC::GetCondorId ( char *lgfile, int *cID, int *pID )
+{
+#ifdef FILE_MASTER
+
+    ReadUserLog log;
+    ULogEvent *event;
+    ULogEventOutcome outcome;
+
+    log.initialize ( lgfile );
+    outcome = log.readEvent( event );
+    while ( outcome == ULOG_OK && event->eventNumber != ULOG_SUBMIT )
+    {
+	outcome = log.readEvent ( event );
+    }
+
+    if ( outcome != ULOG_OK ) 
+    {
+	*cID = -1;
+	*pID = -1;
+	return;
+    }
+
+    *cID = event->cluster;
+    *pID = event->proc;
+    return;
+#endif
+    return;
+}
+
+
+void
+MWFileRC::sort_exec_class_ratio ( int *temp )
+{
+	int i, j;
+	double ii, jj;
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		temp[i] = i;
+	}
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		for ( j = i + 1; j < exec_classes; j++ )
+		{
+			ii = ((double)MW_exec_class_num_workers[temp[i]]) / exec_class_target_num_workers[temp[i]];
+			jj = ((double)MW_exec_class_num_workers[temp[j]]) / exec_class_target_num_workers[temp[j]];
+			if ( jj > ii )
+			{
+				int temp = j;
+				j = i;
+				i = temp;
+			}
+		}
+	}
+	return;
+}
+
+//---------------------------------------------------------------------------
+// hostaddlogic():
+//	If the number of workers are less than the target number of workers 
+// just spawns the remaining. current_num_workers holds the information about the
+// the current number of workers.
+//---------------------------------------------------------------------------
+int
+MWFileRC::hostaddlogic ( int *num_workers )
+{
+	/* This awfully complex function determines the conditions
+	under which it being called, and then calls condor_submit
+	asking for the correct number of hosts.
+
+	- num_workers - an array of size exec_classes that contains
+	the number of workers in each arch class.
+	- hostadd_reqs: The number of outstanding HOSTADDs out there
+	- target_num_workers: Set by the user...
+	*/
+
+	MWprintf ( 10, "In hostaddlogic \n" );
+	if ( !hostadd_reqs ) 
+	{
+		/* if this doesn't exist yet, we won't do anything */
+		return 0; 
+	}       
+
+	/* number of hosts to ask for at a time. The idea is that we'll
+	have double this outstanding at a time - and this amounts
+	to 12 for 1, 2, or 3 arch classes. */
+	int i;          
+	int *sorted_order = new int [exec_classes];
+	int *num_execs = new int[exec_classes];
+	int cur;
+	int req;
+	sort_exec_class_ratio ( sorted_order );
+	int status;
+                        
+	MWprintf ( 60, "hal: target: %d.\n", target_num_workers );
+
+	int HOSTINC = hostinc_;
+
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		cur = sorted_order[i];
+		if ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] >= exec_class_target_num_workers[cur] ) continue;
+		if ( hostadd_reqs[cur] > 0 ) continue;
+		if ( exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] ) > HOSTINC )
+			req = HOSTINC;
+		else
+		       req = exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] );
+		status = do_spawn ( req, cur );
+		if ( status > 0 )
+		{
+			MWprintf ( 10, "Added %d workers of exec_class %d\n", req, i );
+			hostadd_reqs[cur] += status;
+		}
+		else
+		{
+			MWprintf ( 10, "ERROR!! Failed to submit workers of exec_class %d\n", i );
+		}
+	}
+
+	write_RMstate ( );
+
+	delete [] sorted_order;
+	delete [] num_execs;
+	return 0;
+}
+
+
+//---------------------------------------------------------------------------
+// GetWorkerCounter ():
+//	Gets the next message to be sent to the worker.
+//---------------------------------------------------------------------------
+int 
+MWFileRC::GetWorkerCounter ( char *file )
+{
+    int cal = 0;
+    int task_num = 0; 
+    char c[2]; c[1] = '\0';
+    bool end = FALSE;
+    bool first = TRUE;
+
+    if ( !file ) return 0;
+
+    FILE *fp = Open ( file, "r" );
+    if ( fp == NULL ) return 0;
+
+    while ( fscanf(fp, "%c", &c[0] ) >= 0 )
+    {
+	if ( isdigit ( c[0] ) > 0 )
+	{
+	    cal = cal * 10 + atoi(c);
+	    end = FALSE;
+	}
+	else if ( isspace(c[0]) > 0 )
+	{
+	}
+	else if ( c[0] == OK )
+	{
+	    task_num = cal;
+	    cal = 0;
+	    end = TRUE;
+	    first = FALSE;
+	}
+	else if ( c[0] == SYNC || c[0] == ESYNC )
+	{
+	    cal = 0;
+	    end = TRUE;
+	}
+    }
+    Close ( fp );
+    if ( first == TRUE ) return 0;
+    if ( end == TRUE ) 
+    {
+	return task_num + 1;
+    }
+    else 
+    {
+	return task_num;
+    }
+}
+
+
+
+//---------------------------------------------------------------------------
+// GetCounter ():
+//	Gets the next message to be received from the worker.
+//---------------------------------------------------------------------------
+int 
+MWFileRC::GetCounter ( char *file )
+{
+
+	char c[2]; c[1] = '\0';
+	int num_cal = 0;
+	int task_num = 0;
+	bool end = TRUE;
+
+	FILE *fp = Open ( file, "r" );
+	if ( !fp ) return 0;
+
+	while ( fscanf(fp, "%c", &c[0] ) >= 0 )
+    {
+		if ( isdigit ( c[0] ) > 0 )
+		{
+			num_cal = num_cal * 10 + atoi(c);
+			end = FALSE;
+		}
+		else if ( c[0] == OK )
+		{
+			task_num = num_cal;
+			num_cal = 0;
+			end = TRUE;
+		}
+	}
+	Close ( fp );
+	
+	if ( end ) return task_num + 1;
+	else return task_num;
+}
+
+
+void
+MWFileRC::killWorker ( int i )
+{
+    char exe[_POSIX_PATH_MAX];
+    MWprintf ( 10, "Killing condor job %d.%d\n", fileWorkers[i].condorID,
+    						fileWorkers[i].condorprocID );
+    sprintf ( exe, "%s/bin/condor_rm %d.%d", CONDOR_DIR, fileWorkers[i].condorID,
+						fileWorkers[i].condorprocID);
+    system ( exe );
+}
+
+
+void
+MWFileRC::InitStructures ( )
+{
+	int i;
+
+	fileWorkers = new struct FileWorker[target_num_workers];
+
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		fileWorkers[i].state = FILE_FREE;
+		fileWorkers[i].served = -1;
+		fileWorkers[i].event_no = 0;
+		fileWorkers[i].id = -1;
+	}
+
+	hostadd_reqs = new int[exec_classes];
+	for ( i = 0; i < exec_classes; i++ )
+		hostadd_reqs[i] = 0;
+}
+
+
+// Here you have to resuscicate and fill in the appropriate structures
+// By This time target_num_workers has been filled up.
+// We should not touch target_num_workers. All things go into current_num_workers.
+int
+MWFileRC::read_RMstate ( FILE *fp )
+{
+	int i, temp;
+	int temp1, temp2, temp3, temp4;
+	char target_file[_POSIX_PATH_MAX];
+
+	sprintf ( target_file, "%s/%s", control_directory, moment_worker_file );
+
+	
+	FILE *numwf = Open ( target_file, "r" );
+	if ( numwf == NULL )
+	{
+		MWprintf ( 10, "Coudn't open the moment_worker_file for reading\n");
+		InitStructures ( );
+		return 0;
+	}
+
+	if ( fscanf ( numwf, "%d %d", &temp, &subId ) < 0 )
+	{
+		MWprintf (10, "Was unable to read the moment worker file\n");
+		InitStructures ( );
+		Close ( numwf );
+		return 0;
+	}
+
+	if ( temp != target_num_workers )
+	{
+		MWprintf ( 10, "Something wrong with the target_num_workers\n");
+		if ( temp > target_num_workers )
+			target_num_workers = temp;
+	}
+
+	InitStructures ( );
+
+	while ( fscanf ( numwf, "%d %d %d %d ", &temp1, &temp2, &temp3, &temp4 ) > 0 )
+	{
+		if ( temp1 > target_num_workers )
+		{
+			MWprintf ( 10, "ERROR!! Some Big Time Screwup, how can id be greater than target_num_workers\n");
+			::exit(1);
+		}
+		fileWorkers[temp1].id = temp1;
+		fileWorkers[temp1].condorID = temp2;
+		fileWorkers[temp1].condorprocID = temp3;
+		fileWorkers[temp1].exec_class = temp4;
+	}
+
+    Close ( numwf );
+
+	resuscicate();
+
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		if ( fileWorkers[i].state == FILE_SUBMITTED )
+			hostadd_reqs[fileWorkers[i].exec_class]++;
+	}
+
+    return 0;
+}
+
+
+int
+MWFileRC::write_RMstate ( FILE *filp )
+{
+	int i;
+	FILE *fp;
+	char target_file[_POSIX_PATH_MAX];
+	char cmd[4 * _POSIX_PATH_MAX];
+    
+	sprintf ( target_file, "%s/%s", control_directory, moment_worker_file );
+	
+	fp = Open ( "temp_File", "w" );
+	if  ( fp == NULL )
+	{
+		MWprintf ( 10, "Cannot open the file temp_File for writing\n");
+		return -1;
+	}
+
+//	fprintf ( fp, "%d %d ", max_num_workers, subId );
+	fprintf ( fp, "%d %d ", target_num_workers, subId );
+
+	for ( i = 0; i < exec_classes; i++ )
+	{
+//		fprintf ( fp, "%d ", hostadd_reqs[i] );
+		for ( int j = 0; j < target_num_workers; j++ )
+		{
+			if ( fileWorkers[j].state != FILE_FREE && fileWorkers[j].exec_class == i )
+				fprintf ( fp, "%d %d %d %d ", j, fileWorkers[j].condorID, fileWorkers[j].condorprocID, fileWorkers[j].exec_class );
+		}
+/*
+		for ( int j = 0; j < 2 * HOSTINC; j++ )
+			if ( hostaddind_reqs[i][j] != -1 ) 
+				fprintf ( fp, "%d ", hostaddind_reqs[i][j] );
+*/
+	}
+
+	Close ( fp );
+
+	sprintf ( cmd, "mv temp_File %s", target_file );
+//	if ( rename ( "temp_File", target_file ) < 0 )
+	if ( system ( cmd ) < 0 )
+	{
+		MWprintf (10, "Could not move the new RM_status file %d\n", errno);
+		return -1;
+	}
+
+	return 0;
+}
+
+char*
+MWFileRC::process_executable_name ( char *exec, int ex_cl, int ar_cl )
+{
+	int i;
+	char newstring[_POSIX_PATH_MAX];
+	char arch[100], opsys[100];
+	char *index;
+	char *req = arch_class_attributes[ar_cl];
+	char *newexec = new char[_POSIX_PATH_MAX];
+	char exe[4 * _POSIX_PATH_MAX];
+	strcpy ( newstring, req );
+	sprintf ( newexec, "mw_exec%d", ex_cl );
+
+	for ( unsigned i = 0; i < strlen ( newstring ); i++ )
+	{
+		int k = newstring[i];
+		if( ! ( ( k == 'u' || k == 'x' ) && newstring[i-1] == '4' ) ) 
+		{
+			k = toupper(k);
+		}
+		newstring[i] = k;
+	}
+
+    i = 0;
+    index = strstr ( newstring, "OPSYS" );
+    index += 5;
+    while ( *index == ' ' || *index == '=' || *index == '"' || *index == '\\' ) index++;
+    while ( *index != ')' && *index != '"' && *index != '\\' ) opsys[i++] = *index++;
+    opsys[i] = '\0';
+
+    i = 0;
+    index = strstr ( newstring, "ARCH" );
+    index += 4;
+    while ( *index == ' ' || *index == '=' || *index == '"' || *index == '\\' ) index++;
+    while ( *index != ')' && *index != '"' && *index != '\\' ) arch[i++] = *index++;
+    arch[i] = '\0';
+
+    sprintf ( newexec, "%s.%s.%s", newexec, opsys, arch );
+    remove ( newexec );
+
+    MWprintf ( 10, "Making a link from %s to %s\n", exec, newexec );
+#ifdef WINDOWS
+    sprintf ( exe, "copy %s %s", exec, newexec );
+#else
+    sprintf ( exe, "ln -s %s %s", exec, newexec );
+#endif
+    system ( exe );
+
+    return newexec;
+}
+
+//BUFFER
+int 
+MWFileRC::recv_all( int from_whom, int msgtag )
+{
+	MWprintf(91, "Not implemented yet for MW-File.\n");
+	return 0;
+}
+
+int 
+MWFileRC::setrbuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-File.\n");
+	return -1;
+}
+
+int 
+MWFileRC::freebuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-File.\n");
+	return -1;
+}
+
+MWList<void> * 
+MWFileRC::recv_buffers()
+{
+	MWprintf(91, "Not implemented yet for MW-File.\n");
+	return NULL;
+}
+
+int 
+MWFileRC::next_buf()
+{
+	MWprintf(91, "Not implemented yet for MW-File.\n");
+	return -1;
+}
+	
+
+
+int
+MWFileRC::sendFileToMaster(char *filename) {
+#ifdef USE_CHIRP
+#ifndef FILE_MASTER
+	struct chirp_client *client;
+
+		// We connect each time, so that we don't have thousands
+		// of idle connections hanging around the master
+	MWprintf(60, "Sending %s to master\n", filename);
+	client = chirp_client_connect_default();
+	if (!client) {
+		MWprintf(10, "MWFileRC:sendFileToMaster cannot chirp_connect to master, exitting\n");
+		exit(-1);
+	}
+
+	FILE *rfd = ::fopen(filename, "r");
+	if (rfd == NULL) {
+		chirp_client_disconnect(client);
+		MWprintf(10, "MWFileRC:sendFileToMaster can't open filename %s:%s\n", filename, strerror(errno));
+		return -1;
+	}
+
+	int wfd = chirp_client_open(client, filename, "cwat", 0777);
+	if (wfd < 0) {
+		::fclose(rfd);
+		chirp_client_disconnect(client);
+		MWprintf(10, "MWFfileRC:sendFileToMaster can't chirp_client_open %s:%d\n", filename, wfd);
+		return -1;
+	}
+
+	char buf[1024];
+
+	int num_read = 0;
+	do {
+		num_read = ::fread(buf, 1, 1024, rfd);
+		if (num_read < 0) {
+			fclose(rfd);
+			chirp_client_close(client, wfd);
+			chirp_client_disconnect(client);
+			MWprintf(10, "MWFileRC:sendFileToMaster local read error on %s\n", filename);
+			return -1;
+		}
+		int num_written = chirp_client_write(client, wfd, buf, num_read);
+		if (num_written != num_read) {
+			fclose(rfd);
+			chirp_client_close(client, wfd);
+			chirp_client_disconnect(client);
+			MWprintf(10, "MWFileRC:sendFileToMaster couldn't chirp_write as much as we read\n");
+			return -1;
+		}
+
+	} while (num_read == 1024);
+
+	::fclose(rfd);
+	chirp_client_close(client, wfd);
+	chirp_client_disconnect(client);
+		
+#endif
+#endif
+	return 0;
+}
+
+int
+MWFileRC::getFileFromMaster(char *filename) {
+#ifdef USE_CHIRP
+#ifndef FILE_MASTER
+	struct chirp_client *client = 0;
+
+	MWprintf(60, "Fetching %s from master\n", filename);
+
+		// We connect each time, so that we don't have thousands
+		// of idle connections hanging around the master
+
+	client = chirp_client_connect_default();
+	if (!client) {
+		MWprintf(10, "MWFileRC:getFileFromMaster cannot chirp_connect to master, waiting\n");
+		return -1;
+	}
+
+	int rfd = chirp_client_open(client, filename, "r", 0);
+	if (rfd < 0) {
+		MWprintf(10, "MWFileRC:getFileFromMaster can't chirp_client_open %s:%d\n", filename, rfd);
+		chirp_client_disconnect(client);
+		return -1;
+	}
+
+	FILE *wfd = ::fopen(filename, "w+");
+	if (wfd == NULL) {
+		MWprintf(10, "MWFileRC:getFileFromMaster can't open filename %s: %s\n", filename, strerror(errno));
+		chirp_client_close(client, rfd);
+		chirp_client_disconnect(client);
+		return -1;
+	}
+
+
+	char buf[1024];
+
+	int num_read = 0;
+	do {
+		num_read = chirp_client_read(client, rfd, buf, 1024);
+		if (num_read < 0) {
+			MWprintf(10, "MWFileRC:getFileFromMaster couldn't chirp_read\n");
+			::fclose(wfd);
+			chirp_client_close(client, rfd);
+			chirp_client_disconnect(client);
+			return -1;
+		}
+
+		int num_written = fwrite(buf, 1, num_read, wfd);
+		if (num_written < 0) {
+			MWprintf(10, "MWFileRC:GetFileFromMaster local read error on %s\n", filename);
+			::fclose(wfd);
+			chirp_client_close(client, rfd);
+			chirp_client_disconnect(client);
+			return -1;
+		}
+
+	} while (num_read == 1024);
+
+	::fclose(wfd);
+	chirp_client_close(client, rfd);
+	chirp_client_disconnect(client);
+	return 0;
+#endif
+#endif
+	return 0;
+
+}
+
diff --git a/MW/src/RMComm/MW-File/MWFileRC.h b/MW/src/RMComm/MW-File/MWFileRC.h
new file mode 100644
index 0000000..c69df89
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileRC.h
@@ -0,0 +1,397 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWFILERC_H
+#define MWFILERC_H
+
+#include "../MWRMComm.h"
+#include "MWFileWorker.h"
+#include "MWList.h"
+#include <stdio.h>
+#include <string.h>
+
+/** 
+	A Resource Management and Communication class that uses Condor 
+	for underlying support of resource managament. Some crude inter-process 
+	communication is provided using the userlog feature of Condor.
+	resource management.
+*/
+
+
+enum FileRCEvents 
+{
+	FileHostDelete,		/* Not yet implemented */
+	FileHostAdd,		/* Host gets added */
+	FileTaskExit,		/* Task has exited */
+	FileTaskSuspend,	/* Task has been suspended */
+	FileTaskResume,		/* Task resumed */
+	FileChecksumError,	/* Checksum error */
+	FileNumEvents		/* Number of events */
+};
+
+class MWFileRC : public MWRMComm
+{
+
+	public:
+
+		///  Constructor 
+		MWFileRC( bool val, int id );
+
+		///  Destructor 
+		~MWFileRC() {};
+
+		/**  A function that inits some internal structures */
+		void InitStructures ( );
+
+		/** @name A. Resource Management Routines
+
+		Here we implement the pure virtual functions found in 
+		ur parent class, MWRMComm.
+		*/
+		//@{
+
+		/**  Initialises. Depending on whether it is master or worker instance
+		     it initializes all the internal variables. */
+		int setup ( int argc, char *argv[], int *mytid, int *mastertid );
+
+		/**  Shutdown. Kills all the workers if it is master */
+		void exit ( int exitval );
+
+		/**  Initialize workers if already some have started up */
+		int init_beginning_workers ( int *nworkers, MWWorkerID ***workers );
+
+		/** Restart function */
+		int restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg );
+
+		/**  This function is actually a misonomer. It DOES NOT spawn a new
+		     worker. Rather it just inits the structure that is passed on to 
+		     it */
+		int start_worker ( MWWorkerID *w );
+
+		/**  This function removes a existing worker */
+		int removeWorker ( MWWorkerID *w );
+
+		/**  Figure out whether or not to generate a new worker depending on
+		     whether new requests have been made */
+		int hostaddlogic ( int *w );
+
+		/** A routine for reading in the MW-File state at the time 
+		 *  of checkpointing.
+		 */
+		int read_RMstate ( FILE *fp = NULL );
+
+		/** A routine for writing in the MW-File state at the time 
+		 *  of checkpointing.
+		 */
+		int write_RMstate ( FILE *fp = NULL );
+
+		char* process_executable_name ( char *execut, int, int );
+
+		//@}
+
+		/** @name B. Communication Routines
+
+			Unlike MWPvmRC, the communication routines are non-trivial 
+			because Condor provides no inter-process comminucation.
+			Thus we use files for communication. So a send is essentially
+			a file write operation and a recv is a file-read operation.
+			We maintain 2 lists:- The sendList and recvList for taking 
+			care of what is to be written/read to/from the files. As in
+			pvm a user beings by calling initsend which creates a new list.
+			Calls to pack insert into the list what is being packed. And
+			finally a send writes the entire thing into a file 
+			identified by the destination. Corresponding things happpen
+			in recv.
+		*/
+		//@{
+
+		/**	A Function called to know which worker had an exception event */
+		void who ( int *wh );
+
+		/**  Initialize the send buffer */
+		int initsend ( int useless = 0 );
+	
+		/**  Send function */
+		int send ( int toWhom, int msgtag );
+	
+		/**  Recv function */
+		int  recv ( int fromWhom, int msgtag );
+	
+		/** Non-blocking version of Recv */
+		int nrecv (int fromWhom, int msgtag);
+
+		/**  Get some info about the recv buffer */
+		int bufinfo ( int buf_id, int *len, int *tag, int *sending_host );
+	
+		/// pack some bytes
+		int pack ( const char *bytes, int nitem, int stride = 1 );
+	
+		/// float
+		int pack ( const float *f, int nitem, int stride = 1 );
+	
+		/// double
+		int pack ( const double *d, int nitem, int stride = 1 );
+	
+		/// int
+		int pack ( const int *i, int nitem, int stride = 1 );
+	
+		/// unsigned int
+		int pack ( const unsigned int *ui, int nitem, int stride = 1 );
+	
+		/// short
+		int pack ( const short *sh, int nitem, int stride = 1 );
+	
+		/// unsigned short
+		int pack ( const unsigned short *ush, int nitem, int stride = 1 );
+	
+		/// long
+		int pack ( const long *l, int nitem, int stride = 1 );
+	
+		/// unsigned long
+		int pack ( const unsigned long *ul, int nitem, int stride = 1 );
+	
+		/// string
+		int pack ( const char  *str );
+	
+		/// Unpack some bytes
+		int unpack ( char *bytes, int nitem, int stride = 1 );
+	
+		/// float
+		int unpack ( float *f, int nitem, int stride = 1 );
+	
+		///double
+		int unpack ( double *d, int nitem, int stride = 1 );
+	
+		/// int
+		int unpack ( int *i, int nitem, int stride = 1 );
+	
+		/// unsigned int
+		int unpack ( unsigned int *ui, int nitem, int stride = 1 );
+	
+		/// short
+		int unpack ( short *sh, int nitem, int stride = 1 );
+	
+		/// unsigned short
+		int unpack ( unsigned short *ush, int nitem, int stride = 1 );
+	
+		/// long
+		int unpack ( long *l, int nitem, int stride = 1 );
+	
+		/// unsigned long
+		int unpack ( unsigned long *ul, int nitem, int stride = 1 );
+	
+		/// string
+		int unpack ( char  *str );
+	
+		//@}
+
+	private:
+
+		/** @name Internal event processing functions */
+
+		//@{
+
+		/**	Handle a message from the worker */
+		int handle_finished_worker ( int i );
+
+		/**	Is Called when a host is resumed */
+		int handle_resumed_worker ( int i );
+
+		/**	Is Called when a host is suspended */
+		int handle_suspended_worker ( int i );
+
+		/**	Is Called when a task is dead */
+		int handle_killed_worker ( int i );
+
+		/** Called when the worker starts executing first */
+		int handle_executing_worker( int i );
+
+		/**	Called in no_checkpoint mode */
+		int handle_transited_worker( int i );
+
+		/**	Is called when the worker detects that the master has 
+		 * come up
+		 */
+		int handle_master_executing ();
+
+		/**	Is Called when a message is received by the worker. */
+		int handle_work ( int msgtag );
+
+		//@}
+
+		/**	@name Checkpoint Files processing functions. */
+
+		//@{
+
+		/**	Always get the last result */
+		void CheckLogFilesRunning ( );
+
+		/**	Determine whether worker i has sent a message */
+		bool IsComplete ( int i );
+
+		/**	Is Called when we are recovering from a crash */
+		void CheckLogFilesResuscicate ( char *, struct FileWorker& );
+
+		//@}
+
+		/** @name Functions used upon restart */
+
+		//@{
+
+		/**	The main resuscicate function */
+		void resuscicate ( );
+
+		/** 	The helping routine for resuscicate */
+		int GetWorkerCounter ( char *file );
+
+		/**	Another helping routine */
+		int GetCounter ( char *file1 );
+
+		/**	Find the condor_ID of the worker with this log file */
+		void GetCondorId ( char *lgfile, int *cId, int *pId );
+
+		//@}
+
+		/** @name Internal worker management functions */
+
+		//@{
+
+		/**	Create workers, basically do a condor_submit */
+		int do_spawn ( int numworkers, int arch );
+
+		/**	Kill a worker */
+		void killWorker ( int i );
+
+		//@}
+
+		
+		/** if using CHIRP IO, send a file */
+		int sendFileToMaster( char *filename);
+
+		/** if using CHIRP IO, get a file */
+		int getFileFromMaster( char *filename);
+
+	/**	Master receive */
+	int master_recv ( int fromWhom, int msgtag );
+
+	/**	Worker receive */
+	int worker_recv ( int fromWhom, int msgtag );
+
+	void sort_exec_class_ratio ( int *);
+
+
+	/**	The bool indicates the mode of the RC instance 
+	 *  a true value means that it is a master and a false means that 
+	 * it is a worker.
+	 *  We need to make it a tristate as somtimes an RC can be both
+	 *  a master and a worker.
+	 */
+	bool isMaster;
+
+	/**	The value is the id that the worker gets. For master it is
+	 * of no use.
+	 */
+	int FileRCID;
+
+	/**	The expected number of the next message */
+	int expected_number;
+
+	/**	The expected_number of the next message that the master is
+	 * expecting 
+	 */
+	int master_expected_number;
+
+	/**	The directory where all the workers have to send their output */
+	char output_directory[256];
+
+	/**	The directory where the master has to send the work */
+	char input_directory[256];
+
+	/**	The control directory the master reads for all resource 
+	 *   management functions.
+	 */
+	char control_directory[256];
+
+	/**	The file in the control directory that will contain the momentary
+	 *  number of workers. 
+	 */
+	char moment_worker_file[256];
+
+	/**  An array of the number of workers */
+	struct FileWorker *fileWorkers;
+
+	/**  A list of all the items that are sent in a send after a series of 
+	 *   packs.
+	 */
+	MWList<void> *sendList;
+
+	/**  A list of all the items that are received */
+	MWList<void> *recvList;
+
+	/**  This is a variable that keeps the cycle in effect. The receive
+	 * of ours goes in cycles to ensure fairness to the messages from all
+	 * the slaves.
+	 */
+	int cyclePosition;
+
+	/**  This determines with what frequency should we check the log files
+	 */
+	int CHECKLOG_FREQ;
+
+	/**  This keeps the track of how many cycles were made.
+	 */
+	int turnNo;
+
+	/**  The tag of the message that just came in	*/
+	int msgTag;
+
+	/**  The message came from whom 	*/
+	int whomRecv;
+
+	int SIMUL_SEND;
+
+	/**  A variable to keep track of submit files */
+	int subId;
+
+	/**  A variable array keeping track of how many have been requested */
+	int *hostadd_reqs;
+
+	/**  The checksum calculated */
+	long long checksum;
+
+	/**  The worker timeout in minutes */
+	long worker_timeout;
+
+	/** The non-blocking recv() functions */
+	public:
+		int	recv_all( int from_whom, int msgtag );	// returns the number of new buffers
+		int 	setrbuf(int bid);		// switch the active receive buffer
+							// return the old active buf_id
+		int	freebuf(int bid);		// free the receive buffer.
+		MWList<void> * recv_buffers();			// return the recv_buf_list
+		int 	next_buf();			// advance the active buffer to the next valid buffer 
+							// in the recv_buf_list.
+
+};
+#endif
+
diff --git a/MW/src/RMComm/MW-File/MWFileRCSymbol.h b/MW/src/RMComm/MW-File/MWFileRCSymbol.h
new file mode 100644
index 0000000..1d7cd57
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileRCSymbol.h
@@ -0,0 +1,37 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWFILERCSYMBOL_H
+#define MWFILERCSYMBOL_H
+
+// This file lists all the symbols that have been used in the wait files.
+
+#define OK '$'
+
+#define WRONGINITFILE '@'
+
+#define SYNC '^'
+
+#define ESYNC '!'
+
+#endif
diff --git a/MW/src/RMComm/MW-File/MWFileSend.h b/MW/src/RMComm/MW-File/MWFileSend.h
new file mode 100644
index 0000000..5fad478
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileSend.h
@@ -0,0 +1,58 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWFILESEND_H
+#define MWFILESEND_H
+
+#include "MWFileTypes.h"
+#include <stdlib.h>
+#include <string.h>
+
+class FileSendBuffer
+{
+  public:
+	FileType type;
+	void *data;
+	int size;
+
+	FileSendBuffer ( void *dt, FileType tp, int sz )
+	{
+	    int siz;
+	    if ( tp == STRING ) 
+		siz = sizeof(char) * sz;
+	    else
+		siz = sz;
+
+	    data = (void *) malloc ( siz );
+	    memcpy ( data, dt, siz );
+	    type = tp;
+	    size = sz;
+	}
+
+	~FileSendBuffer ( )
+	{
+	    if ( data != NULL ) free(data);
+	}
+};
+#endif
+
diff --git a/MW/src/RMComm/MW-File/MWFileTypes.h b/MW/src/RMComm/MW-File/MWFileTypes.h
new file mode 100644
index 0000000..eab83ba
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileTypes.h
@@ -0,0 +1,42 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWFILETYPES_H
+#define MWFILETYPES_H
+
+enum FileType
+{
+	INT,
+	CHAR,
+	LONG,
+	FLOAT,
+	DOUBLE,
+	UNSIGNED_INT,
+	SHORT,
+	UNSIGNED_SHORT,
+	UNSIGNED_LONG,
+	STRING,
+	NUM_FILE_TYPES
+};
+#endif
+
diff --git a/MW/src/RMComm/MW-File/MWFileWorker.h b/MW/src/RMComm/MW-File/MWFileWorker.h
new file mode 100644
index 0000000..9d4b42c
--- /dev/null
+++ b/MW/src/RMComm/MW-File/MWFileWorker.h
@@ -0,0 +1,68 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWFILEWORKER_H
+#define MWFILEWORKER_H
+
+enum FileWorkerState
+{ 
+    FILE_FREE,
+    FILE_SUBMITTED,
+    FILE_EXECUTE,	// Started executing for the first time.
+    FILE_RUNNING, 
+    FILE_KILLED, 
+    FILE_SUSPENDED,
+    FILE_RESUMED,
+    FILE_IDLE,
+    FILE_TRANSIT,
+};
+
+
+struct FileWorker
+{
+    int id;
+
+    // What is the message number that I have to look next for.
+    int counter;
+
+    // What is the message that the worker is looking for.
+    int worker_counter;
+
+    // What is the condor_id of the worker.
+    int condorID;
+
+    // What is the proc id.
+    int condorprocID;
+
+    FileWorkerState state;
+
+    int arch;
+
+    int event_no;
+
+    /** What was last served */
+    int served;
+
+	int exec_class;
+};
+
+#endif
diff --git a/MW/src/RMComm/MW-File/Makefile.in b/MW/src/RMComm/MW-File/Makefile.in
new file mode 100644
index 0000000..65c2a5e
--- /dev/null
+++ b/MW/src/RMComm/MW-File/Makefile.in
@@ -0,0 +1,143 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS =
+
+# Libraries to be built, and dependent source files
+LIBRARIES = libMWfileworker.a libMWfilemaster.a
+libMWfilemaster_a_SOURCES = MWFileRCM.ii 
+libMWfilemaster_a_LIBADD = MWFileRCM.o 
+libMWfilemaster_a_DEPENDENCIES =  MWFileRCM.o 
+libMWfilemaster_a_OBJECTS =
+
+libMWfileworker_a_SOURCES = MWFileRCW.ii chirp_client.c
+libMWfileworker_a_LIBADD = MWFileRCW.o chirp_client.o
+libMWfileworker_a_DEPENDENCIES =  MWFileRCW.o chirp_client.o
+libMWfileworker_a_OBJECTS = 
+
+INCLUDES = -I. -I.. -I../.. -I$(CONDOR_DIR)/include $(MEASURE_DEFN)
+INCLUDEFILES = MWFileRC.h MWFileSend.h MWFileTypes.h MWFileWorker.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+
+libMWfilemaster.a: $(libMWfilemaster_a_OBJECTS) $(libMWfilemaster_a_DEPENDENCIES)
+	-rm -f libMWfilemaster.a
+	$(AR) cru libMWfilemaster.a $(libMWfilemaster_a_OBJECTS) $(libMWfilemaster_a_LIBADD)
+	$(RANLIB) libMWfilemaster.a
+	cp libMWfilemaster.a $(MW_LIBDIR) 
+
+libMWfileworker.a: $(libMWfileworker_a_OBJECTS) $(libMWfileworker_a_DEPENDENCIES)
+	-rm -f libMWfileworker.a
+	$(AR) cru libMWfileworker.a $(libMWfileworker_a_OBJECTS) $(libMWfileworker_a_LIBADD)
+	$(RANLIB) libMWfileworker.a
+	cp libMWfileworker.a $(MW_LIBDIR)
+
+MWFileRCM.ii:MWFileRC.C
+	$(CXX) -E $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DFILE_MASTER MWFileRC.C > MWFileRCM.ii
+
+MWFileRCM.o:MWFileRCM.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DFILE_MASTER MWFileRCM.ii
+
+MWFileRCW.ii:MWFileRC.C
+	$(CXX) -E $(DEFS) $(MISC_DEFN) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWFileRC.C > MWFileRCW.ii
+
+MWFileRCW.o:MWFileRCW.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWFileRCW.ii
+
+chirp_client.o: chirp_client.c
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) chirp_client.c
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.ii *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.ii *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
+
diff --git a/MW/src/RMComm/MW-File/chirp_client.c b/MW/src/RMComm/MW-File/chirp_client.c
new file mode 100644
index 0000000..a219976
--- /dev/null
+++ b/MW/src/RMComm/MW-File/chirp_client.c
@@ -0,0 +1,623 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/*
+Chirp C Client
+
+This public domain software is provided "as is".  See the Chirp License
+for details.
+*/
+
+#include "chirp_protocol.h"
+#include "chirp_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include <unistd.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+static int tcp_connect( const char *host, int port );
+static void chirp_fatal_request( const char *name );
+static void chirp_fatal_response();
+static int get_result( FILE *s );
+static int convert_result( int response );
+static int simple_command(struct chirp_client *c,char const *fmt,...);
+static void vsprintf_chirp(char *command,char const *fmt,va_list args);
+static char const *read_url_param(char const *url,char *buffer,size_t length);
+
+
+struct chirp_client {
+	FILE *stream;
+};
+
+/*
+  chirp_client_connect_url()
+
+  Sets path_part to the position of the start of the path information
+  in the URL and connects to the specified Chirp server.
+
+  URL format:
+    chirp:host.name:port/path   (absolute path)
+    chirp:host.name:port./path  (relative path)
+    chirp:/path                 (absolute path)
+    chirp:./path                (relative path)
+    chirp:path                  (sloppy relative path)
+
+  Note that the initial part of a sloppy relative path can be confused
+  for a host:port specification if it happens to look like one.  Example:
+  'chirp:strange:1/file'.  For this reason, it is better to use one of
+  the non-sloppy formats.
+
+  In all of the above URL formats, any number of extra connection
+  parameters may be inserted before the path part (including  the leading
+  '/' or '.').  These are of the form ";parameter=value" where parameter
+  and value are encoded using the standard Mime type
+  application/x-www-form-url encoded, just like the parameters in a typical
+  HTTP GET CGI request, but using ';' instead of '&' as the delimiter.
+
+  At this time, no connection parameters are defined, and any that
+  are supplied are simply ignored.
+
+*/
+
+struct chirp_client *
+chirp_client_connect_url( const char *url, const char **path_part)
+{
+	struct chirp_client *client;
+	char const *str;
+	char *host = NULL;
+	int port = 0;
+
+	if(strncmp(url,"chirp:",6)) {
+		//bare file name
+		*path_part = url;
+		return chirp_client_connect_default();
+	}
+
+	url += 6; // "chirp:"
+
+	if(*url != '/' && *url != '\\' && *url != ';' && *url != '.' \
+	   && (str = strchr(url,':')))
+	{
+		char *end;
+		port = strtol(str+1,&end,10);
+		if(port && end > str+1 && 
+		   (*end == '\0' || *end == '/' || *end == '\\' ||
+		    *end == '.' || *end == ';'))
+		{
+			//URL form chirp:host.name:port...
+			//Note that we try to avoid getting here on a "sloppy"
+			//relative path that happens to contain a ':' but
+			//which is not followed by a valid port/path.
+
+			host = (char *)malloc(str-url+1);
+			strncpy(host,url,str-url);
+			host[str-url] = '\0';
+
+			url = end;
+		}
+	}
+
+	while(*url == ';') { //parse connection parameters
+		char param[CHIRP_LINE_MAX];
+		char value[CHIRP_LINE_MAX];
+
+		url = read_url_param(++url,param,sizeof(param));
+		if(!url) {
+			errno = EINVAL;
+			return NULL;
+		}
+
+		if(*url == '=') {
+			url = read_url_param(++url,value,sizeof(value));
+			if(!url) {
+				errno = EINVAL;
+				return NULL;
+			}
+		}
+		else *value = '\0';
+
+		//No connection parameters are defined at this time!
+		//Handle them here when they are defined.
+	}
+
+	*path_part = url;
+
+	if(!host) { //URL must be in form 'chirp:path'
+		client = chirp_client_connect_default();
+	}
+	else {
+		client = chirp_client_connect(host,port);
+	}
+
+	free(host);
+	return client;
+}
+
+struct chirp_client *
+chirp_client_connect_default()
+{
+	FILE *file;
+	int fields;
+	int save_errno;
+	struct chirp_client *client;
+	char host[CHIRP_LINE_MAX];
+	char cookie[CHIRP_LINE_MAX];
+	int port;
+	int result;
+
+	file = fopen("chirp.config","r");
+	if(!file) return 0;
+
+	fields = fscanf(file,"%s %d %s",host,&port,cookie);
+	fclose(file);
+
+	if(fields!=3) {
+		errno = EINVAL;
+		return 0;
+	}
+
+	client = chirp_client_connect(host,port);
+	if(!client) return 0;
+
+	result = chirp_client_cookie(client,cookie);
+	if(result!=0) {
+		save_errno = errno;
+		chirp_client_disconnect(client);
+		errno = save_errno;
+		return 0;
+	}
+
+	return client;
+}
+
+struct chirp_client *
+chirp_client_connect( const char *host, int port )
+{
+	struct chirp_client *c;
+	int save_errno;
+	int fd;
+
+	c = (chirp_client *) malloc(sizeof(*c));
+	if(!c) return 0;
+
+	fd = tcp_connect(host,port);
+	if(fd<0) {
+		save_errno = errno;
+		free(c);
+		errno = save_errno;
+		return 0;
+	}
+
+	c->stream = fdopen(fd,"w+");
+	if(!c->stream) {
+		save_errno = errno;
+		close(fd);
+		free(c);
+		errno = save_errno;
+		return 0;
+	}
+
+	return c;
+}
+
+void
+chirp_client_disconnect( struct chirp_client *c )
+{
+	fclose(c->stream);
+	free(c);
+}
+
+int
+chirp_client_cookie( struct chirp_client *c, const char *cookie )
+{
+	return simple_command(c,"cookie %s\n",cookie);
+}
+
+int
+chirp_client_login( struct chirp_client *c, const char *name, const char *password )
+{
+	return simple_command(c,"login %s %s\n",name,password);
+}
+
+int
+chirp_client_lookup( struct chirp_client *c, const char *logical_name, char **url )
+{
+	int result;
+	int actual;
+
+	result = simple_command(c,"lookup %s\n",logical_name);
+	if(result>0) {
+		*url = (char *)malloc(result);
+		if(*url) {
+			actual = fread(*url,1,result,c->stream);
+			if(actual!=result) chirp_fatal_request("lookup");
+		} else {
+			chirp_fatal_request("lookup");
+		}
+	}
+
+	return result;
+}
+
+int
+chirp_client_constrain( struct chirp_client *c, const char *expr)
+{
+	return simple_command(c,"constrain %s\n",expr);
+}
+
+int
+chirp_client_get_job_attr( struct chirp_client *c, const char *name, char **expr )
+{
+	int result;
+	int actual;
+
+	result = simple_command(c,"get_job_attr %s\n",name);
+	if(result>0) {
+		*expr = (char *)malloc(result);
+		if(*expr) {
+			actual = fread(*expr,1,result,c->stream);
+			if(actual!=result) chirp_fatal_request("get_job_attr");
+		} else {
+			chirp_fatal_request("get_job_attr");
+		}
+	}
+
+	return result;
+}
+
+int
+chirp_client_set_job_attr( struct chirp_client *c, const char *name, const char *expr )
+{
+	return simple_command(c,"set_job_attr %s %s\n",name,expr);
+}
+
+int
+chirp_client_open( struct chirp_client *c, const char *path, const char *flags, int mode )
+{
+	return simple_command(c,"open %s %s %d\n",path,flags,mode);
+}
+
+int
+chirp_client_close( struct chirp_client *c, int fd )
+{
+	return simple_command(c,"close %d\n",fd);
+}
+
+int
+chirp_client_read( struct chirp_client *c, int fd, void *buffer, int length )
+{
+	int result;
+	int actual;
+
+	result = simple_command(c,"read %d %d\n",fd,length);
+
+	if( result>0 ) {
+		actual = fread(buffer,1,result,c->stream);
+		if(actual!=result) chirp_fatal_request("read");
+	}
+
+	return result;
+}
+
+int
+chirp_client_write( struct chirp_client *c, int fd, const void *buffer, int length )
+{
+	int actual;
+	int result;
+
+	result = fprintf(c->stream,"write %d %d\n",fd,length);
+	if(result<0) chirp_fatal_request("write");
+
+	result = fflush(c->stream);
+	if(result<0) chirp_fatal_request("write");
+
+	actual = fwrite(buffer,1,length,c->stream);
+	if(actual!=length) chirp_fatal_request("write");
+
+	return convert_result(get_result(c->stream));
+}
+
+int
+chirp_client_unlink( struct chirp_client *c, const char *path )
+{
+	return simple_command(c,"unlink %s\n",path);
+}
+
+int
+chirp_client_rename( struct chirp_client *c, const char *oldpath, const char *newpath )
+{
+	return simple_command(c,"rename %s %s\n",oldpath,newpath);
+}
+int
+chirp_client_fsync( struct chirp_client *c, int fd )
+{
+	return simple_command(c,"fsync %d\n",fd);
+}
+
+int
+chirp_client_lseek( struct chirp_client *c, int fd, int offset, int whence )
+{
+	return simple_command(c,"lseek %d %d %d\n",fd,offset,whence);
+}
+
+int
+chirp_client_mkdir( struct chirp_client *c, char const *name, int mode )
+{
+	return simple_command(c,"mkdir %s %d\n",name,mode);
+}
+
+int
+chirp_client_rmdir( struct chirp_client *c, char const *name )
+{
+	return simple_command(c,"rmdir %s\n",name);
+}
+
+
+static int
+convert_result( int result )
+{
+	if(result>=0) {
+		return result;
+	} else {
+		switch(result) {
+			case CHIRP_ERROR_NOT_AUTHENTICATED:
+			case CHIRP_ERROR_NOT_AUTHORIZED:
+				errno = EACCES;
+				break;
+			case CHIRP_ERROR_DOESNT_EXIST:
+				errno = ENOENT;
+				break;
+			case CHIRP_ERROR_ALREADY_EXISTS:
+				errno = EEXIST;
+				break;
+			case CHIRP_ERROR_TOO_BIG:
+				errno = EFBIG;
+				break;
+			case CHIRP_ERROR_NO_SPACE:
+				errno = ENOSPC;
+				break;
+			case CHIRP_ERROR_NO_MEMORY:
+				errno = ENOMEM;
+				break;
+			case CHIRP_ERROR_INVALID_REQUEST:
+				errno = EINVAL;
+				break;
+			case CHIRP_ERROR_TOO_MANY_OPEN:
+				errno = EMFILE;
+				break;
+			case CHIRP_ERROR_BUSY:
+				errno = EBUSY;
+				break;
+			case CHIRP_ERROR_TRY_AGAIN:
+				errno = EAGAIN;
+				break;
+			case CHIRP_ERROR_UNKNOWN:
+				chirp_fatal_response();
+				break;
+		}
+		return -1;
+	}
+}
+
+static int
+get_result( FILE *s )
+{
+	char line[CHIRP_LINE_MAX];
+	char *c;
+	int result;
+	int fields;
+
+	c = fgets(line,CHIRP_LINE_MAX,s);
+	if(!c) chirp_fatal_response();
+
+	fields = sscanf(line,"%d",&result);
+	if(fields!=1) chirp_fatal_response();
+
+#ifdef CHIRP_DEBUG
+	fprintf(stderr,"chirp received: %s\n",line);
+#endif
+
+	return result;
+}
+
+static void
+chirp_fatal_request( const char *name )
+{
+	fprintf(stderr,"chirp: couldn't %s: %s\n",name,strerror(errno));
+	abort();
+}
+
+static
+void chirp_fatal_response()
+{
+	fprintf(stderr,"chirp: couldn't get response from server: %s\n",strerror(errno));
+	abort();
+}
+
+static int
+tcp_connect( const char *host, int port )
+{
+	struct hostent *h;
+	struct sockaddr_in address;
+	int success;
+	int fd;
+
+	h = gethostbyname(host);
+	if(!h) return -1;
+
+	address.sin_port = htons(port);
+	address.sin_family = h->h_addrtype;
+	memcpy(&address.sin_addr.s_addr,h->h_addr_list[0],sizeof(address.sin_addr.s_addr));
+
+	fd = socket( AF_INET, SOCK_STREAM, 0 );
+	if(fd<0) return -1;
+
+	success = connect( fd, (struct sockaddr *) &address, sizeof(address) );
+	if(success<0) {
+		close(fd);
+		return -1;
+	}
+
+	return fd;
+}
+
+/*
+  vsprintf_chirp -- simple sprintf capabilities with character escaping
+
+  The following format characters are interpreted:
+
+  %d -- decimal
+  %s -- word (whitespace is escaped)
+  %% -- output %
+*/
+
+void
+vsprintf_chirp(char *command,char const *fmt,va_list args)
+{
+	char       *c;
+	char const *f;
+
+	c = command;
+	f = fmt;
+	while(*f) {
+		if(*f == '%') {
+			switch(*(++f)) {
+			case 'd':
+				f++;
+				sprintf(c,"%d",va_arg(args,int));
+				c += strlen(c);
+				break;
+			case 's': {
+				char const *w = va_arg(args,char const *);
+				f++;
+				while(*w) {
+					switch(*w) {
+					case ' ':
+					case '\t':
+					case '\n':
+					case '\r':
+					case '\\':
+						*(c++) = '\\';
+						/*fall through*/
+					default:
+						*(c++) = *(w++);
+					}
+				}
+				break;
+			}
+			case '%':
+				*(c++) = *(f++);
+				break;
+			default:
+				chirp_fatal_request(f);
+			}
+		} else {
+			*(c++) = *(f++);
+		}
+	}
+	*(c++) = '\0';
+}
+
+int
+simple_command(struct chirp_client *c,char const *fmt,...)
+{
+	int     result;
+	char    command[CHIRP_LINE_MAX];
+	va_list args;
+
+	va_start(args,fmt);
+	vsprintf_chirp(command,fmt,args);
+	va_end(args);
+
+#ifdef DEBUG_CHIRP
+	fprintf(stderr,"chirp sending: %s",command);
+#endif
+
+	result = fputs(command,c->stream);
+
+
+
+	if(result < 0) chirp_fatal_request(fmt);
+
+	result = fflush(c->stream);
+	if(result < 0) chirp_fatal_request(fmt);
+
+	return convert_result(get_result(c->stream));
+}
+
+char const *
+read_url_param(char const *url,char *buffer,size_t length)
+{
+	size_t bufpos = 0;
+
+	while(*url != '\0' && *url != '.' && *url != '/'
+	      && *url != '=' && *url != ';' && *url != '\\')
+	{
+		if(bufpos >= length) return NULL;	
+
+		switch(*url) {
+		case '+':
+			buffer[bufpos++] = ' ';
+			break;
+		case '%': { //form-url-encoded escape sequence
+			//following two characters are hex digits
+			char d = tolower(*(++url));
+
+			if(d >= '0' && d <= '9') d -= '0';
+			else if(d >= 'a' && d <= 'f') d = d - 'a' + 0xA;
+			else return NULL; //invalid hex digit
+
+			buffer[bufpos] = d<<4;
+
+			d = tolower(*(++url));
+
+			if(d >= '0' && d <= '9') d -= '0';
+			else if(d >= 'a' && d <= 'f') d = d - 'a' + 0xA;
+			else return NULL; //invalid hex digit
+
+			buffer[bufpos++] |= d;
+
+			break;
+		}
+		default:
+			buffer[bufpos++] = *url;
+			break;
+		}
+
+		url++;
+	}
+
+	if(bufpos >= length) return NULL;
+	buffer[bufpos] = '\0';
+
+	return url;
+}
diff --git a/MW/src/RMComm/MW-File/chirp_client.h b/MW/src/RMComm/MW-File/chirp_client.h
new file mode 100644
index 0000000..419d5a4
--- /dev/null
+++ b/MW/src/RMComm/MW-File/chirp_client.h
@@ -0,0 +1,202 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/*
+Chirp C Client
+
+This public domain software is provided "as is".  See the Chirp License
+for details.
+*/
+
+#ifndef CHIRP_CLIENT_H
+#define CHIRP_CLIENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+Error codes:
+
+-1   NOT_AUTHENTICATED The client has not authenticated its identity.
+-2   NOT_AUTHORIZED    The client is not authorized to perform that action.
+-3   DOESNT_EXIST      There is no object by that name.
+-4   ALREADY_EXISTS    There is already an object by that name.
+-5   TOO_BIG           That request is too big to execute.
+-6   NO_SPACE          There is not enough space to store that.
+-7   NO_MEMORY         The server is out of memory.
+-8   INVALID_REQUEST   The form of the request is invalid.
+-9   TOO_MANY_OPEN     There are too many resources in use.
+-10  BUSY              That object is in use by someone else.
+-11  TRY_AGAIN         A temporary condition prevented the request.
+-12  UNKNOWN           An unknown error occurred.
+*/
+
+struct chirp_client * chirp_client_connect_default();
+/*chirp_client_connect_default()
+  Opens connection to the default chirp server.  The default connection
+  information is determined by reading ./chirp.config.  Under Condor,
+  the starter can automatically create this file if you specify
+  +WantIOProxy=True in the submit file.
+*/
+struct chirp_client * chirp_client_connect( const char *host, int port );
+/*chirp_client_connect()
+  Connect to a chirp server at the specified address.
+ */
+
+struct chirp_client * chirp_client_connect_url( const char *url, const char **path_part);
+/*
+  chirp_client_connect_url()
+
+  Sets path_part to the position of the start of the path information
+  in the URL and connects to the specified Chirp server.
+
+  URL format:
+    chirp:host.name:port/path   (absolute path)
+    chirp:host.name:port./path  (relative path)
+    chirp:/path                 (absolute path)
+    chirp:./path                (relative path)
+    chirp:path                  (sloppy relative path)
+
+  Note that the initial part of a sloppy relative path can be confused
+  for a host:port specification if it happens to look like one.  Example:
+  'chirp:strange:1/file'.  For this reason, it is better to use one of
+  the non-sloppy formats.
+
+  In all of the above URL formats, any number of extra connection
+  parameters may be inserted before the path part (including  the leading
+  '/' or '.').  These are of the form ";parameter=value" where parameter
+  and value are encoded using the standard Mime type
+  application/x-www-form-url encoded, just like the parameters in a typical
+  HTTP GET CGI request, but using ';' instead of '&' as the delimiter.
+
+  At this time, no connection parameters are defined, and any that
+  are supplied are simply ignored.
+
+*/
+
+void chirp_client_disconnect( struct chirp_client *c );
+/*chirp_client_disconnect()
+  Closes the connection to a chirp server.
+*/
+
+int chirp_client_cookie( struct chirp_client *c, const char *cookie );
+/*chirp_client_cookie
+  Authenticate with the server using the specified cookie.
+ */
+
+int chirp_client_lookup( struct chirp_client *c, const char *logical_name, char **url );
+/*chirp_client_lookup()
+  Ask the chirp server to translate the filename "logical_name".  This is
+  done internally on any filename presented to chirp_client_open().  Under
+  Condor, the shadow may translate the path using the same mechanisms
+  available to redirect paths in Standard Universe.
+*/
+
+int chirp_client_constrain( struct chirp_client *c, const char *expr );
+/*chirp_client_constrain()
+  When running under Condor, set the job's requirement expression.
+*/
+
+int chirp_client_get_job_attr( struct chirp_client *c, const char *name, char **expr );
+/*chirp_client_get_job_attr()
+  When running under Condor, obtain the value of a job ClassAd attribute.
+*/
+
+int chirp_client_set_job_attr( struct chirp_client *c, const char *name, const char *expr );
+/*chirp_client_set_job_attr()
+  When running under Condor, set the value of a job ClassAd attribute.
+*/
+
+int chirp_client_open( struct chirp_client *c, const char *path, const char *flags, int mode );
+/*chirp_client_open()
+  Open a file through the chirp server.  Note that if you want to create a
+  new file, you _must_ include "c" or "x" in the flags.  The mode is the same
+  as in the POSIX open() call.
+
+  Flags:
+		r - open for reading
+		w - open for writing
+		a - force all writes to append
+		t - truncate before use
+		c - create if it doesn't exist
+		x - fail if 'c' is given and the file already exists
+
+  Returns an integer file handle to be used in future chirp_client() functions.
+  On error, returns a value less than 0.
+*/
+
+int chirp_client_close( struct chirp_client *c, int fd );
+/*chirp_client_close()
+  Closes a file opened via chirp_client_open().
+*/
+
+int chirp_client_read( struct chirp_client *c, int fd, void *buffer, int length );
+/*chirp_client_read()
+  Reads from a file and puts the result in a buffer.  The number of bytes
+  actually read is returned.
+*/
+
+int chirp_client_write( struct chirp_client *c, int fd, const void *buffer, int length );
+/*chirp_client_write()
+  Writes from a buffer into a file.  On success, returns the number of
+  bytes written, which will always be the number of bytes requested.
+  On error, returns a negative error code.
+*/
+
+int chirp_client_unlink( struct chirp_client *c, const char *path );
+/*chirp_client_unlink()
+  Removes a file.
+*/
+
+int chirp_client_rename( struct chirp_client *c, const char *oldpath, const char *newpath );
+/*chirp_client_rename()
+  Renames a file.
+*/
+
+int chirp_client_fsync( struct chirp_client *c, int fd );
+/*chirp_client_fsync()
+  Flushes any buffered data to disk.
+*/
+
+int chirp_client_lseek( struct chirp_client *c, int fd, int offset, int whence );
+/*chirp_client_lseek()
+  Changes the read/write file offset.  The values for whence are the same
+  as for the POSIX lseek() call.
+*/
+
+int chirp_client_mkdir( struct chirp_client *c, char const *name, int mode );
+/*chirp_client_mkdir()
+  Create a directory with the specified mode.
+*/
+
+int chirp_client_rmdir( struct chirp_client *c, char const *name );
+/*chirp_client_rmdir()
+  Removes an empty directory.
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/MW/src/RMComm/MW-File/chirp_protocol.h b/MW/src/RMComm/MW-File/chirp_protocol.h
new file mode 100644
index 0000000..5ba0232
--- /dev/null
+++ b/MW/src/RMComm/MW-File/chirp_protocol.h
@@ -0,0 +1,50 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+/*
+Chirp C Client
+
+This public domain software is provided "as is".  See the Chirp License
+for details.
+*/
+
+#ifndef CHIRP_PROTOCOL_H
+#define CHIRP_PROTOCOL_H
+
+#define CHIRP_LINE_MAX 1024
+#define CHIRP_VERSION 2
+
+#define CHIRP_ERROR_NOT_AUTHENTICATED -1
+#define CHIRP_ERROR_NOT_AUTHORIZED -2
+#define CHIRP_ERROR_DOESNT_EXIST -3
+#define CHIRP_ERROR_ALREADY_EXISTS -4
+#define CHIRP_ERROR_TOO_BIG -5
+#define CHIRP_ERROR_NO_SPACE -6
+#define CHIRP_ERROR_NO_MEMORY -7
+#define CHIRP_ERROR_INVALID_REQUEST -8
+#define CHIRP_ERROR_TOO_MANY_OPEN -9
+#define CHIRP_ERROR_BUSY -10
+#define CHIRP_ERROR_TRY_AGAIN -11
+#define CHIRP_ERROR_UNKNOWN -127
+
+#endif
+
diff --git a/MW/src/RMComm/MW-Independent/MWIndRC.C b/MW/src/RMComm/MW-Independent/MWIndRC.C
new file mode 100644
index 0000000..14bfc0e
--- /dev/null
+++ b/MW/src/RMComm/MW-Independent/MWIndRC.C
@@ -0,0 +1,500 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWIndRC.h"
+#include <MW.h>
+#include <MWDriver.h>
+#include <MWTask.h>
+#include <MWWorker.h>
+
+MWRMComm * GlobalRMComm = new MWIndRC ( );
+MWRMComm * MWTask::RMC = GlobalRMComm;
+MWRMComm * MWDriver::RMC = GlobalRMComm;
+MWRMComm * MWWorker::RMC = GlobalRMComm;
+
+MWIndRC::MWIndRC() 
+{
+    target_num_workers = -1;
+    num_arches = -1;
+    // memset ( worker_requirements, 0, (16 * 1024 ));
+    // num_arches = 1;
+}
+		/// Destructor...
+MWIndRC::~MWIndRC()
+{
+	/// Nothing to delete
+}
+
+void 
+MWIndRC::hostadd ( )
+{
+    last_tag = HOSTADD;
+    return;
+}
+
+void 
+MWIndRC::exit( int exitval ) 
+{ 
+    // ::exit ( exitval ); 
+}
+
+int 
+MWIndRC::setup ( int argc, char *argv[], int *my_id, int *master_id ) 
+{
+    *my_id = 2;
+    *master_id = 0;
+    return 0; 
+};
+
+
+int 
+MWIndRC::config( int *nhosts, int *narches, MWWorkerID ***w ) 
+{ 
+	// Nothing to configure either
+    return 0; 
+}
+	
+int 
+MWIndRC::start_worker ( MWWorkerID *w ) 
+{ 
+    if (!w) return -1; 
+    w->set_id1 ( 2 );
+    w->set_arch ( 0 );
+    w->set_exec_class(0); 	// XXX should have done this!
+    return 0;
+};
+
+int 
+MWIndRC::init_beginning_workers ( int *nworkers, MWWorkerID ***workers ) 
+{
+    return 0;
+};
+
+int
+MWIndRC::restart_beginning_workers( int *nworkers, MWWorkerID ***workers, MWmessages msg ){
+	return init_beginning_workers( nworkers, workers);
+}
+
+int 
+MWIndRC::removeWorker( MWWorkerID *w ) 
+{
+    return 0;
+};
+
+int 
+MWIndRC::read_RMstate( FILE *fp )
+{
+    return 0;
+}
+
+int 
+MWIndRC::write_RMstate ( FILE *fp )
+{ 
+    return 0;
+}
+
+int 
+MWIndRC::hostaddlogic( int *num_workers )
+{
+    return 0; 
+}
+
+int 
+MWIndRC::initsend ( int encoding )
+{ 
+    ind_sendbuf.num_sent = 0;
+    return 0;
+}
+
+int 
+MWIndRC::send ( int to_whom, int msgtag ) 
+{ 
+    last_tag = msgtag;
+	sent_data = true; 
+    return 0;
+}
+
+int 
+MWIndRC::recv ( int from_whom, int msgtag ) 
+{ 
+    memcpy ( &ind_recvbuf.buf, &ind_sendbuf.buf, INDP_BUF_SIZE * sizeof(char) ); 
+    ind_recvbuf.num_sent = 0;
+	sent_data = false;
+    return 0;
+}
+
+int
+MWIndRC::nrecv ( int from_whom, int msgtag )
+{
+	if ( !sent_data )
+	{
+		last_tag = NO_MESSAGE;
+		sent_data = false;
+		return 0;
+	}
+	else	
+	{
+		recv ( from_whom, msgtag );
+	}
+	return 0;
+}
+
+int 
+MWIndRC::bufinfo ( int buf_id, int *len, int *tag, int *from ) 
+{ 
+    *tag = last_tag; 
+    return 0;
+}
+
+void
+MWIndRC::who ( int *wh )
+{
+        unpack ( wh, 1, 1 );
+}
+
+
+int 
+MWIndRC::pack ( const char *bytes,         int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( char ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &bytes[ i * stride ], sizeof(char) );
+	ind_sendbuf.num_sent += sizeof(char);
+	num_sent += sizeof(char);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const float *f,            int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( float ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &f[ i * stride ], sizeof(float) );
+	ind_sendbuf.num_sent += sizeof(float);
+	num_sent += sizeof(float);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const double *d,           int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( double ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &d[ i * stride ], sizeof(double) );
+	ind_sendbuf.num_sent += sizeof(double);
+	num_sent += sizeof(double);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const int *in,              int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( int ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &in[ i * stride ], sizeof(int) );
+	ind_sendbuf.num_sent += sizeof(int);
+	num_sent += sizeof(int);
+    }
+    return 0;
+}
+		
+int 
+MWIndRC::pack ( const unsigned int *ui,    int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( unsigned int ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &ui[ i * stride ], sizeof(unsigned int) );
+	ind_sendbuf.num_sent += sizeof(unsigned int);
+	num_sent += sizeof(unsigned int);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const short *sh,           int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( short ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &sh[ i * stride ], sizeof(short) );
+	ind_sendbuf.num_sent += sizeof(short);
+	num_sent += sizeof(short);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const unsigned short *ush, int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( unsigned short ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &ush[ i * stride ], sizeof(unsigned short) );
+	ind_sendbuf.num_sent += sizeof(unsigned short);
+	num_sent += sizeof(unsigned short);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const long *l,             int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( long ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &l[ i * stride ], sizeof(long) );
+	ind_sendbuf.num_sent += sizeof(long);
+	num_sent += sizeof(long);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const unsigned long *ul,   int nitem, int stride )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	// ASSERT ( num_sent + sizeof ( unsigned long ) <= 1024 * 64 );
+	memcpy ( &(ind_sendbuf.buf[num_sent]), &ul[ i * stride ], sizeof(unsigned long) );
+	ind_sendbuf.num_sent += sizeof(unsigned long);
+	num_sent += sizeof(unsigned long);
+    }
+    return 0;
+}
+
+int 
+MWIndRC::pack ( const char *string )
+{
+    int num_sent = ind_sendbuf.num_sent;
+    // ASSERT ( num_sent + sizeof(int) + sizeof( char ) * strlen (string) <= 1024 * 64 );
+    int len = strlen(string);
+    memcpy ( &(ind_sendbuf.buf[num_sent]), &len, sizeof(int) );
+    ind_sendbuf.num_sent += sizeof(int);
+    num_sent += sizeof(int);
+    memcpy ( &(ind_sendbuf.buf[num_sent]), string, len * sizeof(char) );
+    ind_sendbuf.num_sent += sizeof(char) * len;
+    num_sent += sizeof(char) * len;
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( char *bytes,         int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	char temp;
+	memcpy ( &temp,&(ind_recvbuf.buf[num_sent]), sizeof(char) );
+	ind_recvbuf.num_sent += sizeof(char);
+	num_sent += sizeof(char);
+	bytes[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( float *f,            int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	float temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(float) );
+	ind_recvbuf.num_sent += sizeof(float);
+	num_sent += sizeof(float);
+	f[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( double *d,           int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	double temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(double) );
+	ind_recvbuf.num_sent += sizeof(double);
+	num_sent += sizeof(double);
+	d[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( int *i,              int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int ii = 0; ii < nitem; ii++ )
+    {
+	int temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(int) );
+	ind_recvbuf.num_sent += sizeof(int);
+	num_sent += sizeof(int);
+	i[ii * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( unsigned int *ui,    int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	unsigned int temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(unsigned int) );
+	ind_recvbuf.num_sent += sizeof(unsigned int);
+	num_sent += sizeof(unsigned int);
+	ui[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( short *sh,           int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	short temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(short) );
+	ind_recvbuf.num_sent += sizeof(short);
+	num_sent += sizeof(short);
+	sh[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( unsigned short *ush, int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	unsigned short temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(unsigned short) );
+	ind_recvbuf.num_sent += sizeof(unsigned short);
+	num_sent += sizeof(unsigned short);
+	ush[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( long *l,             int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	long temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(long) );
+	ind_recvbuf.num_sent += sizeof(long);
+	num_sent += sizeof(long);
+	l[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( unsigned long *ul,   int nitem, int stride )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    for ( int i = 0; i < nitem; i++ )
+    {
+	unsigned long temp;
+	memcpy ( &temp, &(ind_recvbuf.buf[num_sent]), sizeof(unsigned long) );
+	ind_recvbuf.num_sent += sizeof(unsigned long);
+	num_sent += sizeof(unsigned long);
+	ul[i * stride] = temp;
+    }
+    return 0;
+}
+
+int 
+MWIndRC::unpack ( char *string )
+{
+    int num_sent = ind_recvbuf.num_sent;
+    int len;
+    memcpy ( &len, &(ind_recvbuf.buf[num_sent]), sizeof(int) );
+    ind_recvbuf.num_sent += sizeof(int);
+    num_sent += sizeof(int);
+    memcpy ( string, &(ind_recvbuf.buf[num_sent]), len * sizeof(char) );
+    ind_recvbuf.num_sent += sizeof(char) * len;
+    num_sent += sizeof(char) * len;
+    string[len] = '\0';
+    return 0;
+}
+//BUFFER
+int 
+MWIndRC::recv_all( int from_whom, int msgtag )
+{
+	MWprintf(91, "Not implemented yet for MW-Ind.\n");
+	return 0;
+}
+
+int 
+MWIndRC::setrbuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-Ind.\n");
+	return -1;
+}
+
+int 
+MWIndRC::freebuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-Ind.\n");
+	return -1;
+}
+
+MWList<void> * 
+MWIndRC::recv_buffers()
+{
+	MWprintf(91, "Not implemented yet for MW-Ind.\n");
+	return NULL;
+}
+
+int 
+MWIndRC::next_buf()
+{
+	MWprintf(91, "Not implemented yet for MW-Ind.\n");
+	return -1;
+}
+	
diff --git a/MW/src/RMComm/MW-Independent/MWIndRC.h b/MW/src/RMComm/MW-Independent/MWIndRC.h
new file mode 100644
index 0000000..824f62e
--- /dev/null
+++ b/MW/src/RMComm/MW-Independent/MWIndRC.h
@@ -0,0 +1,230 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWINDRC_H
+#define MWINDRC_H
+#include "../MWRMComm.h"
+
+/** This class is an derived from the Resource Management (RM) and
+	Communication (Comm) layer. In MW-Ind, there is just one worker and one master
+	and both are on the same machine. And not just that both are same process!!
+	Send and Recv are merely memcpy. This class I deem is useful for debugging purposes.
+	The api etc all will remain the same when using this layer. All the user has to do
+	is to compile it with the INDEPENDENT flag and use this as the RMComm layer. See into
+	the fibonacci example for more details on the makefile. And then just launch the 
+	application as a process. That's it.
+*/
+
+class MWIndRC : public MWRMComm 
+{
+    public:
+		/** Constructor.  Sets data to -1's. */
+	MWIndRC();
+		/// Destructor...
+	~MWIndRC();
+
+	void hostadd ( );
+
+		/** @name A. Resource Management Functions
+
+			Here are all the methods you could want to have for managing 
+			a set of machines.  See each method for details...
+		*/
+		//@{
+
+		/** System shutdown.  Does not return.  
+		    @param exitval The value to call ::exit() with 
+		*/
+	void exit( int exitval );
+
+		/** Initialization of the master process.  This will be called
+			one time only when the master starts up.  
+			@return 0 on success, -1 on failure
+		 */
+	int setup( int argc, char* argv[], int *my_id, int *master_id);
+
+		/** What is there to configure? Nothing.
+		*/
+	int config( int *nhosts, int *narches, MWWorkerID ***w );
+	
+		/** Just init the workerID to a worker. This is an idempotent function.
+		*/
+	int start_worker( MWWorkerID *w );
+
+		/** This routine is used to start up multiple workers at 
+			the beginning of a run.  In MW-Ind there is no initial worker.
+			Simply return 0.
+		*/
+	int init_beginning_workers( int *nworkers, MWWorkerID ***workers );
+
+		/** Called at the time of restart */
+	int restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg );
+			
+
+		/** Remove a worker from the virtual machine.  MW-Ind has 
+			no concept of host management. Hence all are null.
+		 */
+	int removeWorker( MWWorkerID *w );
+		//@}
+
+		/** @name B. Checkpointing Functions */
+		//@{
+
+		/** Do nothing */
+	int read_RMstate( FILE *fp );
+
+	int write_RMstate ( FILE *fp );
+		//@}
+
+ protected: 
+	
+		/** @name D. Host Management Members */
+		//@{
+		/** This will figure out if we need to ask for more hosts
+			or remove hosts.  In MW-Ind version there is just one worker.
+			So this function is NULL.
+		*/
+	int hostaddlogic( int *num_workers );
+
+		//@}
+
+#define INDP_BUF_SIZE 1024*1024*64
+	
+	struct SendBuf {
+		int num_sent;
+		char buf[INDP_BUF_SIZE];
+	};
+	struct SendBuf ind_sendbuf, ind_recvbuf;
+	int last_tag;
+	bool sent_data;
+
+ public:
+
+		/** @name The Communication Routines
+			These communication primitives use memcpy as the communication
+			mechanism for the transfer of data.
+
+		*/
+	
+		//@{
+		
+		/**     A Function called to know which worker had an exception event */
+	void who ( int *wh );
+
+		/** Initialize a buffer for sending some data.
+			@param encoding Defined by each application.  0 = default */
+	int initsend ( int encoding = 0 );
+		/** Send the data that has been packed. 
+			@param to_whom An identifier for the recipient
+			@param msgtag A 'tag' to identify that type of message */
+	int send ( int to_whom, int msgtag );
+
+		/** Receive some data that has been packed.  Just a memcpy
+			@param from_whom From a specific source; -1 is from all
+			@param msgtag With a certain tag; -1 is all. */
+	int recv ( int from_whom, int msgtag );
+
+	int nrecv ( int from_whom, int msgtag );	
+
+		/** Provide info on the message just received */
+	int bufinfo ( int buf_id, int *len, int *tag, int *from );
+
+		/** @name Pack Functions
+			
+			In the following pack() functions, there are some common themes.
+			First, each stuffs some data into a buffer to be sent.  The
+			nitem parameter is just a count of the number of items.  The 
+			stride parameter specifies *which* items to pack.  1 implies
+			all, 2 would be every 2nd item, 3 is every 3rd item, etc. 
+
+			The return value is user defined.  It should be standardized, 
+			but I'll do that later.
+		*/
+		//@{
+
+		/// Pack some bytes
+	int pack ( const char *bytes,         int nitem, int stride = 1 );
+		/// float
+	int pack ( const float *f,            int nitem, int stride = 1 );
+		/// double
+	int pack ( const double *d,           int nitem, int stride = 1 );
+		/// int
+	int pack ( const int *i,              int nitem, int stride = 1 );
+		/// unsigned int
+	int pack ( const unsigned int *ui,    int nitem, int stride = 1 );
+		/// short
+	int pack ( const short *sh,           int nitem, int stride = 1 );
+		/// unsigned short
+	int pack ( const unsigned short *ush, int nitem, int stride = 1 );
+		/// long
+	int pack ( const long *l,             int nitem, int stride = 1 );
+		/// unsigned long
+	int pack ( const unsigned long *ul,   int nitem, int stride = 1 );
+		/// Pack a NULL-terminated string
+	int pack ( const char *string );
+
+		//@}
+
+		/** @name Unpack Functions
+			
+			These unpack functions unpack data packed with the pack() 
+			functions.  See the pack() functions for more details.
+
+		*/
+		//@{
+
+		/// Unpack some bytes
+	int unpack ( char *bytes,         int nitem, int stride = 1 );
+		/// float
+	int unpack ( float *f,            int nitem, int stride = 1 );
+		/// double
+	int unpack ( double *d,           int nitem, int stride = 1 );
+		/// int
+	int unpack ( int *i,              int nitem, int stride = 1 );
+		/// unsigned int
+	int unpack ( unsigned int *ui,    int nitem, int stride = 1 );
+		/// short
+	int unpack ( short *sh,           int nitem, int stride = 1 );
+		/// unsigned short
+	int unpack ( unsigned short *ush, int nitem, int stride = 1 );
+		/// long
+	int unpack ( long *l,             int nitem, int stride = 1 );
+		/// unsigned long
+	int unpack ( unsigned long *ul,   int nitem, int stride = 1 );
+		/// Unpack a NULL-terminated string
+	int unpack ( char *string );
+		//@}
+		//@}
+
+	/** The non-blocking recv() functions */
+	public:
+		int	recv_all( int from_whom, int msgtag );	// returns the number of new buffers
+		int 	setrbuf(int bid);		// switch the active receive buffer
+							// return the old active buf_id
+		int	freebuf(int bid);		// free the receive buffer.
+		MWList<void> * recv_buffers();			// return the recv_buf_list
+		int 	next_buf();			// advance the active buffer to the next valid buffer 
+							// in the recv_buf_list.
+
+};
+#endif
+
diff --git a/MW/src/RMComm/MW-Independent/Makefile.in b/MW/src/RMComm/MW-Independent/Makefile.in
new file mode 100644
index 0000000..6c28e83
--- /dev/null
+++ b/MW/src/RMComm/MW-Independent/Makefile.in
@@ -0,0 +1,122 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+ENABLE_MWINDEPENDENT= @ENABLE_MWINDEPENDENT@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS =
+
+# Libraries to be built, and dependent source files
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+LIBRARIES = libMWRC_indp.a
+else
+LIBRARIES =
+endif
+libMWRC_indp_a_SOURCES = MWIndRC.C
+libMWRC_indp_a_LIBADD = MWIndRC.o
+libMWRC_indp_a_DEPENDENCIES =  MWIndRC.o
+libMWRC_indp_a_OBJECTS =
+
+INCLUDES = -g -I. -I.. -I../.. -I$(CONDOR_DIR)/include $(MEASURE_DEFN)
+INCLUDEFILES = MWIndRC.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+
+libMWRC_indp.a: $(libMWRC_indp_a_OBJECTS) $(libMWRC_indp_a_DEPENDENCIES)
+	-rm -f libMWRC_indp.a
+	$(AR) cru libMWRC_indp.a $(libMWRC_indp_a_OBJECTS) $(libMWRC_indp_a_LIBADD)
+	$(RANLIB) libMWRC_indp.a
+	cp libMWRC_indp.a $(MW_LIBDIR)
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
+
diff --git a/MW/src/RMComm/MW-Socket/MWSocketRC.C b/MW/src/RMComm/MW-Socket/MWSocketRC.C
new file mode 100644
index 0000000..308b777
--- /dev/null
+++ b/MW/src/RMComm/MW-Socket/MWSocketRC.C
@@ -0,0 +1,2114 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifdef WINDOWS
+
+#define FD_SETSIZE 1024
+#include <winsock2.h>
+#define close closesocket
+#define popen _popen
+#define pclose _pclose
+#define sleep _sleep
+#define EINTR WSAEINTR
+#define errno WSAGetLastError()
+#else 
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <signal.h>
+#include <netinet/in.h>
+
+#endif
+
+#include <ctype.h>
+
+#ifdef __svr4__
+#include <strings.h>
+#endif
+
+#include "MWSocketRC.h"
+#include <MWDriver.h>
+#include <MWWorkerID.h>
+#include <MWTask.h>
+#include <MWWorker.h>
+#include <MWSystem.h>
+
+#define MAX_TCP_BUFFER (64*1024)
+
+#ifdef SOCKET_MASTER
+MWRMComm * MWDriver::RMC = new MWSocketRC( TRUE, 0 );
+MWRMComm * MWTask::RMC = MWDriver::RMC;
+MWRMComm * MWWorker::RMC = NULL;
+#else
+MWRMComm * MWWorker::RMC = new MWSocketRC ( FALSE, 0 );
+MWRMComm * MWTask::RMC = MWWorker::RMC;
+MWRMComm * MWDriver::RMC = NULL;
+#endif
+
+extern int *MW_exec_class_num_workers;
+
+#ifdef USE_POLL
+#include <sys/poll.h>
+#endif
+
+/* 
+ * Instead of ifdef'ing this for platforms that don't have it
+ * we have our own, so that we are always compiling it, and
+ * always know that it is correct.
+ */
+
+char *mw_inet_ntop( int family, const void *addrptr, char *strptr, size_t len)
+{
+	const u_char *p = ( const u_char *) addrptr;
+
+	if ( family == AF_INET )
+	{
+		char temp[16];
+		sprintf( temp, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
+		strcpy( strptr, temp);
+		return(strptr);
+	}
+	return( NULL);
+}
+
+int cyclePosition = 0;
+bool toBlock = TRUE;
+static bool timedOut;
+static int  timeOutSocket = -1;
+
+#ifndef WINDOWS
+void alarmed(int signo) {
+      timedOut = true;
+      close(timeOutSocket);
+      write(1, "Alarm timed out\n", 17);
+}
+
+void brokenPipeHandler ( int sig )
+{
+	MWprintf ( 10, "Got the signal %d\n", sig );
+	signal ( SIGPIPE, brokenPipeHandler );
+	return;
+}
+#endif
+
+MWSocketRC::MWSocketRC ( bool master, int id )
+{
+	isMaster = master;
+	if ( isMaster )
+		socketId = 8997;
+	else
+		socketId = id;
+	strcpy ( control_directory, "submit_files" );
+	strcpy ( worker_number_file, "worker_number_file" );
+
+#ifdef WINDOWS
+	WORD version = MAKEWORD(2,2);
+	WSADATA d;
+	WSAStartup(version, &d);
+#endif
+	
+	//by jae	
+	pre_send_done = false;
+	m_poll_timeout = 5; // Default value is 5 sec
+}
+
+MWSocketRC::~MWSocketRC ( )
+{
+	delete []hostadd_reqs;
+	delete []socketWorkers;
+}
+
+int
+MWSocketRC::setup ( int argc, char *argv[], int *mytid, int *mastertid )
+{
+	struct hostent *hptr;
+
+	char **ptr;
+	char str[16];
+
+	subId = 0;
+
+	if ( isMaster == TRUE )
+	{
+		turnNo = 0;
+		*mytid = socketId;
+		*mastertid = socketId;
+		hostadd_reqs = NULL;
+		masterId = socketId;
+		masterSocket = 8997;
+
+		char myname[256];
+		MWSystem::gethostname(myname, 256);
+
+		if ( (hptr = gethostbyname(myname)) == NULL)
+		{
+			MWprintf ( 10, "Cannot do a gethostbyname: errno %d\n", errno );
+			::exit(1);
+		}
+
+		ptr = hptr->h_addr_list;
+		strcpy ( masterAddress, ((char *)mw_inet_ntop(hptr->h_addrtype, *ptr, str, sizeof(str))) );
+
+		socketComm = creatAndBind ( masterSocket );
+
+		if ( listen( socketComm, 50 ) < 0 )
+		{
+			MWprintf ( 10, "Listen failed: errno %d\n", errno );
+			close ( socketComm );
+			::exit(1);
+		}
+
+		FD_ZERO ( &rfds );
+		FD_SET ( socketComm, &rfds );
+
+		for ( int i = 0; i < 4096; i++ )
+		{
+			reverseMap[i] = -1;
+		}
+
+		// If the directory doesn't exist make it, ignoring the error
+		// if it does exist
+
+		char buf[256];
+		sprintf(buf, "mkdir %s", control_directory);
+		system(buf);
+
+		// Windows doesn't raise signals on broken pipe writes
+#ifndef WINDOWS
+		signal ( SIGPIPE, brokenPipeHandler );
+#endif
+	}
+	else
+	{
+		struct sockaddr_in myAddr;
+
+		*mastertid = atoi ( argv[2] );
+		socketId = atoi ( argv[1] );
+		masterSocket = atoi ( argv[3] );
+		*mytid = socketId;
+		strcpy ( masterAddress, argv[4] );
+		socketComm = creatAndBind ( 0 );
+
+		memset(&myAddr, 0, sizeof(myAddr));
+		myAddr.sin_family = AF_INET;
+		(myAddr.sin_addr).s_addr = inet_addr(masterAddress);
+		myAddr.sin_port = htons(masterSocket);
+
+		int retryCount = 0;
+
+tryAgain:
+		if ( connect ( socketComm, (struct sockaddr *)&myAddr, sizeof(myAddr) ) < 0 )
+		{
+			MWprintf ( 10, "Connect failed with the master: errno %d\n", errno );
+			if (retryCount++ < 24) {
+				sleep(5);
+				goto tryAgain;
+			}
+			::exit(1);
+		}
+		MWprintf ( 10, "Connect succeeded\n");
+
+		char buf[sizeof(int)];
+		marshall_int ( socketId, buf );
+		if ( finalSend ( socketComm, buf, sizeof(int), 0 ) < 0 )
+		{
+			MWprintf ( 10, "Initial Send failed to the master: errno %d\n", errno );
+			::exit(1);
+		}
+	}
+
+	return 0;
+}
+
+void
+MWSocketRC::exit ( int retval )
+{
+	if ( isMaster )
+	{
+		killWorkers ( );
+		closeSockets ( );
+	}else {
+		// by jae
+		::exit ( retval );
+	}
+}
+
+int
+MWSocketRC::init_beginning_workers ( int *nworkers, MWWorkerID ***workers )
+{
+	int i;
+
+	MWprintf ( 10, "In MWSocketRC::init_beginning_workers()\n");
+	hostadd_reqs = new int[num_arches];
+
+	for ( i = 0; i < num_arches; i++ )
+	{
+		hostadd_reqs[i] = 0;
+	}
+
+
+	socketWorkers = new SocketWorker[target_num_workers];
+	for ( i = 0; i < target_num_workers; i++ )
+	{
+		socketWorkers[i].state = MWSocket_FREE;
+		socketWorkers[i].socket = -1;
+	}
+	*nworkers = 0;
+
+	return 0;
+}
+
+int
+MWSocketRC::restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg )
+{
+	return init_beginning_workers ( nworkers, workers );
+}
+
+void
+MWSocketRC::who ( int *wh )
+{
+	unpack ( wh, 1, 1 );
+}
+
+int
+MWSocketRC::start_worker ( MWWorkerID *w )
+{
+	w->set_id1 ( whomRecv );
+	w->set_id2 ( whomRecv );
+	w->set_arch ( socketWorkers[whomRecv].arch );
+	w->set_exec_class ( socketWorkers[whomRecv].exec_class );
+
+	hostadd_reqs[socketWorkers[whomRecv].exec_class]--;
+
+	return 0;
+}
+
+int
+MWSocketRC::removeWorker ( MWWorkerID *w )
+{
+	// char buf[_POSIX_PATH_MAX];
+
+	if ( !w ) 
+	{
+		MWprintf (10, "Worker ID cannot be NULL in removeWorker\n" );
+		return -1;
+	}
+
+	return killWorker ( w->get_id1() );
+}
+
+int
+MWSocketRC::hostaddlogic ( int *numworkers )
+{
+	/* This awfully complex function determines the conditions
+	under which it being called, and then calls condor_submit
+	asking for the correct number of hosts.
+
+	- num_workers - an array of size exec_classes that contains
+	the number of workers in each arch class.
+	- hostadd_reqs: The number of outstanding HOSTADDs out there
+	- target_num_workers: Set by the user...
+	*/
+
+	MWprintf ( 10, "In hostaddlogic \n" );
+	if ( !hostadd_reqs ) 
+	{
+		/* if this doesn't exist yet, we won't do anything */
+		return 0; 
+	}       
+
+	/* number of hosts to ask for at a time. The idea is that we'll
+	have double this outstanding at a time - and this amounts
+	to 12 for 1, 2, or 3 arch classes. */
+	int i;          
+	int *sorted_order = new int [exec_classes];
+	int cur;
+	int req;
+	sort_exec_class_ratio ( sorted_order );
+	int status;
+                        
+	MWprintf ( 60, "hal: target: %d\n", target_num_workers );
+
+	int HOSTINC = hostinc_;
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		cur = sorted_order[i];
+		MWprintf(60, "hal:  cur: %d, num_workers: %d, hostadd_reqs: %d, target: %d\n", cur, 
+			 MW_exec_class_num_workers[cur], hostadd_reqs[cur], 
+			 exec_class_target_num_workers[cur]);
+		if ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] >= exec_class_target_num_workers[cur] ) continue;
+		if ( hostadd_reqs[cur] > 0 ) continue;
+		if ( exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] ) > HOSTINC )
+			req = HOSTINC;
+		else
+			req = exec_class_target_num_workers[cur] - ( MW_exec_class_num_workers[cur] + hostadd_reqs[cur] );
+		status = do_spawn ( req, cur );
+		if ( status > 0 )
+		{
+			MWprintf ( 10, "Added %d workers of exec_class %d\n", req, i );
+			hostadd_reqs[cur] += status;
+		}
+		else
+		{
+			MWprintf ( 10, "ERROR!! Failed to submit workers of exec_class %d\n", i );
+		}
+	}
+
+	delete [] sorted_order;
+	return 0;
+}
+
+void
+MWSocketRC::sort_exec_class_ratio ( int *temp )
+{
+	int i, j;
+	double ii, jj;
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		temp[i] = i;
+	}
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		for ( j = i + 1; j < exec_classes; j++ )
+		{
+			ii = ((double)MW_exec_class_num_workers[temp[i]]) / exec_class_target_num_workers[temp[i]];
+			jj = ((double)MW_exec_class_num_workers[temp[j]]) / exec_class_target_num_workers[temp[j]];
+			if ( jj > ii )
+			{
+				int temp = j;
+				j = i;
+				i = temp;
+			}
+		}
+	}
+	return;
+}
+
+
+int
+MWSocketRC::read_RMstate ( FILE *myfp )
+{
+	char temp[_POSIX_PATH_MAX];
+	int cluster, subcluster;
+	FILE *fp;
+
+	sprintf ( temp, "%s/%s", control_directory, worker_number_file );
+	fp = fopen ( temp, "r" );
+	if ( fp )
+	{
+		while ( fscanf ( fp, "%d %d", &cluster, &subcluster ) > 0 )
+		{
+			char condor_cmd[ 3 * _POSIX_PATH_MAX];
+			sprintf ( condor_cmd, "condor_rm %d.%d", cluster, subcluster );
+			if ( system ( condor_cmd ) < 0 )
+			{
+				MWprintf ( 10, "Couldn't remove the job %d.%d\n", cluster, subcluster );
+			}
+		}
+		fclose ( fp );
+	}
+	return 0;
+}
+
+int
+MWSocketRC::write_RMstate ( FILE *myfp )
+{
+	FILE *fp;
+	char temp[_POSIX_PATH_MAX];
+	char cmd[3 * _POSIX_PATH_MAX];
+
+	sprintf ( temp, "%s/%s", control_directory, worker_number_file );
+#ifdef WINDOWS
+	sprintf ( cmd, "copy temp %s\\%s", control_directory, worker_number_file );
+	printf("Before rename cmd is %s\n", cmd);
+#else
+	sprintf ( cmd, "/bin/mv temp %s/%s", control_directory, worker_number_file );
+#endif
+	fp = fopen ( "temp", "w" );
+	if ( !fp )
+	{
+		MWprintf ( 10, "DANGER!!, MW was not able to write into file temp\n" );
+		return -1;
+	}
+
+	for ( int i = 0; i < target_num_workers; i++ )
+	{
+		if ( socketWorkers[i].state == MWSocket_FREE )
+			continue;
+
+		fprintf ( fp, "%d %d\n", socketWorkers[i].cId, socketWorkers[i].subcId );
+	}
+
+	fclose ( fp );
+
+	if ( system ( cmd ) < 0 )
+	{
+		MWprintf ( 10, "Couldn't mv file temp into the actual file\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+char*
+MWSocketRC::process_executable_name ( char *exec, int ex_cl, int ar_cl )
+{
+	int i;
+	char newstring[_POSIX_PATH_MAX];
+	char arch[100], opsys[100];
+	char *index;
+	char *req = arch_class_attributes[ar_cl];
+	char *newexec = new char[_POSIX_PATH_MAX];
+	char exe[4 * _POSIX_PATH_MAX];
+	strcpy ( newstring, req );
+	sprintf ( newexec, "mw_exec%d", ex_cl );
+
+
+	MWprintf(20, "MWSocketRC::process_executable_name %s %d %d\n", exec, ex_cl, ar_cl);
+	// Use unsigned int to make gcc -Wall happy
+
+	// Change everything to capitals, except in cases...
+	// 1) u, x newstring[i-1] == '4' ?
+	// 2) k == 'u' || k == 'x' and newstring[i+1] == '8' (handles arch==x86_64)
+	for ( unsigned ii = 0; ii < strlen ( newstring ); ii++ )
+	{
+		int k = newstring[ii];
+		if( ! ( ( k == 'u' || k == 'x' ) && 
+			( (newstring[ii-1] == '4') || (newstring[ii+1] == '8') ) ) )
+		{
+			k = toupper(k);
+		}
+		newstring[ii] = k;
+	}
+
+    i = 0;
+    index = strstr ( newstring, "OPSYS" );
+	
+	if (index == NULL) {
+		MWprintf(10, "ERROR: OPSYS not specified in add_executable requirements string\n");
+		MWprintf(10, "newstring is %s\n", newstring);
+		exit(-1);
+	}
+
+    index += 5;
+    while ( *index == ' ' || *index == '=' || *index == '"' || *index == '\\' ) index++;
+    while ( *index && *index != ')' && *index != '"' && *index != '\\' ) opsys[i++] = *index++;
+    opsys[i] = '\0';
+
+    i = 0;
+    index = strstr ( newstring, "ARCH" );
+	if (index == NULL) {
+		MWprintf(10, "ERROR: ARCH not specified in add_executable requirements string\n");
+		exit(-1);
+	}
+    index += 4;
+    while ( *index == ' ' || *index == '=' || *index == '"' || *index == '\\' ) index++;
+    while ( *index && *index != ')' && *index != '"' && *index != '\\' ) arch[i++] = *index++;
+    arch[i] = '\0';
+
+    sprintf ( newexec, "%s.%s.%s.exe", newexec, opsys, arch );
+    unlink ( newexec );
+
+    MWprintf ( 10, "Making a link from %s to %s\n", exec, newexec );
+#if defined(WINDOWS) || defined(CYGWIN)
+    sprintf ( exe, "copy %s %s", exec, newexec );
+#else
+    sprintf ( exe, "ln -s %s %s", exec, newexec );
+#endif
+    system ( exe );
+
+    return newexec;
+}
+
+int
+MWSocketRC::initsend ( int useless )
+{
+	messageSize = 0;
+	pre_send_done = false;
+	return 0;
+}
+
+int
+MWSocketRC::send ( int toWhom, int msgtag )
+{
+	char buffer[3*sizeof(int)];
+	int retVal;
+	int sendingSocket;
+
+	if ( isMaster )
+		sendingSocket = socketWorkers[toWhom].socket;
+	else {
+		// by jae
+		// Worker
+		if( pre_send_done ) {
+			return 0;
+		}
+		sendingSocket = socketComm;
+	}
+
+	marshall_int ( msgtag, buffer );
+	marshall_int ( messageSize, buffer + sizeof(msgtag) );
+	marshall_int ( socketId, buffer + sizeof(msgtag) + sizeof(messageSize) );
+
+	retVal = finalSend ( sendingSocket, buffer, 3 * sizeof(int), 0 );
+	if ( retVal < 0 ) 
+		return retVal;
+	retVal = finalSend ( sendingSocket, sendBuffer, messageSize, 0 );
+
+	return retVal;
+}
+
+//by jae
+int
+MWSocketRC::pre_send (int msgtag )
+{
+	if( pre_send_done ) {
+		return 0;
+	}
+
+	if ( isMaster ) {
+		MWprintf ( 10, "ERROR: pre_send is not implemented for Master\n");
+		return -1;
+	}
+
+	int retVal = send(0, msgtag);
+	pre_send_done = true;
+
+	return retVal;
+}
+
+int
+MWSocketRC::finalSend ( int s, char *buf, size_t len, int flags )
+{
+#ifdef __svr4__
+	ssize_t retVal;
+#else
+	int retVal; 
+#endif
+
+
+	do
+	{
+		retVal = ::send ( s, buf, len, flags );
+	} while ( (retVal == -1) && (errno == EINTR ));
+
+	if (retVal == -1) {
+		MWprintf(10, "FinalSend::send returned -1 errno %d\n", errno);
+		return -1;
+	}
+
+	if ( retVal < (int)len ) // Make gcc -Wall happy
+	{
+		return finalSend(s, buf + retVal, len - retVal, flags);
+	}
+
+	return retVal;
+}
+
+int
+MWSocketRC::recv ( int fromWhom, int msgtag )
+{
+	recvPointer = 0;
+	if ( isMaster )
+		return masterrecv ( fromWhom, msgtag );
+	else
+		return workerrecv ( fromWhom, msgtag );
+}
+
+int
+MWSocketRC::masterrecv ( int fromWhom, int msgtag )
+{
+	char buffer[ 3 * sizeof(int) ];
+
+	// if fromWhom == -1, receive from anyone
+    if ( fromWhom <= 0 ) {
+		return masterrecvany();
+	}
+
+	// Otherwise, from one particular someone
+	{
+		// to recv from someone.
+		int retVal = finalRecv ( socketWorkers[fromWhom].socket, buffer, 3 * sizeof(int), 0 );
+		if ( retVal < 0 )
+			return retVal;
+
+		while ( msgtag > 0 && unmarshall_int ( buffer ) != msgtag )
+		{
+			retVal = finalRecv ( socketWorkers[fromWhom].socket, recvBuffer,
+							unmarshall_int ( &buffer[sizeof(int)] ), 0 );
+			if ( retVal < 0 )
+				return retVal;
+
+			retVal = finalRecv ( socketWorkers[fromWhom].socket, buffer, 3 * sizeof(int), 0 );
+			if ( retVal < 0 )
+				return retVal;
+		}
+
+		retVal = finalRecv ( socketWorkers[fromWhom].socket, recvBuffer,
+							unmarshall_int ( &buffer[sizeof(int)] ), 0 );
+
+		recvSize = retVal;
+		msgTag = unmarshall_int ( buffer );
+		whomRecv = fromWhom;
+		return retVal;
+	}
+}
+
+#ifdef USE_POLL
+
+int
+MWSocketRC::masterrecvany()
+{
+	struct pollfd pollfds[target_num_workers + 1];
+
+	int index = 0;
+	for (int i = 0; i < target_num_workers; i++) {
+		if (socketWorkers[i].socket > 0) {
+			if( socketWorkers[i].state == MWSocket_THREAD ) {
+				// skip sockets attacehd to threads
+				continue;
+			}
+			pollfds[index].fd = socketWorkers[i].socket;
+			pollfds[index].events = POLLIN; 
+			index++;
+		}
+	}
+
+	pollfds[index].fd = socketComm;
+	pollfds[index].events = POLLIN; 
+
+	index++;
+
+	int r;
+	do {
+			errno = 0;
+			//jae
+			//r = poll(pollfds, index, -1);
+			r = poll(pollfds, index, m_poll_timeout*1000);
+	} while (errno == EINTR);
+
+	if (r == -1) {
+		MWprintf(10, "poll returned -1, errno = %d\n", errno);
+		return -1;
+	}
+
+	//by jae
+	if( r == 0 ) {
+		// timeout
+		MWprintf(10, "poll timeout\n");
+		return -1;
+	}
+
+	// For all the non-accept'ing sockets
+	for (int j = 0; j < index - 1; j++) {
+		if (pollfds[j].revents & POLLHUP) {
+			// It doesn't look like linux returns this on a socket, but
+			// just in case it does...
+			return handle_killed_worker(reverseMap[pollfds[j].fd]);
+		}
+		if (pollfds[j].revents & POLLIN) {
+			return handle_finished_worker(reverseMap[pollfds[j].fd]);
+		}
+
+		if (pollfds[j].revents != 0) {
+			MWprintf(10, "Unexpected return from poll for fd %d: %x\n", pollfds[j].fd, pollfds[j].revents);
+		}
+	}
+
+	if (pollfds[index - 1].revents) {
+		return handle_starting_worker();
+	}
+
+
+	MWprintf(10, "USE_POLL::masterrecvany shouldn't get here\n");
+	return -1;
+
+}
+#endif
+
+#ifndef USE_POLL
+int 
+MWSocketRC::masterrecvany()
+{
+
+		int retVal;
+		int i;
+		FD_ZERO ( &rfds );
+		FD_SET ( socketComm, &rfds );
+
+		for ( i = 0; i < FD_SETSIZE; i++ )
+		{
+			int worker_id = reverseMap[i];
+			if ( worker_id >= 0 )
+			{
+				if( socketWorkers[worker_id].state == MWSocket_THREAD ) {
+					// skip sockets attacehd to threads
+					continue;
+				}
+				FD_SET ( i, &rfds );
+			}
+		}
+
+
+		struct timeval timeout;
+		timeout.tv_usec = 0;
+		timeout.tv_sec = m_poll_timeout;
+
+		do
+		{
+			retVal = select ( FD_SETSIZE, &rfds, NULL, NULL, &timeout );
+		} while ((retVal == -1) && ( errno == EINTR ));
+
+		//by jae
+		if( retVal == 0 ) {
+			// timeout
+			MWprintf(10, "select timeout\n");
+			return -1;
+		}
+
+		if ( retVal < 0 )
+		{
+			MWprintf ( 10, "Select returned -1, errno = %d\n", errno );
+			//exit(1);
+			// don't need to exit if select returns zero, just remove the worker that went down
+            fd_set temprfds;
+            FD_ZERO ( &rfds );
+            for ( i = 0; i < FD_SETSIZE; i++ )
+            {
+                int worker_id = reverseMap[i];
+                if ( worker_id >= 0 )
+                {
+					if( socketWorkers[worker_id].state == MWSocket_THREAD ) {
+						// skip sockets attacehd to threads
+						continue;
+					}
+
+                    struct timeval zero;
+                    zero.tv_sec=0;
+                    zero.tv_usec=0;
+                    FD_ZERO ( &temprfds );
+                    FD_SET ( i, &temprfds );
+                    int selRet;
+                    do
+                    {
+                        selRet = select ( FD_SETSIZE, &temprfds, NULL, NULL, &zero );
+                    } while ( errno == EINTR );
+                    if( selRet < 0 )
+                    {
+                        int len = handle_killed_worker ( reverseMap[i] );
+                        reverseMap[i] = -1;
+                        return len;
+                    }
+                }
+			}
+		}
+		if ( retVal == 0 )
+		{
+			MWprintf ( 10, "Unexpected 0 return from select, exitting\n" );
+			exit(1);
+		}
+
+		return checkSockets ( );
+}
+
+#endif
+int
+MWSocketRC::workerrecv ( int fromWhom, int msgtag )
+{
+	// int temp;
+	int retVal;
+	char buffer [ 3 * sizeof(int) ];
+
+	retVal = finalRecv ( socketComm, buffer, 3 * sizeof(int), 0 );
+	if ( retVal < 0 )
+		return retVal;
+
+	while ( msgtag > 0 && unmarshall_int( buffer ) != msgtag )
+	{
+		retVal = finalRecv ( socketComm, recvBuffer, unmarshall_int ( &buffer[sizeof(int)] ), 0 );
+		if ( retVal < 0 )
+			return retVal;
+
+		retVal = finalRecv ( socketComm, buffer, 3 * sizeof(int), 0 );
+		if ( retVal < 0 )
+			return retVal;
+	}
+
+	retVal = finalRecv ( socketComm, recvBuffer, unmarshall_int( &buffer[sizeof(int)] ), 0 );
+
+	recvSize = retVal;
+	msgTag = unmarshall_int ( buffer );
+	whomRecv = fromWhom;
+	return retVal;
+}
+
+int
+MWSocketRC::nrecv ( int fromWhom, int msgtag )
+{
+    recvPointer = 0;
+    if( isMaster )
+	{
+		MWprintf(10, "Master should not call this\n");
+		exit(-1);
+	}
+	int retVal;
+	char buffer [ 3 * sizeof(int) ];
+
+	retVal = nfinalRecv ( socketComm, buffer, 3 * sizeof(int), 0 );
+	if ( retVal == -2 ) // nothing in the socket, return from call
+	{
+		recvSize = 0;//retVal;
+		msgTag = NO_MESSAGE;
+		whomRecv = fromWhom;
+        return 0;
+	}
+	while ( msgtag > 0 && unmarshall_int( buffer ) != msgtag )
+	{
+		retVal = finalRecv ( socketComm, recvBuffer, unmarshall_int ( &buffer[sizeof(int)] ), 0 );
+		if ( retVal < 0 )
+			return retVal;
+
+		retVal = finalRecv ( socketComm, buffer, 3 * sizeof(int), 0 );
+		if ( retVal < 0 )
+			return retVal;
+	}
+	retVal = finalRecv ( socketComm, recvBuffer, unmarshall_int( &buffer[sizeof(int)] ), 0 );
+	recvSize = retVal;
+	msgTag = unmarshall_int ( buffer );
+	whomRecv = fromWhom;
+	return retVal;
+}
+
+int
+MWSocketRC::nfinalRecv ( int s, void *buf, size_t len, int flags )
+{
+	int retVal;
+
+	fd_set sfd;
+	FD_ZERO( &sfd );
+	FD_SET( s, &sfd );
+	struct timeval zero;
+	zero.tv_sec=0; zero.tv_usec=0;
+	int selRet = select(s+1, &sfd, NULL, NULL, &zero);
+	if( selRet == 0 )
+		return -2;
+
+	do
+	{
+		retVal = ::recv ( s, (char *)buf, len, MSG_PEEK );
+/*  
+if(retVal == -1 && errno == EAGAIN){
+            fcntl(s, F_SETFL, fdflags);
+            MWprintf(51,"Nothing in socket, returning\n");
+            return -1;
+            }
+*/
+	} while ( errno == EINTR || retVal < (int)len ); // Make -Wall happy
+
+	do
+	{
+        retVal = ::recv ( s, (char *)buf, len, flags );
+	} while ((retVal == -1) && ( errno == EINTR ));
+
+	if ( retVal < (int)len ) // Make gcc -Wall happy
+	{
+		MWprintf ( 10, "Couldn't properly do a recv from socket %d: retVal = %d, errno = %d\n", s, retVal, errno );
+		return -1;
+	}
+
+	return retVal;
+}
+
+int
+MWSocketRC::finalRecv ( int s, char *b, size_t len, int flags )
+{
+	int retVal; 
+
+	char *buf = (char *) b;
+
+	int total = 0;
+	retVal = 0;
+
+	timedOut = false;
+	timeOutSocket = s;
+
+	do
+	{
+
+			// First time through, these are no-ops
+		len -= retVal;
+		buf += retVal;
+
+		retVal = ::recv ( s, buf, len, flags );
+
+		if( (timedOut == true) || (retVal < 0 && errno != EINTR)) {
+			MWprintf(10, "recv returned -1: errno is %d\n", errno);
+			return -1;
+		}
+
+        if ( retVal == 0 ) return 0; // Socket closed
+
+		if (errno == EINTR) {
+			retVal = 0;
+		}
+		total += retVal;
+		
+	} while (( errno == EINTR ) || (retVal < (int)len)) ;
+
+	if ( retVal < (int)len ) // Make gcc -Wall happy
+	{
+		return 0;
+	}
+
+	return total;
+}
+
+int
+MWSocketRC::creatAndBind ( int port )
+{
+	int retVal;
+	int bufSize = MAX_TCP_BUFFER;
+	struct sockaddr_in myAddr;
+
+	retVal = socket ( AF_INET, SOCK_STREAM, 0 );
+	if ( retVal < 0 )
+	{
+		MWprintf ( 10, "Couldn't open a socket errno %d\n", errno );
+		::exit(1);
+	}
+	if ( setsockopt( retVal, SOL_SOCKET, SO_SNDBUF, (char *)&bufSize, sizeof(int)) != 0)
+	{
+		MWprintf ( 10, "Couldn't set the send buffer size: errno %d\n", errno );
+		close ( retVal );
+		::exit(1);
+	}
+	if ( setsockopt( retVal, SOL_SOCKET, SO_RCVBUF, (char *)&bufSize, sizeof(int)) != 0)
+	{
+		MWprintf ( 10, "Couldn't set the recv buffer size: errno %d\n", errno );
+		close ( retVal );
+		::exit(1);
+	}
+	memset(&myAddr, 0, sizeof(myAddr));
+	myAddr.sin_family = AF_INET;
+	(myAddr.sin_addr).s_addr = htonl(INADDR_ANY);
+	myAddr.sin_port = htons(port);
+
+	int range = 50; // range of ports to scan
+	int range_counter = 0;
+	while( bind( retVal, (struct sockaddr *) &myAddr, sizeof(myAddr) ) < 0 && range_counter < range)
+	{
+		//MWprintf ( 10, "Couldn't bind the socket to port: errno %d\n", errno );
+		port++;
+		myAddr.sin_port = htons(port);
+		range_counter++;
+		//close ( retVal );
+		//::exit(1);
+	}
+	if ( range_counter >= range )
+	{
+		MWprintf ( 10, "Couldn't bind the socket to port: errno %d\n", errno );
+		close ( retVal );
+		::exit(1);
+	}
+	else
+		MWprintf ( 10, "Socket bound to port: %d\n", port );
+	if ( isMaster == TRUE )
+		masterSocket = port;
+
+	return retVal;
+}
+
+int
+MWSocketRC::checkSockets ( )
+{
+	char buf;
+	int len = 1;
+	// First we check the read list
+	for ( int i = 0; i < FD_SETSIZE; i++ )
+	{
+		if ( i == socketComm )
+			continue;
+
+		if ( FD_ISSET ( i, &rfds ) )
+		{
+			cyclePosition = i;
+			toBlock = FALSE;
+			FD_CLR ( i, &rfds );
+
+			//by jae
+			int worker_id = reverseMap[i];
+			if( worker_id >= 0 ) {
+				if( socketWorkers[worker_id].state == MWSocket_THREAD ) {
+					continue;
+				}
+			}
+
+			int retVal;
+			do
+			{
+				retVal = ::recv ( i, &buf, len, MSG_PEEK );
+			} while ( (retVal < 0) && (errno == EINTR ));
+			if ( errno != 0 )
+			{
+				len = handle_killed_worker ( reverseMap[i] );
+				reverseMap[i] = -1;
+				return len;
+			}
+			else if ( retVal <= 0 )
+			{
+				len = handle_killed_worker ( reverseMap[i] );
+                reverseMap[i] = -1;
+                return len;
+			}
+			else
+			{
+				return handle_finished_worker ( reverseMap[i] );
+			}
+		}
+	}
+
+	// Finally let us examine the socketComm.
+	if ( FD_ISSET ( socketComm, &rfds ) )
+	{
+		// someone is trying to connect to us.
+		FD_CLR ( socketComm, &rfds );
+		return handle_starting_worker ( );
+	}
+	cyclePosition = 0;
+	toBlock = TRUE;
+	return -1;
+}
+
+int
+MWSocketRC::handle_starting_worker ( )
+{
+	int temp;
+	int remote;
+	char buf[sizeof(int)];
+
+	temp = accept ( socketComm, 0, 0 ); 
+	if ( temp < 0 )
+	{
+		MWprintf ( 10, "Accept failed: errno %d\n", errno );
+		return -1;
+	}
+
+#ifndef WINDOWS
+	signal(SIGALRM, alarmed);
+	alarm(5);
+#endif
+	if ( finalRecv ( temp, buf, sizeof(int), 0 ) < 0 )
+	{
+		MWprintf ( 10, "First recv from the new guy failed: errno %d\n", errno );
+#ifndef WINDOWS
+	alarm(0);
+#endif
+		close ( temp );
+		return -1;
+	}
+#ifndef WINDOWS
+	alarm(0);
+#endif
+	remote = unmarshall_int ( buf );
+
+	if ( !&socketWorkers[remote] )
+	{
+		MWprintf ( 10, "How can the socket worker structure be null from a worker that is starting\n");
+		return -1;
+	}
+
+    if ( socketWorkers[remote].socket != -1 )
+    {  
+		close(temp);
+
+		// What's happened here is that the worker has died and been restarted by
+		// Condor, but the socket connection hasn't gone away.  This can happen!
+		// Since we don't have user-level keep-alives, if a machine's kernel panics,
+		// or loses power, it is possible for Condor to realize the machine has gone
+		// away before we do.  Since we can only return one value to the higher level,
+		// we close the new socket (which will make the new worker restart again), 
+		// and mark the old worker dead to the upper level. 
+
+        int len = handle_killed_worker ( remote );
+        if ( reverseMap[socketWorkers[remote].socket] == remote ) // if mapping of socket to worker not already taken by another worker, invalidate
+            reverseMap[socketWorkers[remote].socket] = -1;
+        MWprintf(10, "worker %d tried to come back from eviction, killed it\n",remote);
+        return len;
+   }
+
+	socketWorkers[remote].state = MWSocket_EXECUTING;
+	socketWorkers[remote].socket = temp;
+	if ( socketWorkers[remote].socket < 0 )
+	{
+		MWprintf ( 10, "Accept failed: errno %d\n", errno );
+		return -1;
+	}
+	FD_SET ( socketWorkers[remote].socket, &rfds );
+	reverseMap[socketWorkers[remote].socket] = remote;
+
+	whomRecv = remote;
+	msgTag = MWSocketMessageTags[MWSocketHostAdd];
+	recvSize = 0;
+	return 0;
+}
+
+int
+MWSocketRC::handle_finished_worker ( int i )
+{
+	// int temp;
+	int retVal;
+	char buffer [ 3 * sizeof(int) ];
+
+	//by jae
+	if( i < 0 ) {
+		return -1;
+	}
+
+	if ( !&socketWorkers[i] )
+	{
+		MWprintf ( 10, "How can the socket worker structure be null from a worker that is executing\n");
+		return -1;
+	}
+
+	//by jae
+	if( socketWorkers[i].state == MWSocket_THREAD ) {
+		return -1;
+	}
+
+#ifndef WINDOWS
+	signal(SIGALRM, alarmed);
+	alarm(5);
+#endif
+	retVal = finalRecv ( socketWorkers[i].socket, buffer, 3 * sizeof(int), 0 );
+	if ( retVal < 0 ) {
+#ifndef WINDOWS
+	alarm(0);
+#endif
+		return retVal;
+	}
+#ifndef WINDOWS
+	alarm(0);
+#endif
+
+	if (retVal == 0) {
+		MWprintf(10, "read from worker returned 0, killing off disconnected worker\n");
+		return handle_killed_worker(i);
+	}
+	retVal = finalRecv ( socketWorkers[i].socket, recvBuffer, unmarshall_int ( &buffer[sizeof(int)] ), 0 );
+
+	recvSize = retVal;
+	msgTag = unmarshall_int ( buffer ) ;
+	whomRecv = i;
+	return retVal;
+}
+
+int
+MWSocketRC::handle_killed_worker ( int i )
+{
+	MWprintf ( 10, "A worker is killed %d\n", i );
+	//by jae
+	if( i < 0 ) {
+		return -1;
+	}
+	if ( !&socketWorkers[i] )
+	{
+		MWprintf ( 10, "How can the socket worker structure be null from a worker that is executing\n");
+		return -1;
+	}
+
+	marshall_int ( i, recvBuffer );
+	recvSize = sizeof(int);
+	msgTag = MWSocketMessageTags[MWSocketTaskExit];
+	whomRecv = i;
+
+	killWorker(i);
+	return 0;
+}
+
+int
+MWSocketRC::bufinfo ( int buf_id, int *len, int *tag, int *sending_host )
+{
+	*sending_host = whomRecv;
+	*tag = msgTag;
+	*len = recvSize;
+	return 0;
+}
+
+int
+MWSocketRC::do_spawn ( int nWorkers, int ex_cl )
+{
+	int cID = -1;
+	int i;
+
+	char sub_file[_POSIX_PATH_MAX];
+	char sub_file1[_POSIX_PATH_MAX];
+	char temp[65536];
+	char exe[_POSIX_PATH_MAX];
+	FILE *ptr;
+	char requirements[10 * _POSIX_PATH_MAX]; // 10 is max num executables
+
+	if ( nWorkers <= 0 ) return 0;
+
+	int *ids = new int[nWorkers];
+
+	sprintf( sub_file1, "submit_file.%d", subId );
+	sprintf( sub_file, "./%s/submit_file.%d", control_directory, subId++ );
+	sprintf( exe, "condor_submit ./%s/%s", control_directory, sub_file1 );
+
+
+	FILE *f = Open( sub_file, "w" );
+	if ( f == NULL )
+	{
+		MWprintf ( 10, "Couldn't open the submitfile for writing\n");
+		return -1;
+	}
+    	
+	int index = 0;
+	for ( i = 0; i < target_num_workers && index < nWorkers; i++ ) 
+	{
+		if ( socketWorkers[i].state == MWSocket_FREE ) 
+		{
+			ids[index++] = i;
+		}
+	}
+
+	if ( index < nWorkers ) 
+	{
+		MWprintf ( 10, "In MW-File hostaddlogic asking for more workers than target_num_workers\n");
+		MWprintf ( 10, "Had asked %d workers but I am adding only %d\n", nWorkers, index );
+		nWorkers = index;
+	}
+
+	fprintf ( f, "Universe = Vanilla\n");
+	fprintf( f, "Executable = mw_exec%d.$$(Opsys).$$(Arch).exe\n", ex_cl );
+
+	bool tempfirst = TRUE;
+	for ( i = 0; i < num_executables; i++ )
+	{
+		if ( worker_executables[i]->exec_class == ex_cl )
+		{
+			if ( tempfirst == TRUE )
+			{
+				sprintf ( requirements, "( ( %s ) ", arch_class_attributes[worker_executables[i]->arch_class] );
+				tempfirst = FALSE;
+			}
+			else
+			{
+				sprintf ( requirements, "%s || ( %s ) ", requirements, arch_class_attributes[worker_executables[i]->arch_class] );
+			}
+		}
+	}
+	//strcat ( requirements, "&& (Machine==\"quasar-16.biostat.wisc.edu\")");
+	strcat ( requirements, " )" );
+	for ( i = 0; i < nWorkers; i++ ) 
+	{
+		fprintf( f, "arguments = %d %d %d %s\n", ids[i], masterId, masterSocket, masterAddress );
+		fprintf( f, "log = %s/log_file\n", control_directory );
+
+		fprintf( f, "Output = output_file.%d\n", ids[i] );
+		fprintf( f, "Error = error_file.%d\n", ids[i] );
+						       
+		fprintf( f, "Requirements = %s\n ", requirements );
+
+		fprintf( f, "should_transfer_files = Yes\n"); 
+		fprintf( f, "when_to_transfer_output = ON_EXIT\n");
+
+		FILE *userf = Open( "worker_attributes", "r" );
+		if( userf == NULL ) 
+		{
+			MWprintf( 10, "No worker_attributes file, assuming Condor defaults\n" );
+		}
+		else 
+		{
+			int c;
+			while( ( c = getc( userf ) ) != EOF ) 
+			{
+				putc( c, f );
+			}
+			Close( userf );
+		}
+
+
+			// send worker MWprintf back immediately, don't wait
+			// for worker exit.  May want to turn this off for
+			// better performance, but this is really handy for debugging
+
+		// This causes windows clients to hang, so leave off by default
+		//fprintf( f, "stream_output = true\n");
+		//fprintf( f, "stream_error = true\n");
+
+			// Have Condor give us workers sorted by MIPS
+		fprintf( f, "rank = Mips\n");
+		
+			// If a job starts, then exits before connecting to the
+			// socket master, we want condor to restart the job.
+			// otherwise, the master doen't know the job has left
+			// the queue, and will wait indefinitely for it to start
+			// only need this for Socket
+		fprintf( f, "on_exit_remove = false\n");
+		fprintf( f, "Queue\n" );
+	}
+	fclose( f );
+
+	MWprintf (10, "About to call condor_submit %s\n", exe);
+	ptr = popen ( exe, "r" );
+	if ( ptr != NULL ) 
+	{
+		while ( fscanf(ptr, "%s", temp ) >= 0 ) 
+		{
+
+			if ( strcmp ( temp, "cluster" ) == 0 ) 
+			{
+
+				fscanf( ptr, "%s", temp );
+				cID = atoi ( temp );
+				MWprintf ( 10, "Spawned to cluster %d\n", cID );
+				break;
+			}
+		}
+		if ( ptr ) pclose ( ptr ); 
+		for ( i = 0; i < nWorkers; i++ ) 
+		{
+			int tempp = ids[i];
+			socketWorkers[tempp].state = MWSocket_SUBMITTED;
+			socketWorkers[tempp].cId = cID;
+			socketWorkers[tempp].subcId = i;
+			socketWorkers[tempp].arch = -1;
+			socketWorkers[tempp].socket = -1;
+			socketWorkers[tempp].exec_class = ex_cl;
+		}
+	}
+	else 
+	{
+		MWprintf ( 10, "Couldn't popen in FileRC\n");
+		return -1;
+	}
+
+	delete []ids;
+	write_RMstate ( NULL );
+	return nWorkers;
+}
+
+int
+MWSocketRC::pack ( const char *bytes, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(char) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(char), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride;
+	for ( int i = 0; i < nitem; i++ )
+	{
+		memcpy ( &sendBuffer[messageSize], &(bytes [ i * stride ]), sizeof(char) );
+		messageSize += sizeof(char);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const float *f, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(float) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(float), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(float);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_float ( f[ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(float);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const double *d, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(double) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(double), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(double);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_double ( d [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(double);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const int *ii, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(int) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(int), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(int);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_int ( ii [ i * stride ],  &sendBuffer[messageSize] );
+		messageSize += sizeof(int);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const unsigned int *ui, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(unsigned int) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(unsigned int), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+
+	bytes_packed_ += nitem / stride * sizeof(unsigned int);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_uint ( ui [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(unsigned int);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const short *sh, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(short) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(short), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(short);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_short ( sh [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(short);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const unsigned short *us, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(unsigned short) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(unsigned short), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(unsigned short);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_ushort ( us [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(unsigned short);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const long *l, int nitem, int stride )
+{
+   
+	if ( messageSize + nitem * sizeof(long) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(long), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(long);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_long ( l [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(long);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const unsigned long *ul, int nitem, int stride )
+{
+	if ( messageSize + nitem * sizeof(unsigned long) > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + nitem * sizeof(unsigned long), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += nitem / stride * sizeof(unsigned long);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		marshall_ulong ( ul [ i * stride ], &sendBuffer[messageSize] );
+		messageSize += sizeof(unsigned long);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::pack ( const char *str )
+{
+	int len = strlen ( str );
+
+	if ( messageSize + sizeof(int) * len > MWSOCKET_MAX_MSG_SIZE )
+	{
+		MWprintf ( 10, "ERROR: Maximum Message size exceeded, (%d > %d), cannot pack\n",
+			   messageSize + len * sizeof(int), MWSOCKET_MAX_MSG_SIZE);
+		return -1;
+	}
+
+	bytes_packed_ += strlen(str);
+	marshall_int ( len, &sendBuffer[messageSize] );
+	messageSize += sizeof(int);
+	memcpy ( &sendBuffer[messageSize], str, len );
+	messageSize += len;
+
+	return 0;
+}
+
+// by jae
+// Send raw data directly
+int MWSocketRC::raw_pack( char* buf, int len ) 
+{
+	// Currently, this function works only for Worker
+	if( isMaster ) {
+		MWprintf ( 10, "ERROR: raw_pack is not implemented for Master\n");
+		return -1;
+	}
+
+	return finalSend ( socketComm, buf, len, 0 );
+}
+
+void MWSocketRC::thread_start(int worker_id) 
+{
+	socketWorkers[worker_id].state = MWSocket_THREAD;
+}
+
+void MWSocketRC::thread_stop(int worker_id) 
+{
+	if( socketWorkers[worker_id].state == MWSocket_THREAD ) {
+		socketWorkers[worker_id].state = MWSocket_EXECUTING;
+	}
+}
+
+/// Read raw data from Worker ID
+int MWSocketRC::raw_unpack( int from_whom, char* buf, int len ) 
+{
+	if( !isMaster ) {
+		MWprintf ( 10, "ERROR: raw_unpack is not implemented for Worker\n");
+		return -1;
+	}
+	if ( from_whom < 0 ) {
+		MWprintf ( 10, "ERROR: raw_unpack has invalid Worker ID\n");
+		return -1;
+	}
+
+	return finalRecv ( socketWorkers[from_whom].socket, buf, len, 0 );
+}
+
+int
+MWSocketRC::unpack ( char *bytes, int nitem, int stride )
+{
+	if ( int(recvPointer + nitem * sizeof(char)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(char);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		memcpy ( &(bytes [ i * stride ]), &recvBuffer[recvPointer], sizeof(char) );
+		recvPointer += sizeof(char);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( float *f, int nitem, int stride )
+{
+	if ( int(recvPointer + nitem * sizeof(float)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(float);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		f [ i * stride ] = unmarshall_float ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(float);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( double *d, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(double)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(double);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		 d [ i * stride ] = unmarshall_double ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(double);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( int *ii, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(int)) > recvSize ) // Make gcc -Wall happy
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(int);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		ii [ i * stride ] = unmarshall_int ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(int);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( unsigned int *ui, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(unsigned int)) > recvSize ) // Make gcc -Wall happy
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned int);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		ui [ i * stride ] = unmarshall_uint ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(unsigned int);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( short *sh, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(short)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(short);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		sh [ i * stride ] = unmarshall_short ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(short);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( unsigned short *us, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(unsigned short)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned short);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		us [ i * stride ] = unmarshall_ushort ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(unsigned short);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( long *l, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(long)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(long);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		l [ i * stride ] = unmarshall_long ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(long);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( unsigned long *ul, int nitem, int stride )
+{
+	if ( int (recvPointer + nitem * sizeof(unsigned long)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned long);
+	for ( int i = 0; i < nitem; i++ )
+	{
+		ul [ i * stride ] = unmarshall_ulong ( &recvBuffer[recvPointer] );
+		recvPointer += sizeof(unsigned long);
+	}
+
+	return 0;
+}
+
+int
+MWSocketRC::unpack ( char *str )
+{
+	int len;
+
+	if ( int (recvPointer + sizeof(int)) > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	len = unmarshall_int ( &recvBuffer[recvPointer] );
+	recvPointer += sizeof(int);
+
+	if ( recvPointer + len > recvSize )
+	{
+		MWprintf ( 10, "ERROR: You can't unpack more than what's received\n");
+		return -1;
+	}
+
+	memcpy ( str, &recvBuffer[recvPointer], len );
+	str[len] = '\0';
+	recvPointer += len;
+
+	bytes_unpacked_ += strlen(str);
+
+	return 0;
+}
+
+int
+MWSocketRC::killWorkers ( )
+{
+	for ( int i = 0; i < target_num_workers; i++ )
+	{
+		if ( socketWorkers[i].state == MWSocket_SUBMITTED || socketWorkers[i].state == MWSocket_EXECUTING || socketWorkers[i].state == MWSocket_THREAD) 
+		{
+			char exe[ 8 * _POSIX_PATH_MAX];
+
+			sprintf ( exe, "condor_rm %d.%d", socketWorkers[i].cId, socketWorkers[i].subcId );
+			if ( system ( exe ) < 0 )
+			{
+				MWprintf ( 10, "ERROR: Couldnt kill the worker %d, condor job %d.%d\n", i, socketWorkers[i].cId, socketWorkers[i].subcId );
+			}
+		}
+	}
+
+	return 0;
+}
+
+void
+MWSocketRC::closeSockets ( )
+{
+	close ( socketComm );
+	return;
+}
+
+int
+MWSocketRC::killWorker ( int i )
+{
+	//by jae
+	if( i < 0 ) {
+		return -1;
+	}
+
+	close ( socketWorkers[i].socket );
+	hostadd_reqs[socketWorkers[i].exec_class]++;
+
+    socketWorkers[i].state = MWSocket_SUBMITTED;
+	socketWorkers[i].socket = -1;
+    write_RMstate ( NULL );
+	return 0;
+}
+
+inline void
+MWSocketRC::marshall_int ( int n, char *buf )
+{
+	unsigned int k = htonl ( n );
+	memcpy ( buf, &k, sizeof(int) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_uint ( unsigned int n, char *buf )
+{
+	unsigned int k = htonl ( n );
+	memcpy ( buf, &k, sizeof(unsigned int) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_short ( short n, char *buf )
+{
+	unsigned short k = htons ( n );
+	memcpy ( buf, &k, sizeof(short) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_ushort ( unsigned short n, char *buf )
+{
+	unsigned short k = htons ( n );
+	memcpy ( buf, &k, sizeof(unsigned short) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_long ( long n, char *buf )
+{
+	long k = htonl ( n );
+	memcpy ( buf, &k, sizeof(long) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_ulong ( unsigned long n, char *buf )
+{
+	unsigned long k = htonl ( n );
+	memcpy ( buf, &k, sizeof(unsigned long) );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_float ( float n, char *buf )
+{
+	int k = *(int *)&n; 
+	marshall_int ( k, buf );
+	return;
+}
+
+inline void
+MWSocketRC::marshall_double ( double n, char *buf )
+{
+
+		// Union utopia is the best flavor of babcock ice cream
+	union utopia {
+		double d;
+		struct {
+			int low;
+			int high;
+		} ints;
+		char   bytes[8];
+	};
+
+	union utopia u;
+	u.d = n;
+
+
+	if ( htonl ( 3 ) == 3 )
+	{
+		marshall_int ( u.ints.low,  buf );
+		marshall_int ( u.ints.high, buf + sizeof(int) );
+	}
+	else
+	{
+		marshall_int ( u.ints.high, buf );
+		marshall_int ( u.ints.low, buf + sizeof(int) );
+	}
+	return;
+}
+
+inline int
+MWSocketRC::unmarshall_int ( char *buf )
+{
+	int k;
+	memcpy ( &k, buf, sizeof(int) );
+	return ntohl ( k );
+}
+
+inline unsigned int
+MWSocketRC::unmarshall_uint ( char *buf )
+{
+	unsigned int k;
+	memcpy ( &k, buf, sizeof(unsigned int) );
+	return ntohl ( k );
+}
+
+inline short
+MWSocketRC::unmarshall_short ( char *buf )
+{
+	short k;
+	memcpy ( &k, buf, sizeof(short) );
+	return ntohs ( k );
+}
+
+inline unsigned short
+MWSocketRC::unmarshall_ushort ( char *buf )
+{
+	unsigned short k;
+	memcpy ( &k, buf, sizeof(unsigned short) );
+	return ntohs ( k );
+}
+
+inline long
+MWSocketRC::unmarshall_long ( char *buf )
+{
+	long k;
+	memcpy ( &k, buf, sizeof(long) );
+	return ntohl ( k );
+}
+
+inline unsigned long
+MWSocketRC::unmarshall_ulong ( char *buf )
+{
+	unsigned long k;
+	memcpy ( &k, buf, sizeof(unsigned long) );
+	return ntohl ( k );
+}
+
+inline float
+MWSocketRC::unmarshall_float ( char *buf )
+{
+	int k = unmarshall_int ( buf );
+	float f = *(float *)&k;
+	return f;
+}
+
+inline double
+MWSocketRC::unmarshall_double ( char *buf )
+{
+	double d;
+	int f,s;
+
+	f = unmarshall_int ( buf );
+	s = unmarshall_int ( buf + sizeof(int) );
+	if ( ntohl ( 3 ) == 3 )
+	{
+		memcpy ( &d, &f, sizeof(int) );
+		memcpy ( ((char *)&d) + sizeof(int), &s, sizeof(int) );
+	}
+	else
+	{
+		memcpy ( &d, &s, sizeof(int) );
+		memcpy ( ((char *)&d) + sizeof(int), &f, sizeof(int) );
+	}
+	return d;
+}
+
+#ifdef NWSENABLED
+typedef int (*callBackFcnDefn)(void* arg, int status);
+void setRestartFunction ( 
+				callBackFcnDefn /*cbRestart*/, 
+				void* 			/*cbRestartArg*/, 
+				callBackFcnDefn /*cbCkpt*/, 
+				void* 			/*cbCkptArg*/ )
+{
+}
+
+#endif
+//BUFFER
+int 
+MWSocketRC::recv_all( int from_whom, int msgtag )
+{
+	MWprintf(91, "Not implemented yet for MW-Socket.\n");
+	return 0;
+}
+
+int 
+MWSocketRC::setrbuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-Socket.\n");
+	return -1;
+}
+
+int 
+MWSocketRC::freebuf( int bid )
+{
+	MWprintf(91, "Not implemented yet for MW-Socket.\n");
+	return -1;
+}
+
+MWList<void>* 
+MWSocketRC::recv_buffers()
+{
+	MWprintf(91, "Not implemented yet for MW-Socket.\n");
+	return NULL;
+}
+
+int 
+MWSocketRC::next_buf()
+{
+	MWprintf(91, "Not implemented yet for MW-Socket.\n");
+	return -1;
+}
diff --git a/MW/src/RMComm/MW-Socket/MWSocketRC.h b/MW/src/RMComm/MW-Socket/MWSocketRC.h
new file mode 100644
index 0000000..27c6373
--- /dev/null
+++ b/MW/src/RMComm/MW-Socket/MWSocketRC.h
@@ -0,0 +1,434 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+  *
+  * Condor Software Copyright Notice
+  * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+  * University of Wisconsin-Madison, WI.
+  *
+  * This source code is covered by the Condor Public License, which can
+  * be found in the accompanying LICENSE.TXT file, or online at
+  * www.condorproject.org.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+  * RIGHT.
+  *
+  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+
+#ifndef MWSOCKETRC_H
+#define MWSOCKETRC_H
+
+#include "../MWRMComm.h"
+#include <stdio.h>
+
+#ifdef WINDOWS
+#define _POSIX_PATH_MAX 1024
+#endif
+
+typedef enum { MWSocket_FREE, MWSocket_SUBMITTED, MWSocket_EXECUTING, MWSocket_THREAD } SocketWorkerState;
+#define MWSOCKET_MAX_MSG_SIZE (16 * 1024 * 1024)
+
+#define MWSocketHostAdd 0
+#define MWSocketHostDelete 1
+#define MWSocketTaskExit 2
+#define MWSocketTaskSuspend 3
+#define MWSocketTaskResume 4
+#define MWSocketChecksumError 5
+
+static int MWSocketMessageTags[] = 
+		{	HOSTADD,
+			HOSTDELETE,
+			HOSTDELETE,
+			HOSTSUSPEND,
+			HOSTRESUME,
+			CHECKSUM_ERROR
+		};
+
+typedef struct
+{
+	SocketWorkerState state;
+	int arch;
+	int cId;
+	int subcId;
+	int socket;
+	int exec_class;
+}SocketWorker;
+
+/** 
+	A Resource Management and Communication class that uses Condor 
+	for underlying support of resource managament. Some crude inter-process 
+	communication is provided using the userlog feature of Condor.
+	resource management.
+
+*/
+
+class MWSocketRC : public MWRMComm
+{
+
+  public:
+
+	///  Constructor 
+	MWSocketRC( bool maste, int id );
+
+	///  Destructor 
+	~MWSocketRC();
+
+ /** @name A. Resource Management Routines
+
+	 Here we implement the pure virtual functions found in 
+	 ur parent class, MWRMComm.
+ */
+ //@{
+
+	/**  Initialises. Depending on whether it is master or worker instance
+	     it initializes all the internal variables. */
+	int setup ( int argc, char *argv[], int *mytid, int *mastertid );
+
+	/**  Shutdown. Kills all the workers if it is master */
+	void exit ( int exitval );
+
+	/**  Initialize workers if already some have started up */
+	int init_beginning_workers ( int *nworkers, MWWorkerID ***workers );
+
+	/** Restart function */
+	int restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg );
+
+	/**  This function is actually a misonomer. It DOES NOT spawn a new
+	     worker. Rather it just inits the structure that is passed on to 
+	     it */
+	int start_worker ( MWWorkerID *w );
+
+	/**  This function removes a existing worker */
+	int removeWorker ( MWWorkerID *w );
+
+	/**  Figure out whether or not to generate a new worker depending on
+	     whether new requests have been made */
+	int hostaddlogic ( int *w );
+
+	/** A routine for reading in the MW-File state at the time 
+	 *  of checkpointing.
+	 */
+	int read_RMstate ( FILE *fp = NULL );
+
+	/** A routine for writing in the MW-File state at the time 
+	 *  of checkpointing.
+	 */
+	int write_RMstate ( FILE *fp = NULL );
+
+	char* process_executable_name ( char *execut, int, int );
+
+		//@}
+
+	/** @name B. Communication Routines
+
+		Unlike MWPvmRC, the communication routines are non-trivial 
+		because Condor provides no inter-process comminucation.
+		Thus we use files for communication. So a send is essentially
+		a file write operation and a recv is a file-read operation.
+		We maintain 2 lists:- The sendList and recvList for taking 
+		care of what is to be written/read to/from the files. As in
+		pvm a user beings by calling initsend which creates a new list.
+		Calls to pack insert into the list what is being packed. And
+		finally a send writes the entire thing into a file 
+		identified by the destination. Corresponding things happpen
+		in recv.
+	*/
+	//@{
+
+	/** A Function called to know which worker had an exception event */
+	void who ( int *wh );
+
+	/**  Initialize the send buffer */
+	int initsend ( int useless = 0 );
+
+	/**  Send function */
+	int send ( int toWhom, int msgtag );
+
+	// by jae
+	/** Send function for Jae */
+	int pre_send ( int msgtag );
+	void setPollTimeOut(int secs) { m_poll_timeout = secs; }
+
+	/**  Recv function */
+	int  recv ( int fromWhom, int msgtag );
+
+	/**  Non-blocking version of recv */
+	int nrecv (int fromWhom, int msgtag);
+
+	/**  Get some info about the recv buffer */
+	int bufinfo ( int buf_id, int *len, int *tag, int *sending_host );
+
+	/// pack some bytes
+	int pack ( const char *bytes, int nitem, int stride = 1 );
+
+	/// float
+	int pack ( const float *f, int nitem, int stride = 1 );
+
+	/// double
+	int pack ( const double *d, int nitem, int stride = 1 );
+
+	/// int
+	int pack ( const int *i, int nitem, int stride = 1 );
+
+	/// unsigned int
+	int pack ( const unsigned int *ui, int nitem, int stride = 1 );
+
+	/// short
+	int pack ( const short *sh, int nitem, int stride = 1 );
+
+	/// unsigned short
+	int pack ( const unsigned short *ush, int nitem, int stride = 1 );
+
+	/// long
+	int pack ( const long *l, int nitem, int stride = 1 );
+
+	/// unsigned long
+	int pack ( const unsigned long *ul, int nitem, int stride = 1 );
+
+	/// string
+	int pack ( const char  *str );
+
+	/// by jae
+	/***************************/
+	void thread_start(int worker_id);
+	void thread_stop(int worker_id);
+
+	/// Send raw data directly
+	int raw_pack( char* buf, int len );
+
+	/// Read raw data from Worker ID
+	int raw_unpack( int from_whom, char* buf, int len );
+	/***************************/
+
+	/// Unpack some bytes
+	int unpack ( char *bytes, int nitem, int stride = 1 );
+
+	/// float
+	int unpack ( float *f, int nitem, int stride = 1 );
+
+	///double
+	int unpack ( double *d, int nitem, int stride = 1 );
+
+	/// int
+	int unpack ( int *i, int nitem, int stride = 1 );
+
+	/// unsigned int
+	int unpack ( unsigned int *ui, int nitem, int stride = 1 );
+
+	/// short
+	int unpack ( short *sh, int nitem, int stride = 1 );
+
+	/// unsigned short
+	int unpack ( unsigned short *ush, int nitem, int stride = 1 );
+
+	/// long
+	int unpack ( long *l, int nitem, int stride = 1 );
+
+	/// unsigned long
+	int unpack ( unsigned long *ul, int nitem, int stride = 1 );
+
+	/// string
+	int unpack ( char  *str );
+
+		//@}
+  private:
+
+	/**	Some private functions */
+	/** Some marshalling functions */
+	/// int
+	inline void marshall_int ( int n, char *buf );
+
+	/// unsigned int
+	inline void marshall_uint ( unsigned int n, char *buf );
+
+	/// short
+	inline void marshall_short ( short n, char *buf );
+
+	/// unsigned short
+	inline void marshall_ushort ( unsigned short n, char *buf );
+
+	/// long
+	inline void marshall_long ( long n, char *buf );
+
+	/// unsigned long
+	inline void marshall_ulong ( unsigned long n, char *buf );
+
+	/// float
+	inline void marshall_float ( float n, char *buf );
+
+	/// double
+	inline void marshall_double ( double n, char *buf );
+
+	/** Some unmarhsalling routines */
+	/// int
+	inline int unmarshall_int ( char *buf );
+
+	/// unsigned int
+	inline unsigned int unmarshall_uint ( char *buf );
+
+	/// short
+	inline short unmarshall_short ( char *buf );
+
+	/// unsigned short
+	inline unsigned short unmarshall_ushort ( char *buf );
+
+	/// long
+	inline long unmarshall_long ( char *buf );
+
+	/// unsigned long
+	inline unsigned long unmarshall_ulong ( char *buf );
+
+	/// float
+	inline float unmarshall_float ( char *buf );
+
+	/// double
+	inline double unmarshall_double ( char *buf );
+
+	/**	Handle a message from the worker */
+	int handle_finished_worker ( int i );
+
+	/**	Is Called when a task is dead */
+	int handle_killed_worker ( int i );
+
+	/** 	Called when the worker starts executing first */
+	int handle_starting_worker( );
+
+	/**	Create a worker */
+	int do_spawn ( int numworkers, int arch );
+
+	/** Kill all the workers */
+	int killWorkers ( );
+
+	/**	Kill a worker */
+	int killWorker ( int i );
+
+	/** Final closing of sockets */
+	void closeSockets ( );
+
+	/** A primitive Send function */
+	int finalSend ( int s, char *buf, size_t len, int flags );
+
+	/** A primitive Recv function */
+	int finalRecv ( int s, char *buf, size_t len, int flags );
+
+	int nfinalRecv ( int s, void *buf, size_t len, int flags );
+
+	/**	Master receive */
+	int masterrecv ( int fromWhom, int msgtag );
+
+	/**	Worker receive */
+	int workerrecv ( int fromWhom, int msgtag );
+
+	/** Master recive from anyone */
+	int masterrecvany();
+
+	/** A generic function to create and bind a socket to a address */
+	int creatAndBind ( int port );
+
+	/** The function that checks the sockets */
+	int checkSockets ( );
+
+	/** A function to sort the exec_classes */
+	void sort_exec_class_ratio ( int *temp );
+
+	/**	The bool indicates the mode of the RC instance 
+	 *  a true value means that it is a master and a false means that 
+	 * it is a worker.
+	 *  We need to make it a tristate as somtimes an RC can be both
+	 *  a master and a worker.
+	 */
+	bool isMaster;
+
+	/**	The value is the id that the worker gets. For master it is
+	 * of no use.
+	 */
+	int socketId;
+
+	/** The id of the master */
+	int masterId;
+
+	/** The address of the master */
+	char masterAddress[_POSIX_PATH_MAX];
+	/** The value of the master Socket */
+	int masterSocket;
+
+	/** The actual Socket */
+	int socketComm;
+
+	char control_directory[_POSIX_PATH_MAX];
+
+	char worker_number_file[_POSIX_PATH_MAX];
+
+	/**  	The number of workers that were present. This is an internal
+	 *   variable that will be used for copying the entire thing when 
+	 *   the target number changes. This is the number that will be maintained close to 
+	 *   target_num_workers.
+	 */
+	int current_num_workers;
+
+	/**  The number of submitted workers */
+	int submitted_num_workers;
+
+	/**  An array of the number of workers */
+	SocketWorker *socketWorkers;
+
+	/** A reverse map in the master from socket to socketWorkers */
+	int reverseMap[4096];
+
+	/**  This keeps the track of how many cycles were made.
+	 */
+	int turnNo;
+
+	/**  The tag of the message that just came in	*/
+	int msgTag;
+
+	/**  The message came from whom 	*/
+	int whomRecv;
+
+	/**  A variable to keep track of submit files */
+	int subId;
+
+	/**  A variable array keeping track of how many have been requested */
+	int *hostadd_reqs;
+
+	/**  A variable array keeping track of how many workers of each arch */
+	int *num_workers;
+
+	/**  The worker timeout in minutes */
+	long worker_timeout;
+
+	/** For the sake of transmission */
+	char sendBuffer[MWSOCKET_MAX_MSG_SIZE];
+	/** The current message size */
+	int messageSize;
+
+	/** For the sake of reception */
+	char recvBuffer[MWSOCKET_MAX_MSG_SIZE];
+	/** The received message size */
+	int recvSize;
+	int recvPointer;
+	fd_set rfds;
+
+	//by jae
+	bool	pre_send_done;
+	int 	m_poll_timeout;
+
+	/** The non-blocking recv() functions */
+	public:
+		int	recv_all( int from_whom, int msgtag );	// returns the number of new buffers
+		int 	setrbuf(int bid);		// switch the active receive buffer
+							// return the old active buf_id
+		int	freebuf(int bid);		// free the receive buffer.
+		MWList<void> * recv_buffers();			// return the recv_buf_list
+		int 	next_buf();			// advance the active buffer to the next valid buffer 
+							// in the recv_buf_list.
+
+};
+#endif
+
diff --git a/MW/src/RMComm/MW-Socket/Makefile.in b/MW/src/RMComm/MW-Socket/Makefile.in
new file mode 100644
index 0000000..ec25881
--- /dev/null
+++ b/MW/src/RMComm/MW-Socket/Makefile.in
@@ -0,0 +1,139 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(DEBUG_CHECKER) $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $@
+
+# Subdirectories
+SUBDIRS =  
+
+# Libraries to be built, and dependent source files
+LIBRARIES = libMWsocketworker.a libMWsocketmaster.a
+libMWsocketmaster_a_SOURCES = MWSocketRCM.ii
+libMWsocketmaster_a_LIBADD = MWSocketRCM.o
+libMWsocketmaster_a_DEPENDENCIES =  MWSocketRCM.o
+libMWsocketmaster_a_OBJECTS =
+
+libMWsocketworker_a_SOURCES = MWSocketRCW.ii
+libMWsocketworker_a_LIBADD = MWSocketRCW.o
+libMWsocketworker_a_DEPENDENCIES =  MWSocketRCW.o
+libMWsocketworker_a_OBJECTS = 
+
+INCLUDES = -g -I. -I.. -I../.. -I$(CONDOR_DIR)/include $(MEASURE_DEFN)
+INCLUDEFILES = MWSocketRC.h 
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+
+libMWsocketmaster.a: $(libMWsocketmaster_a_OBJECTS) $(libMWsocketmaster_a_DEPENDENCIES)
+	-rm -f libMWsocketmaster.a
+	$(AR) cru libMWsocketmaster.a $(libMWsocketmaster_a_OBJECTS) $(libMWsocketmaster_a_LIBADD)
+	$(RANLIB) libMWsocketmaster.a
+	cp libMWsocketmaster.a $(MW_LIBDIR) 
+
+libMWsocketworker.a: $(libMWsocketworker_a_OBJECTS) $(libMWsocketworker_a_DEPENDENCIES)
+	-rm -f libMWsocketworker.a
+	$(AR) cru libMWsocketworker.a $(libMWsocketworker_a_OBJECTS) $(libMWsocketworker_a_LIBADD)
+	$(RANLIB) libMWsocketworker.a
+	cp libMWsocketworker.a $(MW_LIBDIR) 
+
+MWSocketRCM.ii:MWSocketRC.C
+	$(CXX) -E $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DSOCKET_MASTER MWSocketRC.C > MWSocketRCM.ii
+
+MWSocketRCM.o:MWSocketRCM.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -DSOCKET_MASTER MWSocketRCM.ii
+
+MWSocketRCW.ii:MWSocketRC.C
+	$(CXX) -E $(DEFS) $(MISC_DEFN) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWSocketRC.C > MWSocketRCW.ii
+
+MWSocketRCW.o:MWSocketRCW.ii
+	$(CXX) -c $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) MWSocketRCW.ii
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C b/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C
new file mode 100644
index 0000000..fa4a1f0
--- /dev/null
+++ b/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C
@@ -0,0 +1,754 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWStaticMPIRC.h"
+#include <MW.h>
+#include <MWDriver.h>
+#include <MWTask.h>
+#include <MWWorker.h>
+#include <stdio.h>
+
+MWStaticMPIRC * MWGlobalMPIRMComm = new MWStaticMPIRC();
+MWRMComm * MWDriver::RMC = MWGlobalMPIRMComm;
+MWRMComm * MWTask::RMC = MWGlobalMPIRMComm;
+MWRMComm * MWWorker::RMC = MWGlobalMPIRMComm;
+
+extern int *MW_exec_class_num_workers;
+//#define S_PRINT
+
+MWStaticMPIRC::MWStaticMPIRC ( )
+{
+	
+	is_master = FALSE;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** In MWStaticMPIRC -- constructor ****\n");
+#endif
+}	
+
+MWStaticMPIRC::~MWStaticMPIRC ( )
+{
+	
+}	
+	
+void MWStaticMPIRC::init_env(int argc, char* argv[])
+{
+
+	MPI_Init(&argc, &argv);
+#ifdef S_PRINT
+	MWprintf(10, "**** In MWStaticMPIRC -- init_env ****\n");
+#endif
+}
+
+bool MWStaticMPIRC::is_master_proc()
+{
+	int myId;
+   	MPI_Comm_rank(MPI_COMM_WORLD, &myId);
+#ifdef S_PRINT
+	MWprintf(10, "****PID = %d In MWStaticMPIRC -- is_master_proc ****\n", myId);
+#endif
+  	if (myId == 0)
+		return true;
+ 	else
+		return false;
+}
+/* Implementation of comm / rm class for mpi_finalize. */
+void MWStaticMPIRC::exit( int exitval ) 
+{
+	MWprintf ( 50, "Before MPI_Finalize\n" );
+	MPI_Finalize();
+	MWprintf ( 50, "After MPI_Finalize\n" );
+	::exit(exitval);
+	
+}	
+
+
+int  
+MWStaticMPIRC::setup( int argc, char *argv[], int *id, int *master_id ) 
+{
+	MWprintf ( 10, "In MWStaticMPIRC::setup()\n");
+	//Check the process id
+        MPI_Comm_rank(MPI_COMM_WORLD, id);
+#ifdef S_PRINT
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- setup ****\n", id);
+#endif
+	
+	sendBuffer = new Msg_buf();
+	recvBuffer = new Msg_buf();
+	//In MPI the master has pid=0
+	
+	*master_id = 0;
+
+	if ( *id == 0 ) {
+	   	MWprintf ( 40, "I have no parent, therefore I'm the master.\n" );
+	   	is_master = TRUE;
+	   	*master_id = 0;
+		return 0;
+   	} else {
+	   	is_master = FALSE;
+		return 0;
+	
+	}
+    
+	
+}
+
+int 
+MWStaticMPIRC::config( int *nhosts, int *narches, MWWorkerID ***workers ) 
+{
+	if ( !is_master ) {
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+	
+	*narches = 1;
+	MWprintf ( 70, "In MWStaticMPIRC::config()\n" );
+#ifdef S_PRINT
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- config() ****\n", id);
+#endif
+
+	if ( *workers ) {
+		MWprintf ( 10, "workers should be NULL when called.\n" );
+		return -1;
+	}
+	//Numero di processi compreso il master
+	int numProc;
+	MPI_Comm_size(MPI_COMM_WORLD, &numProc);
+	*nhosts = numProc - 1; 
+	MWprintf ( 70, "In MWStaticMPIRC::config(). Number of processes are %d \n", *nhosts );
+	
+	
+	//The number of workers is number of processes-master (nhost -1 ) 
+	(*workers) = new MWWorkerID*[*nhosts];
+	for ( int i=0 ; i<*nhosts ; i++ ) {
+		(*workers)[i] = new MWWorkerID;
+		(*workers)[i]->set_arch ( 0 );
+			/* Do domething creative with speed later! */
+	}
+
+	return 0;
+} 
+
+int
+MWStaticMPIRC::start_worker ( MWWorkerID *w ) 
+{
+	
+	if ( !is_master ) 
+	{
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+#ifdef S_PRINT
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- start_worker ****\n", id);
+#endif
+
+	MWprintf ( 50, "In MWStaticMPIRC::start_worker()\n" );
+	if ( !w ) 
+	{
+		MWprintf ( 10, "w cannot be NULL!\n" );
+		return -1;
+	}
+
+		return 0;
+}
+
+int
+MWStaticMPIRC::init_beginning_workers( int *nworkers, MWWorkerID ***workers ) 
+{
+	if ( !is_master ) 
+	{
+		MWprintf ( 10, "Slaves not allowed in this privaledged call!\n" );
+		return -1;
+	}
+#ifdef S_PRINT
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- init_beginning workers() ****\n", id);
+#endif
+
+	int i, j, narches;
+	MWprintf ( 50, "In MWStaticMPIRC::init_beginning_workers\n" );
+
+		/* config allocates memory for workers */
+	if ( config( nworkers, &narches, workers ) < 0 ) 
+	{
+		return -1;
+	}
+
+	num_arches = narches;
+
+    	MWprintf ( 40, "Number of hosts at start: %d.\n", *nworkers );
+    	MWprintf ( 40, "Number of arch. classes:  %d.\n", num_arches );
+
+	hostadd_reqs = new int*[exec_classes];
+	for ( i = 0; i < exec_classes; i++ )
+	{
+		hostadd_reqs[i] = new int[num_arches];
+		for ( j = 0 ; j < num_arches ; j++ ) 
+		{
+			hostadd_reqs[i][j] = 0;
+		}
+	}
+
+	for ( i=0 ; i<(*nworkers) ; i++ ) 
+	{
+		//do_spawn( (*workers)[i] );
+		(*workers)[i]->set_id1(i+1);
+		(*workers)[i]->set_id2(0);
+		(*workers)[i]->set_exec_class(0);
+		(*workers)[i]->set_executable(0);
+		(*workers)[i]->set_arch(0);
+	}
+	
+	return 0;
+}
+
+
+int
+MWStaticMPIRC::restart_beginning_workers ( int *nworkers, MWWorkerID ***workers, MWmessages msg )
+{
+#ifdef S_PRINT
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- restart_beginning_workers ****\n", id);
+#endif
+	return init_beginning_workers ( nworkers, workers );
+}
+
+
+int
+MWStaticMPIRC::initsend ( int encoding ) 
+{
+#ifdef S_PRINT
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MWprintf(10, "**** PID = %d In MWStaticMPIRC -- initsend ****\n", id);
+#endif
+	sendBuffer->reset();
+	sendPosition = 0;
+	return 0; 
+}
+
+
+int
+MWStaticMPIRC::send ( int to_whom, int msgtag ) 
+{  
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+#ifdef S_PRINT
+	MWprintf(10, "***** PID %d : Send to %d mstgag %d size = %d ***** \n", id, to_whom, msgtag, sendBuffer->size);
+#endif
+   	return MPI_Send(sendBuffer->data, sendBuffer->size, MPI_PACKED, to_whom, msgtag, MPI_COMM_WORLD);
+	
+}
+
+int
+MWStaticMPIRC::nrecv( int from_whom, int msgtag)
+{
+    recvPosition = 0;	
+    if (is_master)  
+      return masterrecv(from_whom, msgtag);	    
+    else
+      return iworkerrecv(from_whom, msgtag);   
+}
+    
+   
+ 
+int MWStaticMPIRC::iworkerrecv(int from_whom, int msgtag)
+{
+   int flag, bytes;
+   MPI_Status status;
+   int id;
+   MPI_Comm_rank(MPI_COMM_WORLD, &id);
+#ifdef S_PRINT
+   MWprintf(10, "**** PID %d : iworkerrecv from = %d msgtag = %d ****\n", id, from_whom, msgtag);	
+#endif
+   MPI_Iprobe(from_whom, msgtag, MPI_COMM_WORLD, &flag, &status); 
+   if (flag <= 0) {
+    return flag;
+   }
+   else {
+     recvBuffer->reset(); 	
+     MPI_Get_count( &status, MPI_PACKED, &bytes );
+     recvBuffer->resize(bytes); 
+     recvBuffer->sender = status.MPI_SOURCE;
+     recvBuffer->tag = status.MPI_TAG;
+     recvBuffer->size = bytes;   
+     return MPI_Recv(recvBuffer->data, recvBuffer->size, MPI_PACKED, recvBuffer->sender, recvBuffer->tag, MPI_COMM_WORLD,&status);
+     
+    }
+
+   
+
+}
+
+int MWStaticMPIRC::masterrecv (int from_whom, int msgtag) {
+ 
+    
+    int *buf_id = NULL;
+    int bytes;
+    MPI_Status status;
+    buf_id = new int;
+    int id;
+    MPI_Comm_rank(MPI_COMM_WORLD, &id);
+#ifdef S_PRINT
+    MWprintf(10, "**** PID %d : imasterrecv from = %d msgtag = %d ****\n", id, from_whom, msgtag);		 	
+#endif
+    (*buf_id) = MPI_Probe(from_whom, msgtag, MPI_COMM_WORLD,&status); 
+    if (buf_id > 0) {
+    	MPI_Get_count( &status, MPI_PACKED, &bytes );
+        recvBuffer->reset();
+	recvBuffer->resize(bytes);
+        recvBuffer->sender = status.MPI_SOURCE;
+        recvBuffer->tag = status.MPI_TAG;
+        recvBuffer->size = bytes;   
+        MPI_Recv(recvBuffer->data, recvBuffer->size, MPI_PACKED, recvBuffer->sender, recvBuffer->tag, MPI_COMM_WORLD,&status);
+        return *buf_id;
+     } 
+     else
+      return 0;
+ 
+} 
+
+ int
+MWStaticMPIRC::recv( int from_whom, int msgtag)
+{
+	recvPosition = 0;
+	if (from_whom == -1)
+	   from_whom = MPI_ANY_SOURCE;
+	if (msgtag == -1)
+	   msgtag = MPI_ANY_TAG;	
+	
+	int *buf_id = new int;
+	int retVal;
+    	MPI_Status status;
+   	int bytes, myId;
+     	MPI_Comm_rank(MPI_COMM_WORLD, &myId);
+#ifdef S_PRINT
+
+	MWprintf(40, "**** PID %d : MPI_Probe in recv myId = %d from_whom = %d and tag = % d ****\n", myId, myId, from_whom, msgtag);
+#endif
+	retVal = MPI_Probe(from_whom, msgtag, MPI_COMM_WORLD,&status); 
+        if (retVal >= 0) 
+        {
+        	MPI_Get_count( &status, MPI_PACKED, &bytes );
+		recvBuffer->reset();
+		recvBuffer->resize(bytes);
+		recvBuffer->sender = status.MPI_SOURCE;
+		recvBuffer->tag = status.MPI_TAG;
+		recvBuffer->size = bytes; 
+		MPI_Recv(recvBuffer->data, recvBuffer->size, MPI_PACKED, recvBuffer->sender, recvBuffer->tag, MPI_COMM_WORLD,&status);
+		*buf_id = 1;
+	 }
+	 else
+	 {
+	  *buf_id = 0;
+	 }
+	
+	return *buf_id;
+
+}
+
+int MWStaticMPIRC::bufinfo ( int buf_id, int *len, int *tag, int *from ) 
+{
+	
+        *len = recvBuffer->size;
+        *tag = recvBuffer->tag;
+	*from = recvBuffer->sender;
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+#ifdef S_PRINT
+
+	MWprintf(40, "**** PID %d : MWStaticMPIRC::bufinfo: len %d tag %d from %d ****\n",id, *len, *tag, *from);
+#endif
+	return 0;
+
+}
+int 
+MWStaticMPIRC::recv_all( int from_whom, int msgtag )
+{
+
+	MWprintf(91, "Not implemented yet recv_all for MW-StaticMPI.\n");
+	return 0;
+}
+
+
+
+int 
+MWStaticMPIRC::setrbuf( int bid )
+{
+	MWprintf(91, "Not implemented yet setrbuf for MW-StaticMPI.\n");
+	return -1;
+}
+
+int 
+MWStaticMPIRC::freebuf( int bid )
+{
+	MWprintf(91, "Not implemented yet freebuf for MW-StaticMPI.\n");
+	return -1;
+}
+
+MWList<void>* 
+MWStaticMPIRC::recv_buffers()
+{
+	MWprintf(91, "Not implemented yet recv_buffers for MW-StaticMPI.\n");
+	return NULL;
+}
+
+int 
+MWStaticMPIRC::next_buf()
+{
+	MWprintf(91, "Not implemented yet next_buf for MW-StaticMPI.\n");
+	return -1;
+}
+
+int
+MWStaticMPIRC::pack (const char *bytes, int nitem, int stride ) 
+{
+	bytes_packed_ += nitem / stride;
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof bytes);
+	MPI_Pack(const_cast<char *> (bytes), (nitem*stride), MPI_CHAR, 
+		 sendBuffer->data, sendBuffer->max_size, 
+		 &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Pack char bytes = %s nitem = %d sendPosition = %d stride = %d ****\n", id, bytes, nitem, sendPosition, stride);
+#endif
+	return  0;
+}
+
+int
+MWStaticMPIRC::pack (const float *f, int nitem, int stride  )
+{
+	bytes_packed_ += nitem / stride * sizeof(float);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof f);
+	MPI_Pack(const_cast<float *> (f), (nitem*stride), MPI_FLOAT, 
+		 sendBuffer->data, sendBuffer->max_size, 
+		 &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT	
+	MWprintf(10, "**** PID %d : Pack float data = %f nitem = %d sendPosition = %d stride = %d ****\n", id, *f, nitem, sendPosition, stride);
+#endif
+
+ 	return 0; 
+}
+
+
+int 
+MWStaticMPIRC::pack(const double *d, int nitem, int stride)
+{ 
+	bytes_packed_ += nitem / stride * sizeof(double);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof d);
+	MPI_Pack(const_cast<double *> (d), (nitem*stride), MPI_DOUBLE, sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** PID %d : Pack double sendPosition = %d nitem*stride = %d size = %d stride = %d ****\n", id,  sendPosition, nitem*stride, sendBuffer->size, stride);
+#endif
+	return 0; 
+}
+
+
+int 
+MWStaticMPIRC::pack(const int *i, int nitem, int stride)
+{ 
+	bytes_packed_ += nitem / stride * sizeof(int);
+	int id, dim;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof i);
+        MPI_Pack(const_cast<int *> (i), (nitem*stride), MPI_INT, sendBuffer->data, 
+		 sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** PID %d : Pack int data = %d nitem = %d sendPosition = %d stride = %d ****\n", id, *i, nitem, sendPosition, stride); 
+#endif
+
+	return 0; 
+}
+
+	
+int 
+MWStaticMPIRC::pack(const unsigned int *ui, int nitem, int stride)
+{ 
+	bytes_packed_ += nitem / stride * sizeof(unsigned int);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Pack(const_cast<unsigned int *> (ui), (nitem*stride), MPI_UNSIGNED, 
+		 sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Pack ui data = %ui nitem = %d sendPosition = %d stride = %d ****\n", id, *ui, nitem, sendPosition, stride); 
+#endif
+	return 0; 
+};
+
+int 
+MWStaticMPIRC::pack(const short *sh, int nitem, int stride )
+{ 	
+	bytes_packed_ += nitem / stride * sizeof(short);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof sh);
+	MPI_Pack(const_cast<short *> (sh), (nitem*stride), MPI_SHORT, 
+		 sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** PID %d : Pack sh data = %sh nitem = %d sendPosition = %d stride = %d ****\n", id, *sh, nitem, sendPosition, stride); 
+#endif
+	return 0; 
+};
+
+int 
+MWStaticMPIRC::pack (const unsigned short *ush, int nitem, int stride  )
+{ 
+	bytes_packed_ += nitem / stride * sizeof(unsigned short);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof ush);
+	MPI_Pack(const_cast<unsigned short *> (ush), (nitem*stride), MPI_UNSIGNED_SHORT, 
+		 sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** PID %d : Pack ush data = %ush nitem = %d sendPosition = %d stride = %d ****\n", id, *ush, nitem, sendPosition, stride ); 
+#endif
+	return 0; 
+};
+
+int 
+MWStaticMPIRC::pack(const long *l, int nitem, int stride )
+{ 
+	bytes_packed_ += nitem / stride * sizeof(long);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof l);
+	MPI_Pack(const_cast<long *> (l), (nitem*stride), MPI_LONG, sendBuffer->data, 
+		 sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Pack l data = %l nitem = %d sendPosition = %d stride = %d ****\n", id, *l, nitem, sendPosition, stride); 
+#endif
+	return 0; 
+};
+
+
+int 
+MWStaticMPIRC::pack(const unsigned long *ul,   int nitem, int stride )
+{ 
+	bytes_packed_ += nitem / stride * sizeof(unsigned long);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem*sizeof ul);
+	MPI_Pack(const_cast<unsigned long *> (ul), (nitem*stride), MPI_UNSIGNED_LONG, 
+		 sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT
+	MWprintf(10, "**** PID %d : Pack ul data = %ul nitem = %d sendPosition = %d ****\n", id, *ul, nitem, sendPosition); 
+#endif
+	return 0; 
+};
+
+int MWStaticMPIRC::pack(const char *str)
+{ 
+	bytes_packed_ += strlen(str);
+	int nitem = strlen(str);
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	sendBuffer->resize(nitem);
+
+	MPI_Pack(&nitem, 1, MPI_INT, sendBuffer->data, sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	MPI_Pack(const_cast<char *> (str), nitem, MPI_CHAR, sendBuffer->data, 
+		 sendBuffer->max_size, &sendPosition, MPI_COMM_WORLD);
+	sendBuffer->size = sendPosition;
+
+#ifdef S_PRINT	
+	MWprintf(10, "**** PID %d : Pack str data = %s nitem = %d sendPosition = %d ****\n", id, str, nitem, sendPosition);
+#endif
+	return 0; 
+};
+	
+int MWStaticMPIRC::unpack( char *bytes, int nitem, int stride )
+{ 
+	
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition, bytes, nitem, MPI_CHAR, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack bytes data = %s nitem = %d recvPosition = %d ****\n", id, bytes, (nitem*stride), recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(char);
+	return 0; 
+};
+
+	/// float
+int MWStaticMPIRC::unpack( float *f,            int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition , &f, (nitem*stride), MPI_FLOAT, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack float data = %f nitem = %d recvPosition = %d ****\n", id, *f, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(float);
+	return 0; 
+};
+
+		/// double
+int MWStaticMPIRC::unpack( double *d, int nitem, int stride )
+{ 
+	int id, dim;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	dim = (sizeof d)*nitem;
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition , d, (nitem*stride), MPI_DOUBLE, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack double recvPosition = %d ****\n", id, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(double);
+	return 0; 
+};
+
+		/// int
+int MWStaticMPIRC::unpack( int *i, int nitem, int stride )
+{ 
+	int id, dim = (sizeof i)*nitem;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition ,i , (nitem*stride), MPI_INT, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack int data = %i nitem = %d recvPosition = %d ****\n", id, *i, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(int);
+	return 0; 
+};
+
+		/// unsigned int
+int MWStaticMPIRC::unpack( unsigned int *ui,    int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition, &ui, (nitem*stride), MPI_UNSIGNED, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack ui data = %ui nitem = %d recvPosition = %d ****\n", id, *ui, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned int);
+	return 0; 
+};
+
+		/// short
+int MWStaticMPIRC::unpack( short *sh,           int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition , &sh, (nitem*stride), MPI_SHORT, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack sh data = %sh nitem = %d recvPosition = %d ****\n", id, *sh, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(short);
+	return 0; 
+};
+
+		/// unsigned short
+int MWStaticMPIRC::unpack( unsigned short *ush, int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition, &ush , (nitem*stride), MPI_UNSIGNED_SHORT, MPI_COMM_WORLD);
+#ifdef S_PRINT
+
+	MWprintf(10, "**** PID %d : Unpack ush data = %ush nitem = %d recvPosition = %d ****\n", id, *ush, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned short);
+	return 0; 
+};
+
+		/// long
+int MWStaticMPIRC::unpack( long *l,             int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition, &l , (nitem*stride), MPI_LONG, MPI_COMM_WORLD);
+#ifdef S_PRINT 
+
+	MWprintf(10, "**** PID %d : Unpack l data = %l nitem = %d recvPosition = %d ****\n", id, *l, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(long);
+	return 0; 
+};
+
+		/// unsigned long
+int MWStaticMPIRC::unpack( unsigned long *ul,   int nitem, int stride )
+{ 
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition, &ul, (nitem*stride), MPI_UNSIGNED_LONG, MPI_COMM_WORLD);
+#ifdef S_PRINT 
+	MWprintf(10, "**** PID %d : Unpack ul data = %ul nitem = %d recvPosition = %d ****\n", id, *ul, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += nitem / stride * sizeof(unsigned long);
+	return 0; 
+};
+
+		/// Unpack a NULL-terminated string
+int MWStaticMPIRC::unpack( char *str )
+{ 
+ 	char* data, nitem;
+	int id;
+	MPI_Comm_rank(MPI_COMM_WORLD, &id);
+	//Spacchetto prima la dimensione della stringa e poi la stringa stessa
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition , &nitem , 1 ,MPI_INT, MPI_COMM_WORLD);	
+	MPI_Unpack(recvBuffer->data, recvBuffer->size, &recvPosition ,str , nitem ,MPI_CHAR, MPI_COMM_WORLD);
+	str[nitem] = '\0'; 	
+#ifdef S_PRINT 
+	MWprintf(10, "**** PID %d : Unpack str data = %s nitem = %d recvPosition = %d ****\n", id, str, nitem, recvPosition);
+#endif
+	bytes_unpacked_ += strlen(str);
+	return 0; 
+};
+
+int 
+MWStaticMPIRC::write_RMstate ( FILE *fp = NULL )
+{
+    // No MPI specific functions
+    return 0;
+}
diff --git a/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h b/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h
new file mode 100644
index 0000000..bd7bd70
--- /dev/null
+++ b/MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h
@@ -0,0 +1,371 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWSTATICMPIRC_H
+#define MWSTATICMPIRC_H
+
+#define MPICH_SKIP_MPICXX
+#define KB64 1048576
+
+#include "MWRMComm.h"
+#include "MWList.h"
+
+extern "C" {
+#include "mpi.h"
+}
+//#include "/usr/local/mpich-g2/include/mpi.h"
+
+class Msg_buf  
+{
+public:
+	Msg_buf(int max_size = KB64)
+	{ 
+          data = new char[max_size]; 
+          size = 0;
+          pos = 0;
+	  tag = 0;
+        };
+
+	
+	/// Destructor
+	virtual ~Msg_buf( ) { delete[] data; };
+
+	/// Set everything to default
+	void reset(int max_size = KB64)
+	{
+	  tag = 0;
+	  max_size = max_size;
+	  size = 0;
+	  pos = 0;
+	  id = -1;
+	  delete[] data;
+	  data = new char[max_size];
+	}
+	//@}
+
+	/// Resize the buffer if it is not ehough place to add <code> add_size </code>.
+	void resize(int add_size)
+	{
+	  if( size + add_size <= max_size)
+	    return;
+	  max_size = size + add_size + KB64;
+  	  char* tmp = new char[max_size];
+	  memcpy(tmp, data, size);
+          delete[] data;
+	  data = tmp;
+	}
+	
+	/// Message tag.
+	int tag;
+
+	/// Pointer to the data
+	char* data;
+
+
+	/// Allocated size.
+	int max_size;
+
+	/// Current message size
+	int size;
+
+	/// Current position in the buffer to read from the buffer
+	int pos;
+	
+	/// ID of the buffer
+	int id;
+	
+	/// Sender pid.
+	int sender;
+};
+
+
+
+
+class MWStaticMPIRC: public MWRMComm 
+{
+
+	
+
+public:
+
+		/** Constructor.  Sets data to -1's. */
+	MWStaticMPIRC();
+
+		/// Destructor...
+	~MWStaticMPIRC();
+
+		/** @name A. Resource Management Functions
+
+		Here are all the methods you could want to have for managing 
+		a set of machines.  See each method for details...
+		*/
+		//@{
+
+		/** System shutdown.  Does not return.  
+		    @param exitval The value to call ::exit() with 
+		*/
+		 void exit( int exitval );
+
+		/** Initialization of the master process.  This will be called
+			one time only when the master starts up.  
+			@return 0 on success, -1 on failure
+		*/
+		int setup( int argc, char* argv[], int *my_id, int *master_id ) ;
+
+		void init_env(int argc, char* argv[]);
+		bool is_master_proc();
+
+		/** This returns the state of the "virtual machine" - aka the 
+			set of workers under the master's control.  
+			@param nhosts The number of hosts
+			@param narches The number of architechture classes
+			@param w A pointer to a pointer to an array of pointers.  
+			This should be NULL when called; config() will allocate
+			the memory using new and return it to you.  Don't forget
+			to delete not only the elements in that array, but 
+			also the array itself.  The array will have nhosts
+			elements, and they will each represent a worker 
+			machine.
+			@return 0 on success, -1 on error.
+		*/
+		int config( int *nhosts, int *narches, MWWorkerID ***w ) ;
+	
+		/** Start a worker on a machine that has been given to you.
+			This is really only important if the process of starting
+			a worker is two-stage.  For instance, in pvm, you
+			first get a machine.  THEN you have to spawn an 
+			executable on that machine.  For something like MW-files, 
+			once you get a worker it already has the executable 
+			started on it.  In that case this will basically be
+			a no-op.  
+			@param w A pointer to a MWWorkerID.  This must point
+			to allocated memory.  It is filled with info like the
+			machine name, id2, and the arch.
+			@return id2 on success, -1 on failure
+		*/
+		int start_worker( MWWorkerID *w ) ;
+
+		
+	
+		/** Start up the workers that are given to us at the beginning. 
+			See base class comments for more details.
+			@param nworkers The number of workers at start
+			@param workers A pointer to an array of pointers to 
+			       MWWorkerID classes.  This call will new() memory 
+				   for the MWWorkerIDs.  Also, if (*w)[n]->id2 is
+				   -1, that means that the spawn failed for 
+				   worker number n.
+		*/
+		int init_beginning_workers ( int *nworkers, MWWorkerID ***workers );
+
+		/** Called at the time of restart */
+		int restart_beginning_workers ( int *nworkers, MWWorkerID ***worker, MWmessages msg );
+
+		/** Remove a worker.  Basically, call pvm_delhosts(). */
+		int removeWorker( MWWorkerID *w ){ return 0; };
+
+		/** Read some state. A null function */
+		int read_RMstate ( FILE *fp ){ return 0; };
+
+		/** Write some state. A null function */
+		int write_RMstate ( FILE *fp );
+		
+		
+		//@}
+
+	private:
+		/** @name Other Functions to be implemented */
+
+		//@{
+
+		/** Figure out wether or not to ask for hosts, and how many... 
+			@param num_workers An array of size num_arches that contains
+			the number of workers in each arch class.
+		 */
+		int hostaddlogic( int *num_workers ){ return 0; };
+
+		/** Do the pvm_spawn and associated stuff */
+		int do_spawn( MWWorkerID *w ){ return 0; };
+
+		/** Set up the proper notifies for a task & host tid */
+		int setup_notifies ( int task_tid ){ return 0; };
+
+		/** This function says to pvm: "I would like another machine, 
+			please".
+			@param howmany The number of machines to request
+			@param archnum The arch class number to ask for. */
+		int ask_for_host( int howmany, int archnum ){ return 0; };
+
+		/** Shows the pvm virtual machine according to pvm.  Used
+			for debugging purposes{ return 0; }; not normally called. */
+		void conf(){ };
+	
+		/** Helper for hostaddlogic().  Returns the index of the min
+			element in array, which is of length len */
+		int min ( int *array, int len ){ return 0; };
+
+		/** Funzioni di ricezione del worker e del master */
+
+ 		int iworkerrecv(int from_whom, int msgtag);
+		int masterrecv(int from_whom, int msgtag);
+		
+		/** The number of outstanding requests for a particular 
+			arch. */
+		//int *hostadd_reqs{ return 0; };
+
+		/** The requests per exec_classes */
+		int **hostadd_reqs;
+
+		MWList<void> * submit_list;
+
+		//@}
+
+		/** Am I the master process or not? */
+		int is_master;
+
+	public:
+
+
+		/** @name C. Communication Routines
+			
+			These are essentially thin wrappers of PVM calls.
+		*/
+		//@{
+
+		///
+		int initsend ( int encoding = 0);
+
+		///
+		int send ( int to_whom, int msgtag );
+
+		///
+		int recv ( int from_whom, int msgtag );
+
+        	/// non-blocking version of receive
+       		int nrecv (int fromWhom, int msgtag);
+
+		/** Provide info on the message just received */
+		int bufinfo ( int buf_id, int *len, int *tag, int *from );
+
+		/** Tells the affected party */
+		void who ( int *id ){  };
+
+		/// Pack some bytes
+		int pack ( const char *bytes,         int nitem, int stride = 1 );
+
+		/// float
+		int pack ( const float *f,            int nitem, int stride = 1 );
+
+		/// double
+		int pack ( const double *d,           int nitem, int stride = 1 );
+
+		/// int
+		int pack ( const int *i,              int nitem, int stride = 1 );
+
+		/// unsigned int
+		int pack ( const unsigned int *ui,    int nitem, int stride = 1 );
+
+		/// short
+		int pack ( const short *sh,           int nitem, int stride = 1 );
+
+		/// unsigned short
+		int pack ( const unsigned short *ush, int nitem, int stride = 1 );
+
+		/// long
+		int pack ( const long *l,             int nitem, int stride = 1 );
+
+		/// unsigned long
+		int pack ( const unsigned long *ul,   int nitem, int stride = 1 );
+
+		/// Pack a NULL-terminated string
+		int pack ( const char *str );
+	
+		/// Unpack some bytes
+		int unpack ( char *bytes,         int nitem, int stride = 1 );
+
+		/// float
+		int unpack ( float *f,            int nitem, int stride = 1 );
+
+		/// double
+		int unpack ( double *d,           int nitem, int stride = 1 );
+
+		/// int
+		int unpack ( int *i,              int nitem, int stride = 1 );
+
+		/// unsigned int
+		int unpack ( unsigned int *ui,    int nitem, int stride = 1 );
+
+		/// short
+		int unpack ( short *sh,           int nitem, int stride = 1 );
+
+		/// unsigned short
+		int unpack ( unsigned short *ush, int nitem, int stride = 1 );
+
+		/// long
+		int unpack ( long *l,             int nitem, int stride = 1 );
+
+		/// unsigned long
+		int unpack ( unsigned long *ul,   int nitem, int stride = 1 );
+
+		/// Unpack a NULL-terminated string
+		int unpack ( char *str );
+		
+		
+		//@}
+
+	private:
+		/** @name C. Some Misc Helper functions
+		*/
+
+		//@{
+	    
+        /** Number of sent messages */  	
+            int num_send_msgs;
+
+	/** Number of received messages */
+            int num_recv_msgs;
+	
+
+ 	/** The current message to send */
+            Msg_buf *sendBuffer;
+
+        /** For the sake of transmission */
+	    Msg_buf *recvBuffer;
+	  	
+	    int sendPosition;
+	    int recvPosition;
+		//@}
+		/** The non-blocking recv functions */
+	public:
+		int	recv_all( int from_whom, int msgtag );	// returns the number of new buffers
+		int 	setrbuf(int bid);		// switch the active receive buffer
+							// return the old active buf_id
+		int	freebuf(int bid);		// free the receive buffer.
+		MWList<void>* recv_buffers();			// return the recv_buf_list
+		int 	next_buf();			// advance the active buffer to the next valid buffer 
+							// in the recv_buf_list.
+		int 	switch_buf_back();		// Switch the active receive buffer to the buffer
+							// on the head of the recv_buf_list;
+};
+
+extern MWStaticMPIRC *MWGlobalMPIRMComm;
+#endif
diff --git a/MW/src/RMComm/MW-StaticMPI/Makefile.in b/MW/src/RMComm/MW-StaticMPI/Makefile.in
new file mode 100644
index 0000000..bbf3e8b
--- /dev/null
+++ b/MW/src/RMComm/MW-StaticMPI/Makefile.in
@@ -0,0 +1,120 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MPICXX = @MPICXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+ENABLE_MWINDEPENDENT= @ENABLE_MWINDEPENDENT@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+
+CXXCOMPILE = $(DEBUG_CHECKER) $(MPICXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+
+# Subdirectories
+SUBDIRS =
+
+# Libraries to be built, and dependent source files
+LIBRARIES = libMWRC_mpi.a 
+libMWRC_mpi_a_SOURCES = MWStaticMPIRC.C
+libMWRC_mpi_a_LIBADD = MWStaticMPIRC.o
+libMWRC_mpi_a_DEPENDENCIES =  MWStaticMPIRC.o
+libMWRC_mpi_a_OBJECTS =
+
+INCLUDES = -g -I. -I.. -I../.. $(MEASURE_DEFN)
+INCLUDEFILES = MWStaticMPIRC.h 
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+
+libMWRC_mpi.a: $(libMWRC_mpi_a_OBJECTS) $(libMWRC_mpi_a_DEPENDENCIES)
+	-rm -f libMWRC_mpi.a
+	$(AR) cru libMWRC_mpi.a $(libMWRC_mpi_a_OBJECTS) $(libMWRC_mpi_a_LIBADD)
+	$(RANLIB) libMWRC_mpi.a
+	cp libMWRC_mpi.a $(MW_LIBDIR) 
+
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Common
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
+
+
+
diff --git a/MW/src/RMComm/MWRMComm.C b/MW/src/RMComm/MWRMComm.C
new file mode 100644
index 0000000..406092a
--- /dev/null
+++ b/MW/src/RMComm/MWRMComm.C
@@ -0,0 +1,457 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#include "MWRMComm.h"
+
+#ifdef WINDOWS
+#define _POSIX_PATH_MAX 1024
+#endif
+
+MWRMComm::MWRMComm()
+{
+	exec_classes = 0;
+	num_arches = 0;
+	arch_class_attributes = NULL;
+	num_executables = tempnum_executables = 0;
+	hostinc_ = 6;
+
+	worker_executables = NULL;
+	worker_checkpointing = false;	
+
+	target_num_workers = 0;
+	exec_class_target_num_workers = NULL;
+	MW_exec_class_num_workers = NULL;
+}
+
+
+MWRMComm::~MWRMComm()
+{
+	int i;
+
+	if ( arch_class_attributes )
+		{
+			for ( i = 0; i < num_arches; i++ )
+				if ( arch_class_attributes[i] )
+					delete [] arch_class_attributes[i];
+		}
+
+	if ( worker_executables )
+		{
+			for ( i = 0; i < num_executables; i++ )
+				if ( worker_executables[i] )
+					{
+						delete [] worker_executables[i]->executable;
+						delete [] worker_executables[i]->executable_name;
+						delete [] worker_executables[i]->attributes;
+						delete worker_executables[i];
+					}
+		}
+
+	if ( exec_class_target_num_workers )
+		delete [] exec_class_target_num_workers;
+
+	if ( MW_exec_class_num_workers )
+		delete [] MW_exec_class_num_workers;
+}
+
+void MWRMComm::exit( int exitval )
+{
+	::exit ( exitval );
+}
+
+int MWRMComm::write_checkpoint( FILE *fp )
+{
+	int i;
+
+	MWprintf ( 80, "Writing checkpoint for MWPvmRC layer.\n" );
+
+	fprintf ( fp, "%d \n", exec_classes );
+	fprintf ( fp, "%d \n", num_arches );
+	for ( i = 0 ; i<num_arches ; i++ ) 
+		{
+			if ( arch_class_attributes && arch_class_attributes[i] )
+				fprintf ( fp, "1 %d %s\n", strlen(arch_class_attributes[i]), arch_class_attributes[i] );
+			else
+				fprintf ( fp, "0 " );
+		}
+
+	fprintf ( fp, "%d \n", num_executables );
+	for ( i = 0; i < num_executables; i++ )
+		{
+			fprintf ( fp, "%d %d %s %s\n", worker_executables[i]->arch_class, 
+					  worker_executables[i]->exec_class, worker_executables[i]->executable, 
+					  worker_executables[i]->executable_name );
+			if ( worker_executables[i]->attributes != NULL )
+				fprintf ( fp, "1 %d %s\n", strlen(worker_executables[i]->attributes), 
+						  worker_executables[i]->attributes );
+			else
+				fprintf ( fp, "0 " );
+		}
+
+	for ( i = 0; i < exec_classes; i++ )
+		{
+			fprintf ( fp, "%d ", exec_class_target_num_workers[i] );
+		}
+	fprintf ( fp, "\n");
+
+	write_RMstate ( fp );
+	return 0;
+}
+
+int MWRMComm::read_checkpoint( FILE *fp )
+{
+	int temp;
+	int i;
+	MWprintf ( 50, "Reading checkpoint in MWPvmRC layer.\n" );
+	fscanf ( fp, "%d %d", &exec_classes, &num_arches );
+	MWprintf ( 50, "Target num workers: %d    Num arches %d.\n", 
+			   target_num_workers, num_arches );
+	arch_class_attributes = new char*[num_arches];
+	target_num_workers = 0;
+	for ( i = 0; i < num_arches; i++ )
+		{
+			fscanf ( fp, "%d ", &temp );
+			if ( temp == 1 )
+				{
+					fscanf ( fp, "%d ", &temp );
+					arch_class_attributes[i] = new char[temp+1];
+					fgets ( arch_class_attributes[i], temp + 1, fp );
+				}
+			else
+				arch_class_attributes[i] = NULL;
+		}
+
+	fscanf ( fp, "%d ", &num_executables );
+	MWprintf ( 50, "%d Worker executables:\n", num_executables );
+	worker_executables = new struct RMC_executable*[num_executables];
+	for ( i = 0 ; i < num_executables; i++ ) 
+		{
+			worker_executables[i] = new struct RMC_executable;
+			worker_executables[i]->executable = new char[_POSIX_PATH_MAX];
+			worker_executables[i]->executable_name = new char[_POSIX_PATH_MAX];
+			fscanf ( fp, "%d %d %s %s", &worker_executables[i]->arch_class,
+					 &worker_executables[i]->exec_class, worker_executables[i]->executable,
+					 worker_executables[i]->executable_name );
+			fscanf ( fp, "%d ", &temp );
+			if ( temp == 1 )
+				{
+					fscanf ( fp, "%d ", &temp );
+					worker_executables[i]->attributes = new char[temp+1];
+					fgets ( worker_executables[i]->attributes, temp + 1, fp );
+				}
+			else
+				worker_executables[i]->attributes = NULL;
+		}
+
+	MW_exec_class_num_workers = new int[exec_classes];
+	exec_class_target_num_workers = new int[exec_classes];
+	for ( i = 0; i < exec_classes; i++ )
+		{
+			fscanf ( fp, "%d ", &exec_class_target_num_workers[i] );
+			target_num_workers += exec_class_target_num_workers[i];
+			MW_exec_class_num_workers[i] = 0;
+		}
+
+	read_RMstate ( fp );
+	return 0;
+}
+
+int MWRMComm::read_RMstate( FILE *fp ) 
+{ 
+	return 0;
+}
+
+int MWRMComm::write_RMstate( FILE *fp )
+{
+	return 0;
+}
+
+
+// An exec class is a partition of the total number
+// of running workers, and can be of Any architecture 
+void
+MWRMComm::set_num_exec_classes ( int num )
+{
+	exec_classes = num;
+
+	if (exec_class_target_num_workers) {
+		delete [] exec_class_target_num_workers;
+		delete [] MW_exec_class_num_workers;
+	}
+
+	exec_class_target_num_workers = new int[num];
+	MW_exec_class_num_workers = new int[num];
+	for ( int i = 0; i < num; i++ )
+		{
+			exec_class_target_num_workers[i] = 0;
+			MW_exec_class_num_workers[i] = 0;
+		}
+	
+}
+
+int
+MWRMComm::get_num_exec_classes ( )
+{
+	return exec_classes;
+}
+
+// arch_classes are the different opsys/arch combos
+// we will be running with
+void
+MWRMComm::set_num_arch_classes ( int num )
+{
+	char **tmp_arch_class_attributes = new char*[num];
+
+	MWprintf(80, "MWRMComm::set_num_arch_classes to %d\n", num);
+	for (int i = 0 ; i < num; i++) {
+		tmp_arch_class_attributes[i] = NULL;
+	}
+
+	if (arch_class_attributes) {
+		for (int i = 0; i < num_arches; i++) {
+			tmp_arch_class_attributes[i] = arch_class_attributes[i];
+		}
+		delete [] arch_class_attributes;
+	}
+
+	num_arches = num;
+	arch_class_attributes = tmp_arch_class_attributes;
+}
+
+void
+MWRMComm::set_arch_class_attributes ( int arch_class, const char *attr )
+{
+	MWprintf(80, "MWRMComm::set_arch_class_attributes for arch class %d to %s\n", arch_class, attr);
+	if ( arch_class >= num_arches ) {
+		MWprintf(10, "Warning: arch_class %d >= num_arches (%d)\n", arch_class, num_arches);
+		exit(-1);
+		return;
+	}
+	arch_class_attributes[arch_class] = new char[strlen(attr)+1];
+	strcpy ( arch_class_attributes[arch_class], attr );
+}
+
+int
+MWRMComm::get_num_arch_classes ( )
+{
+	return num_arches;
+}
+
+void
+MWRMComm::set_num_executables ( int num )
+{
+	int i = 0; 
+
+	struct RMC_executable **tmp_executables = new RMC_executable*[num];
+
+	if (worker_executables != NULL) {
+		for ( i = 0; i < num_executables; i++ ) {
+			tmp_executables[i] = worker_executables[i];
+				//Jeff changed this.
+			worker_executables[i] = NULL;
+		}
+		
+		delete [] worker_executables;
+	}
+
+	worker_executables = tmp_executables;
+	num_executables = num;
+}
+
+int
+MWRMComm::get_num_executables() {
+	return num_executables;
+}
+
+void MWRMComm::add_executable( int exec_class, int arch_class, char *exec_name, 
+							   char *requirements )
+{
+	if ( !exec_name )
+		return;
+
+	if( arch_class >= num_arches ) 
+		{
+			MWprintf( 10, "set_worker_attributes(): incrementing num_arches to %d\n", 
+					  arch_class + 1 );
+			num_arches = arch_class + 1;
+		}
+
+	MWprintf(31, "tempnum_executables = %d\n", tempnum_executables);
+	worker_executables[tempnum_executables] = new struct RMC_executable;
+	worker_executables[tempnum_executables]->arch_class = arch_class;
+	worker_executables[tempnum_executables]->exec_class = exec_class;
+	worker_executables[tempnum_executables]->executable = new char [ strlen(exec_name) + 1 ];
+	strcpy ( worker_executables[tempnum_executables]->executable, exec_name );
+	worker_executables[tempnum_executables]->executable_name = 
+		process_executable_name ( worker_executables[tempnum_executables]->executable, 
+								  exec_class, arch_class );
+	if ( !requirements )
+		{
+			worker_executables[tempnum_executables]->attributes = NULL;
+		}
+	else
+		{
+			worker_executables[tempnum_executables]->attributes = new char [ strlen(requirements) + 1 ];
+			strcpy ( worker_executables[tempnum_executables]->attributes, requirements );
+		}
+	tempnum_executables++;
+}
+
+// This is the new, easy way to add executables.  No more worrying about getting
+// calling order right, or setting up the wrong number of arrays.
+// We assume that this will be called a couple of times at startup, so 
+// efficiency isn't a big concern.
+
+void
+MWRMComm::add_executable(const char *exec_name, const char *requirements)
+{
+	verify_file_exists(exec_name);
+		// exec class is the notion that you want to partition
+		// the number of executables into two or more groups, and
+		// try to maintain a different number in each group.
+
+		// Most codes don't need this, so always force it to one,
+		// no matter how many executables we have
+	set_num_exec_classes(1);
+
+		// make a new arch_class, and give it this requirements
+	int num_arches = get_num_arch_classes();
+	if (num_arches == -1) {
+		num_arches = 0;
+	}
+	set_num_arch_classes(1 + num_arches);
+	set_arch_class_attributes(get_num_arch_classes() - 1, requirements);
+
+		// make a new executable
+	set_num_executables(1 + get_num_executables());
+
+	RMC_executable *e = new struct RMC_executable;
+	e->exec_class = 0;
+	e->arch_class = get_num_arch_classes() - 1;
+	e->executable   = strdup(exec_name);
+	e->attributes = ""; // Where is this used?
+	e->executable_name = 
+		process_executable_name ( e->executable, 
+								  e->exec_class, e->arch_class );
+	worker_executables[get_num_executables() - 1] = e;
+}
+
+char* MWRMComm::process_executable_name( char *exec_name, int ex_cl, int ar_cl )
+{
+	char *newone = new char[strlen(exec_name) + 1];
+	strcpy ( newone, exec_name );
+	return newone;
+}
+
+// XXX Newly added get function so that we can know the target number of workers
+//   and change the number for runtime adaptation
+
+int 
+MWRMComm::get_target_num_workers ( int exec_class )
+{
+	if (exec_class == -1)
+		return target_num_workers;
+	
+	if ( (exec_class > exec_classes) || (exec_class < -1) ) 
+		return -1;
+
+	return exec_class_target_num_workers[exec_class];
+}
+
+void 
+MWRMComm::set_worker_increment(int newinc)
+{
+	if (newinc <= 0) {
+		MWprintf(1, "Unreasonable value: %d for set_worker_increment().  Ignoring.\n", newinc); 
+		return;
+	}
+	hostinc_ = newinc < target_num_workers ? newinc : target_num_workers;
+}
+
+int 
+MWRMComm::get_worker_increment() const
+{
+	return hostinc_; 
+}
+
+void
+MWRMComm::set_target_num_workers ( int num_workers )
+{
+	set_target_num_workers ( -1, num_workers );
+}
+
+void
+MWRMComm::set_target_num_workers ( int exec_class, int num_workers )
+{
+	if ( exec_classes <= 0 )
+		{
+			exec_classes = 1;
+			exec_class_target_num_workers = new int[exec_classes];
+			exec_class_target_num_workers[0] = 0;
+		}
+
+	if ( exec_class < 0 )
+		{
+			exec_class_target_num_workers[0] = num_workers;
+			target_num_workers = exec_class_target_num_workers[0];
+			return;
+		}
+
+	target_num_workers -= exec_class_target_num_workers[exec_class];
+	exec_class_target_num_workers[exec_class] = num_workers;
+	target_num_workers += exec_class_target_num_workers[exec_class];
+	return;
+}
+
+void MWRMComm::set_worker_checkpointing( bool wc )
+{
+	if( wc == true )
+		MWprintf( 10, "Warning!  Worker checkpointing not available in this CommRM implementation\n" );
+	worker_checkpointing = false;
+}
+
+void 
+MWRMComm::verify_file_exists(const char *exec_name) {
+	FILE *f = fopen(exec_name, "r");
+	if (f == NULL) {
+		MWprintf(10, "ERROR: add_executable with %s, which doesn't exist or isn't readable\n", exec_name);
+	} else {
+		fclose(f);
+	}
+}
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq c-tab-always-indent nil)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/RMComm/MWRMComm.h b/MW/src/RMComm/MWRMComm.h
new file mode 100644
index 0000000..100bce0
--- /dev/null
+++ b/MW/src/RMComm/MWRMComm.h
@@ -0,0 +1,493 @@
+/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
+ *
+ * Condor Software Copyright Notice
+ * Copyright (C) 1990-2004, Condor Team, Computer Sciences Department,
+ * University of Wisconsin-Madison, WI.
+ *
+ * This source code is covered by the Condor Public License, which can
+ * be found in the accompanying LICENSE.TXT file, or online at
+ * www.condorproject.org.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
+ * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
+ * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
+ * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
+ * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
+ * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
+ * RIGHT.
+ *
+ ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/
+#ifndef MWRMCOMM_H
+#define MWRMCOMM_H
+#include <MWWorkerID.h>
+#include "MWList.h"
+
+/** This class is an abstract layer over a Resource Management (RM) and
+	Communication (Comm) layer.  Hence the RMComm name.  It is designed
+	to abstract away the differences between various systems.  
+
+	The member functions in this class fall into two categories:  
+	Resource Management and Message Passing (Communication).  The "master"
+	in a master-worker application will use both; the worker will only
+	use the communication facilities.
+*/
+
+enum MWRMCommErrors {
+	WORKER_TIMEOUT = -50,
+	UNABLE_TO_WAKE = -49,
+	CANNOT_OPEN_INPUT_FILE = -48,
+	SCANF_ERROR_ON_INPUT_FILE = -47,
+	MESSAGE_SEQUENCE_ERROR = -46,
+	UNKNOWN_DATA_TYPE = -45,
+	WAITFILE_PROTOCOL_ERROR = -44,
+	FAIL_MASTER_SEND = -43,
+	CHECKSUM_ERROR_EXIT = -42,
+	UNKNOWN_COMMAND = -41,
+	INIT_REPLY_FAILURE = -40,
+	UNPACK_FAILURE = -39
+};
+
+struct RMC_executable
+{
+	int arch_class;
+	int exec_class;
+	char *executable;
+	char *executable_name;
+	char *attributes;
+};
+
+class MWRMComm {
+
+	friend class MWDriver;
+
+public:
+
+		/** Constructor.  Sets data to -1's. */
+	MWRMComm();
+
+		/// Destructor...
+	virtual ~MWRMComm();
+
+		/** @name A. Resource Management Functions
+
+		Here are all the methods you could want to have for managing 
+		a set of machines.  See each method for details...
+		*/
+		//@{
+
+		/** System shutdown.  Does not return.  
+		    @param exitval The value to call ::exit() with 
+		*/
+	virtual void exit( int exitval );
+
+		/** Initialization of the master process.  This will be called
+			one time only when the master starts up.  
+			@return 0 on success, -1 on failure
+		*/
+	virtual int setup( int argc, char* argv[], int *my_id, int *master_id ) = 0;
+
+		/** This returns the state of the "virtual machine" - aka the 
+			set of workers under the master's control.  
+			@param nhosts The number of hosts
+			@param narches The number of architechture classes
+			@param w A pointer to a pointer to an array of pointers.  
+			This should be NULL when called; config() will allocate
+			the memory using new and return it to you.  Don't forget
+			to delete not only the elements in that array, but 
+			also the array itself.  The array will have nhosts
+			elements, and they will each represent a worker 
+			machine.
+			@return 0 on success, -1 on error.
+		*/
+	virtual int config( int *nhosts, int *narches, MWWorkerID ***w ) { return 0; };
+	
+		/** Start a worker on a machine that has been given to you.
+			This is really only important if the process of starting
+			a worker is two-stage.  For instance, in pvm, you
+			first get a machine.  THEN you have to spawn an 
+			executable on that machine.  For something like MW-files, 
+			once you get a worker it already has the executable 
+			started on it.  In that case this will basically be
+			a no-op.  
+			@param w A pointer to a MWWorkerID.  This must point
+			to allocated memory.  It is filled with info like the
+			machine name, id2, and the arch.
+			@return id2 on success, -1 on failure
+		*/
+	virtual int start_worker( MWWorkerID *w ) = 0;
+
+		/** This routine is used to start up multiple workers at 
+			the beginning of a run.  It should only be called one
+			time.  It basically does a config() to find out what
+			machines are available, and then starts a worker on 
+			each of them.  You may want to check the implementations
+			for details...
+			@param nworkers The number of workers at the start (returned!)
+			@param workers A pointer to a pointer to an array of
+			MWWorkerID pointers.  The memory management for this 
+			is the same as it is for the config() call - it should
+			be null when called and will point to allocated memory
+			when it comes back.
+			@return 0 on success, -1 on failure
+		*/
+	virtual int init_beginning_workers( int *nworkers, MWWorkerID ***workers ) = 0;
+
+		/** Remove a worker from the virtual machine.  This call 
+			will delete w, so don't reference that memory again!
+			@param w The MWWorkerID of the machine to remove.
+			@return 0 on success, a negative number on failure
+		*/
+	virtual int removeWorker( MWWorkerID *w ) = 0;
+		//@}
+
+		/** @name B. Checkpointing Functions */
+		//@{
+		/** Write out internal state to a FILE *
+		 */
+	virtual int write_checkpoint( FILE * fp );
+
+		/** Read in restart information from a FILE * 
+		 */
+	virtual int read_checkpoint( FILE * fp );
+
+		/** Some Low level specific read/write functions */
+	virtual int read_RMstate( FILE *fp ); 
+		///
+	virtual int write_RMstate ( FILE *fp );
+
+		/** A function to restart the workers. This is called at restart from
+			a ckpt file and it is meant to re-init all the workers.
+		*/
+	virtual int restart_beginning_workers ( int *num, MWWorkerID ***tempWorkers, MWmessages msg ) = 0;
+		//@}
+
+		/** @name C. Executable Management Interface functions */
+		//@{
+
+		/** Set the number of executable classes */
+	void set_num_exec_classes ( int num );
+
+		/** Returns the above number */
+	int get_num_exec_classes ( );
+
+		/** Set the number of arch classes */
+	void set_num_arch_classes( int n );
+
+		/** set the arch attribute */
+	void set_arch_class_attributes ( int arch_class, const char *attr );
+
+		/** Return the number of arch classes */
+	int get_num_arch_classes();
+
+		/** Set the number of executables */
+	void set_num_executables ( int num );
+
+	int get_num_executables();
+
+		/** Set the name of the binary and the requirements string 
+			for an arch class.  Technically, the requirements string 
+			is not needed for MWPvmRC - it is defined in the submit
+			file.  It *is* needed in the MWFileRC, however, for job
+			submission.
+			@param arch_class This specifies which arch class the above
+			requirements will apply to.
+			@param exec_name The name of the worker executable for 
+			this arch class.
+			@param requirements A string containing the "requirements" 
+			attribute of a given arch class of workers.  This will 
+			be something that can be used in a submit file, like 
+			"(arch == \"INTEL\" && opsys == \"SOLARIS26\")"
+		*/
+	void add_executable ( int exec_class, int arch_class, char *exec_name, 
+						  char *requirements ); 
+
+		// The new, better way to do the above
+	void add_executable(const char *exec_name, const char *requirements);
+
+		/** If the RM software needs to "process" the executable name in
+			some way, this is done here.
+		*/
+	virtual char* process_executable_name ( char* exec_name, int ex_cl, int num_arc );
+
+		/** Set whether or not you would like worker checkpointing 
+			(if the CommRM implementation has the capability)
+		*/
+	virtual void set_worker_checkpointing( bool wc );
+
+protected:
+
+		/** The number of exec classes */
+	int exec_classes;
+
+		/** The number of different arch classes. */
+	int num_arches;
+
+		/** The arch attributes */
+	char **arch_class_attributes;
+
+		/** The number of executables */
+	int num_executables;
+	int tempnum_executables;
+
+		/** An array containing the {\bf full} pathnames of the executables.
+			Element 0 is for arch "0", element 1 is for arch "1", etc.
+			Usually read in get get_userinfo().
+		*/
+	struct RMC_executable **worker_executables;
+
+		/// Would you like the workers to be checkpointed
+	bool worker_checkpointing;
+
+		/* moved here from MWDriver.C, to separate RMC and MW more */
+	int *MW_exec_class_num_workers;
+
+		//@}
+
+public: 
+	
+		/** @name D. Host Management Members */
+		//@{
+		/** Set a "target" number of workers across all arches.  This 
+			is useful if you don't care how many you get of each arch... 
+			@param num_workers The target number of workers 
+		*/
+	void set_target_num_workers( int num_workers );
+
+	void set_target_num_workers( int exec_class, int num_workers );
+		
+		// XXX Let the MWDriver/user know our current target number of workers
+	int get_target_num_workers(int exec_class = -1);
+
+		/** The RMComm will requests this many workers at a time */
+	void set_worker_increment(int newinc);
+	
+	int get_worker_increment() const;
+
+protected:
+
+		/** This will figure out if we need to ask for more hosts
+			or remove hosts.  It is called whenever a host is added
+			or removed from the system, or set_target_num_workers()
+			is called.
+			@param num_workers A pointer to an array of length
+			num_arches that contains the number of workers for 
+			each arch class.
+			@return If we have more workers than we need, we return a
+			positive number as the "excess" that can be deleted.  
+		*/
+	virtual int hostaddlogic( int *num_workers ) = 0;
+
+		/** The desired number of workers */
+	int target_num_workers;
+
+		/** The desired number of workers, exec_class wise */
+	int *exec_class_target_num_workers;
+
+		/** The current */
+	int hostinc_;
+
+		//@}
+  
+public:
+
+		/** @name The Communication Routines
+
+		These message passing routines are very closely modeled on
+		PVM's message passing facility.  They are, however, pretty
+		generic in that any message passing interface should be 
+		able to implement them.
+		*/
+	
+		//@{
+
+		/** Initialize a buffer for sending some data.
+			@param encoding Defined by each application.  0 = default */
+	virtual int initsend ( int encoding = 0 ) = 0;
+		/** Send the data that has been packed. 
+			@param to_whom An identifier for the recipient
+			@param msgtag A 'tag' to identify that type of message */
+	virtual int send ( int to_whom, int msgtag ) = 0;
+
+	//by jae
+	virtual int pre_send ( int msgtag) { return -1; }
+	virtual void setPollTimeOut(int secs) {}
+
+		/** Receive some data that has been packed.  Should make this 
+			more PVM-independent; will do this sometime.
+			@param from_whom From a specific source; -1 is from all
+			@param msgtag With a certain tag; -1 is all. */
+	virtual int recv ( int from_whom, int msgtag ) = 0;
+
+        /** non-blocking receive. This is the same as recv except it 
+			returns the NO_MESSAGE tag instead of blocking if there is
+			no data in the buffer */
+	virtual int nrecv( int from_whom, int msgtag){return ABORT;};
+
+		/** Provide info on the message just received */
+	virtual int bufinfo ( int buf_id, int *len, int *tag, int *from ) = 0;
+
+		/** For some system events like HOSTDELETE, TASKEXIT, etc, this will tell
+			who was affected */
+	virtual void who ( int *wh ) = 0;
+
+		/** Needed only for MW-Independent */
+	virtual void hostadd ( ) { };
+
+		/** @name Pack Functions
+			
+		In the following pack() functions, there are some common themes.
+		First, each stuffs some data into a buffer to be sent.  The
+		nitem parameter is just a count of the number of items.  The 
+		stride parameter specifies *which* items to pack.  1 implies
+		all, 2 would be every 2nd item, 3 is every 3rd item, etc. 
+
+		The return value is user defined.  It should be standardized, 
+		but I'll do that later.
+		*/
+		//@{
+
+		/// Pack some bytes
+	virtual int pack ( const char *bytes,         int nitem, int stride = 1 ) = 0;
+		/// float
+	virtual int pack ( const float *f,            int nitem, int stride = 1 ) = 0;
+		/// double
+	virtual int pack ( const double *d,           int nitem, int stride = 1 ) = 0;
+		/// int
+	virtual int pack ( const int *i,              int nitem, int stride = 1 ) = 0;
+		/// unsigned int
+	virtual int pack ( const unsigned int *ui,    int nitem, int stride = 1 ) = 0;
+		/// short
+	virtual int pack ( const short *sh,           int nitem, int stride = 1 ) = 0;
+		/// unsigned short
+	virtual int pack ( const unsigned short *ush, int nitem, int stride = 1 ) = 0;
+		/// long
+	virtual int pack ( const long *l,             int nitem, int stride = 1 ) = 0;
+		/// unsigned long
+	virtual int pack ( const unsigned long *ul,   int nitem, int stride = 1 ) = 0;
+		/// Pack a NULL-terminated string
+	virtual int pack ( const char *string ) = 0;
+
+		/// by jae
+	virtual void thread_start(int worker_id) {};
+	virtual void thread_stop(int worker_id) {};
+		/// Send raw data directly
+	virtual int raw_pack( char* buf, int len ) { return 0; };
+
+		/// Read raw data from Worker ID
+	virtual int raw_unpack( int from_whom, char* buf, int len ) { return 0; };
+
+		//@}
+
+		/** @name Unpack Functions
+			
+		These unpack functions unpack data packed with the pack() 
+		functions.  See the pack() functions for more details.
+
+		*/
+		//@{
+
+		/// Unpack some bytes
+	virtual int unpack ( char *bytes,         int nitem, int stride = 1 ) = 0;
+		/// float
+	virtual int unpack ( float *f,            int nitem, int stride = 1 ) = 0;
+		/// double
+	virtual int unpack ( double *d,           int nitem, int stride = 1 ) = 0;
+		/// int
+	virtual int unpack ( int *i,              int nitem, int stride = 1 ) = 0;
+		/// unsigned int
+	virtual int unpack ( unsigned int *ui,    int nitem, int stride = 1 ) = 0;
+		/// short
+	virtual int unpack ( short *sh,           int nitem, int stride = 1 ) = 0;
+		/// unsigned short
+	virtual int unpack ( unsigned short *ush, int nitem, int stride = 1 ) = 0;
+		/// long
+	virtual int unpack ( long *l,             int nitem, int stride = 1 ) = 0;
+		/// unsigned long
+	virtual int unpack ( unsigned long *ul,   int nitem, int stride = 1 ) = 0;
+		/// Unpack a NULL-terminated string
+	virtual int unpack ( char *string ) = 0;
+
+		//@}
+		//@}
+
+		///
+	double get_bytes_packed() const { return bytes_packed_; }
+
+		///
+	double get_bytes_unpacked() const { return bytes_unpacked_; }	
+	
+		/** When investigating the master-side bottleneck problem, we realized 
+		 *  that sometimes the master can't handle all the messages sent from the 
+		 *  many masters and the RMComm layer. The messages are accumulated in the 
+		 *  RMComm layer's buffer (especially in the case of using MW-CondorPvm), 
+		 *  but the master can't see them, not to mention process them or delete 
+		 *  useless messages. This makes the master unable to accormodate the chanegs
+		 *  in the environment, also makes most of the workers waiting for new tasks.
+
+		 *  One way to deal with this situation is to pull all the messages in the 
+		 *  underlying message passing layer and let the master buffer them by 
+		 *  itself, to separate the message receiving and message processing steps. 
+		 *
+		 *  Thus we will introduce a FIFO list of buf_id (list of *int), each of the
+		 *  buf_id points to a message buffer in PVM (and likewise in the other 
+		 *  RMComms). The original message processing steps are: 
+		 *  	RMC->recv()
+		 *  	RMC->bufinfo()
+		 *  	RMC->unpack(), RMC->unpack()
+		 *  And now the process will be the same, but implementation is different:
+		 *  	RMC->recv_all()	pull all messages out (in a non-blocking way) and 
+		 *  			put each message's buf_id into the FIFO list.
+		 *  	RMC->recv()	blocking recv	
+		 *  	RMC->bufinfo()	examine the buf_info of the buffer with given buf_id
+		 *  	RMC->setrbuf()	will be used to switch the active receive buffer
+		 *  	RMC->freebuf()  will be used to free useless receive buffer
+		 *  	RMC->unpack()
+		 *  	
+		 *  All recv will via the buffer_list now!
+		 */
+protected:	
+		/* both the master and worker can have it! */
+	MWList<void> *recv_buf_list;	
+
+		///	Keeps the number of bytes packed
+	double bytes_packed_;
+
+		/// Holds the number of bytes unpacked
+	double bytes_unpacked_;
+
+public:
+		/* returns the number of new buffers */
+	virtual int recv_all( int from_whom, int msgtag ) = 0;	
+		/* switch the active receive buffer, return the old active buf_id */
+	virtual int setrbuf(int bid) = 0;		
+		/* free the receive buffer. */
+	virtual int freebuf(int bid) = 0;		
+		/* advance the active buffer to the next valid buffer in the recv_buf_list. */
+	virtual int next_buf() = 0;			
+		/* return the recv_buf_list */
+	virtual MWList<void>* recv_buffers() = 0;	
+ private:
+	void verify_file_exists(const char *);
+};
+
+#endif
+
+/*
+  Local Variables:
+  mode: c++
+  eval: (setq c-basic-offset 4)
+  eval: (setq c-comment-only-line-offset 4)
+  eval: (setq c-indent-level 4)
+  eval: (setq c-brace-imaginary-offset 0)
+  eval: (setq c-brace-offset 0)
+  eval: (setq c-argdecl-indent 0)
+  eval: (setq c-label-offset -4)
+  eval: (setq c-continued-statement-offset 4)
+  eval: (setq c-continued-brace-offset -4)
+  eval: (setq c-tab-always-indent nil)
+  eval: (setq tab-width 4)
+  End:
+*/
diff --git a/MW/src/RMComm/Makefile.in b/MW/src/RMComm/Makefile.in
new file mode 100644
index 0000000..7be0bdb
--- /dev/null
+++ b/MW/src/RMComm/Makefile.in
@@ -0,0 +1,155 @@
+#-------------------------------------------------------------------------
+# This file was automatically generated by Automake, and manually modified 
+# to make it simpler and cleaner. There are three sections in the file:
+# 1) Macros
+# 2) Recursive Rules and Suffixes (implicit rules)
+# 3) Explicit Rules
+#-------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------
+#   Section 1) Macros
+#-------------------------------------------------------------------------
+top_srcdir = @top_srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+
+CONDOR_DIR = @CONDOR_DIR@
+CXX = @CXX@
+MEASURE_DEFN = @MEASURE_DEFN@
+MISC_DEFN = @MISC_DEFN@
+MISC_LIB = @MISC_LIB@
+MW_LIBDIR = @MW_LIBDIR@
+MW_LIBDIR_DEBUG = @MW_LIBDIR_DEBUG@
+ENABLE_MWINDEPENDENT = @ENABLE_MWINDEPENDENT@
+PVM_ROOT = @PVM_ROOT@
+RANLIB = @RANLIB@
+USE_MWFILE = @USE_MWFILE@
+INSTALL = @INSTALL@
+SOCKET_LIB = @SOCKET_LIB@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+AR = ar
+
+DEFS = @DEFS@ -I.
+LIBS = @LIBS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+CXXFLAGS = @CXXFLAGS@ -Wall
+
+# Subdirectories
+# only MW-Independent if building sans condor, 
+ifeq ($(CONDOR_DIR), no)
+SUBDIRS := MW-Independent
+else
+
+# If we've got condor, we will have MW-Socket
+SUBDIRS := MW-Independent MW-Socket
+
+ifneq ($(PVM_ROOT), no)
+# Here we have Condor  and pvm
+SUBDIRS := $(SUBDIRS) MW-CondorPVM
+endif
+
+ifneq ($(USE_MWFILE), no)
+# Here we have Condor  and pvm
+SUBDIRS := $(SUBDIRS) MW-File
+endif
+
+ifneq ($(USE_MPI), no)
+SUBDIRS := $(SUBDIRS) MW-StaticMPI
+endif
+
+endif
+
+###  Libraries to be built, and dependent source files
+# If ENDABLE_INDEPENDENT is yes (you can do that by configure --with-independent).
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+LIBRARIES = libMWRMComm.a libMWRMComm_indp.a
+else
+LIBRARIES = libMWRMComm.a
+endif
+
+libMWRMComm_a_SOURCES = MWRMComm.C
+libMWRMComm_a_OBJECTS =  MWRMComm.o
+
+libMWRMComm_indp_a_OBJECTS =  MWRMCommInd.o
+
+# To work with Insure, need to "setenv DEBUG_BUILD='insure'" and write/copy a good .psrc file
+ifdef DEBUG_BUILD
+DEBUG_CHECKER = $(DEBUG_BUILD)
+MW_LIBDIR = $(MW_LIBDIR_DEBUG)
+endif
+INCLUDES = -I. -I.. -I../src/MWControlTasks -IMW-File -IMW-CondorPVM -IMW-Socket $(MISC_DEFN) $(MEASURE_DEFN) #-I$(CONDOR_DIR)/include
+CXXCOMPILE = $(DEBUG_CHECKER) $(CXX) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+INDP_CXXCOMPILE = $(CXXCOMPILE) -DINDEPENDENT
+
+INCLUDEFILES = MWRMComm.h
+
+#-------------------------------------------------------------------------
+#   Section 2) Explicit and Implicit Rules
+#-------------------------------------------------------------------------
+
+all: $(LIBRARIES)
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+libMWRMComm.a: $(libMWRMComm_a_OBJECTS) $(libMWRMComm_a_DEPENDENCIES)
+	-rm -f libMWRMComm.a
+	$(AR) cru libMWRMComm.a $(libMWRMComm_a_OBJECTS) $(libMWRMComm_a_LIBADD)
+	$(RANLIB) libMWRMComm.a
+	cp libMWRMComm.a $(MW_LIBDIR) 
+
+ifeq ($(ENABLE_MWINDEPENDENT), yes)
+libMWRMComm_indp.a: $(libMWRMComm_indp_a_OBJECTS)
+	-rm -f libMWRMComm_indp.a
+	$(AR) cru libMWRMComm_indp.a $(libMWRMComm_indp_a_OBJECTS)
+	$(RANLIB) libMWRMComm_indp.a
+	cp libMWRMComm_indp.a $(MW_LIBDIR)
+MWRMCommInd.o:MWRMComm.C
+	$(INDP_CXXCOMPILE) -o MWRMCommInd.o -c MWRMComm.C
+endif
+
+.SUFFIXES: .C .o
+
+.C.o:
+	$(CXXCOMPILE) -c $<
+
+#-------------------------------------------------------------------------
+#   Section 3) Recursive Rules: Auto-generated
+#-------------------------------------------------------------------------
+install: $(LIBRARIES)
+	$(mkinstalldirs) $(libdir)
+	@list='$(LIBRARIES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(libdir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(libdir)/$$p; \
+	    echo " $(RANLIB) $(libdir)/$$p"; \
+	    $(RANLIB) $(libdir)/$$p; \
+	  fi; \
+	done
+	$(mkinstalldirs) $(includedir)
+	@list='$(INCLUDEFILES)'; for p in $$list; do \
+	  if test -f $$p; then \
+	    echo "  ${INSTALL} -m 644 $$p $(includedir)/$$p"; \
+	    $(INSTALL) -m 644 $$p $(includedir)/$$p; \
+	  fi; \
+	done	
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+check:
+
+clean:
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+distclean:
+	-rm -f Makefile *.tar *.gz
+	-rm -rf .deps
+	-rm -f config.cache config.log stamp-h stamp-h[0-9]*
+	-rm -f *.o *.a *core *.ii
+	[ "__$(SUBDIRS)" = "__" ] || for subdir in `echo "$(SUBDIRS)"`; do (cd $$subdir && $(MAKE) $@) ; done
+
+.PHONY: all check clean distclean install
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..4be7bb5
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,91 @@
+if HAVE_CONDOR
+  MAYBE_MW = MW
+endif
+
+ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main display perl examples doc html tests
+SUBDIRS = $(MAYBE_MW) $(ALWAYS_BUILT)
+DIST_SUBDIRS = $(ALWAYS_BUILT)
+
+EXTRA_DIST = LICENSE COPYING $(MW_DIST)
+
+# Possibly regenerate version file if this is a git repository.
+$(top_srcdir)/version.m4: FORCE
+	@cd $(top_srcdir); if test -r version.sh; then ./version.sh; fi
+.PHONY: FORCE
+
+MW_DIST = \
+	MW/acinclude.m4 \
+	MW/aclocal.m4 \
+	MW/configure \
+	MW/configure.in \
+	MW/COPYING \
+	MW/doxygen.conf \
+	MW/INSTALL \
+	MW/install-sh \
+	MW/Makefile.in \
+	MW/missing \
+	MW/mkinstalldirs \
+	MW/README \
+	MW/src/BlackBox/MWDriver_blackbox.C \
+	MW/src/BlackBox/MWDriver_blackbox.h \
+	MW/src/BlackBox/MWTask_blackbox.C \
+	MW/src/BlackBox/MWTask_blackbox.h \
+	MW/src/BlackBox/MWWorkerMain_blackbox.C \
+	MW/src/BlackBox/MWWorker_blackbox.C \
+	MW/src/BlackBox/MWWorker_blackbox.h \
+	MW/src/BlackBox/Makefile.in \
+	MW/src/MW.C \
+	MW/src/MW.h \
+	MW/src/MWControlTasks/MWNWSTask.C \
+	MW/src/MWControlTasks/MWNWSTask.h \
+	MW/src/MWControlTasks/Makefile.in \
+	MW/src/MWDriver.C \
+	MW/src/MWDriver.h \
+	MW/src/MWGroup.C \
+	MW/src/MWGroup.h \
+	MW/src/MWList.C \
+	MW/src/MWList.h \
+	MW/src/MWMasterMain.C \
+	MW/src/MWStats.C \
+	MW/src/MWStats.h \
+	MW/src/MWSystem.h \
+	MW/src/MWTask.C \
+	MW/src/MWTask.h \
+	MW/src/MWTaskContainer.C \
+	MW/src/MWTaskContainer.h \
+	MW/src/MWUnixSystem.C \
+	MW/src/MWWinSystem.C \
+	MW/src/MWWorker.C \
+	MW/src/MWWorker.h \
+	MW/src/MWWorkerID.C \
+	MW/src/MWWorkerID.h \
+	MW/src/MWWorkerMain.C \
+	MW/src/MWprintf.C \
+	MW/src/MWprintf.h \
+	MW/src/Makefile.in \
+	MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C \
+	MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h \
+	MW/src/RMComm/MW-CondorPVM/Makefile.in \
+	MW/src/RMComm/MW-File/MWFileError.h \
+	MW/src/RMComm/MW-File/MWFileRC.C \
+	MW/src/RMComm/MW-File/MWFileRC.h \
+	MW/src/RMComm/MW-File/MWFileRCSymbol.h \
+	MW/src/RMComm/MW-File/MWFileSend.h \
+	MW/src/RMComm/MW-File/MWFileTypes.h \
+	MW/src/RMComm/MW-File/MWFileWorker.h \
+	MW/src/RMComm/MW-File/Makefile.in \
+	MW/src/RMComm/MW-File/chirp_client.c \
+	MW/src/RMComm/MW-File/chirp_client.h \
+	MW/src/RMComm/MW-File/chirp_protocol.h \
+	MW/src/RMComm/MW-Independent/MWIndRC.C \
+	MW/src/RMComm/MW-Independent/MWIndRC.h \
+	MW/src/RMComm/MW-Independent/Makefile.in \
+	MW/src/RMComm/MW-Socket/MWSocketRC.C \
+	MW/src/RMComm/MW-Socket/MWSocketRC.h \
+	MW/src/RMComm/MW-Socket/Makefile.in \
+	MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C \
+	MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h \
+	MW/src/RMComm/MW-StaticMPI/Makefile.in \
+	MW/src/RMComm/MWRMComm.C \
+	MW/src/RMComm/MWRMComm.h \
+	MW/src/RMComm/Makefile.in
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..6db73e7
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,872 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = .
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/configure $(am__configure_deps) \
+	$(srcdir)/config.h.in $(top_srcdir)/display/mad/manifest.mf.in \
+	COPYING README build-aux/ar-lib build-aux/compile \
+	build-aux/config.guess build-aux/config.sub build-aux/depcomp \
+	build-aux/install-sh build-aux/missing \
+	$(top_srcdir)/build-aux/ar-lib $(top_srcdir)/build-aux/compile \
+	$(top_srcdir)/build-aux/config.guess \
+	$(top_srcdir)/build-aux/config.sub \
+	$(top_srcdir)/build-aux/install-sh \
+	$(top_srcdir)/build-aux/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES = display/mad/manifest.mf
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
+	ctags-recursive dvi-recursive html-recursive info-recursive \
+	install-data-recursive install-dvi-recursive \
+	install-exec-recursive install-html-recursive \
+	install-info-recursive install-pdf-recursive \
+	install-ps-recursive install-recursive installcheck-recursive \
+	installdirs-recursive pdf-recursive ps-recursive \
+	tags-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+am__recursive_targets = \
+  $(RECURSIVE_TARGETS) \
+  $(RECURSIVE_CLEAN_TARGETS) \
+  $(am__extra_recursive_targets)
+AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
+	cscope distdir dist dist-all distcheck
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
+	$(LISP)config.h.in
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+CSCOPE = cscope
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
+am__post_remove_distdir = $(am__remove_distdir)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+DIST_TARGETS = dist-gzip
+distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+ at HAVE_CONDOR_TRUE@MAYBE_MW = MW
+ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main display perl examples doc html tests
+SUBDIRS = $(MAYBE_MW) $(ALWAYS_BUILT)
+DIST_SUBDIRS = $(ALWAYS_BUILT)
+EXTRA_DIST = LICENSE COPYING $(MW_DIST)
+MW_DIST = \
+	MW/acinclude.m4 \
+	MW/aclocal.m4 \
+	MW/configure \
+	MW/configure.in \
+	MW/COPYING \
+	MW/doxygen.conf \
+	MW/INSTALL \
+	MW/install-sh \
+	MW/Makefile.in \
+	MW/missing \
+	MW/mkinstalldirs \
+	MW/README \
+	MW/src/BlackBox/MWDriver_blackbox.C \
+	MW/src/BlackBox/MWDriver_blackbox.h \
+	MW/src/BlackBox/MWTask_blackbox.C \
+	MW/src/BlackBox/MWTask_blackbox.h \
+	MW/src/BlackBox/MWWorkerMain_blackbox.C \
+	MW/src/BlackBox/MWWorker_blackbox.C \
+	MW/src/BlackBox/MWWorker_blackbox.h \
+	MW/src/BlackBox/Makefile.in \
+	MW/src/MW.C \
+	MW/src/MW.h \
+	MW/src/MWControlTasks/MWNWSTask.C \
+	MW/src/MWControlTasks/MWNWSTask.h \
+	MW/src/MWControlTasks/Makefile.in \
+	MW/src/MWDriver.C \
+	MW/src/MWDriver.h \
+	MW/src/MWGroup.C \
+	MW/src/MWGroup.h \
+	MW/src/MWList.C \
+	MW/src/MWList.h \
+	MW/src/MWMasterMain.C \
+	MW/src/MWStats.C \
+	MW/src/MWStats.h \
+	MW/src/MWSystem.h \
+	MW/src/MWTask.C \
+	MW/src/MWTask.h \
+	MW/src/MWTaskContainer.C \
+	MW/src/MWTaskContainer.h \
+	MW/src/MWUnixSystem.C \
+	MW/src/MWWinSystem.C \
+	MW/src/MWWorker.C \
+	MW/src/MWWorker.h \
+	MW/src/MWWorkerID.C \
+	MW/src/MWWorkerID.h \
+	MW/src/MWWorkerMain.C \
+	MW/src/MWprintf.C \
+	MW/src/MWprintf.h \
+	MW/src/Makefile.in \
+	MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.C \
+	MW/src/RMComm/MW-CondorPVM/MWCondorPvmRC.h \
+	MW/src/RMComm/MW-CondorPVM/Makefile.in \
+	MW/src/RMComm/MW-File/MWFileError.h \
+	MW/src/RMComm/MW-File/MWFileRC.C \
+	MW/src/RMComm/MW-File/MWFileRC.h \
+	MW/src/RMComm/MW-File/MWFileRCSymbol.h \
+	MW/src/RMComm/MW-File/MWFileSend.h \
+	MW/src/RMComm/MW-File/MWFileTypes.h \
+	MW/src/RMComm/MW-File/MWFileWorker.h \
+	MW/src/RMComm/MW-File/Makefile.in \
+	MW/src/RMComm/MW-File/chirp_client.c \
+	MW/src/RMComm/MW-File/chirp_client.h \
+	MW/src/RMComm/MW-File/chirp_protocol.h \
+	MW/src/RMComm/MW-Independent/MWIndRC.C \
+	MW/src/RMComm/MW-Independent/MWIndRC.h \
+	MW/src/RMComm/MW-Independent/Makefile.in \
+	MW/src/RMComm/MW-Socket/MWSocketRC.C \
+	MW/src/RMComm/MW-Socket/MWSocketRC.h \
+	MW/src/RMComm/MW-Socket/Makefile.in \
+	MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.C \
+	MW/src/RMComm/MW-StaticMPI/MWStaticMPIRC.h \
+	MW/src/RMComm/MW-StaticMPI/Makefile.in \
+	MW/src/RMComm/MWRMComm.C \
+	MW/src/RMComm/MWRMComm.h \
+	MW/src/RMComm/Makefile.in
+
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh: Makefile
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+	@test -f $@ || rm -f stamp-h1
+	@test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+display/mad/manifest.mf: $(top_builddir)/config.status $(top_srcdir)/display/mad/manifest.mf.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run 'make' without going through this Makefile.
+# To change the values of 'make' variables: instead of editing Makefiles,
+# (1) if the variable is set in 'config.status', edit 'config.status'
+#     (which will cause the Makefiles to be regenerated when you run 'make');
+# (2) otherwise, pass the desired values on the 'make' command line.
+$(am__recursive_targets):
+	@fail=; \
+	if $(am__make_keepgoing); then \
+	  failcom='fail=yes'; \
+	else \
+	  failcom='exit 1'; \
+	fi; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-recursive
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-recursive
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscope: cscope.files
+	test ! -s cscope.files \
+	  || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
+clean-cscope:
+	-rm -f cscope.files
+cscope.files: clean-cscope cscopelist
+cscopelist: cscopelist-recursive
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+	-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    $(am__make_dryrun) \
+	      || test -d "$(distdir)/$$subdir" \
+	      || $(MKDIR_P) "$(distdir)/$$subdir" \
+	      || exit 1; \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -755 \
+		-exec chmod u+rwx,go+rx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__post_remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__post_remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
+	$(am__post_remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
+	$(am__post_remove_distdir)
+
+dist-tarZ: distdir
+	@echo WARNING: "Support for shar distribution archives is" \
+	               "deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__post_remove_distdir)
+
+dist-shar: distdir
+	@echo WARNING: "Support for distribution archives compressed with" \
+		       "legacy program 'compress' is deprecated." >&2
+	@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__post_remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__post_remove_distdir)
+
+dist dist-all:
+	$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
+	$(am__post_remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir)
+	chmod u+w $(distdir)
+	mkdir $(distdir)/_build $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	    --srcdir=.. --prefix="$$dc_install_base" \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__post_remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(am__recursive_targets) all install-am install-strip
+
+.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
+	am--refresh check check-am clean clean-cscope clean-generic \
+	cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \
+	dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \
+	distcheck distclean distclean-generic distclean-hdr \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs installdirs-am \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Possibly regenerate version file if this is a git repository.
+$(top_srcdir)/version.m4: FORCE
+	@cd $(top_srcdir); if test -r version.sh; then ./version.sh; fi
+.PHONY: FORCE
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/README b/README
new file mode 100644
index 0000000..f77918d
--- /dev/null
+++ b/README
@@ -0,0 +1,357 @@
+
+==================================================================
+                        FSA
+
+        Distance-based multiple sequence alignment
+==================================================================
+
+FSA is a probabilistic multiple sequence alignment algorithm which uses
+a "distance-based" approach to aligning homologous protein, RNA or DNA
+sequences.  Much as distance-based phylogenetic reconstruction methods
+like Neighbor-Joining build a phylogeny using only pairwise divergence
+estimates, FSA builds a multiple alignment using only pairwise
+estimations of homology.  This is made possible by the sequence
+annealing technique for constructing a multiple alignment from pairwise
+comparisons, developed by Ariel Schwartz in
+"Posterior Decoding Methods for Optimization and Control of Multiple
+Alignments." Ph.D. Thesis, UC Berkeley. 2007.
+
+FSA brings the high accuracies previously available only for small-scale 
+analyses of proteins or RNAs to large-scale problems such as aligning 
+thousands of sequences or megabase-long sequences.  FSA introduces
+several novel methods for constructing better alignments:
+
+  * FSA uses machine-learning techniques to estimate gap and
+    substitution parameters on the fly for each set of input sequences.
+    This "query-specific learning" alignment method makes FSA very robust: it
+    can produce superior alignments of sets of homologous sequences
+    which are subject to very different evolutionary constraints.
+
+  * FSA is capable of aligning hundreds or even thousands of sequences
+    using a randomized inference algorithm to reduce the computational
+    cost of multiple alignment.  This randomized inference can be over
+    ten times faster than a direct approach with little loss of
+    accuracy.
+
+  * FSA can quickly align very long sequences using the "anchor
+    annealing" technique for resolving anchors and projecting them with
+    transitive anchoring.  It then stitches together the alignment
+    between the anchors using the methods described above.
+
+  * The included GUI, MAD (Multiple Alignment Display), can display
+    the intermediate alignments produced by FSA, where each character
+    is colored according to the probability that it is correctly
+    aligned.
+
+FSA was created by Robert Bradley. It was developed by Robert Bradley,
+Colin Dewey, Jaeyoung Do, Sudeep Juvekar, Lior Pachter, Adam Roberts,
+and Michael Smoot, along with assistance from many other people.
+All have made intellectual contributions and contributed code.
+
+Please contact us at fsa at math.berkeley.edu with any questions, feedback, etc.
+
+If you use FSA, please cite:
+Bradley RK, Roberts A, Smoot M, Juvekar S, Do J, Dewey C, Holmes I, Pachter L (2009) Fast Statistical Alignment. PLoS Computational Biology. 5:e1000392.
+(This manuscript can be found in the doc/ directory.)
+
+
+==================================================================
+
+                   INSTALLATION
+
+FSA is built and installed by running the following commands:
+
+./configure
+make
+make install
+
+If you wish to install the fsa files in a location other than your
+system's standard directories (which usually requires root permissions),
+specify the top-level installation directory with the --prefix option to
+configure.  For example,
+
+./configure --prefix=$HOME
+
+specifies that binaries should be installed in $HOME/bin, libraries in
+$HOME/lib, etc..
+
+If you wish to align long sequences, then you must install MUMmer,
+which FSA calls to get candidate anchors between sequences.
+You can download MUMmer from http://mummer.sourceforge.net/.
+When running configure, you must either have the mummer executable in your path
+or specify the executable with the --with-mummer option to configure, e.g.
+
+./configure --with-mummer=/usr/local/MUMmer3.20/mummer
+
+if it is located at /usr/local/MUMmer3.20/mummer.
+
+FSA can also call exonerate to detect remote homology.
+You can download exonerate from http://www.ebi.ac.uk/~guy/exonerate/.
+When running configure, you must either have the exonerate executable in your path
+or specify the executable with the --with-exonerate option to configure, e.g.
+
+./configure --with-exonerate=/usr/local/bin/exonerate
+
+if it is located at /usr/local/bin/exonerate.
+
+
+==================================================================
+
+                      USAGE
+
+FSA accepts FASTA-format input files and outputs multi-FASTA
+alignments by default.  The most basic usage is:
+  fsa <mysequences.fa> >myalignedsequences.mfa
+or
+  fsa --stockholm <mysequences.fa> >myalignedsequences.stk
+
+Many options are provided.  Please see html/FAQ.html for more information.
+
+
+==================================================================
+
+                    REFERENCES
+
+Source code in 'seq/' and 'util/' is from Ian Holmes's DART library, 
+which is used for input and output routines.
+
+FSA's DP code was generated by HMMoC by Gerton Lunter. The
+'aligner' example distributed with HMMoC, which implements a 
+learning procedure for gap parameters, was an inspiration for FSA's
+learning strategies. FSA's banding code is taken directly from the
+'aligner' example.
+
+The sequence annealing technique for constructing a multiple
+alignment from pairwise comparisons was developed by Ariel Schwartz.
+The implementation of sequence annealing in FSA is based on
+the original implementation in AMAP by Ariel Schwartz and Lior Pachter.
+
+The anchor annealing approach used in FSA is modeled after the recursive
+anchoring strategy used in MAVID by Nicolas Bray and Lior Pachter.
+
+The MAD GUI interface to FSA was written by Adam Roberts based on
+a preliminary version by Michael Smoot.
+
+Please see:
+
+I. Holmes and R. Durbin. "Dynamic Programming Alignment Accuracy." Journal of Computational Biology. 1998, 5 (3):493-504.
+G.A. Lunter. "HMMoC - a Compiler for Hidden Markov Models." Bioinformatics. 2007, 23 (18):2485-2487.
+A.S. Schwartz. "Posterior Decoding Methods for Optimization and Control of Multiple Alignments." Ph.D. Thesis, UC Berkeley. 2007.
+A.S. Schwartz and L. Pachter. "Multiple Alignment by Sequence Annealing." Bioinformatics. 2007, 23 (2):e24-e29.
+N. Bray and L. Pachter "MAVID: Constrained Ancestral Alignment of Multiple Sequences." Genome Research. 2004, 14:693-699.
+
+
+==================================================================
+
+                        COPYRIGHT
+
+Copyright (C) 2008. The Regents of the University of California (Regents).
+All Rights Reserved.  Permission to use, copy, modify, and distribute this software
+and its documentation for educational, research, and not-for-profit purposes,
+without fee and without a signed licensing agreement, is hereby granted,
+provided that the above copyright notice, this paragraph and the following two paragraphs
+appear in all copies, modifications, and distributions.
+Contact
+The Office of Technology Licensing, UC Berkeley, 2150 Shattuck Avenue,
+Suite 510, Berkeley, CA 94720-1620, (510) 643-7201
+for commercial licensing opportunities.
+Created by
+Robert K. Bradley, Departments of Math and Molecular and Cell Biology,
+University of California, Berkeley.
+
+IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
+INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE
+AND ITS DOCUMENTATION, EVEN IF REGENTS HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE AND
+ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".
+REGENTS HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
+UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+
+==================================================================
+
+                        LICENSE
+
+
+Please see the file LICENSE distributed with FSA.
+
+
+FSA is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3 of the License, or
+(at your option) any later version.
+
+FSA is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with FSA; if not, write to the Free Software Foundation, Inc.,
+51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+==================================================================
+
+                    VERSION HISTORY
+
+1.01, 7/10/2008
+  -- Initial import to Git (Robert Bradley)
+
+1.02, 7/21/08
+  -- Faster anchor annealing (Robert Bradley)
+  -- GUI added to package (Adam Roberts)
+
+1.03, 7/25/08
+  -- Improved GUI features (Adam Roberts)
+
+1.04, 7/28/08
+  -- Moved to autotools (Colin Dewey)
+
+1.05, 8/21/08
+  -- Optional anchor annealing in protein space (Robert Bradley)
+  -- Reduced GUI memory usage (Adam Roberts)
+  -- Many accuracy measures for GUI (Adam Roberts and Robert Bradley)
+
+1.06, 8/29/08
+  -- Homology no longer forced at anchor boundaries (Robert Bradley)
+  -- Scripts for evaluating alignment accuracies according to FSA's model (Robert Bradley)
+
+1.07, 9/2/08
+  -- GUI bugfix for displaying extremely certain alignments (Robert Bradley)
+      (Alignment inference is unaffected.)
+
+1.08, 9/15/08
+  -- Miscellaneous compilation fixes (Robert Bradley)
+  -- Fix for learning on highly-conserved alignments (Robert Bradley)
+
+1.09, 10/22/08
+  -- Much faster sequence annealing (Robert Bradley, Colin Dewey & Lior Pachter)
+  -- Better memory usage for long sequences (Robert Bradley)
+  -- Optional Mercator constraints (Robert Bradley and Colin Dewey)
+  -- Optional anchoring with exonerate (Robert Bradley)
+  -- GUI can export TIFF images (Robert Bradley)
+  -- gapcleaner fix (Robert Bradley)
+  -- Parallelization mode (Jaeyoung Do and Colin Dewey)
+  -- Database mode (Jaeyoung Do and Colin Dewey)
+  -- Added submitted manuscript as manual.
+
+(The below versions are labeled as "major.minor.bugfix")
+
+1.10.0, 10/30/08
+  -- --nucprot option and utility programs translate and prot2codon (Robert Bradley & Colin Dewey)
+  -- Bugfixes for anchoring with both Mercator & exonerate (Robert Bradley & Colin Dewey)
+  -- Bugfixes for parallelization & database modes (Jaeyoung Do & Colin Dewey)
+
+1.11.0, 11/11/08
+  -- housekeeping tasks (Robert Bradley):
+       - gaps stripped from input sequences
+       - error thrown if 2 alignable sequence are left unaligned due to RAM constraints
+  -- hardmasked sequence is left unaligned by default (Robert Bradley)
+
+1.11.1, 11/13/08
+  -- Bugfixes for anchoring with both Mercator & exonerate (Robert Bradley & Colin Dewey)
+  -- Compilation fixes for g++ 4.4 (Robert Bradley)
+
+1.11.2, 11/14/08
+  -- Bugfix for GUI compilation (Colin Dewey)
+
+1.12.0, 11/22/08
+  -- Perl scripts to interact with FSA-Mercator
+     whole-genome alignments (Robert Bradley & Colin Dewey)
+  -- Switch to using only ungapped exonerate anchors (Robert Bradley & Colin Dewey)
+
+1.12.1, 11/27/08
+  -- Source code documentation updated for Doxygen compatibility (Robert Bradley)
+
+1.13.0, 1/9/09
+  -- C++ tools for working with FSA-Mercator whole-genome alignments (Robert Bradley & Colin Dewey)
+     (Note that the deprecated Perl scripts had a serious bug for - strand extraction!)
+  -- Bugfix for softmasking with exonerate (Robert Bradley & Colin Dewey)
+  -- Completely re-written sequence and alignment representation code (Robert Bradley)
+  -- Use a model with 2 sets, rather than 1 set, of indel states by default
+  -- Turn iterative refinement on by default with an unlimited number of steps
+
+1.13.1, 1/9/09
+  -- Bugfix and better automated options for --nucprot (Robert Bradley)
+
+1.13.2, 1/12/09
+  -- Compilation fixes for g++ 4.4 (Robert Bradley)
+
+1.13.3, 1/14/09
+  -- Bugfix for alphabet case-sensitivity during learning (Robert Bradley)
+
+1.13.4, 2/6/09
+  -- Bugfix for % ID calculation for sliced alignments (Robert Bradley)
+  -- More intuitive default anchoring options (Colin Dewey)
+  -- Bugfix for hardmasked error after compilation without MUMmer on OS X 10.4 (Robert Bradley)
+
+1.14.0, 3/11/09
+  -- Added experimental --tree-weights option (Robert Bradley)
+  -- Added experimental --load-probs option (Robert Bradley)
+  -- Changed default behavior when two sequences have no detectable homology; see new option --require-homology (Robert Bradley)
+  -- New utility program slice_fasta to extract subsequences from FASTA files (Robert Bradley).
+
+1.14.1, 3/20/09
+  -- Changed Mercator-related short options to use upper-case letters (Robert Bradley).
+  -- Mercator slicing stuff now assumes a + strand if strand is unspecified; previously implicitly assumed - (Robert Bradley)
+  -- Tiny bugfix for map_gff_coords: --force-entry was accidentally on by default (Robert Bradley)
+  -- Bugfix for GUI compilation on Linux (Colin Dewey)
+
+1.14.2, 3/23/09
+  -- Updated FSA preprint (Robert Bradley).
+
+1.14.3, 3/31/09
+  -- Bugfix for recognizing DNA sequences with a lot of hardmasked sequence as protein (Robert Bradley)
+
+1.14.4, 4/2/09
+  -- Compilation bugfixes for some Linux systems where floor isn't declared (Robert Bradley)
+  -- Added FSA preprint accepted by PLoS Computational Biology (Robert Bradley)
+
+1.14.5, 4/14/09
+  -- Handle "NA" fields in Mercator maps (Robert Bradley)
+  -- Bugfix for automatic available RAM detection for some Linux distributions (Colin Dewey)
+  -- Parallelization and database modes are disabled by default (Colin Dewey)
+  -- Bugfix for strange behavior where all sequences are left unaligned under some older compilers (Colin Dewey)
+
+1.15.0, 6/12/09
+  -- Options to use k-mer similarities to choose sequence pairs for alignment, rather than just randomly (Robert Bradley & Colin Dewey)
+     * New options include --mst-min, --mst-max, --mst-palm, --degree and --kmer.
+     * Deprecated --training-number and --training-fraction options.
+  -- Memory usage in --maxsn mode reduced by ~2X (Robert Bradley & Colin Dewey)
+     The above two changes result in significantly-better large (> 100 sequences) alignments.
+  -- New program slice_fasta_gff (Robert Bradley)
+  -- Compiler flags for 64-bit systems to ensure that all available RAM is used if requested (Robert Bradley)
+  -- Published manuscript (http://www.ploscompbiol.org/article/info:doi/10.1371/journal.pcbi.1000392) included in doc/
+  -- Bugfix for automatic setting of --maxram for available RAM assessment (Colin Dewey)
+
+1.15.1, 7/15/09
+  -- Refactored alignment code to speed up the FSA-Mercator tools (Robert Bradley)
+
+1.15.2, 7/16/09
+  -- Minor compilation fix for g++ 4.1.2 (Robert Bradley)
+
+1.15.3, 10/14/09
+  -- Minor bugfix for running in --anchored --translated mode (Robert Bradley)
+
+1.15.4, 8/5/09
+  -- Minor bugfix for Mercator constraints which are all Ns in one species (Robert Bradley)
+
+1.15.5, 8/10/09
+  -- Use tr1/unordered_set for annealing if available (Robert Bradley)
+
+1.15.6, 6/22/11
+  -- Minor compilation fix for gcc 4.5.2 (Robert Bradley)
+
+1.15.7, 1/30/12
+  -- Minor compilation fix for gcc 4.6 (Robert Bradley)
+
+1.15.8, 11/22/13
+  -- Minor compilation fix for Ubuntu 13.04 (Robert Bradley; thanks to Alastair Fyfe for suggestion)
+
+1.15.9, 5/16/14
+  -- Compilation fix for HMMoC code, plus minor changes to prevent warnings on Apple LLVM version 5.1 (Robert Bradley; thanks to Renato Gama for suggestion)
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..c5587c9
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,114 @@
+
+AC_DEFUN([AC_CXX_NAMESPACES],
+[AC_CACHE_CHECK(whether the compiler implements namespaces,
+ac_cv_cxx_namespaces,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([namespace Outer { namespace Inner { int i = 0; }}],
+                [using namespace Outer::Inner; return i;],
+ ac_cv_cxx_namespaces=yes, ac_cv_cxx_namespaces=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_namespaces" = yes; then
+  AC_DEFINE(HAVE_NAMESPACES,,[define if the compiler implements namespaces])
+fi
+])
+
+AC_DEFUN([AC_CXX_GNUCXX_HASHMAP],[
+AC_CACHE_CHECK(whether the compiler supports __gnu_cxx::hash_map,
+ac_cv_cxx_gnucxx_hashmap,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <ext/hash_map>
+using __gnu_cxx::hash_map;],
+ [],
+ ac_cv_cxx_gnucxx_hashmap=yes, ac_cv_cxx_gnucxx_hashmap=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_gnucxx_hashmap" = yes; then
+  AC_DEFINE(HAVE_GNUCXX_HASHMAP,,[define if the compiler supports __gnu_cxx::hash_map])
+fi
+])
+
+AC_DEFUN([AC_CXX_HAVE_EXT_HASH_MAP],
+[AC_CACHE_CHECK(whether the compiler has ext/hash_map,
+ac_cv_cxx_have_ext_hash_map,
+[AC_REQUIRE([AC_CXX_NAMESPACES])
+  AC_LANG_SAVE
+  AC_LANG_CPLUSPLUS
+  AC_TRY_COMPILE([#include <ext/hash_map>
+#ifdef HAVE_NAMESPACES
+using namespace std;
+#endif],[hash_map<int, int> t; return 0;],
+  ac_cv_cxx_have_ext_hash_map=yes, ac_cv_cxx_have_ext_hash_map=no)
+  AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_have_ext_hash_map" = yes; then
+   AC_DEFINE(HAVE_EXT_HASH_MAP,,[define if the compiler has ext/hash_map])
+fi
+])
+
+AC_DEFUN([AC_CXX_STLPORT_HASHMAP],[
+AC_CACHE_CHECK(whether the compiler supports std::hash_map,
+ac_cv_cxx_stlport_hashmap,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <hash_map>
+using std::hash_map;],
+ [],
+ ac_cv_cxx_stlport_hashmap=yes, ac_cv_cxx_stlport_hashmap=no)
+ AC_LANG_RESTORE
+])
+if test "$ac_cv_cxx_stlport_hashmap" = yes; then
+  AC_DEFINE(HAVE_STLPORT_HASHMAP,,[define if the compiler supports std::hash_map])
+fi
+])
+
+
+#################################################################################
+# The below definitions for AC_TYPE_UINTMAX_T AND AC_TYPE_UNSIGNED_LONG_LONG_INT
+# were taken from the Autoconf types.m4 file;
+# they're included here since older distributions of autoconf don't
+# have these macros defined.
+#################################################################################
+
+# AC_TYPE_UINTMAX_T
+# -----------------
+AC_DEFUN([AC_TYPE_UINTMAX_T],
+[
+  AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+  AC_CHECK_TYPE([uintmax_t],
+    [AC_DEFINE([HAVE_UINTMAX_T], 1,
+       [Define to 1 if the system has the type `uintmax_t'.])],
+    [test $ac_cv_type_unsigned_long_long_int = yes \
+       && ac_type='unsigned long long int' \
+       || ac_type='unsigned long int'
+     AC_DEFINE_UNQUOTED([uintmax_t], [$ac_type],
+       [Define to the widest unsigned integer type
+	if <stdint.h> and <inttypes.h> do not define.])])
+])
+
+
+# AC_TYPE_UNSIGNED_LONG_LONG_INT
+# ------------------------------
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+  AC_CACHE_CHECK([for unsigned long long int],
+    [ac_cv_type_unsigned_long_long_int],
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+	  [[unsigned long long int ull = 18446744073709551615ULL;
+	    typedef int a[(18446744073709551615ULL <= (unsigned long long int) -1
+			   ? 1 : -1)];
+	   int i = 63;]],
+	  [[unsigned long long int ullmax = 18446744073709551615ull;
+	    return (ull << 63 | ull >> 63 | ull << i | ull >> i
+		    | ullmax / ull | ullmax % ull);]])],
+       [ac_cv_type_unsigned_long_long_int=yes],
+       [ac_cv_type_unsigned_long_long_int=no])])
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+    AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], 1,
+      [Define to 1 if the system has the type `unsigned long long int'.])
+  fi
+])
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..1cbf5e4
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1210 @@
+# generated automatically by aclocal 1.14.1 -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
+[m4_warning([this file was generated for autoconf 2.69.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically 'autoreconf'.])])
+
+# Copyright (C) 2002-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.14'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.14.1], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.14.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_AR([ACT-IF-FAIL])
+# -------------------------
+# Try to determine the archiver interface, and trigger the ar-lib wrapper
+# if it is needed.  If the detection of archiver interface fails, run
+# ACT-IF-FAIL (default is to abort configure with a proper error message).
+AC_DEFUN([AM_PROG_AR],
+[AC_BEFORE([$0], [LT_INIT])dnl
+AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([ar-lib])dnl
+AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false])
+: ${AR=ar}
+
+AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface],
+  [AC_LANG_PUSH([C])
+   am_cv_ar_interface=ar
+   AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])],
+     [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([am_ar_try])
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD'
+        AC_TRY_EVAL([am_ar_try])
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+     ])
+   AC_LANG_POP([C])])
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  m4_default([$1],
+             [AC_MSG_ERROR([could not determine $AR interface])])
+  ;;
+esac
+AC_SUBST([AR])dnl
+])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to '$srcdir/foo'.  In other projects, it is set to
+# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is '.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ([2.52])dnl
+ m4_if([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+       [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+m4_if([$1], [CC],   [depcc="$CC"   am_compiler_list=],
+      [$1], [CXX],  [depcc="$CXX"  am_compiler_list=],
+      [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+      [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'],
+      [$1], [UPC],  [depcc="$UPC"  am_compiler_list=],
+      [$1], [GCJ],  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                    [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES.
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE([dependency-tracking], [dnl
+AS_HELP_STRING(
+  [--enable-dependency-tracking],
+  [do not reject slow dependency extractors])
+AS_HELP_STRING(
+  [--disable-dependency-tracking],
+  [speeds up one-time build])])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each '.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
+m4_define([AC_PROG_CC],
+m4_defn([AC_PROG_CC])
+[_AM_PROG_CC_C_O
+])
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.65])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[AC_DIAGNOSE([obsolete],
+             [$0: two- and three-arguments forms are deprecated.])
+m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(
+  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  [ok:ok],,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
+ AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
+AM_MISSING_PROG([AUTOCONF], [autoconf])
+AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
+AM_MISSING_PROG([AUTOHEADER], [autoheader])
+AM_MISSING_PROG([MAKEINFO], [makeinfo])
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES([CC])],
+		  [m4_define([AC_PROG_CC],
+			     m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES([CXX])],
+		  [m4_define([AC_PROG_CXX],
+			     m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES([OBJC])],
+		  [m4_define([AC_PROG_OBJC],
+			     m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
+		  [_AM_DEPENDENCIES([OBJCXX])],
+		  [m4_define([AC_PROG_OBJCXX],
+			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
+])
+AC_REQUIRE([AM_SILENT_RULES])dnl
+dnl The testsuite driver may need to know about EXEEXT, so add the
+dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
+dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
+  fi
+fi])
+
+dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST([install_sh])])
+
+# Copyright (C) 2003-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it is modern enough.
+# If it is, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  AC_MSG_WARN(['missing' script is too old or missing])
+fi
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# --------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_CC_C_O
+# ---------------
+# Like AC_PROG_CC_C_O, but changed for automake.  We rewrite AC_PROG_CC
+# to automatically call this.
+AC_DEFUN([_AM_PROG_CC_C_O],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+AC_LANG_PUSH([C])dnl
+AC_CACHE_CHECK(
+  [whether $CC understands -c and -o together],
+  [am_cv_prog_cc_c_o],
+  [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i])
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+AC_LANG_POP([C])])
+
+# For backward compatibility.
+AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_RUN_LOG(COMMAND)
+# -------------------
+# Run COMMAND, save the exit status in ac_status, and log it.
+# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
+AC_DEFUN([AM_RUN_LOG],
+[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
+   ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   (exit $ac_status); }])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$[*]" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$[*]" != "X $srcdir/configure conftest.file" \
+	&& test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment])
+     fi
+     if test "$[2]" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT([yes])
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+AC_CONFIG_COMMANDS_PRE(
+  [AC_MSG_CHECKING([that generated files are newer than configure])
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   AC_MSG_RESULT([done])])
+rm -f conftest.file
+])
+
+# Copyright (C) 2009-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_SILENT_RULES([DEFAULT])
+# --------------------------
+# Enable less verbose build rules; with the default set to DEFAULT
+# ("yes" being less verbose, "no" or empty being verbose).
+AC_DEFUN([AM_SILENT_RULES],
+[AC_ARG_ENABLE([silent-rules], [dnl
+AS_HELP_STRING(
+  [--enable-silent-rules],
+  [less verbose build output (undo: "make V=1")])
+AS_HELP_STRING(
+  [--disable-silent-rules],
+  [verbose build output (undo: "make V=0")])dnl
+])
+case $enable_silent_rules in @%:@ (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
+esac
+dnl
+dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
+dnl do not support nested variable expansions.
+dnl See automake bug#9928 and bug#10237.
+am_make=${MAKE-make}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [if AS_ECHO([['TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using '$V' instead of '$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor 'install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in "make install-strip", and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# --------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004-2013 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of 'v7', 'ustar', or 'pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+#
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+
+m4_if([$1], [v7],
+  [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
+
+  [m4_case([$1],
+    [ustar],
+     [# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
+      if test $am_uid -le $am_max_uid; then
+         AC_MSG_RESULT([yes])
+      else
+         AC_MSG_RESULT([no])
+         _am_tools=none
+      fi
+      AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
+      if test $am_gid -le $am_max_gid; then
+         AC_MSG_RESULT([yes])
+      else
+        AC_MSG_RESULT([no])
+        _am_tools=none
+      fi],
+
+  [pax],
+    [],
+
+  [m4_fatal([Unknown tar format])])
+
+  AC_MSG_CHECKING([how to create a $1 tar archive])
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_$1-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        AM_RUN_LOG([$_am_tar --version]) && break
+      done
+      am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x $1 -w "$$tardir"'
+      am__tar_='pax -L -x $1 -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+      am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+      am__untar='cpio -i -H $1 -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_$1}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      AM_RUN_LOG([$am__untar <conftest.tar])
+      AM_RUN_LOG([cat conftest.dir/file])
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+  AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/build-aux/ar-lib b/build-aux/ar-lib
new file mode 100755
index 0000000..fe2301e
--- /dev/null
+++ b/build-aux/ar-lib
@@ -0,0 +1,270 @@
+#! /bin/sh
+# Wrapper for Microsoft lib.exe
+
+me=ar-lib
+scriptversion=2012-03-01.08; # UTC
+
+# Copyright (C) 2010-2013 Free Software Foundation, Inc.
+# Written by Peter Rosin <peda at lysator.liu.se>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+
+# func_error message
+func_error ()
+{
+  echo "$me: $1" 1>&2
+  exit 1
+}
+
+file_conv=
+
+# func_file_conv build_file
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv in
+	mingw)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_at_file at_file operation archive
+# Iterate over all members in AT_FILE performing OPERATION on ARCHIVE
+# for each of them.
+# When interpreting the content of the @FILE, do NOT use func_file_conv,
+# since the user would need to supply preconverted file names to
+# binutils ar, at least for MinGW.
+func_at_file ()
+{
+  operation=$2
+  archive=$3
+  at_file_contents=`cat "$1"`
+  eval set x "$at_file_contents"
+  shift
+
+  for member
+  do
+    $AR -NOLOGO $operation:"$member" "$archive" || exit $?
+  done
+}
+
+case $1 in
+  '')
+     func_error "no command.  Try '$0 --help' for more information."
+     ;;
+  -h | --h*)
+    cat <<EOF
+Usage: $me [--help] [--version] PROGRAM ACTION ARCHIVE [MEMBER...]
+
+Members may be specified in a file named with @FILE.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "$me, version $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test $# -lt 3; then
+  func_error "you must specify a program, an action and an archive"
+fi
+
+AR=$1
+shift
+while :
+do
+  if test $# -lt 2; then
+    func_error "you must specify a program, an action and an archive"
+  fi
+  case $1 in
+    -lib | -LIB \
+    | -ltcg | -LTCG \
+    | -machine* | -MACHINE* \
+    | -subsystem* | -SUBSYSTEM* \
+    | -verbose | -VERBOSE \
+    | -wx* | -WX* )
+      AR="$AR $1"
+      shift
+      ;;
+    *)
+      action=$1
+      shift
+      break
+      ;;
+  esac
+done
+orig_archive=$1
+shift
+func_file_conv "$orig_archive"
+archive=$file
+
+# strip leading dash in $action
+action=${action#-}
+
+delete=
+extract=
+list=
+quick=
+replace=
+index=
+create=
+
+while test -n "$action"
+do
+  case $action in
+    d*) delete=yes  ;;
+    x*) extract=yes ;;
+    t*) list=yes    ;;
+    q*) quick=yes   ;;
+    r*) replace=yes ;;
+    s*) index=yes   ;;
+    S*)             ;; # the index is always updated implicitly
+    c*) create=yes  ;;
+    u*)             ;; # TODO: don't ignore the update modifier
+    v*)             ;; # TODO: don't ignore the verbose modifier
+    *)
+      func_error "unknown action specified"
+      ;;
+  esac
+  action=${action#?}
+done
+
+case $delete$extract$list$quick$replace,$index in
+  yes,* | ,yes)
+    ;;
+  yesyes*)
+    func_error "more than one action specified"
+    ;;
+  *)
+    func_error "no action specified"
+    ;;
+esac
+
+if test -n "$delete"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  for member
+  do
+    case $1 in
+      @*)
+        func_at_file "${1#@}" -REMOVE "$archive"
+        ;;
+      *)
+        func_file_conv "$1"
+        $AR -NOLOGO -REMOVE:"$file" "$archive" || exit $?
+        ;;
+    esac
+  done
+
+elif test -n "$extract"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  if test $# -gt 0; then
+    for member
+    do
+      case $1 in
+        @*)
+          func_at_file "${1#@}" -EXTRACT "$archive"
+          ;;
+        *)
+          func_file_conv "$1"
+          $AR -NOLOGO -EXTRACT:"$file" "$archive" || exit $?
+          ;;
+      esac
+    done
+  else
+    $AR -NOLOGO -LIST "$archive" | sed -e 's/\\/\\\\/g' | while read member
+    do
+      $AR -NOLOGO -EXTRACT:"$member" "$archive" || exit $?
+    done
+  fi
+
+elif test -n "$quick$replace"; then
+  if test ! -f "$orig_archive"; then
+    if test -z "$create"; then
+      echo "$me: creating $orig_archive"
+    fi
+    orig_archive=
+  else
+    orig_archive=$archive
+  fi
+
+  for member
+  do
+    case $1 in
+    @*)
+      func_file_conv "${1#@}"
+      set x "$@" "@$file"
+      ;;
+    *)
+      func_file_conv "$1"
+      set x "$@" "$file"
+      ;;
+    esac
+    shift
+    shift
+  done
+
+  if test -n "$orig_archive"; then
+    $AR -NOLOGO -OUT:"$archive" "$orig_archive" "$@" || exit $?
+  else
+    $AR -NOLOGO -OUT:"$archive" "$@" || exit $?
+  fi
+
+elif test -n "$list"; then
+  if test ! -f "$orig_archive"; then
+    func_error "archive not found"
+  fi
+  $AR -NOLOGO -LIST "$archive" || exit $?
+fi
diff --git a/build-aux/compile b/build-aux/compile
new file mode 100755
index 0000000..531136b
--- /dev/null
+++ b/build-aux/compile
@@ -0,0 +1,347 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand '-c -o'.
+
+scriptversion=2012-10-14.11; # UTC
+
+# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey at cygnus.com>.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+nl='
+'
+
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent tools from complaining about whitespace usage.
+IFS=" ""	$nl"
+
+file_conv=
+
+# func_file_conv build_file lazy
+# Convert a $build file to $host form and store it in $file
+# Currently only supports Windows hosts. If the determined conversion
+# type is listed in (the comma separated) LAZY, no conversion will
+# take place.
+func_file_conv ()
+{
+  file=$1
+  case $file in
+    / | /[!/]*) # absolute file, and not a UNC file
+      if test -z "$file_conv"; then
+	# lazily determine how to convert abs files
+	case `uname -s` in
+	  MINGW*)
+	    file_conv=mingw
+	    ;;
+	  CYGWIN*)
+	    file_conv=cygwin
+	    ;;
+	  *)
+	    file_conv=wine
+	    ;;
+	esac
+      fi
+      case $file_conv/,$2, in
+	*,$file_conv,*)
+	  ;;
+	mingw/*)
+	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
+	  ;;
+	cygwin/*)
+	  file=`cygpath -m "$file" || echo "$file"`
+	  ;;
+	wine/*)
+	  file=`winepath -w "$file" || echo "$file"`
+	  ;;
+      esac
+      ;;
+  esac
+}
+
+# func_cl_dashL linkdir
+# Make cl look for libraries in LINKDIR
+func_cl_dashL ()
+{
+  func_file_conv "$1"
+  if test -z "$lib_path"; then
+    lib_path=$file
+  else
+    lib_path="$lib_path;$file"
+  fi
+  linker_opts="$linker_opts -LIBPATH:$file"
+}
+
+# func_cl_dashl library
+# Do a library search-path lookup for cl
+func_cl_dashl ()
+{
+  lib=$1
+  found=no
+  save_IFS=$IFS
+  IFS=';'
+  for dir in $lib_path $LIB
+  do
+    IFS=$save_IFS
+    if $shared && test -f "$dir/$lib.dll.lib"; then
+      found=yes
+      lib=$dir/$lib.dll.lib
+      break
+    fi
+    if test -f "$dir/$lib.lib"; then
+      found=yes
+      lib=$dir/$lib.lib
+      break
+    fi
+    if test -f "$dir/lib$lib.a"; then
+      found=yes
+      lib=$dir/lib$lib.a
+      break
+    fi
+  done
+  IFS=$save_IFS
+
+  if test "$found" != yes; then
+    lib=$lib.lib
+  fi
+}
+
+# func_cl_wrapper cl arg...
+# Adjust compile command to suit cl
+func_cl_wrapper ()
+{
+  # Assume a capable shell
+  lib_path=
+  shared=:
+  linker_opts=
+  for arg
+  do
+    if test -n "$eat"; then
+      eat=
+    else
+      case $1 in
+	-o)
+	  # configure might choose to run compile as 'compile cc -o foo foo.c'.
+	  eat=1
+	  case $2 in
+	    *.o | *.[oO][bB][jJ])
+	      func_file_conv "$2"
+	      set x "$@" -Fo"$file"
+	      shift
+	      ;;
+	    *)
+	      func_file_conv "$2"
+	      set x "$@" -Fe"$file"
+	      shift
+	      ;;
+	  esac
+	  ;;
+	-I)
+	  eat=1
+	  func_file_conv "$2" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-I*)
+	  func_file_conv "${1#-I}" mingw
+	  set x "$@" -I"$file"
+	  shift
+	  ;;
+	-l)
+	  eat=1
+	  func_cl_dashl "$2"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-l*)
+	  func_cl_dashl "${1#-l}"
+	  set x "$@" "$lib"
+	  shift
+	  ;;
+	-L)
+	  eat=1
+	  func_cl_dashL "$2"
+	  ;;
+	-L*)
+	  func_cl_dashL "${1#-L}"
+	  ;;
+	-static)
+	  shared=false
+	  ;;
+	-Wl,*)
+	  arg=${1#-Wl,}
+	  save_ifs="$IFS"; IFS=','
+	  for flag in $arg; do
+	    IFS="$save_ifs"
+	    linker_opts="$linker_opts $flag"
+	  done
+	  IFS="$save_ifs"
+	  ;;
+	-Xlinker)
+	  eat=1
+	  linker_opts="$linker_opts $2"
+	  ;;
+	-*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+	*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
+	  func_file_conv "$1"
+	  set x "$@" -Tp"$file"
+	  shift
+	  ;;
+	*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
+	  func_file_conv "$1" mingw
+	  set x "$@" "$file"
+	  shift
+	  ;;
+	*)
+	  set x "$@" "$1"
+	  shift
+	  ;;
+      esac
+    fi
+    shift
+  done
+  if test -n "$linker_opts"; then
+    linker_opts="-link$linker_opts"
+  fi
+  exec "$@" $linker_opts
+  exit 1
+}
+
+eat=
+
+case $1 in
+  '')
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand '-c -o'.
+Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file 'INSTALL'.
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit $?
+    ;;
+  cl | *[/\\]cl | cl.exe | *[/\\]cl.exe )
+    func_cl_wrapper "$@"      # Doesn't return...
+    ;;
+esac
+
+ofile=
+cfile=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as 'compile cc -o foo foo.c'.
+	# So we strip '-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no '-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # '.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use '[/\\:.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/config.guess b/build-aux/config.guess
new file mode 100755
index 0000000..dc84c68
--- /dev/null
+++ b/build-aux/config.guess
@@ -0,0 +1,1501 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner.  Please send patches (context
+# diff format) to <config-patches at gnu.org> and include a ChangeLog
+# entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep -q __ELF__
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+	echo i386-pc-auroraux${UNAME_RELEASE}
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep -q __LP64__
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    authenticamd | genuineintel | EM64T)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    8664:Windows_NT:*)
+	echo x86_64-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep -q ld.so.1
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	LIBC=gnu
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+	echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:* | mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef ${UNAME_MACHINE}
+	#undef ${UNAME_MACHINE}el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=${UNAME_MACHINE}el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=${UNAME_MACHINE}
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    i386)
+		eval $set_cc_for_build
+		if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+		  if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		      (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		      grep IS_64BIT_ARCH >/dev/null
+		  then
+		      UNAME_PROCESSOR="x86_64"
+		  fi
+		fi ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/build-aux/config.sub b/build-aux/config.sub
new file mode 100755
index 0000000..2a55a50
--- /dev/null
+++ b/build-aux/config.sub
@@ -0,0 +1,1705 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+#   Free Software Foundation, Inc.
+
+timestamp='2009-11-20'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted GNU ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray | -microblaze)
+		os=
+		basic_machine=$1
+		;;
+        -bluegene*)
+	        os=-cnk
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| rx \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| ubicom32 \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* | rx-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| ubicom32-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	bluegene*)
+		basic_machine=powerpc-ibm
+		os=-cnk
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+        microblaze)
+		basic_machine=microblaze-xilinx
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+        -auroraux)
+	        os=-auroraux
+		;;
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+	      | -sym* | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-cnk*|-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/build-aux/depcomp b/build-aux/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/build-aux/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
+# Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/install-sh b/build-aux/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/build-aux/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/missing b/build-aux/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/build-aux/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/build-aux/test-driver b/build-aux/test-driver
new file mode 100755
index 0000000..32bf39e
--- /dev/null
+++ b/build-aux/test-driver
@@ -0,0 +1,127 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2012-06-27.10; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake at gnu.org> or send patches to
+# <automake-patches at gnu.org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+  esac
+  shift
+done
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..0609867
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,167 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Path to exonerate */
+#undef EXONERATE_EXEC
+
+/* Define to 1 if you have condor */
+#undef HAVE_CONDOR
+
+/* Define to 1 if you have the declaration of `CTL_HW', and to 0 if you don't.
+   */
+#undef HAVE_DECL_CTL_HW
+
+/* Define to 1 if you have the declaration of `HW_PHYSMEM', and to 0 if you
+   don't. */
+#undef HAVE_DECL_HW_PHYSMEM
+
+/* Define to 1 if you have the declaration of `sysctl', and to 0 if you don't.
+   */
+#undef HAVE_DECL_SYSCTL
+
+/* Define to 1 if you have the `floor' function. */
+#undef HAVE_FLOOR
+
+/* Define to 1 if you have the `fork' function. */
+#undef HAVE_FORK
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have postgres */
+#undef HAVE_POSTGRES
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#undef HAVE_PTRDIFF_T
+
+/* Define to 1 if you have the `regcomp' function. */
+#undef HAVE_REGCOMP
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcspn' function. */
+#undef HAVE_STRCSPN
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strspn' function. */
+#undef HAVE_STRSPN
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if `mem_unit' is a member of `struct sysinfo'. */
+#undef HAVE_STRUCT_SYSINFO_MEM_UNIT
+
+/* Define to 1 if `totalram' is a member of `struct sysinfo'. */
+#undef HAVE_STRUCT_SYSINFO_TOTALRAM
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <tr1/unordered_map> header file. */
+#undef HAVE_TR1_UNORDERED_MAP
+
+/* Define to 1 if you have the <tr1/unordered_set> header file. */
+#undef HAVE_TR1_UNORDERED_SET
+
+/* Define to 1 if the system has the type `uintmax_t'. */
+#undef HAVE_UINTMAX_T
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#undef HAVE_UNSIGNED_LONG_LONG_INT
+
+/* Define to 1 if you have the `vfork' function. */
+#undef HAVE_VFORK
+
+/* Define to 1 if you have the <vfork.h> header file. */
+#undef HAVE_VFORK_H
+
+/* Define to 1 if `fork' works. */
+#undef HAVE_WORKING_FORK
+
+/* Define to 1 if `vfork' works. */
+#undef HAVE_WORKING_VFORK
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Path to mummer */
+#undef MUMMER_EXEC
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
+   do not define. */
+#undef uintmax_t
+
+/* Define as `fork' if `vfork' does not work. */
+#undef vfork
diff --git a/configure b/configure
new file mode 100755
index 0000000..06b58de
--- /dev/null
+++ b/configure
@@ -0,0 +1,8958 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.69 for FSA 1.15.9.
+#
+# Report bugs to <fsa at math.berkeley.edu>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: fsa at math.berkeley.edu about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='FSA'
+PACKAGE_TARNAME='fsa'
+PACKAGE_VERSION='1.15.9'
+PACKAGE_STRING='FSA 1.15.9'
+PACKAGE_BUGREPORT='fsa at math.berkeley.edu'
+PACKAGE_URL=''
+
+ac_unique_file="config.h.in"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+enable_option_checking=no
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+HAVE_JAVAC_FALSE
+HAVE_JAVAC_TRUE
+HAVE_JAVAC
+subdirs
+HAVE_CONDOR_FALSE
+HAVE_CONDOR_TRUE
+HAVE_CONDOR
+HAVE_POSTGRES_FALSE
+HAVE_POSTGRES_TRUE
+EXONERATE_EXEC
+MUMMER_EXEC
+MAD_MAIN_CLASS
+HAVE_CONDOR_COMPILE
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+EGREP
+GREP
+CXXCPP
+RANLIB
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+am__nodep
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+ac_ct_AR
+AR
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_silent_rules
+enable_dependency_tracking
+enable_universal
+enable_intel64
+enable_force_32bit
+enable_optim
+enable_debug
+enable_profile
+enable_fast_math
+enable_condor_compile
+enable_applet
+with_mummer
+with_exonerate
+with_postgresql
+with_condor
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CXX
+CXXFLAGS
+CCC
+CXXCPP
+MAD_MAIN_CLASS'
+ac_subdirs_all='MW'
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval $ac_prev=\$ac_option
+    ac_prev=
+    continue
+  fi
+
+  case $ac_option in
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error $? "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r "$srcdir/$ac_unique_file"; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures FSA 1.15.9 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking ...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/fsa]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of FSA 1.15.9:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-silent-rules   less verbose build output (undo: "make V=1")
+  --disable-silent-rules  verbose build output (undo: "make V=0")
+  --enable-dependency-tracking
+                          do not reject slow dependency extractors
+  --disable-dependency-tracking
+                          speeds up one-time build
+  --enable-universal      enable universal binary (Intel Apple only)
+  --enable-intel64        optimize for Intel64 CPU such as Xeon and Core2
+  --enable-force-32bit    force 32-bit compilation (takes precedence over all
+                          other compilation flags)
+  --enable-optim[=0|1|2|3]
+                          set optimization level (default is 3)
+  --enable-debug          enable debugging info (default is no)
+  --enable-profile        enable profiling (default is no)
+  --disable-fast-math     disable fast-math optimization
+  --enable-condor-compile Build for condor standard environment (default is
+                          no)
+  --enable-applet         Build the MAD GUI as an applet (default is no)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-mummer[=yes|no|check|PATH]
+                          Use MUMmer for aligning long sequences. Specify PATH
+                          to MUMmer executable if not in current path. [check]
+  --with-exonerate[=yes|no|check|PATH]
+                          Use exonerate for aligning long sequences. Specify
+                          PATH to exonerate executable if not in current path.
+                          [check]
+  --with-postgresql[=yes|no|check]
+                          Enable option to use database mode using PostgreSQL
+                          [no]
+  --with-condor[=yes|no|check]
+                          Enable option to use parallel mode using condor [no]
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  CXXCPP      C++ preprocessor
+  MAD_MAIN_CLASS
+              Main class for MAD GUI
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <fsa at math.berkeley.edu>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+FSA configure 1.15.9
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_cxx_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( $as_echo "## ------------------------------------ ##
+## Report this to fsa at math.berkeley.edu ##
+## ------------------------------------ ##"
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_mongrel
+
+# ac_fn_cxx_try_run LINENO
+# ------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_cxx_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_run
+
+# ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES
+# ---------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_cxx_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_header_compile
+
+# ac_fn_cxx_check_type LINENO TYPE VAR INCLUDES
+# ---------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_cxx_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_type
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
+# ac_fn_cxx_check_decl LINENO SYMBOL VAR INCLUDES
+# -----------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
+ac_fn_cxx_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_decl
+
+# ac_fn_cxx_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ------------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_cxx_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_member
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by FSA $as_me 1.15.9, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *\'*)
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append ac_configure_args1 " '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    $as_echo "## ---------------- ##
+## Cache variables. ##
+## ---------------- ##"
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    $as_echo "## ----------------- ##
+## Output variables. ##
+## ----------------- ##"
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      $as_echo "## ----------- ##
+## confdefs.h. ##
+## ----------- ##"
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val=\$ac_cv_env_${ac_var}_value
+  eval ac_new_val=\$ac_env_${ac_var}_value
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+ac_config_headers="$ac_config_headers config.h"
+
+ac_aux_dir=
+for ac_dir in build-aux "$srcdir"/build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+am__api_version='1.14'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if ${ac_cv_path_install+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;;
+esac
+
+# Do 'set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   am_has_slept=no
+   for am_try in 1 2; do
+     echo "timestamp, slept: $am_has_slept" > conftest.file
+     set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+     if test "$*" = "X"; then
+	# -L didn't work.
+	set X `ls -t "$srcdir/configure" conftest.file`
+     fi
+     if test "$*" != "X $srcdir/configure conftest.file" \
+	&& test "$*" != "X conftest.file $srcdir/configure"; then
+
+	# If neither matched, then we have a broken ls.  This can happen
+	# if, for instance, CONFIG_SHELL is bash and it inherits a
+	# broken ls alias from the environment.  This has actually
+	# happened.  Such a system could not be considered "sane".
+	as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
+  alias in your environment" "$LINENO" 5
+     fi
+     if test "$2" = conftest.file || test $am_try -eq 2; then
+       break
+     fi
+     # Just in case.
+     sleep 1
+     am_has_slept=yes
+   done
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error $? "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+# If we didn't sleep, we still need to ensure time stamps of config.status and
+# generated files are strictly newer.
+am_sleep_pid=
+if grep 'slept: no' conftest.file >/dev/null 2>&1; then
+  ( sleep 1 ) &
+  am_sleep_pid=$!
+fi
+
+rm -f conftest.file
+
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --is-lightweight"; then
+  am_missing_run="$MISSING "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using 'strip' when the user
+# run "make install-strip".  However 'strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the 'STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if ${ac_cv_path_mkdir+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# Check whether --enable-silent-rules was given.
+if test "${enable_silent_rules+set}" = set; then :
+  enableval=$enable_silent_rules;
+fi
+
+case $enable_silent_rules in # (((
+  yes) AM_DEFAULT_VERBOSITY=0;;
+   no) AM_DEFAULT_VERBOSITY=1;;
+    *) AM_DEFAULT_VERBOSITY=1;;
+esac
+am_make=${MAKE-make}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
+if ${am_cv_make_support_nested_variables+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if $as_echo 'TRUE=$(BAR$(V))
+BAR0=false
+BAR1=true
+V=1
+am__doit:
+	@$(TRUE)
+.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then
+  am_cv_make_support_nested_variables=yes
+else
+  am_cv_make_support_nested_variables=no
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+$as_echo "$am_cv_make_support_nested_variables" >&6; }
+if test $am_cv_make_support_nested_variables = yes; then
+    AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AM_BACKSLASH='\'
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='fsa'
+ VERSION='1.15.9'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# For better backward compatibility.  To be removed once Automake 1.9.x
+# dies out for good.  For more background, see:
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
+# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
+mkdir_p='$(MKDIR_P)'
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+
+# We'll loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar plaintar pax cpio none'
+
+# The POSIX 1988 'ustar' format is defined with fixed-size fields.
+      # There is notably a 21 bits limit for the UID and the GID.  In fact,
+      # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
+      # and bug#13588).
+      am_max_uid=2097151 # 2^21 - 1
+      am_max_gid=$am_max_uid
+      # The $UID and $GID variables are not portable, so we need to resort
+      # to the POSIX-mandated id(1) utility.  Errors in the 'id' calls
+      # below are definitely unexpected, so allow the users to see them
+      # (that is, avoid stderr redirection).
+      am_uid=`id -u || echo unknown`
+      am_gid=`id -g || echo unknown`
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether UID '$am_uid' is supported by ustar format" >&5
+$as_echo_n "checking whether UID '$am_uid' is supported by ustar format... " >&6; }
+      if test $am_uid -le $am_max_uid; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+      else
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+         _am_tools=none
+      fi
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GID '$am_gid' is supported by ustar format" >&5
+$as_echo_n "checking whether GID '$am_gid' is supported by ustar format... " >&6; }
+      if test $am_gid -le $am_max_gid; then
+         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+      else
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+        _am_tools=none
+      fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to create a ustar tar archive" >&5
+$as_echo_n "checking how to create a ustar tar archive... " >&6; }
+
+  # Go ahead even if we have the value already cached.  We do so because we
+  # need to set the values for the 'am__tar' and 'am__untar' variables.
+  _am_tools=${am_cv_prog_tar_ustar-$_am_tools}
+
+  for _am_tool in $_am_tools; do
+    case $_am_tool in
+    gnutar)
+      for _am_tar in tar gnutar gtar; do
+        { echo "$as_me:$LINENO: $_am_tar --version" >&5
+   ($_am_tar --version) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } && break
+      done
+      am__tar="$_am_tar --format=ustar -chf - "'"$$tardir"'
+      am__tar_="$_am_tar --format=ustar -chf - "'"$tardir"'
+      am__untar="$_am_tar -xf -"
+      ;;
+    plaintar)
+      # Must skip GNU tar: if it does not support --format= it doesn't create
+      # ustar tarball either.
+      (tar --version) >/dev/null 2>&1 && continue
+      am__tar='tar chf - "$$tardir"'
+      am__tar_='tar chf - "$tardir"'
+      am__untar='tar xf -'
+      ;;
+    pax)
+      am__tar='pax -L -x ustar -w "$$tardir"'
+      am__tar_='pax -L -x ustar -w "$tardir"'
+      am__untar='pax -r'
+      ;;
+    cpio)
+      am__tar='find "$$tardir" -print | cpio -o -H ustar -L'
+      am__tar_='find "$tardir" -print | cpio -o -H ustar -L'
+      am__untar='cpio -i -H ustar -d'
+      ;;
+    none)
+      am__tar=false
+      am__tar_=false
+      am__untar=false
+      ;;
+    esac
+
+    # If the value was cached, stop now.  We just wanted to have am__tar
+    # and am__untar set.
+    test -n "${am_cv_prog_tar_ustar}" && break
+
+    # tar/untar a dummy directory, and stop if the command works.
+    rm -rf conftest.dir
+    mkdir conftest.dir
+    echo GrepMe > conftest.dir/file
+    { echo "$as_me:$LINENO: tardir=conftest.dir && eval $am__tar_ >conftest.tar" >&5
+   (tardir=conftest.dir && eval $am__tar_ >conftest.tar) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+    rm -rf conftest.dir
+    if test -s conftest.tar; then
+      { echo "$as_me:$LINENO: $am__untar <conftest.tar" >&5
+   ($am__untar <conftest.tar) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+      { echo "$as_me:$LINENO: cat conftest.dir/file" >&5
+   (cat conftest.dir/file) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }
+      grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+    fi
+  done
+  rm -rf conftest.dir
+
+  if ${am_cv_prog_tar_ustar+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  am_cv_prog_tar_ustar=$_am_tool
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_tar_ustar" >&5
+$as_echo "$am_cv_prog_tar_ustar" >&6; }
+
+
+
+
+
+
+# POSIX will say in a future version that running "rm -f" with no argument
+# is OK; and we want to be able to make that assumption in our Makefile
+# recipes.  So use an aggressive probe to check that the usage we want is
+# actually supported "in the wild" to an acceptable degree.
+# See automake bug#10828.
+# To make any issue more visible, cause the running configure to be aborted
+# by default if the 'rm' program in use doesn't match our expectations; the
+# user can still override this though.
+if rm -f && rm -fr && rm -rf; then : OK; else
+  cat >&2 <<'END'
+Oops!
+
+Your 'rm' program seems unable to run without file operands specified
+on the command line, even when the '-f' option is present.  This is contrary
+to the behaviour of most rm programs out there, and not conforming with
+the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
+
+Please tell bug-automake at gnu.org about your system, including the value
+of your $PATH and any error possibly output before this message.  This
+can help us improve future automake versions.
+
+END
+  if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
+    echo 'Configuration will proceed anyway, since you have set the' >&2
+    echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
+    echo >&2
+  else
+    cat >&2 <<'END'
+Aborting the configuration process, to ensure you take notice of the issue.
+
+You can download and install GNU coreutils to get an 'rm' implementation
+that behaves properly: <http://www.gnu.org/software/coreutils/>.
+
+If you want to complete the configuration process using your problematic
+'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
+to "yes", and re-run configure.
+
+END
+    as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5
+  fi
+fi
+
+# Set language to c++.
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+# Hack to get rid of a warning introduced by Automake 1.12
+# (see http://code.google.com/p/snappy/issues/detail?id=67).
+
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from 'make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+  am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+if test -n "$ac_tool_prefix"; then
+  for ac_prog in ar lib "link -lib"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$AR" && break
+  done
+fi
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar lib "link -lib"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+fi
+
+: ${AR=ar}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the archiver ($AR) interface" >&5
+$as_echo_n "checking the archiver ($AR) interface... " >&6; }
+if ${am_cv_ar_interface+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+   am_cv_ar_interface=ar
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int some_variable = 0;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+        am_cv_ar_interface=ar
+      else
+        am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&5'
+        { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$am_ar_try\""; } >&5
+  (eval $am_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        if test "$ac_status" -eq 0; then
+          am_cv_ar_interface=lib
+        else
+          am_cv_ar_interface=unknown
+        fi
+      fi
+      rm -f conftest.lib libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_ar_interface" >&5
+$as_echo "$am_cv_ar_interface" >&6; }
+
+case $am_cv_ar_interface in
+ar)
+  ;;
+lib)
+  # Microsoft lib, so override with the ar-lib wrapper script.
+  # FIXME: It is wrong to rewrite AR.
+  # But if we don't then we get into trouble of one sort or another.
+  # A longer-term fix would be to have automake use am__AR in this case,
+  # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something
+  # similar.
+  AR="$am_aux_dir/ar-lib $AR"
+  ;;
+unknown)
+  as_fn_error $? "could not determine $AR interface" "$LINENO" 5
+  ;;
+esac
+
+
+ # Make sure CXXFLAGS is defined so that AC_PROG_CXX doesn't set it.
+CFLAGS="$CFLAGS"
+CXXFLAGS="$CXXFLAGS"
+
+# Check for programs.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
+if ${am_cv_prog_cc_c_o+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+  # Make sure it works both with $CC and with simple cc.
+  # Following AC_PROG_CC_C_O, we do the test twice because some
+  # compilers refuse to overwrite an existing .o file with -o,
+  # though they will create one.
+  am_cv_prog_cc_c_o=yes
+  for am_i in 1 2; do
+    if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
+   ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } \
+         && test -f conftest2.$ac_objext; then
+      : OK
+    else
+      am_cv_prog_cc_c_o=no
+      break
+    fi
+  done
+  rm -f core conftest*
+  unset am_i
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+$as_echo "$am_cv_prog_cc_c_o" >&6; }
+if test "$am_cv_prog_cc_c_o" != yes; then
+   # Losing compiler, so override with the script.
+   # FIXME: It is wrong to rewrite CC.
+   # But if we don't then we get into trouble of one sort or another.
+   # A longer-term fix would be to have automake use am__CC in this case,
+   # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+   CC="$am_aux_dir/compile $CC"
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if ${ac_cv_cxx_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if ${ac_cv_prog_cxx_g+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named 'D' -- because '-MD' means "put the output
+  # in D".
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with
+      # Solaris 10 /bin/sh.
+      echo '/* dummy */' > sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with '-c' and '-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle '-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs.
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # After this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested.
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+      # This compiler won't grok '-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AWK+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+
+# Check for header files.
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if ${ac_cv_prog_CXXCPP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+for ac_header in stdlib.h string.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Check for typedefs, structures, and compiler characteristics.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if ${ac_cv_header_stdbool_h+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #include <stdbool.h>
+             #ifndef bool
+              "error: bool is not defined"
+             #endif
+             #ifndef false
+              "error: false is not defined"
+             #endif
+             #if false
+              "error: false is not 0"
+             #endif
+             #ifndef true
+              "error: true is not defined"
+             #endif
+             #if true != 1
+              "error: true is not 1"
+             #endif
+             #ifndef __bool_true_false_are_defined
+              "error: __bool_true_false_are_defined is not defined"
+             #endif
+
+             struct s { _Bool s: 1; _Bool t; } s;
+
+             char a[true == 1 ? 1 : -1];
+             char b[false == 0 ? 1 : -1];
+             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+             char d[(bool) 0.5 == true ? 1 : -1];
+             /* See body of main program for 'e'.  */
+             char f[(_Bool) 0.0 == false ? 1 : -1];
+             char g[true];
+             char h[sizeof (_Bool)];
+             char i[sizeof s.t];
+             enum { j = false, k = true, l = false * true, m = true * 256 };
+             /* The following fails for
+                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+             _Bool n[m];
+             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             /* Catch a bug in an HP-UX C compiler.  See
+                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+              */
+             _Bool q = true;
+             _Bool *pq = &q;
+
+int
+main ()
+{
+
+             bool e = &s;
+             *pq |= q;
+             *pq |= ! q;
+             /* Refer to every declared value, to avoid compiler optimizations.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+                     + !m + !n + !o + !p + !q + !pq);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_header_stdbool_h=yes
+else
+  ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+   ac_fn_cxx_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+
+if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+ac_fn_cxx_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define pid_t int
+_ACEOF
+
+fi
+
+ac_fn_cxx_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
+$as_echo_n "checking for unsigned long long int... " >&6; }
+if ${ac_cv_type_unsigned_long_long_int+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+unsigned long long int ull = 18446744073709551615ULL;
+	    typedef int a[(18446744073709551615ULL <= (unsigned long long int) -1
+			   ? 1 : -1)];
+	   int i = 63;
+int
+main ()
+{
+unsigned long long int ullmax = 18446744073709551615ull;
+	    return (ull << 63 | ull >> 63 | ull << i | ull >> i
+		    | ullmax / ull | ullmax % ull);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_type_unsigned_long_long_int=yes
+else
+  ac_cv_type_unsigned_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
+$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+
+$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
+
+  fi
+
+
+
+  ac_fn_cxx_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintmax_t" = xyes; then :
+
+$as_echo "#define HAVE_UINTMAX_T 1" >>confdefs.h
+
+else
+  test $ac_cv_type_unsigned_long_long_int = yes \
+       && ac_type='unsigned long long int' \
+       || ac_type='unsigned long int'
+
+cat >>confdefs.h <<_ACEOF
+#define uintmax_t $ac_type
+_ACEOF
+
+fi
+
+
+ac_fn_cxx_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default"
+if test "x$ac_cv_type_ptrdiff_t" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_PTRDIFF_T 1
+_ACEOF
+
+
+fi
+
+
+# Check for unordered_map.
+for ac_header in tr1/unordered_map tr1/unordered_set
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Check for library functions.
+for ac_header in vfork.h
+do :
+  ac_fn_cxx_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
+if test "x$ac_cv_header_vfork_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VFORK_H 1
+_ACEOF
+
+fi
+
+done
+
+for ac_func in fork vfork
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+if test "x$ac_cv_func_fork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
+$as_echo_n "checking for working fork... " >&6; }
+if ${ac_cv_func_fork_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_fork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+
+	  /* By Ruediger Kuhlmann. */
+	  return fork () < 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  ac_cv_func_fork_works=yes
+else
+  ac_cv_func_fork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
+$as_echo "$ac_cv_func_fork_works" >&6; }
+
+else
+  ac_cv_func_fork_works=$ac_cv_func_fork
+fi
+if test "x$ac_cv_func_fork_works" = xcross; then
+  case $host in
+    *-*-amigaos* | *-*-msdosdjgpp*)
+      # Override, as these systems have only a dummy fork() stub
+      ac_cv_func_fork_works=no
+      ;;
+    *)
+      ac_cv_func_fork_works=yes
+      ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
+fi
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+if test "x$ac_cv_func_vfork" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
+$as_echo_n "checking for working vfork... " >&6; }
+if ${ac_cv_func_vfork_works+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_vfork_works=cross
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Thanks to Paul Eggert for this test.  */
+$ac_includes_default
+#include <sys/wait.h>
+#ifdef HAVE_VFORK_H
+# include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+   argument registers are propagated back to the parent.  The compiler
+   is told about this with #include <vfork.h>, but some compilers
+   (e.g. gcc -O) don't grok <vfork.h>.  Test for this by using a
+   static variable whose address is put into a register that is
+   clobbered by the vfork.  */
+static void
+#ifdef __cplusplus
+sparc_address_test (int arg)
+# else
+sparc_address_test (arg) int arg;
+#endif
+{
+  static pid_t child;
+  if (!child) {
+    child = vfork ();
+    if (child < 0) {
+      perror ("vfork");
+      _exit(2);
+    }
+    if (!child) {
+      arg = getpid();
+      write(-1, "", 0);
+      _exit (arg);
+    }
+  }
+}
+
+int
+main ()
+{
+  pid_t parent = getpid ();
+  pid_t child;
+
+  sparc_address_test (0);
+
+  child = vfork ();
+
+  if (child == 0) {
+    /* Here is another test for sparc vfork register problems.  This
+       test uses lots of local variables, at least as many local
+       variables as main has allocated so far including compiler
+       temporaries.  4 locals are enough for gcc 1.40.3 on a Solaris
+       4.1.3 sparc, but we use 8 to be safe.  A buggy compiler should
+       reuse the register of parent for one of the local variables,
+       since it will think that parent can't possibly be used any more
+       in this routine.  Assigning to the local variable will thus
+       munge parent in the parent process.  */
+    pid_t
+      p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+      p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+    /* Convince the compiler that p..p7 are live; otherwise, it might
+       use the same hardware register for all 8 local variables.  */
+    if (p != p1 || p != p2 || p != p3 || p != p4
+	|| p != p5 || p != p6 || p != p7)
+      _exit(1);
+
+    /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
+       from child file descriptors.  If the child closes a descriptor
+       before it execs or exits, this munges the parent's descriptor
+       as well.  Test for this by closing stdout in the child.  */
+    _exit(close(fileno(stdout)) != 0);
+  } else {
+    int status;
+    struct stat st;
+
+    while (wait(&status) != child)
+      ;
+    return (
+	 /* Was there some problem with vforking?  */
+	 child < 0
+
+	 /* Did the child fail?  (This shouldn't happen.)  */
+	 || status
+
+	 /* Did the vfork/compiler bug occur?  */
+	 || parent != getpid()
+
+	 /* Did the file descriptor bug occur?  */
+	 || fstat(fileno(stdout), &st) != 0
+	 );
+  }
+}
+_ACEOF
+if ac_fn_cxx_try_run "$LINENO"; then :
+  ac_cv_func_vfork_works=yes
+else
+  ac_cv_func_vfork_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
+$as_echo "$ac_cv_func_vfork_works" >&6; }
+
+fi;
+if test "x$ac_cv_func_fork_works" = xcross; then
+  ac_cv_func_vfork_works=$ac_cv_func_vfork
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
+$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
+fi
+
+if test "x$ac_cv_func_vfork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
+
+else
+
+$as_echo "#define vfork fork" >>confdefs.h
+
+fi
+if test "x$ac_cv_func_fork_works" = xyes; then
+
+$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
+
+fi
+
+for ac_func in floor memmove pow regcomp sqrt strchr strcspn strspn strstr
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+# Check the platform information.
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+# Set CFLAGS and CXXFLAGS.
+user_CFLAGS=${CFLAGS}
+generic_CFLAGS="-Wall -Wno-tautological-compare"
+ext_CFLAGS=""
+debug_CFLAGS=""
+
+# Try to choose appropriate flags for 64-bit compilation.
+# (This code is borrowed from Cole Trapnell's TopHat (http://tophat.cbcb.umd.edu/).)
+case "${host_cpu}-${host_os}" in
+   i*86-*linux*)
+    ext_CFLAGS="-march=i686";;
+   i*86-darwin*)
+    # Check whether --enable-universal was given.
+if test "${enable_universal+set}" = set; then :
+  enableval=$enable_universal; is_uni=1
+else
+  is_uni=0
+fi
+
+	case $is_uni in
+	  1) CFLAGS="-m64"
+	     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ext_CFLAGS="-arch x86_64 -arch i386 -arch ppc64 -arch ppc"
+else
+  ext_CFLAGS="-arch i386 -arch ppc"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext;;
+	  0) CFLAGS="-m64"
+	     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ext_CFLAGS="-arch x86_64"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext;;
+	esac;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc accepts -m64" >&5
+$as_echo_n "checking if gcc accepts -m64... " >&6; }
+    CFLAGS="-m64"
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ext_CFLAGS="-m64"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  ext_CFLAGS="-D_FILE_OFFSET_BITS=64"; { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext;;
+esac
+
+# Check whether --enable-intel64 was given.
+if test "${enable_intel64+set}" = set; then :
+  enableval=$enable_intel64; ext_CFLAGS="${ext_CFLAGS} -mtune=nocona"
+fi
+
+
+# Option to manually force 32-bit compilation.
+# Check whether --enable-force-32bit was given.
+if test "${enable_force_32bit+set}" = set; then :
+  enableval=$enable_force_32bit; ext_CFLAGS=""
+fi
+
+
+# Add options for compiler flags.
+# Check whether --enable-optim was given.
+if test "${enable_optim+set}" = set; then :
+  enableval=$enable_optim; if test "x$enable_optim" = xyes; then enable_optim=3; fi
+else
+  enable_optim=3
+fi
+
+# Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug;
+else
+  enable_debug=no
+fi
+
+# Check whether --enable-profile was given.
+if test "${enable_profile+set}" = set; then :
+  enableval=$enable_profile;
+else
+  enable_profile=no
+fi
+
+# Check whether --enable-fast-math was given.
+if test "${enable_fast_math+set}" = set; then :
+  enableval=$enable_fast_math;
+else
+  enable_fast_math=yes
+fi
+
+
+# Set compiler flags according to specified options.
+if test "x$enable_optim" != xno; then :
+  ext_CFLAGS="$ext_CFLAGS -O$enable_optim"
+fi
+if test "x$enable_debug" = xyes; then :
+  debug_CFLAGS="-g -DDEBUG"
+else
+  debug_CFLAGS="-DNDEBUG"
+fi
+if test "x$enable_profile" = xyes; then :
+  ext_CFLAGS="$ext_CFLAGS -pg"
+fi
+if test "x$enable_fast_math" = xyes; then :
+  ext_CFLAGS="$ext_CFLAGS -ffast-math"
+fi
+
+# Set CFLAGS and CXXFLAGS with all of the specified options.
+CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
+CXXFLAGS="$CFLAGS"
+
+# Add option for compiling for condor standard environment.
+# Check whether --enable-condor-compile was given.
+if test "${enable_condor_compile+set}" = set; then :
+  enableval=$enable_condor_compile;
+else
+  enable_condor_compile=no
+fi
+
+
+# Set compiler depending on condor option.
+if test "x$enable_condor_compile" = xyes; then :
+  # Extract the first word of "condor_compile", so it can be a program name with args.
+set dummy condor_compile; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_HAVE_CONDOR_COMPILE+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$HAVE_CONDOR_COMPILE"; then
+  ac_cv_prog_HAVE_CONDOR_COMPILE="$HAVE_CONDOR_COMPILE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_HAVE_CONDOR_COMPILE=""yes""
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+HAVE_CONDOR_COMPILE=$ac_cv_prog_HAVE_CONDOR_COMPILE
+if test -n "$HAVE_CONDOR_COMPILE"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_CONDOR_COMPILE" >&5
+$as_echo "$HAVE_CONDOR_COMPILE" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+       if test "x$HAVE_CONDOR_COMPILE" = xyes ; then
+          CXX="condor_compile $CXX"; CC="condor_compile $CC";
+       else
+          { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--enable-condor given, but condor_compile was not found in path
+See \`config.log' for more details" "$LINENO" 5; }
+       fi
+fi
+
+# Add option for building applet.
+# Check whether --enable-applet was given.
+if test "${enable_applet+set}" = set; then :
+  enableval=$enable_applet;
+else
+  enable_applet=no
+fi
+
+
+# Define whether to use applet or not.
+if test "x$enable_applet" = xyes; then :
+  MAD_MAIN_CLASS=mad.MadApplet
+else
+  MAD_MAIN_CLASS=mad.MAD
+fi
+
+
+# Add option for using mummer.
+
+# Check whether --with-mummer was given.
+if test "${with_mummer+set}" = set; then :
+  withval=$with_mummer;
+else
+  with_mummer=check
+fi
+
+
+# Search for mummer executable if not specified.
+if test "x$with_mummer" = xcheck || test "x$with_mummer" = xyes; then :
+  # Extract the first word of "mummer", so it can be a program name with args.
+set dummy mummer; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_MUMMER_EXEC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MUMMER_EXEC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_MUMMER_EXEC="$MUMMER_EXEC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_MUMMER_EXEC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_MUMMER_EXEC" && ac_cv_path_MUMMER_EXEC=""no""
+  ;;
+esac
+fi
+MUMMER_EXEC=$ac_cv_path_MUMMER_EXEC
+if test -n "$MUMMER_EXEC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MUMMER_EXEC" >&5
+$as_echo "$MUMMER_EXEC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+else
+  MUMMER_EXEC=$with_mummer
+fi
+
+# Check mummer executable and if everything is correct, define macro.
+if test "x$MUMMER_EXEC" = xno && test "x$with_mummer" = xyes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-mummer given, but mummer was not found in path
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+if test "x$MUMMER_EXEC" != xno && test ! -x $MUMMER_EXEC; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "\"$MUMMER_EXEC\" is not a valid mummer executable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+if test "x$MUMMER_EXEC" != xno; then :
+
+cat >>confdefs.h <<_ACEOF
+#define MUMMER_EXEC "$MUMMER_EXEC"
+_ACEOF
+
+fi
+
+# Add option for using exonerate.
+
+# Check whether --with-exonerate was given.
+if test "${with_exonerate+set}" = set; then :
+  withval=$with_exonerate;
+else
+  with_exonerate=check
+fi
+
+
+# Search for exonerate executable if not specified.
+if test "x$with_exonerate" = xcheck || test "x$with_exonerate" = xyes; then :
+  # Extract the first word of "exonerate", so it can be a program name with args.
+set dummy exonerate; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_EXONERATE_EXEC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $EXONERATE_EXEC in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_EXONERATE_EXEC="$EXONERATE_EXEC" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_EXONERATE_EXEC="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_EXONERATE_EXEC" && ac_cv_path_EXONERATE_EXEC=""no""
+  ;;
+esac
+fi
+EXONERATE_EXEC=$ac_cv_path_EXONERATE_EXEC
+if test -n "$EXONERATE_EXEC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $EXONERATE_EXEC" >&5
+$as_echo "$EXONERATE_EXEC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+else
+  EXONERATE_EXEC=$with_exonerate
+fi
+
+# Check exonerate executable and if everything is correct, define macro.
+if test "x$EXONERATE_EXEC" = xno && test "x$with_exonerate" = xyes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-exonerate given, but exonerate was not found in path
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+if test "x$EXONERATE_EXEC" != xno && test ! -x $EXONERATE_EXEC; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "\"$EXONERATE_EXEC\" is not a valid exonerate executable
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+if test "x$EXONERATE_EXEC" != xno; then :
+
+cat >>confdefs.h <<_ACEOF
+#define EXONERATE_EXEC "$EXONERATE_EXEC"
+_ACEOF
+
+fi
+
+# Add option for using postgresql.
+
+# Check whether --with-postgresql was given.
+if test "${with_postgresql+set}" = set; then :
+  withval=$with_postgresql;
+else
+  with_postgresql=no
+fi
+
+
+# Check for postgresql.
+if test "x$with_postgresql" = xcheck || test "x$with_postgresql" = xyes; then :
+  # Check for Postgres library
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PQconnectdb in -lpq" >&5
+$as_echo_n "checking for PQconnectdb in -lpq... " >&6; }
+if ${ac_cv_lib_pq_PQconnectdb+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpq  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char PQconnectdb ();
+int
+main ()
+{
+return PQconnectdb ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_pq_PQconnectdb=yes
+else
+  ac_cv_lib_pq_PQconnectdb=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pq_PQconnectdb" >&5
+$as_echo "$ac_cv_lib_pq_PQconnectdb" >&6; }
+if test "x$ac_cv_lib_pq_PQconnectdb" = xyes; then :
+  # Check for Postgres header
+                    ac_fn_cxx_check_header_mongrel "$LINENO" "libpq-fe.h" "ac_cv_header_libpq_fe_h" "$ac_includes_default"
+if test "x$ac_cv_header_libpq_fe_h" = xyes; then :
+  # Check for a function in the Postgres header
+                      ac_fn_cxx_check_decl "$LINENO" "PQgetCopyData" "ac_cv_have_decl_PQgetCopyData" "#include <libpq-fe.h>
+"
+if test "x$ac_cv_have_decl_PQgetCopyData" = xyes; then :
+  HAVE_POSTGRES=yes
+fi
+
+fi
+
+
+fi
+
+fi
+
+if test "x$HAVE_POSTGRES" != xyes && test "x$with_postgresql" = xyes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-postgresql given, but valid postgresql installation not found
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+if test "x$HAVE_POSTGRES" = xyes; then :
+  # Check for crypt library, which is required by postgres on Linux
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5
+$as_echo_n "checking for crypt in -lcrypt... " >&6; }
+if ${ac_cv_lib_crypt_crypt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcrypt  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char crypt ();
+int
+main ()
+{
+return crypt ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  ac_cv_lib_crypt_crypt=yes
+else
+  ac_cv_lib_crypt_crypt=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5
+$as_echo "$ac_cv_lib_crypt_crypt" >&6; }
+if test "x$ac_cv_lib_crypt_crypt" = xyes; then :
+  LIBS="-lcrypt $LIBS"
+fi
+
+       # Add postgres library
+       LIBS="-lpq $LIBS";
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_POSTGRES 1
+_ACEOF
+
+fi
+ if test "x$HAVE_POSTGRES" = xyes; then
+  HAVE_POSTGRES_TRUE=
+  HAVE_POSTGRES_FALSE='#'
+else
+  HAVE_POSTGRES_TRUE='#'
+  HAVE_POSTGRES_FALSE=
+fi
+
+
+# Add option for using condor (parellel mode).
+
+# Check whether --with-condor was given.
+if test "${with_condor+set}" = set; then :
+  withval=$with_condor;
+else
+  with_condor=no
+fi
+
+
+# Check for condor.
+if test "x$with_condor" = xcheck || test "x$with_condor" = xyes; then :
+  # Extract the first word of "condor_submit", so it can be a program name with args.
+set dummy condor_submit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_HAVE_CONDOR+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$HAVE_CONDOR"; then
+  ac_cv_prog_HAVE_CONDOR="$HAVE_CONDOR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_HAVE_CONDOR=""yes""
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+HAVE_CONDOR=$ac_cv_prog_HAVE_CONDOR
+if test -n "$HAVE_CONDOR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_CONDOR" >&5
+$as_echo "$HAVE_CONDOR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+
+if test "x$HAVE_CONDOR" != xyes && test "x$with_condor" = xyes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "--with-condor given, but valid condor installation not found
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+if test "x$HAVE_CONDOR" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_CONDOR 1
+_ACEOF
+
+fi
+
+ if test "x$HAVE_CONDOR" = xyes; then
+  HAVE_CONDOR_TRUE=
+  HAVE_CONDOR_FALSE='#'
+else
+  HAVE_CONDOR_TRUE='#'
+  HAVE_CONDOR_FALSE=
+fi
+
+
+# Build with MW if Condor is found.
+
+
+if test "x$HAVE_CONDOR" = xyes; then :
+  subdirs="$subdirs MW"
+
+fi
+
+# Check for structures/functions that can be used to determine system memory.
+ac_fn_cxx_check_member "$LINENO" "struct sysinfo" "totalram" "ac_cv_member_struct_sysinfo_totalram" "#include <sys/sysinfo.h>
+"
+if test "x$ac_cv_member_struct_sysinfo_totalram" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SYSINFO_TOTALRAM 1
+_ACEOF
+
+
+fi
+ac_fn_cxx_check_member "$LINENO" "struct sysinfo" "mem_unit" "ac_cv_member_struct_sysinfo_mem_unit" "#include <sys/sysinfo.h>
+"
+if test "x$ac_cv_member_struct_sysinfo_mem_unit" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SYSINFO_MEM_UNIT 1
+_ACEOF
+
+
+fi
+
+ac_fn_cxx_check_decl "$LINENO" "sysctl" "ac_cv_have_decl_sysctl" "#include <sys/sysctl.h>
+"
+if test "x$ac_cv_have_decl_sysctl" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_SYSCTL $ac_have_decl
+_ACEOF
+ac_fn_cxx_check_decl "$LINENO" "CTL_HW" "ac_cv_have_decl_CTL_HW" "#include <sys/sysctl.h>
+"
+if test "x$ac_cv_have_decl_CTL_HW" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_CTL_HW $ac_have_decl
+_ACEOF
+ac_fn_cxx_check_decl "$LINENO" "HW_PHYSMEM" "ac_cv_have_decl_HW_PHYSMEM" "#include <sys/sysctl.h>
+"
+if test "x$ac_cv_have_decl_HW_PHYSMEM" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_HW_PHYSMEM $ac_have_decl
+_ACEOF
+
+
+# Check for javac.  If it exists, set automake conditional.
+# Extract the first word of "javac", so it can be a program name with args.
+set dummy javac; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_HAVE_JAVAC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$HAVE_JAVAC"; then
+  ac_cv_prog_HAVE_JAVAC="$HAVE_JAVAC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_HAVE_JAVAC="yes"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_HAVE_JAVAC" && ac_cv_prog_HAVE_JAVAC="no"
+fi
+fi
+HAVE_JAVAC=$ac_cv_prog_HAVE_JAVAC
+if test -n "$HAVE_JAVAC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_JAVAC" >&5
+$as_echo "$HAVE_JAVAC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$HAVE_JAVAC" = xyes; then
+  HAVE_JAVAC_TRUE=
+  HAVE_JAVAC_FALSE='#'
+else
+  HAVE_JAVAC_TRUE='#'
+  HAVE_JAVAC_FALSE=
+fi
+
+
+ac_config_files="$ac_config_files Makefile src/main/Makefile src/manager/Makefile src/fsa/Makefile src/annealing/Makefile src/math/Makefile src/util/Makefile src/seq/Makefile display/Makefile display/mad/manifest.mf perl/Makefile examples/Makefile doc/Makefile doc/version.tex html/Makefile tests/Makefile"
+
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;; #(
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+  if test -w "$cache_file"; then
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+U=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+$as_echo_n "checking that generated files are newer than configure... " >&6; }
+   if test -n "$am_sleep_pid"; then
+     # Hide warnings about reused PIDs.
+     wait $am_sleep_pid 2>/dev/null
+   fi
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
+$as_echo "done" >&6; }
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error $? "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_POSTGRES_TRUE}" && test -z "${HAVE_POSTGRES_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_POSTGRES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_CONDOR_TRUE}" && test -z "${HAVE_CONDOR_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_CONDOR\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${HAVE_JAVAC_TRUE}" && test -z "${HAVE_JAVAC_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_JAVAC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+  *[\\/]* ) as_myself=$0 ;;
+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
+IFS=$as_save_IFS
+
+     ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+  as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
+else
+  as_ln_s='cp -pR'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by FSA $as_me 1.15.9, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <fsa at math.berkeley.edu>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+FSA config.status 1.15.9
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=?*)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
+  *)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error $? "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "src/main/Makefile") CONFIG_FILES="$CONFIG_FILES src/main/Makefile" ;;
+    "src/manager/Makefile") CONFIG_FILES="$CONFIG_FILES src/manager/Makefile" ;;
+    "src/fsa/Makefile") CONFIG_FILES="$CONFIG_FILES src/fsa/Makefile" ;;
+    "src/annealing/Makefile") CONFIG_FILES="$CONFIG_FILES src/annealing/Makefile" ;;
+    "src/math/Makefile") CONFIG_FILES="$CONFIG_FILES src/math/Makefile" ;;
+    "src/util/Makefile") CONFIG_FILES="$CONFIG_FILES src/util/Makefile" ;;
+    "src/seq/Makefile") CONFIG_FILES="$CONFIG_FILES src/seq/Makefile" ;;
+    "display/Makefile") CONFIG_FILES="$CONFIG_FILES display/Makefile" ;;
+    "display/mad/manifest.mf") CONFIG_FILES="$CONFIG_FILES display/mad/manifest.mf" ;;
+    "perl/Makefile") CONFIG_FILES="$CONFIG_FILES perl/Makefile" ;;
+    "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
+    "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+    "doc/version.tex") CONFIG_FILES="$CONFIG_FILES doc/version.tex" ;;
+    "html/Makefile") CONFIG_FILES="$CONFIG_FILES html/Makefile" ;;
+    "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp= ac_tmp=
+  trap 'exit_status=$?
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[	 ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$ac_tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # Let's still pretend it is `configure' which instantiates (i.e., don't
+    # use $as_me), people would be surprised to read:
+    #    /* config.h.  Generated by config.status.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
+  case $ac_file in
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Older Autoconf quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named 'Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running 'make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "$am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || as_fn_exit 1
+fi
+
+#
+# CONFIG_SUBDIRS section.
+#
+if test "$no_recursion" != yes; then
+
+  # Remove --cache-file, --srcdir, and --disable-option-checking arguments
+  # so they do not pile up.
+  ac_sub_configure_args=
+  ac_prev=
+  eval "set x $ac_configure_args"
+  shift
+  for ac_arg
+  do
+    if test -n "$ac_prev"; then
+      ac_prev=
+      continue
+    fi
+    case $ac_arg in
+    -cache-file | --cache-file | --cache-fil | --cache-fi \
+    | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+      ac_prev=cache_file ;;
+    -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+    | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* \
+    | --c=*)
+      ;;
+    --config-cache | -C)
+      ;;
+    -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+      ac_prev=srcdir ;;
+    -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+      ;;
+    -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+      ac_prev=prefix ;;
+    -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+      ;;
+    --disable-option-checking)
+      ;;
+    *)
+      case $ac_arg in
+      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      esac
+      as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
+    esac
+  done
+
+  # Always prepend --prefix to ensure using the same prefix
+  # in subdir configurations.
+  ac_arg="--prefix=$prefix"
+  case $ac_arg in
+  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
+
+  # Pass --silent
+  if test "$silent" = yes; then
+    ac_sub_configure_args="--silent $ac_sub_configure_args"
+  fi
+
+  # Always prepend --disable-option-checking to silence warnings, since
+  # different subdirs can have different --enable and --with options.
+  ac_sub_configure_args="--disable-option-checking $ac_sub_configure_args"
+
+  ac_popdir=`pwd`
+  for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue
+
+    # Do not complain, so a configure script can configure whichever
+    # parts of a large source tree are present.
+    test -d "$srcdir/$ac_dir" || continue
+
+    ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
+    $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+    $as_echo "$ac_msg" >&6
+    as_dir="$ac_dir"; as_fn_mkdir_p
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+    cd "$ac_dir"
+
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      ac_sub_configure=$ac_srcdir/configure.gnu
+    elif test -f "$ac_srcdir/configure"; then
+      ac_sub_configure=$ac_srcdir/configure
+    elif test -f "$ac_srcdir/configure.in"; then
+      # This should be Cygnus configure.
+      ac_sub_configure=$ac_aux_dir/configure
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      ac_sub_configure=
+    fi
+
+    # The recursion is here.
+    if test -n "$ac_sub_configure"; then
+      # Make the cache file name correct relative to the subdirectory.
+      case $cache_file in
+      [\\/]* | ?:[\\/]* ) ac_sub_cache_file=$cache_file ;;
+      *) # Relative name.
+	ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
+      esac
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      # The eval makes quoting arguments work.
+      eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
+	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
+	as_fn_error $? "$ac_sub_configure failed for $ac_dir" "$LINENO" 5
+    fi
+
+    cd "$ac_popdir"
+  done
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
+
+
+# Dump some configuration confirmations.
+echo \
+"
+-- ${PACKAGE_STRING} Configuration Results --
+  C++ compiler:        ${CXX} ${CXXFLAGS}"
+
+if test x"${GCC}" = x"yes" ; then
+   gcc_version=`${CC} --version | head -n 1`
+   echo "  GCC version:         ${gcc_version}"
+else
+   gcc_version=''
+fi
+
+echo \
+"  Host System type:    ${host}
+  Install prefix:      ${prefix}
+
+  See config.h for further configuration information.
+  Email <${PACKAGE_BUGREPORT}> with questions and bug reports.
+"
diff --git a/configure.ac b/configure.ac
new file mode 100755
index 0000000..703abe2
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,303 @@
+
+# Initialize.
+m4_include([version.m4])
+AC_INIT([FSA], VERSION_NUMBER, [fsa at math.berkeley.edu])
+AC_CONFIG_SRCDIR([config.h.in])
+AC_CONFIG_HEADERS([config.h])
+AC_CONFIG_AUX_DIR([build-aux])
+AM_INIT_AUTOMAKE([-Wall -Werror tar-ustar foreign])
+
+# Set language to c++.
+AC_LANG([C++])
+
+# Hack to get rid of a warning introduced by Automake 1.12
+# (see http://code.google.com/p/snappy/issues/detail?id=67).
+m4_pattern_allow([AM_PROG_AR])
+AM_PROG_AR
+
+ # Make sure CXXFLAGS is defined so that AC_PROG_CXX doesn't set it.
+CFLAGS="$CFLAGS"
+CXXFLAGS="$CXXFLAGS"
+
+# Check for programs.
+AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_AWK
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+
+# Check for header files.
+AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
+
+# Check for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+AC_C_INLINE
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_TYPE_UINTMAX_T
+AC_CHECK_TYPES([ptrdiff_t])
+
+# Check for unordered_map.
+AC_CHECK_HEADERS([tr1/unordered_map tr1/unordered_set])
+
+# Check for library functions.
+AC_FUNC_FORK
+AC_CHECK_FUNCS([floor memmove pow regcomp sqrt strchr strcspn strspn strstr])
+
+# Check the platform information.
+AC_CANONICAL_HOST
+
+# Set CFLAGS and CXXFLAGS.
+user_CFLAGS=${CFLAGS}
+generic_CFLAGS="-Wall -Wno-tautological-compare"
+ext_CFLAGS=""
+debug_CFLAGS=""
+
+# Try to choose appropriate flags for 64-bit compilation.
+# (This code is borrowed from Cole Trapnell's TopHat (http://tophat.cbcb.umd.edu/).)
+case "${host_cpu}-${host_os}" in
+   i*86-*linux*)
+    ext_CFLAGS="-march=i686";;
+   i*86-darwin*)
+    AC_ARG_ENABLE([universal],
+		  [AS_HELP_STRING([--enable-universal],
+			          [enable universal binary (Intel Apple only)])],
+		  [is_uni=1], [is_uni=0])
+	case $is_uni in
+	  1) CFLAGS="-m64"
+	     AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+			       [ext_CFLAGS="-arch x86_64 -arch i386 -arch ppc64 -arch ppc"],
+			       [ext_CFLAGS="-arch i386 -arch ppc"]);;
+	  0) CFLAGS="-m64"
+	     AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+			       [ext_CFLAGS="-arch x86_64"],
+			       []);;
+	esac;;
+  *)
+    AC_MSG_CHECKING([if gcc accepts -m64])
+    CFLAGS="-m64"
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+		      [ext_CFLAGS="-m64"; AC_MSG_RESULT([yes])],
+		      [ext_CFLAGS="-D_FILE_OFFSET_BITS=64"; AC_MSG_RESULT([no])]);;
+esac
+
+AC_ARG_ENABLE([intel64],
+	      [AS_HELP_STRING([--enable-intel64],
+		              [optimize for Intel64 CPU such as Xeon and Core2])],
+	      [ext_CFLAGS="${ext_CFLAGS} -mtune=nocona"], [])
+
+# Option to manually force 32-bit compilation.
+AC_ARG_ENABLE([force-32bit],
+	      [AS_HELP_STRING([--enable-force-32bit],
+			      [force 32-bit compilation (takes precedence over all other compilation flags)])],
+	      [ext_CFLAGS=""], [])
+
+# Add options for compiler flags.
+AC_ARG_ENABLE([optim],
+              [AS_HELP_STRING([--enable-optim@<:@=0|1|2|3@:>@],
+	                      [set optimization level (default is 3)])],
+              [if test "x$enable_optim" = xyes; then enable_optim=3; fi],
+              [enable_optim=3])
+AC_ARG_ENABLE([debug],
+              [AS_HELP_STRING([--enable-debug],
+	                      [enable debugging info (default is no)])],
+              [], [enable_debug=no])
+AC_ARG_ENABLE([profile],
+              [AS_HELP_STRING([--enable-profile],
+	                      [enable profiling (default is no)])],
+              [], [enable_profile=no])
+AC_ARG_ENABLE([fast-math],
+              [AS_HELP_STRING([--disable-fast-math],
+	                      [disable fast-math optimization])],
+              [], [enable_fast_math=yes])
+
+# Set compiler flags according to specified options.
+AS_IF([test "x$enable_optim" != xno], [ext_CFLAGS="$ext_CFLAGS -O$enable_optim"])
+AS_IF([test "x$enable_debug" = xyes],
+      [debug_CFLAGS="-g -DDEBUG"],
+      [debug_CFLAGS="-DNDEBUG"])
+AS_IF([test "x$enable_profile" = xyes], [ext_CFLAGS="$ext_CFLAGS -pg"])
+AS_IF([test "x$enable_fast_math" = xyes], [ext_CFLAGS="$ext_CFLAGS -ffast-math"])
+
+# Set CFLAGS and CXXFLAGS with all of the specified options.
+CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
+CXXFLAGS="$CFLAGS"
+
+# Add option for compiling for condor standard environment.
+AC_ARG_ENABLE([condor-compile],
+              [AS_HELP_STRING([--enable-condor-compile],
+	                      [Build for condor standard environment
+                               (default is no)])],
+              [], [enable_condor_compile=no])
+
+# Set compiler depending on condor option.
+AS_IF([test "x$enable_condor_compile" = xyes],
+      [AC_CHECK_PROG([HAVE_CONDOR_COMPILE],[condor_compile],["yes"])
+       if test "x$HAVE_CONDOR_COMPILE" = xyes ; then
+          CXX="condor_compile $CXX"; CC="condor_compile $CC";
+       else
+          AC_MSG_FAILURE([--enable-condor given, but condor_compile was not found in path])
+       fi])
+
+# Add option for building applet.
+AC_ARG_ENABLE([applet],
+              [AS_HELP_STRING([--enable-applet],
+	                      [Build the MAD GUI as an applet
+                               (default is no)])],
+              [],
+	      [enable_applet=no])
+
+# Define whether to use applet or not.
+AS_IF([test "x$enable_applet" = xyes],
+      [MAD_MAIN_CLASS=mad.MadApplet],
+      [MAD_MAIN_CLASS=mad.MAD])
+AC_ARG_VAR([MAD_MAIN_CLASS],[Main class for MAD GUI])
+
+# Add option for using mummer.
+AC_ARG_WITH([mummer],
+            [AS_HELP_STRING([--with-mummer@<:@=yes|no|check|PATH@:>@],
+                            [Use MUMmer for aligning long sequences. Specify
+                             PATH to MUMmer executable if not in current path.
+                             [check]])],
+            [],
+	    [with_mummer=check])
+
+# Search for mummer executable if not specified.
+AS_IF([test "x$with_mummer" = xcheck || test "x$with_mummer" = xyes],
+      [AC_PATH_PROG([MUMMER_EXEC],[mummer],["no"])],
+      [MUMMER_EXEC=$with_mummer])
+
+# Check mummer executable and if everything is correct, define macro.
+AS_IF([test "x$MUMMER_EXEC" = xno && test "x$with_mummer" = xyes],
+      [AC_MSG_FAILURE([--with-mummer given, but mummer was not found in path])])
+AS_IF([test "x$MUMMER_EXEC" != xno && test ! -x $MUMMER_EXEC],
+      [AC_MSG_FAILURE(["$MUMMER_EXEC" is not a valid mummer executable])])
+AS_IF([test "x$MUMMER_EXEC" != xno],
+      [AC_DEFINE_UNQUOTED([MUMMER_EXEC],["$MUMMER_EXEC"],[Path to mummer])])
+
+# Add option for using exonerate.
+AC_ARG_WITH([exonerate],
+            [AS_HELP_STRING([--with-exonerate@<:@=yes|no|check|PATH@:>@],
+                            [Use exonerate for aligning long sequences. Specify
+                             PATH to exonerate executable if not in current path.
+                             [check]])],
+            [],
+	    [with_exonerate=check])
+
+# Search for exonerate executable if not specified.
+AS_IF([test "x$with_exonerate" = xcheck || test "x$with_exonerate" = xyes],
+      [AC_PATH_PROG([EXONERATE_EXEC],[exonerate],["no"])],
+      [EXONERATE_EXEC=$with_exonerate])
+
+# Check exonerate executable and if everything is correct, define macro.
+AS_IF([test "x$EXONERATE_EXEC" = xno && test "x$with_exonerate" = xyes],
+      [AC_MSG_FAILURE([--with-exonerate given, but exonerate was not found in path])])
+AS_IF([test "x$EXONERATE_EXEC" != xno && test ! -x $EXONERATE_EXEC],
+      [AC_MSG_FAILURE(["$EXONERATE_EXEC" is not a valid exonerate executable])])
+AS_IF([test "x$EXONERATE_EXEC" != xno],
+      [AC_DEFINE_UNQUOTED([EXONERATE_EXEC],["$EXONERATE_EXEC"],[Path to exonerate])])
+
+# Add option for using postgresql.
+AC_ARG_WITH([postgresql],
+            [AS_HELP_STRING([--with-postgresql@<:@=yes|no|check@:>@],
+                            [Enable option to use database mode using
+                             PostgreSQL [no]])],
+            [],
+	    [with_postgresql=no])
+
+# Check for postgresql.
+AS_IF([test "x$with_postgresql" = xcheck || test "x$with_postgresql" = xyes],
+      [# Check for Postgres library
+       AC_CHECK_LIB([pq], [PQconnectdb],
+                    # Check for Postgres header
+                    [AC_CHECK_HEADER([libpq-fe.h],
+                      # Check for a function in the Postgres header
+                      [AC_CHECK_DECL([PQgetCopyData],
+                                     [HAVE_POSTGRES=yes], [],
+                                     [#include <libpq-fe.h>])])])])
+
+AS_IF([test "x$HAVE_POSTGRES" != xyes && test "x$with_postgresql" = xyes],
+      [AC_MSG_FAILURE([--with-postgresql given, but valid postgresql installation not found])])
+
+AS_IF([test "x$HAVE_POSTGRES" = xyes],
+      [# Check for crypt library, which is required by postgres on Linux
+       AC_CHECK_LIB([crypt], [crypt], [LIBS="-lcrypt $LIBS"])
+       # Add postgres library
+       LIBS="-lpq $LIBS";
+       AC_DEFINE_UNQUOTED([HAVE_POSTGRES], [1],
+                          [Define to 1 if you have postgres])])
+AM_CONDITIONAL([HAVE_POSTGRES], [test "x$HAVE_POSTGRES" = xyes])
+
+# Add option for using condor (parellel mode).
+AC_ARG_WITH([condor],
+            [AS_HELP_STRING([--with-condor@<:@=yes|no|check@:>@],
+                            [Enable option to use parallel mode using
+                             condor [no]])],
+            [],
+	    [with_condor=no])
+
+# Check for condor.
+AS_IF([test "x$with_condor" = xcheck || test "x$with_condor" = xyes],
+      [AC_CHECK_PROG([HAVE_CONDOR],[condor_submit],["yes"])])
+
+AS_IF([test "x$HAVE_CONDOR" != xyes && test "x$with_condor" = xyes],
+      [AC_MSG_FAILURE([--with-condor given, but valid condor installation not found])])
+
+AS_IF([test "x$HAVE_CONDOR" = xyes],
+      [AC_DEFINE_UNQUOTED([HAVE_CONDOR],[1],[Define to 1 if you have condor])])
+
+AM_CONDITIONAL([HAVE_CONDOR], [test "x$HAVE_CONDOR" = xyes])
+
+# Build with MW if Condor is found.
+AS_IF([test "x$HAVE_CONDOR" = xyes], [AC_CONFIG_SUBDIRS([MW])])
+
+# Check for structures/functions that can be used to determine system memory.
+AC_CHECK_MEMBERS([struct sysinfo.totalram, struct sysinfo.mem_unit],
+                 [], [], [#include <sys/sysinfo.h>])
+AC_CHECK_DECLS([sysctl, CTL_HW, HW_PHYSMEM], [], [], [#include <sys/sysctl.h>])
+
+# Check for javac.  If it exists, set automake conditional.
+AC_CHECK_PROG([HAVE_JAVAC], [javac], [yes], [no])
+AM_CONDITIONAL([HAVE_JAVAC], [test "x$HAVE_JAVAC" = xyes])
+
+AC_CONFIG_FILES([Makefile
+                 src/main/Makefile
+                 src/manager/Makefile
+                 src/fsa/Makefile
+                 src/annealing/Makefile
+                 src/math/Makefile
+                 src/util/Makefile
+                 src/seq/Makefile
+                 display/Makefile
+		 display/mad/manifest.mf
+                 perl/Makefile
+                 examples/Makefile
+		 doc/Makefile
+		 doc/version.tex
+		 html/Makefile
+		 tests/Makefile])
+
+AC_OUTPUT
+
+
+# Dump some configuration confirmations.
+echo \
+"
+-- ${PACKAGE_STRING} Configuration Results --
+  C++ compiler:        ${CXX} ${CXXFLAGS}"
+
+if test x"${GCC}" = x"yes" ; then
+   gcc_version=`${CC} --version | head -n 1`
+   echo "  GCC version:         ${gcc_version}"
+else
+   gcc_version=''
+fi
+
+echo \
+"  Host System type:    ${host}
+  Install prefix:      ${prefix}
+
+  See config.h for further configuration information.
+  Email <${PACKAGE_BUGREPORT}> with questions and bug reports.
+"
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index 6276e6d..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,10 +0,0 @@
-fsa (1.15.9+dfsg-1) UNRELEASED; urgency=low
-
-  * Initial release (Closes: #<bug>)
-    Question to upstream was repeated here
-      https://lists.debian.org/debian-med/2015/10/msg00068.html
-    but the mail bounced with 
-      Final-Recipient: rfc822; rbradley at mit.edu
-      Diagnostic-Code: smtp; 550 5.1.1 <rbradley at mit.edu>... User unknown
-
- -- Andreas Tille <tille at debian.org>  Mon, 21 Dec 2015 16:49:55 +0100
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index d24d2fe..0000000
--- a/debian/control
+++ /dev/null
@@ -1,50 +0,0 @@
-Source: fsa
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>
-Section: science
-Priority: optional
-Build-Depends: debhelper (>= 9),
-               dh-autoreconf,
-               mummer,
-               exonerate,
-#  htcondor is a bit complex to be configured and thus we delay this one:              htcondor,
-               help2man
-Standards-Version: 3.9.6
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/fsa/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/fsa/trunk/
-Homepage: http://fsa.sourceforge.net/
-
-Package: fsa
-Architecture: any
-Depends: ${shlibs:Depends},
-         ${misc:Depends}
-Description: Fast Statistical Alignment of protein, RNA or DNA sequences
- FSA is a probabilistic multiple sequence alignment algorithm which uses
- a "distance-based" approach to aligning homologous protein, RNA or DNA
- sequences. Much as distance-based phylogenetic reconstruction methods
- like Neighbor-Joining build a phylogeny using only pairwise divergence
- estimates, FSA builds a multiple alignment using only pairwise
- estimations of homology. This is made possible by the sequence annealing
- technique for constructing a multiple alignment from pairwise
- comparisons, developed by Ariel Schwartz.
- .
- FSA brings the high accuracies previously available only for
- small-scale analyses of proteins or RNAs to large-scale problems such as
- aligning thousands of sequences or megabase-long sequences. FSA
- introduces several novel methods for constructing better alignments:
-  * FSA uses machine-learning techniques to estimate gap and
-    substitution parameters on the fly for each set of input sequences.
-    This "query-specific learning" alignment method makes FSA very robust:
-    it can produce superior alignments of sets of homologous sequences
-    which are subject to very different evolutionary constraints.
-  * FSA is capable of aligning hundreds or even thousands of sequences
-    using a randomized inference algorithm to reduce the computational
-    cost of multiple alignment. This randomized inference can be over ten
-    times faster than a direct approach with little loss of accuracy.
-  * FSA can quickly align very long sequences using the "anchor
-    annealing" technique for resolving anchors and projecting them with
-    transitive anchoring. It then stitches together the alignment between
-    the anchors using the methods described above.
-  * The included GUI, MAD (Multiple Alignment Display), can display the
-    intermediate alignments produced by FSA, where each character is
-    colored according to the probability that it is correctly aligned
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index ac05452..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,53 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: fsl
-Source: http://sourceforge.net/projects/fsa/files/
-Files-Excluded: */*.jar
-                */*.class
-                display/JMF-2.1.1e
-                display/jai-1_1_3
-                doc
-
-Files: *
-Copyright: © 2010-2014 Ariel Schwartz, Chuong Do, Robert Bradley, Jaeyoung Do, Colin Dewey, Ian Holmes, Lars Barquist
-License: GPL-2+
-
-Files: MW/*
-Copyright: 1990-2004, Condor Team, Computer Sciences Department,
-                      University of Wisconsin-Madison, WI.
-License: Condor-1.1
- This source code is covered by the Condor Public License, which can
- be found in the accompanying LICENSE.TXT file, or online at
- www.condorproject.org.
- .
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
- IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
- FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
- HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
- MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
- ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
- PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
- RIGHT.
-
-Files: debian/*
-Copyright: 2014 Andreas Tille <tille at debian.org>
-License: GPL-2+
-
-License: GPL-2+
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
- .
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
- .
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
- .
-  On Debian systems, the complete text of the GNU General General
-  Public License can be found at /usr/share/common-licenses/GPL-2.
-
diff --git a/debian/docs b/debian/docs
deleted file mode 100644
index 6e7abe4..0000000
--- a/debian/docs
+++ /dev/null
@@ -1,3 +0,0 @@
-README
-html/*.html
-html/*.css
diff --git a/debian/examples b/debian/examples
deleted file mode 100644
index 6947f9d..0000000
--- a/debian/examples
+++ /dev/null
@@ -1 +0,0 @@
-examples/[N-Za-z]*
diff --git a/debian/patches/no-display.patch b/debian/patches/no-display.patch
deleted file mode 100644
index 7de4a54..0000000
--- a/debian/patches/no-display.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Author: Andreas Tille <tille at debian.org>
-Last-Update: Mon, 21 Dec 2015 16:49:55 +0100
-Description: The GUI comes with several JARs without source including
- JAI which makes it definitely non-free - so simply do not build the GUI
- and go with the command line only
-
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -2,7 +2,7 @@ if HAVE_CONDOR
-   MAYBE_MW = MW
- endif
- 
--ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main display perl examples doc html tests
-+ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main perl examples doc html tests
- SUBDIRS = $(MAYBE_MW) $(ALWAYS_BUILT)
- DIST_SUBDIRS = $(ALWAYS_BUILT)
- 
diff --git a/debian/patches/removed-pdf-only-docs.patch b/debian/patches/removed-pdf-only-docs.patch
deleted file mode 100644
index 975f33d..0000000
--- a/debian/patches/removed-pdf-only-docs.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -2,7 +2,7 @@ if HAVE_CONDOR
-   MAYBE_MW = MW
- endif
- 
--ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main perl examples doc html tests
-+ALWAYS_BUILT = src/util src/math src/seq src/manager src/fsa src/annealing src/main perl examples html tests
- SUBDIRS = $(MAYBE_MW) $(ALWAYS_BUILT)
- DIST_SUBDIRS = $(ALWAYS_BUILT)
- 
---- a/configure.ac
-+++ b/configure.ac
-@@ -273,8 +273,6 @@ AC_CONFIG_FILES([Makefile
- 		 display/mad/manifest.mf
-                  perl/Makefile
-                  examples/Makefile
--		 doc/Makefile
--		 doc/version.tex
- 		 html/Makefile
- 		 tests/Makefile])
- 
diff --git a/debian/patches/series b/debian/patches/series
deleted file mode 100644
index 7032061..0000000
--- a/debian/patches/series
+++ /dev/null
@@ -1,2 +0,0 @@
-no-display.patch
-removed-pdf-only-docs.patch
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index c0f6e8b..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,50 +0,0 @@
-#!/usr/bin/make -f
-
-# DH_VERBOSE := 1
-
-VERSION	       := $(shell dpkg-parsechangelog | grep Version: | cut -f2 -d' ' | cut -f1 -d- )
-DEBPKGNAME     := $(shell dpkg-parsechangelog | awk '/^Source:/ {print $$2}')
-
-mandir=$(CURDIR)/debian/$(DEBPKGNAME)/usr/share/man/man1
-bindir=$(CURDIR)/debian/$(DEBPKGNAME)/usr/bin
-
-HELP2MAN = help2man --no-info --version-string="$(VERSION)"
-
-%:
-	dh $@ --with autoreconf
-
-#override_dh_auto_configure:
-#  htcondor is a bit complex to be configured and thus we delay this one
-#	dh_auto_configure -- --enable-condor-compile
-	    # found automatically: --with-mummer=/usr/bin/mummer --with-exonerate=/usr/bin/exonerate
-
-override_dh_auto_test:
-	echo "Tests seem to miss some files:"
-	echo "make[4]: *** No rule to make target 'apps/isect_d.unmappable.bash', needed by 'apps/isect_d.unmappable.bash.log'.  Stop."
-
-override_dh_installman:
-        # try to create man pages whereever possible
-	mkdir -p $(mandir)
-	$(HELP2MAN) \
-	     --name='Distance-based alignment of DNA, RNA and proteins' \
-	     $(bindir)/fsa > $(mandir)/fsa.1
-	$(HELP2MAN) \
-	     --name='Find the most-parsimonious ordering of indels' \
-	     $(bindir)/gapcleaner > $(mandir)/gapcleaner.1
-	$(HELP2MAN) \
-	     --name='Calculate the percentage identity of the passed alignment' \
-	     $(bindir)/percentid > $(mandir)/percentid.1
-	$(HELP2MAN) \
-	     --name='Find the codon alignment corresponding to the given protein alignment' \
-	     $(bindir)/prot2codon > $(mandir)/prot2codon.1
-	$(HELP2MAN) \
-	     --name='Slice a subsequence from an input FASTA file' \
-	     $(bindir)/slice_fasta > $(mandir)/slice_fasta.1
-	$(HELP2MAN) \
-	     --name='Slice subsequences from an input FASTA file' \
-	     $(bindir)/slice_fasta_gff > $(mandir)/slice_fasta_gff.1
-	$(HELP2MAN) \
-	     --name='Translate input nucleotide sequences into protein sequence.' \
-	     $(bindir)/translate > $(mandir)/translate.1
-
-
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
deleted file mode 100644
index 7b5b080..0000000
--- a/debian/upstream/metadata
+++ /dev/null
@@ -1,12 +0,0 @@
-Reference:
-  Author: Robert K. Bradley and Adam Roberts and Michael Smoot and Sudeep Juvekar and Jaeyoung Do and Colin Dewey and Ian Holmes and Lior Pachter
-  Title: Fast Statistical Alignment
-  Journal: PLoS Comput Biol.
-  Year: 2009
-  Volume: 5
-  Number: 5
-  Pages: e1000392
-  DOI: 10.1371/journal.pcbi.1000392
-  PMID: 19478997
-  URL: http://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1000392
-  eprint: http://journals.plos.org/ploscompbiol/article/asset?id=10.1371%2Fjournal.pcbi.1000392.PDF
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index 2b4ced5..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,2 +0,0 @@
-version=3
-http://sf.net/fsa/fsa-(\d[\d\.]+)\.(?:tgz|tbz|txz|(?:tar\.(?:gz|bz2|xz)))
diff --git a/display/Makefile.am b/display/Makefile.am
new file mode 100644
index 0000000..4c936b4
--- /dev/null
+++ b/display/Makefile.am
@@ -0,0 +1,78 @@
+all: mad.jar
+
+JAVA_SOURCES = \
+	mad/AlignDAG.java \
+	mad/Alignment.java \
+	mad/AlignmentPanel.java \
+	mad/Alignments.java \
+	mad/BatchDocument.java \
+	mad/JpegImagesToMovie.java \
+	mad/MAD.java \
+	mad/MadApplet.java \
+	mad/MadPanel.java \
+	mad/Node.java \
+	mad/ProbabilityMatrices.java \
+	mad/PropertyChangeHandler.java \
+	mad/PropertyChangeIDs.java \
+	mad/SaveAsFastaAction.java \
+	mad/SaveAsTiffAction.java \
+	mad/SaveAsMovAction.java \
+	mad/SparseMatrix.java
+
+# Root directory for class files (to be passed as -d option to javac)
+JAVAROOT = .
+
+# JMF directory
+JMF_DIR = JMF-2.1.1e
+
+# JAE directory
+JAI_DIR = jai-1_1_3
+
+# Options to pass to javac
+AM_JAVACFLAGS = -extdirs $(srcdir)/$(JMF_DIR)/lib:$(srcdir)/$(JAI_DIR)/lib \
+		-source 1.5
+
+# Other files that should go into distribution package
+EXTRA_DIST = \
+	mad \
+	classnoinst.stamp \
+	mad.jar \
+	mad/legend.jpg \
+	$(JMF_DIR)/lib/customizer.jar \
+	$(JMF_DIR)/lib/jmf.jar \
+	$(JMF_DIR)/lib/jmf.properties \
+	$(JMF_DIR)/lib/mediaplayer.jar \
+	$(JMF_DIR)/lib/multiplayer.jar \
+	$(JMF_DIR)/readme.html \
+	$(JAI_DIR)/COPYRIGHT-jai.txt \
+	$(JAI_DIR)/LICENSE-jai.txt \
+	$(JAI_DIR)/DISTRIBUTIONREADME-jai.txt \
+	$(JAI_DIR)/THIRDPARTYLICENSEREADME-jai.txt \
+	$(JAI_DIR)/lib/jai_core.jar \
+	$(JAI_DIR)/lib/jai_codec.jar
+
+# Only specify rules for building MAD if javac is available
+if HAVE_JAVAC
+dist_noinst_JAVA = $(JAVA_SOURCES)
+
+mad.jar: mad/manifest.mf \
+	$(JMF_DIR)/lib/jmf.jar \
+	$(JAI_DIR)/lib/jai_core.jar \
+	$(JAI_DIR)/lib/jai_codec.jar \
+	classnoinst.stamp
+	jar cmf $< $@ \
+		-C $(srcdir) mad \
+		-C $(srcdir) $(JMF_DIR)/lib/jmf.jar \
+		-C $(srcdir) $(JAI_DIR)/lib/jai_core.jar \
+		-C $(srcdir) $(JAI_DIR)/lib/jai_codec.jar
+	jar uf $@ mad
+
+# Jar files should be cleaned as well
+CLEANFILES = mad.jar
+else
+EXTRA_DIST += $(JAVA_SOURCES)
+endif #HAVE_JAVAC
+
+# Custom clean hook to remove class files
+clean-local:
+	-find . -name "*.class" -exec rm {} \;
diff --git a/display/Makefile.in b/display/Makefile.in
new file mode 100644
index 0000000..775fe80
--- /dev/null
+++ b/display/Makefile.in
@@ -0,0 +1,503 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at HAVE_JAVAC_FALSE@am__append_1 = $(JAVA_SOURCES)
+subdir = display
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(am__dist_noinst_JAVA_DIST)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__dist_noinst_JAVA_DIST = mad/AlignDAG.java mad/Alignment.java \
+	mad/AlignmentPanel.java mad/Alignments.java \
+	mad/BatchDocument.java mad/JpegImagesToMovie.java mad/MAD.java \
+	mad/MadApplet.java mad/MadPanel.java mad/Node.java \
+	mad/ProbabilityMatrices.java mad/PropertyChangeHandler.java \
+	mad/PropertyChangeIDs.java mad/SaveAsFastaAction.java \
+	mad/SaveAsTiffAction.java mad/SaveAsMovAction.java \
+	mad/SparseMatrix.java
+JAVAC = javac
+CLASSPATH_ENV = CLASSPATH=$(JAVAROOT):$(srcdir)/$(JAVAROOT)$${CLASSPATH:+":$$CLASSPATH"}
+am__java_sources = $(dist_noinst_JAVA)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+JAVA_SOURCES = \
+	mad/AlignDAG.java \
+	mad/Alignment.java \
+	mad/AlignmentPanel.java \
+	mad/Alignments.java \
+	mad/BatchDocument.java \
+	mad/JpegImagesToMovie.java \
+	mad/MAD.java \
+	mad/MadApplet.java \
+	mad/MadPanel.java \
+	mad/Node.java \
+	mad/ProbabilityMatrices.java \
+	mad/PropertyChangeHandler.java \
+	mad/PropertyChangeIDs.java \
+	mad/SaveAsFastaAction.java \
+	mad/SaveAsTiffAction.java \
+	mad/SaveAsMovAction.java \
+	mad/SparseMatrix.java
+
+
+# Root directory for class files (to be passed as -d option to javac)
+JAVAROOT = .
+
+# JMF directory
+JMF_DIR = JMF-2.1.1e
+
+# JAE directory
+JAI_DIR = jai-1_1_3
+
+# Options to pass to javac
+AM_JAVACFLAGS = -extdirs $(srcdir)/$(JMF_DIR)/lib:$(srcdir)/$(JAI_DIR)/lib \
+		-source 1.5
+
+
+# Other files that should go into distribution package
+EXTRA_DIST = mad classnoinst.stamp mad.jar mad/legend.jpg \
+	$(JMF_DIR)/lib/customizer.jar $(JMF_DIR)/lib/jmf.jar \
+	$(JMF_DIR)/lib/jmf.properties $(JMF_DIR)/lib/mediaplayer.jar \
+	$(JMF_DIR)/lib/multiplayer.jar $(JMF_DIR)/readme.html \
+	$(JAI_DIR)/COPYRIGHT-jai.txt $(JAI_DIR)/LICENSE-jai.txt \
+	$(JAI_DIR)/DISTRIBUTIONREADME-jai.txt \
+	$(JAI_DIR)/THIRDPARTYLICENSEREADME-jai.txt \
+	$(JAI_DIR)/lib/jai_core.jar $(JAI_DIR)/lib/jai_codec.jar \
+	$(am__append_1)
+
+# Only specify rules for building MAD if javac is available
+ at HAVE_JAVAC_TRUE@dist_noinst_JAVA = $(JAVA_SOURCES)
+
+# Jar files should be cleaned as well
+ at HAVE_JAVAC_TRUE@CLEANFILES = mad.jar
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign display/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign display/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+classnoinst.stamp: $(am__java_sources)
+	@list1='$?'; list2=; if test -n "$$list1"; then \
+	  for p in $$list1; do \
+	    if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+	    list2="$$list2 $$d$$p"; \
+	  done; \
+	  echo '$(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) '"$$list2"; \
+	  $(CLASSPATH_ENV) $(JAVAC) -d $(JAVAROOT) $(AM_JAVACFLAGS) $(JAVACFLAGS) $$list2; \
+	else :; fi
+	echo timestamp > $@
+
+clean-noinstJAVA:
+	-rm -f *.class classnoinst.stamp
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile classnoinst.stamp
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-local clean-noinstJAVA mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-local \
+	clean-noinstJAVA cscopelist-am ctags-am distclean \
+	distclean-generic distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic pdf pdf-am ps ps-am tags-am uninstall \
+	uninstall-am
+
+all: mad.jar
+
+ at HAVE_JAVAC_TRUE@mad.jar: mad/manifest.mf \
+ at HAVE_JAVAC_TRUE@	$(JMF_DIR)/lib/jmf.jar \
+ at HAVE_JAVAC_TRUE@	$(JAI_DIR)/lib/jai_core.jar \
+ at HAVE_JAVAC_TRUE@	$(JAI_DIR)/lib/jai_codec.jar \
+ at HAVE_JAVAC_TRUE@	classnoinst.stamp
+ at HAVE_JAVAC_TRUE@	jar cmf $< $@ \
+ at HAVE_JAVAC_TRUE@		-C $(srcdir) mad \
+ at HAVE_JAVAC_TRUE@		-C $(srcdir) $(JMF_DIR)/lib/jmf.jar \
+ at HAVE_JAVAC_TRUE@		-C $(srcdir) $(JAI_DIR)/lib/jai_core.jar \
+ at HAVE_JAVAC_TRUE@		-C $(srcdir) $(JAI_DIR)/lib/jai_codec.jar
+ at HAVE_JAVAC_TRUE@	jar uf $@ mad
+
+# Custom clean hook to remove class files
+clean-local:
+	-find . -name "*.class" -exec rm {} \;
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/display/classnoinst.stamp b/display/classnoinst.stamp
new file mode 100644
index 0000000..9788f70
--- /dev/null
+++ b/display/classnoinst.stamp
@@ -0,0 +1 @@
+timestamp
diff --git a/display/mad/AlignDAG.java b/display/mad/AlignDAG.java
new file mode 100644
index 0000000..35fe9a7
--- /dev/null
+++ b/display/mad/AlignDAG.java
@@ -0,0 +1,641 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for different accuracy measures was written by Robert Bradley.
+ */
+
+
+package mad;
+
+import java.util.*;
+//import it.unimi.dsi.fastutil.objects.*;
+
+public class AlignDAG{
+    
+    private Node[] V;  // Vertices in our order.
+    private Node[] oV; // Vertices in AMAP's order.
+    private Node[] startV; // Vertices that begin each sequence
+    private HashMap<Node, Node> mergeDict;
+
+    private double acc;
+    private double sps;
+    private double ppv;
+    private double cert;
+    private double cons;
+
+    private double accDenom;
+    private double spsDenom;
+    private double ppvDenom;
+    private double certDenom;
+    private double consDenom;
+
+    private double deltaAccNorm;
+    private double deltaSPSNorm;
+    private double deltaPPVNorm;
+    private double deltaCertNorm;
+    private double deltaConsNorm;
+
+    private double gapFactorCurrent;  /// the current gap factor
+
+    private int colorScheme;
+    private int mergeOrder;
+
+    private Set<Node> activeNodes;
+    private int numSeqs;
+
+    public AlignDAG (List<String> keys, String[] sequences, HashMap<String, Integer> initDAG, ProbabilityMatrices pm) {
+        this.mergeDict = new HashMap<Node, Node>();
+        this.numSeqs = sequences.length;
+
+	this.colorScheme = 0;
+	this.mergeOrder = 0;
+
+        buildDagFromInit(keys, sequences, initDAG, pm);  
+    }
+    
+    public AlignDAG (List<String> keys, String[] sequences, String[] alignedSeqs, ProbabilityMatrices pm){
+    	this.mergeDict = new HashMap<Node, Node>();
+    	this.numSeqs = sequences.length;
+
+	this.colorScheme = 0;
+	this.mergeOrder = 0;
+
+    	buildDagFromAlign(keys, sequences, alignedSeqs, pm);
+    }
+    
+    /// Update color scheme for all active nodes.
+    /*
+     * Forces re-coloring of all columns according to the new scheme.
+     */
+    public void setColorScheme(int scheme) {
+	this.colorScheme = scheme;
+	Iterator iter = activeNodes.iterator();
+	while (iter.hasNext()) {
+	    ((Node)iter.next()).setColorScheme(scheme);
+	}
+    }
+
+    private void buildDagFromAlign(List<String> keys, String[] sequences, String[] alignedSeqs, ProbabilityMatrices pm){
+
+	acc = 0;
+	sps = 0;
+	ppv = 0;
+	cert = 0;
+	cons = 0;
+
+	accDenom = 0;
+	spsDenom = 0;
+	ppvDenom = 0;
+	certDenom = 0;
+	consDenom = 0;
+
+	deltaAccNorm = 0;
+	deltaSPSNorm = 0;
+	deltaPPVNorm = 0;
+	deltaCertNorm = 0;
+	deltaConsNorm = 0;
+
+	gapFactorCurrent = -1;
+
+    	//Find total length of all sequences and initialize nextIndex array
+    	int[] nextIndex = new int[numSeqs];
+
+       	for(int i = 0; i < numSeqs; i++)
+    		nextIndex[i] = 0;
+    	
+    	Node lastV = null;
+    	
+    	int alignLength = alignedSeqs[0].length();
+        this.V = new Node[alignLength];
+        this.activeNodes = new HashSet<Node>();
+        
+        //Ensure rows are flush.
+        for(int i = 0; i < numSeqs; i++){
+	    if (alignedSeqs[i].length() != alignLength){
+		System.err.println("ERROR: Alternate alignment rows are not flush.");
+		System.exit(-1);
+	    }
+        }
+        
+        //Ensure sequences match.
+    	for (int i = 0; i < alignLength; i++){
+	    int[] seqIndices = new int[numSeqs];
+	    int presentSeqs = 0;
+	    int seqI = -1;
+    		
+	    for(int j = 0; j < numSeqs; j++){
+		char c = alignedSeqs[j].charAt(i);
+		if (c == '-'){
+		    seqIndices[j] = -1;
+		}
+		else if (sequences[j].length() > nextIndex[j] && c == sequences[j].charAt(nextIndex[j])){
+		    seqIndices[j] = nextIndex[j]++;
+		    presentSeqs++;
+		    seqI = j;
+		}
+		else{
+		    System.err.println("ERROR: Sequences in alternate alignment do not match; offending sequence is '" + keys.get(j) + "'.");
+		    System.exit(-1);
+		}
+	    }
+    		
+	    Node v = new Node(seqIndices, seqI, pm);
+	    v.isMerge = (presentSeqs > 1);
+	    v.setColorScheme (colorScheme);
+	    this.V[i] = v;
+	    this.mergeDict.put(v,v);
+
+	    this.acc += v.getAcc();
+	    this.sps += v.getSPS();
+	    this.ppv += v.getPPV();
+	    this.cert += v.getCert();
+	    this.cons += v.getCons();
+
+	    this.accDenom += v.getAccDenom();
+	    this.spsDenom += v.getSPSDenom();
+	    this.ppvDenom += v.getPPVDenom();
+	    this.certDenom += v.getCertDenom();
+	    this.consDenom += v.getConsDenom();
+
+	    this.activeNodes.add(v);
+    		
+	    if (lastV != null)
+            	lastV.fwdEdge = v;
+            lastV = v;
+	    
+    	}
+    	
+    	//Ensure we've reached the end of the original sequence.
+    	for (int i = 0; i < numSeqs; i++){
+	    if (nextIndex[i] != sequences[i].length()){
+		System.err.println("ERROR: Sequences in alternate alignment do not match; offending sequence is '" + keys.get(i) + "'.");
+		System.exit(-1);	
+	    }
+    	}
+    	
+    	this.startV = V;
+
+    }
+
+    private void buildDagFromInit(List<String> keys, String[] sequences, HashMap<String, Integer> initDAG, ProbabilityMatrices pm){
+        Node lastV;
+        String seq;
+
+	acc = 0;
+	sps = 0;
+	ppv = 0;
+	cert = 0;
+	cons = 0;
+
+	accDenom = 0;
+	spsDenom = 0;
+	ppvDenom = 0;
+	certDenom = 0;
+	consDenom = 0;
+
+	deltaAccNorm = 0;
+	deltaSPSNorm = 0;
+	deltaPPVNorm = 0;
+	deltaCertNorm = 0;
+	deltaConsNorm = 0;
+
+	gapFactorCurrent = -1;
+
+       	//Find total length of all sequences
+        int totalLength = 0;
+        for (int i = 0; i < this.numSeqs; i++){
+        	totalLength += sequences[i].length();
+        }
+        
+        this.V = new Node[totalLength];
+        this.oV = new Node[totalLength];
+        this.startV = new Node[numSeqs];
+        this.activeNodes = new HashSet<Node>();
+        
+       	int k = 0;
+        for (int i = 0; i < this.numSeqs; i++){ // iterate through array of sequences
+            lastV = null;
+            seq = sequences[i];
+            
+            for (int j = 0; j < seq.length(); j++){ // iterate through sequence
+        		
+        		// Initialize empty column and indices arrays
+                Node v = new Node(i, j, pm);
+		v.setColorScheme (colorScheme);
+                this.V[k] = v;
+		//                this.oV[initDAG.get(i + "." + (j+1))] = v; //j+1 because index starts at 1
+                this.oV[initDAG.get(i + "." + j)] = v; // j because index starts at 0
+                this.mergeDict.put(v,v);
+
+		this.acc += v.getAcc();
+		this.sps += v.getSPS();
+		this.ppv += v.getPPV();
+		this.cert += v.getCert();
+		this.cons += v.getCons();
+
+		this.accDenom += v.getAccDenom();
+		this.spsDenom += v.getSPSDenom();
+		this.ppvDenom += v.getPPVDenom();
+		this.certDenom += v.getCertDenom();
+		this.consDenom += v.getConsDenom();
+
+                this.activeNodes.add(v);
+                if (lastV != null)
+                    lastV.fwdEdge = v;
+                else
+                	startV[i] = v;
+                lastV = v;
+           		k++;
+            }
+        }
+    }
+    
+    /// Get normalized accuracy for alignment.
+    /*
+     * \return accuracy, or -1 if undefined
+     * Performs bounds-checking.
+     */
+    public double getAlignAccNorm(){
+	if (accDenom == 0.)
+	    return -1;
+    	return SparseMatrix.saneProb (acc / accDenom);
+    }
+
+    /// Get normalized SPS for alignment.
+    /*
+     * \return SPS, or -1 if undefined
+     */
+    public double getAlignSPSNorm(){
+	if (spsDenom == 0.)
+	    return -1;
+    	return SparseMatrix.saneProb (sps / spsDenom);
+    }
+
+    /// Get normalized PPV for alignment.
+    /*
+     * \return PPV, or -1 if undefined
+     */
+    public double getAlignPPVNorm(){
+	if (ppvDenom == 0.)
+	    return -1;
+    	return SparseMatrix.saneProb (ppv / ppvDenom);
+    }
+
+    /// Get normalized certainty for alignment.
+    /*
+     * \return certainty, or -1 if undefined
+     */
+    public double getAlignCertNorm(){
+	if (certDenom == 0.)
+	    return -1;
+    	return SparseMatrix.saneProb (Node.normalizedCertainty (cert / certDenom));
+    }
+
+    /// Get normalized consistency for alignment.
+    /*
+     * \return consistency, or -1 if undefined
+     */
+    public double getAlignConsNorm(){
+	if (consDenom == 0.)
+	    return -1;
+    	return SparseMatrix.saneProb (cons / consDenom);
+    }
+
+    /// Get the change in normalized accuracy.
+    public double getDeltaAccNorm(){
+	return deltaAccNorm;
+    }
+
+    /// Get the change in normalized SPS.
+    public double getDeltaSPSNorm(){
+	return deltaSPSNorm;
+    }
+
+    /// Get the change in normalized PPV.
+    public double getDeltaPPVNorm(){
+	return deltaPPVNorm;
+    }
+
+    /// Get the change in normalized certainty.
+    public double getDeltaCertNorm(){
+	return deltaCertNorm;
+    }
+
+    /// Get the change in normalized consistency.
+    public double getDeltaConsNorm(){
+	return deltaConsNorm;
+    }
+
+    /// Get the implicit current gap factor.
+    /*
+     * -1 if Infinity, implicit current gap factor otherwise
+     */
+    public double getGapFactor(){
+	return gapFactorCurrent;
+    }
+
+    /// Merge two nodes.
+    /*
+     * @param i index of source node in oV
+     * @param j index of dest node in oV
+     */
+    public void merge(int i, int j){
+	    
+	Node n1 = this.mergeDict.get(this.oV[i]);
+        Node n2 = this.mergeDict.get(this.oV[j]);
+        
+        Node m = new Node(n1, n2, mergeOrder++);
+	m.setColorScheme (colorScheme);
+
+	// now update accuracies after the merge
+	// note that the calculation must be done on the unnormalized accuracies
+	deltaAccNorm = m.getAcc() - (n1.getAcc() + n2.getAcc());
+	deltaAccNorm /= (1.0 * m.getAccDenom());
+
+	deltaSPSNorm = m.getSPS() - (n1.getSPS() + n2.getSPS());
+	deltaSPSNorm /= (1.0 * m.getSPSDenom());
+
+	deltaPPVNorm = m.getPPV() - (n1.getPPV() + n2.getPPV());
+	deltaPPVNorm /= (1.0 * m.getPPVDenom());
+
+	deltaCertNorm = m.getCert() - (n1.getCert() + n2.getCert());
+	deltaCertNorm /= (1.0 * m.getCertDenom());
+
+	deltaConsNorm = m.getCons() - (n1.getCons() + n2.getCons());
+	deltaConsNorm /= (1.0 * m.getConsDenom());
+
+	gapFactorCurrent = m.getWeightTgf();
+
+//	System.err.println ("m.getSPS() = " + m.getSPS()
+//			    + "m.getSPSDenom() = " + m.getSPSDenom()
+//			    + "; n1.getSPS() = " + n1.getSPS() + "; n2.getSPS() = " + n2.getSPS()
+//			    + "; n1.getSPSDenom() = " + n1.getSPSDenom() + "; n2.getSPSDenom() = " + n2.getSPSDenom());
+	
+	acc += m.getAcc() - (n1.getAcc() + n2.getAcc());
+	sps += m.getSPS() - (n1.getSPS() + n2.getSPS());
+	ppv += m.getPPV() - (n1.getPPV() + n2.getPPV());
+	cert += m.getCert() - (n1.getCert() + n2.getCert());
+	cons += m.getCons() - (n1.getCons() + n2.getCons());
+
+	accDenom += m.getAccDenom() - (n1.getAccDenom() + n2.getAccDenom());
+	spsDenom += m.getSPSDenom() - (n1.getSPSDenom() + n2.getSPSDenom());
+	ppvDenom += m.getPPVDenom() - (n1.getPPVDenom() + n2.getPPVDenom());
+	certDenom += m.getCertDenom() - (n1.getCertDenom() + n2.getCertDenom());
+	consDenom += m.getConsDenom() - (n1.getConsDenom() + n2.getConsDenom());
+        
+        activeNodes.remove(n1);
+        activeNodes.remove(n2);
+        activeNodes.add(m);
+        updateMergeDict(m, m);
+    }
+    
+    /// Demerge a nodes.
+    /*
+     * @param i index of node to demerge in oV
+     * @param k index of node in oV
+     *
+     * The index k is necessary in order to update the gap factor
+     * after demerging a node.
+     */
+    public void demerge(int i, int k){
+        
+	--mergeOrder;
+
+        Node m = this.mergeDict.get(this.oV[i]);
+        Node n1 = m.n1;
+        Node n2 = m.n2;
+
+	n1.setColorScheme (colorScheme);
+	n2.setColorScheme (colorScheme);
+        
+	// this calculation must be done on the unnormalized accuracies
+        deltaAccNorm = (n1.getAcc() + n2.getAcc()) - m.getAcc();
+	deltaAccNorm /= (1.0 * m.getAccDenom());
+
+        deltaSPSNorm = (n1.getSPS() + n2.getSPS()) - m.getSPS();
+	deltaSPSNorm /= (1.0 * m.getSPSDenom());
+
+        deltaPPVNorm = (n1.getPPV() + n2.getPPV()) - m.getPPV();
+	deltaPPVNorm /= (1.0 * m.getPPVDenom());
+
+        deltaCertNorm = (n1.getCert() + n2.getCert()) - m.getCert();
+	deltaCertNorm /= (1.0 * m.getCertDenom());
+
+        deltaConsNorm = (n1.getCons() + n2.getCons()) - m.getCons();
+	deltaConsNorm /= (1.0 * m.getConsDenom());
+
+	// decrement the gap factor: look up the gap factor for the previous merge
+	if (k >= 0)
+	    gapFactorCurrent = (this.mergeDict.get(this.oV[k])).getWeightTgf();
+	else // if no previous merge, set to dummy value
+	    gapFactorCurrent = -1;
+
+	acc += (n1.getAcc() + n2.getAcc()) - m.getAcc();
+	sps += (n1.getSPS() + n2.getSPS()) - m.getSPS();
+	ppv += (n1.getPPV() + n2.getPPV()) - m.getPPV();
+	cert += (n1.getCert() + n2.getCert()) - m.getCert();
+	cons += (n1.getCons() + n2.getCons()) - m.getCons();
+
+	accDenom += (n1.getAccDenom() + n2.getAccDenom()) - m.getAccDenom();
+	spsDenom += (n1.getSPSDenom() + n2.getSPSDenom()) - m.getSPSDenom();
+	ppvDenom += (n1.getPPVDenom() + n2.getPPVDenom()) - m.getPPVDenom();
+	certDenom += (n1.getCertDenom() + n2.getCertDenom()) - m.getCertDenom();
+	consDenom += (n1.getConsDenom() + n2.getConsDenom()) - m.getConsDenom();
+        
+	if (mergeDict.containsKey(m)){
+	    System.out.println("found it!");
+	}
+	
+	activeNodes.remove(m);
+	activeNodes.add(n1);
+	activeNodes.add(n2);
+        updateMergeDict(n1, n1);
+        updateMergeDict(n2, n2);
+    }
+    
+    private void updateMergeDict(Node n, Node m){
+        if (n.isMerge){
+            Node n1 = n.n1;
+            Node n2 = n.n2;
+            
+            updateMergeDict(n1, m);
+            updateMergeDict(n2, m);
+        }
+        else 
+            this.mergeDict.put(n, m);
+    }
+    
+    public Node[] topoSort(){
+    	Stack<Node> toVisit = new Stack<Node>();
+    	Node u, v, w;
+        Comparator<Node> byRevFinishTime = new NodeFinishTimeComparator();
+    	int time = 0;
+    	
+        Iterator<Node> iter = activeNodes.iterator();
+        while (iter.hasNext()) {
+        	v = iter.next();
+        	v.visited = false;
+        	v.finishTime = -1;
+    	}
+    	
+    	for (int i = 0; i < numSeqs; i++){
+			u = mergeDict.get(startV[i]);
+
+//    		System.out.print ("outer loop: ");
+//			u.output();
+			
+			if (!u.visited){
+				toVisit.push(u);
+//	    		System.out.print ("  pushed: ");
+//	    		u.output();
+			}
+			
+			while (!toVisit.empty()){
+				v = toVisit.pop();
+//				System.out.print (" popped: ");
+//				v.output();
+				if (v.visited){
+					if (v.finishTime < 0) // if not finished
+						v.finishTime = time++;
+				}
+				else{
+					v.visited = true;
+					toVisit.push(v);
+//		    		System.out.print ("  pushed: ");
+//		    		v.output();
+		    		
+		    		Node[] edges = processEdges(v.getFwdEdges());
+					for(int j = 0; j < edges.length; j++) {
+						w  = edges[j];
+						
+						if (!w.visited){
+							toVisit.push(w);			
+//							System.out.print ("   pushed ");
+//							w.output();
+						}
+					}
+				}
+			}
+        }
+
+		iter = activeNodes.iterator();
+		
+		Node[] L = activeNodes.toArray(new Node[0]);
+		Arrays.sort(L, byRevFinishTime);
+        return L;
+    }    
+    
+    // Maps edges to their merged version and sorts array
+    private Node[] processEdges(Collection<Node> edges){
+    	Node[] edgeArray = new Node[edges.size()];
+    	Iterator<Node> iter = edges.iterator();
+    	
+    	int i = 0;
+    	while (iter.hasNext())
+    		edgeArray[i++] = mergeDict.get(iter.next());
+    	
+    	if (edgeArray.length > 1){
+    		Comparator<Node> byNodeSequence = new NodeSequenceComparator();
+    		Arrays.sort(edgeArray, byNodeSequence);
+    		MySorter sorter = new MySorter();
+			edgeArray = sorter.sort(edgeArray);
+    	}
+    	return edgeArray;	
+    }
+    
+
+    
+    private void checkSort(mad.Node[] nArray){
+			int[] maxArray = new int[numSeqs];
+			Node v;
+			
+			for(int i = 0; i < numSeqs; i++){
+				maxArray[i] = -1;
+			}
+			for(int i = 0; i < nArray.length; i++){
+				v = nArray[i];
+				int[] seqIndices = v.getSeqIndices();
+				for(int j = 0; j < numSeqs; j++){
+					if (seqIndices[j] != -1 && maxArray[j] > seqIndices[j]){
+						System.err.println("Sanity check failed!");
+						System.exit(-1);
+					}
+					else if (seqIndices[j] != -1)
+						maxArray[j] = seqIndices[j];
+				}
+			}
+    }
+}
+
+class MySorter{
+	
+	
+	public MySorter(){}
+	
+	public Node[] sort(Node[] nArray){
+		boolean isSorted = false;
+		int[] maxArray;
+		int numSeqs = nArray[0].pm.numSeqs;
+		Node v;
+		
+		while (!isSorted){
+			isSorted = true;
+			maxArray = new int[numSeqs];
+			for(int i = 0; i < numSeqs; i++){
+				maxArray[i] = -1;
+			}
+			for(int i = 0; i < nArray.length; i++){
+				v = nArray[i];
+				boolean switched = false;
+				int[] seqIndices = v.getSeqIndices();
+				for(int j = 0; j < numSeqs; j++){
+					if (seqIndices[j] != -1 && maxArray[j] > seqIndices[j]){
+						if (!switched){
+							switchNodes(nArray, i-1, i);
+							switched = true;
+							isSorted = false;
+						}
+					}
+					else if (seqIndices[j] != -1)
+						maxArray[j] = seqIndices[j];
+				}
+			}
+		}	
+		return nArray;
+	}
+	
+	
+	private Node[] switchNodes(Node[] nArray, int i, int j){
+		Node temp = nArray[i];
+		nArray[i] = nArray[j];
+		nArray[j] = temp;
+		return nArray;
+	}
+}
+
+class NodeFinishTimeComparator implements Comparator<Node> {
+	
+	public int compare(Node n1, Node n2){
+		if (n1.finishTime > n2.finishTime)
+			return -1;
+		return 1;
+	}
+}
+
+class NodeSequenceComparator implements Comparator<Node>{
+	
+	public int compare(Node n1, Node n2){
+		int[] seq1Indices = n1.getSeqIndices();
+		int[] seq2Indices = n2.getSeqIndices();
+		for (int i = 0; i < seq1Indices.length; i++){
+
+			if (seq1Indices[i] != -1 && seq2Indices[i] != -1)
+				if (seq1Indices[i] < seq2Indices[i])
+					return -1;
+				else
+					return 1;	
+		}
+		return 0;
+	}
+}
diff --git a/display/mad/Alignment.java b/display/mad/Alignment.java
new file mode 100644
index 0000000..fd37cbf
--- /dev/null
+++ b/display/mad/Alignment.java
@@ -0,0 +1,328 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for different accuracy measures was written by Robert Bradley.
+ */
+
+package mad;
+
+import java.util.*;
+
+public class Alignment {
+
+    Node[] L; // nodes in topologically sorted order
+    String[] seqs;
+    String[] cols;
+    List<String> keys;
+    AlignDAG aDag;
+    String[] fullSequences;
+    boolean gapsSuppressed;
+    int colorScheme;
+
+    public Alignment(List<String> keys, String[] fullSequences, AlignDAG aDag, boolean suppressGaps, int colorScheme) {
+	this.keys = keys;
+	this.fullSequences = fullSequences;
+	this.aDag = aDag;
+	this.colorScheme = colorScheme;
+	buildSeqsAndCols(suppressGaps, colorScheme);
+    }
+	
+
+    public void buildSeqsAndCols(boolean suppressGaps, int scheme){
+
+	// update color scheme
+	this.colorScheme = scheme;
+
+       	int N = keys.size();
+       	
+    	// Initialize empty StringBuffer array and sanity check
+    	StringBuffer[] cols = new StringBuffer[N];
+    	StringBuffer[] seqs = new StringBuffer[N];
+	int[] sanityCheck = new int[N];
+    	for (int i = 0; i < N; i++){
+	    seqs[i] = new StringBuffer();
+	    cols[i] = new StringBuffer();
+	    sanityCheck[i] = 0;
+    	}
+    	
+    	StringBuffer color = new StringBuffer();
+    	char[] colors;
+    	int[] seqIndices;
+    	Node v;
+    	
+	// update color scheme
+	aDag.setColorScheme (colorScheme);
+    	L = aDag.topoSort();
+    	
+    	//Gap suppression variables
+    	int [] gapCounts = new int[1];
+    	int gapCountDown = 0;
+    	int lastGapCount = 0;
+    	int[] colorSum = new int[N];
+	if (suppressGaps)
+	    gapCounts = getGapCounts(L);
+    	
+    	
+    	// Hide consecutive graps of length greater than 3.
+       	for(int i = 0; i < L.length; i++){
+        	          
+            v = L[i];
+            
+            int[] sI = v.getSeqIndices();
+            for (int z = 0; z<N; z++){
+				if (sI[z] != -1){
+					if (sI[z] != sanityCheck[z])
+						System.err.println("ERROR: " + z + " " + sI[z] + " " + sanityCheck[z]);
+					sanityCheck[z] ++;
+				}		
+            }
+
+			//Handle gap suppression...
+            if (!suppressGaps){}
+            
+            else if (gapCountDown-- == 1){
+            	colorSum = sumArrays(colorSum, v.getColors());
+            	String[][] gapFill = getGapFill(lastGapCount, colorSum, v.seqI);
+            	for (int j = 0; j < N; j++){
+       				seqs[j].append(gapFill[j][0]);
+            		cols[j].append(gapFill[j][1]);
+            	}
+            	continue;
+            }
+    
+            else if (gapCountDown+1 > 0){ // Adding 1 because we already decremented
+            	colorSum = sumArrays(colorSum, v.getColors());
+            	continue;
+            }  
+    
+    		else if ((lastGapCount = gapCounts[i]) > 3){
+            	gapCountDown = lastGapCount - 1;
+            	colorSum = new int[N];
+            	for (int x = 0; x < N; x++)
+            		colorSum[x] = 0;
+            	colorSum = sumArrays(colorSum, v.getColors());
+            	continue;
+            }
+            //...done handling gap suppression.
+            
+                     
+            colors = v.getColors();
+            seqIndices = v.getSeqIndices();
+            
+            for (int j = 0; j < N; j++){
+            	if (seqIndices[j] == -1)
+            		seqs[j].append('-');
+            	else
+            		seqs[j].append(fullSequences[j].charAt(seqIndices[j])); 
+            	cols[j].append(colors[j]);
+            }
+        }
+        
+        // Convert StringBuffers to Strings
+        this.cols = new String[N];
+        this.seqs = new String[N];
+
+        for (int i = 0; i < N; i++){
+        	this.cols[i] = cols[i].toString();
+        	this.seqs[i] = seqs[i].toString();
+        }
+          
+        this.gapsSuppressed = suppressGaps;
+
+    }
+    
+    // Creates an array specifying how many consecutive gaps follow at each starting point (i).
+   	public int[] getGapCounts(Node[] L){
+   	
+    	int[] gapCounts = new int[L.length];
+    	int lastCount = 0;
+    	int lastSeqI = -1;
+    	Node u;
+    	
+    	for (int i = L.length-1; i>=0; i--){
+    		u = L[i];
+    		
+    		if (u.isMerge){
+    			lastCount = 0;
+    			gapCounts[i] = 0;
+    		}
+    		else{
+    			if (lastSeqI != u.seqI)
+    				lastCount = 0;
+    			gapCounts[i] = ++lastCount;
+    			lastSeqI = u.seqI;
+    		}
+    	}
+    	
+    	return gapCounts;
+    }
+    
+    private int[] sumArrays(int[] a1, char[] a2){
+    	for (int i = 0; i < a1.length; i ++){
+    		int c = (int)a2[i];
+    		if (c > 256) // Remove highlighting
+    			c -= 256;
+    		a1[i] += c;
+    		
+    	}
+    	return a1;
+    }
+    
+    // Returns a sequences to suppress a gap of size nGaps.    
+    private String[][] getGapFill(int nGaps, int[] colorSum, int seqI){
+    	//String nonGapSeq = "\u25B6" + nGaps + "\u25C0";
+    	String nonGapSeq = ">" + nGaps + "<";
+    	StringBuffer col;
+    	StringBuffer seq;
+    	
+    	int N = keys.size();
+    	
+    	String[][] results = new String[N][2];
+    	
+    	char avgColor;
+    	
+    	for (int i = 0; i < N; i ++){
+    		seq = new StringBuffer("");
+    		col = new StringBuffer("");
+    		avgColor = (char)Math.rint(colorSum[i]/nGaps);
+    		for (int j = 0; j < nonGapSeq.length(); j++){
+    			seq.append('-');
+    			col.append(avgColor);
+       		}
+    		results[i][0] = seq.toString();
+    		results[i][1] = col.toString();
+    	}
+    	
+    	results[seqI][0] = nonGapSeq;
+    
+    	return results;
+    }
+
+
+	public List<String> getOrderedKeys() {
+		return keys;
+	}
+
+	public String[] getSequences() {
+		return seqs;
+	}
+
+	public String[] getColors() {
+		return cols;
+	}
+
+    /// Get normalized accuracy for alignment.
+    /*
+     * \return accuracy, or -1 if undefined
+     */
+    public double getAccNorm() {
+	return aDag.getAlignAccNorm();
+    }
+
+    /// Get normalized SPS for alignment.
+    /*
+     * \return SPS, or -1 if undefined
+     */
+    public double getSPSNorm() {
+	return aDag.getAlignSPSNorm();
+    }
+
+    /// Get normalized PPV for alignment.
+    /*
+     * \return PPV, or -1 if undefined
+     */
+    public double getPPVNorm() {
+	return aDag.getAlignPPVNorm();
+    }
+
+    /// Get normalized certainty for alignment.
+    /*
+     * \return certainty, or -1 if undefined
+     */
+    public double getCertNorm() {
+	return aDag.getAlignCertNorm();
+    }
+
+    /// Get normalized consistency for alignment.
+    /*
+     * \return consistency, or -1 if undefined
+     */
+    public double getConsNorm() {
+	return aDag.getAlignConsNorm();
+    }
+
+    /// Get the change in normalized accuracy.
+    public double getDeltaAccNorm(){
+	return aDag.getDeltaAccNorm();
+    }
+
+    /// Get the change in normalized SPS.
+    public double getDeltaSPSNorm(){
+	return aDag.getDeltaSPSNorm();
+    }
+
+    /// Get the change in normalized PPV.
+    public double getDeltaPPVNorm(){
+	return aDag.getDeltaPPVNorm();
+    }
+
+    /// Get the change in normalized certainty.
+    public double getDeltaCertNorm(){
+	return aDag.getDeltaCertNorm();
+    }
+
+    /// Get the change in normalized consistency.
+    public double getDeltaConsNorm(){
+	return aDag.getDeltaConsNorm();
+    }
+
+    /// Get the implicit gap factor.
+    /*
+     * \return -1 if Infinity, implicit current gap factor otherwise
+     */
+    public double getGapFactor(){
+	return aDag.getGapFactor();
+    }
+
+	public String toString() {
+		StringBuffer sb = new StringBuffer();
+		sb.append("Weight      = ");
+		sb.append((new Double(getAccNorm())).toString());
+		sb.append("\n");
+		int i = 0;
+		for ( String key : keys ) {
+			sb.append(key);
+			sb.append("\t");
+			sb.append(seqs[i]);
+			sb.append("\n");
+			i++;
+		}
+		sb.append("\n");
+		sb.append("\n");
+
+		return sb.toString();
+	}
+
+	public String toMultiFasta() {
+		if (gapsSuppressed) // This is so that the sequences will be saved without gaps suppression
+		    buildSeqsAndCols(false, 0); // throwaway color scheme
+		
+		StringBuffer sb = new StringBuffer();
+		int i = 0;
+		
+		for ( String key : keys ) {
+			sb.append(">");
+			sb.append(key);
+			sb.append("\n");
+			sb.append(seqs[i]);
+			sb.append("\n");
+			i++;
+		}
+		
+		if (gapsSuppressed)
+		    buildSeqsAndCols(true, 0); // throwaway color scheme
+		
+		return sb.toString();
+	}
+}
diff --git a/display/mad/AlignmentPanel.java b/display/mad/AlignmentPanel.java
new file mode 100644
index 0000000..42f780a
--- /dev/null
+++ b/display/mad/AlignmentPanel.java
@@ -0,0 +1,337 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot and Adam Roberts.
+ */
+
+
+package mad;
+
+
+import javax.swing.*;
+import javax.swing.text.*;
+import java.util.*;
+import java.awt.event.*;
+import java.awt.Dimension;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.font.FontRenderContext;
+
+import java.io.*;
+import java.awt.*;
+import java.awt.image.*;
+import com.sun.image.codec.jpeg.*;
+import javax.media.jai.*;
+import com.sun.media.jai.codec.*;
+
+public class AlignmentPanel extends JTextPane implements ComponentListener, MouseListener {
+
+	Alignments aligns;
+	String[] orderedKeys; 
+	HashMap<Integer, Integer> caretToNode;
+	int index;
+	int numCharsAcross;
+	int nameWidth;
+	int glyphWidth;
+	int glyphHeight;
+	int len; 
+	Font defaultFont;
+	int height;
+	int width;
+	int os;
+	int currPaintIndex;
+	
+    boolean colored;
+
+    public AlignmentPanel(Alignments aligns, int initWidth, boolean colored) {
+		super();
+		this.addMouseListener(this);
+		this.aligns = aligns;
+		this.width = initWidth;
+		this.colored = colored;
+		String[] seqs = aligns.get(0).getSequences();
+		
+		nameWidth = 0;
+		for (String key : aligns.keys)
+			nameWidth = Math.max(nameWidth, key.length());
+		nameWidth += 2;	
+		
+
+		orderedKeys = new String[aligns.keys.size()];
+		int i = 0;
+		for (String key : aligns.keys){
+			StringBuffer blanks = new StringBuffer("");
+			for (int j = 0; j < nameWidth-key.length(); j++)
+				blanks.append(" ");
+			orderedKeys[i++] = " " + key + blanks;
+		}
+			
+		
+		defaultFont = new Font("Courier",Font.BOLD,12);
+		glyphWidth=10;
+		glyphHeight=10;
+		
+		index = 0;
+		currPaintIndex = -2;
+
+		// Aaaaargh
+		if ( System.getProperty("os.name").matches(".*[Mm][Aa][Cc].*") )
+			os = -1;
+		else
+			os = 1;
+			
+		this.setEditable(false);
+
+		sizeScreen( new Dimension(initWidth,0) );
+	}
+
+
+	private void sizeScreen(Dimension d) {
+		width = (int)(d.getWidth()); 
+
+		// find the width of the sequence name
+		FontMetrics fm = getFontMetrics(defaultFont);
+
+		glyphWidth = fm.charWidth('W');
+		glyphHeight = fm.getHeight();
+		
+		
+		// figure out how many multiple alignment rows there will be	
+		int seqAllowedWidth = width - 20 - 2*glyphWidth - nameWidth*glyphWidth - 2*glyphWidth - 20;
+		numCharsAcross = seqAllowedWidth/glyphWidth;
+		
+		if (numCharsAcross > 0){
+			currPaintIndex = -2;
+			paint();
+		}
+
+		revalidate();
+	}
+	
+
+	public void setIndex(int i) {
+		if ( i >= -1 && i < aligns.size() ){
+			index = i;
+			paint();
+		}
+		else
+			System.out.println("invalid index: " + i);
+	}	
+
+	    // The primitive type 'char' in Java acts as an unsigned int taking
+	    // values from 0 to 2^16 (65,536).
+
+    public void paint() {
+	
+	if (index == currPaintIndex)
+	    return;
+	
+	caretToNode = new HashMap<Integer, Integer>();
+	//System.out.println("Starting paint: " + index );
+	String[] seqs = aligns.get(index).getSequences();
+	String[] cols = aligns.get(index).getColors();
+
+		
+	BatchDocument doc = new BatchDocument();
+	Style style = (Style) doc.getStyle(StyleContext.DEFAULT_STYLE);
+	StyleConstants.setFontFamily(style, "Courier");
+	StyleConstants.setBold(style, true);
+	StyleConstants.setFontSize(style, defaultFont.getSize());
+		
+	int pos = 0;
+	int caretPos = 0;
+		
+	while (pos < seqs[0].length()){
+	
+	    for (int i = 0; i < orderedKeys.length; i++ ) {
+		String name = orderedKeys[i];
+		String seq = seqs[i];
+		String colString = cols[i];
+			
+		if ( seq == null )
+		    continue;
+
+		StyleConstants.setForeground(style, Color.black);
+		StyleConstants.setBackground(style, Color.white);
+		doc.appendBatchString(name, style);
+		caretPos += name.length();
+		StyleConstants.setForeground(style, Color.white);
+
+		for(int j = pos; j < pos+numCharsAcross && j < seq.length() ; j++){
+
+		    // get color code
+		    // see Node::getColors() for a description of the encoding used
+		    int colCode = new Integer(colString.charAt(j));
+
+		    if (colored) {
+			// if highlighted
+			if (colCode == 65535) {
+			    StyleConstants.setBackground(style, Color.black);
+			}
+			// if undefined
+			else if (colCode == 256) {
+			    StyleConstants.setBackground(style, Color.lightGray);
+			}
+			// else regular coloration based on accuracy measure
+			else{
+			    StyleConstants.setBackground(style, getColorFromCode(colCode));
+			}
+		    }
+
+		    else {
+		StyleConstants.setForeground(style, Color.black);
+		StyleConstants.setBackground(style, Color.lightGray);
+
+		//			StyleConstants.setBackground(style, Color.lightGray);
+		    }
+
+				
+		    doc.appendBatchString(seq.substring(j,j+1), style);
+					
+		    caretToNode.put(caretPos++, j);
+		}
+		doc.appendBatchLineFeed(style);
+		caretPos++;
+	    }
+	    pos += numCharsAcross;
+	    doc.appendBatchLineFeed(style);
+	    caretPos++;
+	}
+		
+	try{ doc.processBatchUpdates(0);}
+	catch (BadLocationException badLocationException) {System.err.println("Oops");}
+	//System.out.println("Setting document: " + index);
+	this.setStyledDocument(doc);
+	//System.out.println("Finished paint: " + index + "\n");
+		
+	currPaintIndex = index;
+    }
+	
+    public void setColored(boolean colored){
+	this.colored = colored;
+    }
+
+    public Color getColorFromCode(int colCode){
+	if (colCode >= 256){ //Highlighted
+	    return Color.black;
+	}
+	int r = (int)Math.max(Math.round(-0.015564*(colCode-127)*(colCode-382)),0);
+	int g = (int)Math.max(Math.round(-0.015564*(colCode)*(colCode-255)),0);
+	int b = (int)Math.max(Math.round(-0.015564*(colCode+127)*(colCode-127)),0);
+		
+	return new Color(r,g,b);
+    }
+    
+    /// Save the alignment as TIFF.
+    public void saveAsTiff(String filename){
+
+	try {
+
+	    // get the iamge
+	    BufferedImage saveImage = new BufferedImage (this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB);
+	    // paint it
+	    Graphics gc = saveImage.getGraphics();
+	    paint(gc);
+
+	    // Store the image in the TIFF format.
+	    TIFFEncodeParam encodeParam = new TIFFEncodeParam();
+	    //	    encodeParam.setCompression(TIFFEncodeParam.COMPRESSION_DEFLATE);
+
+//	    TIFFField[] extras = new TIFFField[3];
+//	    extras[0] = new TIFFField(282,TIFFField.TIFF_RATIONAL, 1, (Object)new long[][] {{300,(long)1},{(long)0 ,(long)0}});
+//	    extras[1] = new TIFFField(283,TIFFField.TIFF_RATIONAL, 1, (Object)new long[][] {{300,(long)1},{(long)0 ,(long)0}}); // x
+//	    extras[2] = new TIFFField(296, TIFFField.TIFF_SHORT, 1, (Object) new char[] {2}); //2 for inches 	    //y //set resolution unit to inches
+//	    encodeParam.setExtraFields(extras);
+
+//	    final int XRES_TAG = 282;
+//	    final int YRES_TAG = 283;
+//
+//	    int[] resolution = { 300, 1};
+//	    TIFFField xRes = new TIFFField(XRES_TAG, TIFFField.TIFF_RATIONAL, 1, new int[][] { resolution });
+//	    TIFFField yRes = new TIFFField(YRES_TAG, TIFFField.TIFF_RATIONAL, 1, new int[][] { resolution });
+//	    encodeParam.setExtraFields(new TIFFField[] { xRes, yRes});
+
+// above are failed attempts to increase the resolution of the resulting image
+// -- RKB 10/15/08
+
+	    RenderedOp op = JAI.create("filestore", saveImage, filename, "tiff", encodeParam);
+
+	} catch (Exception e) {
+	    System.out.print (e.toString());
+	}
+
+    }
+
+    /// Save the alignment as JPEG.
+    public void saveAsJPEG(String filename){
+	
+        File save_file;
+ 
+         // For encoder
+        BufferedImage saveImage;
+ 
+       
+	try{
+	    FileOutputStream file_out = new FileOutputStream(filename);
+
+	    // get the image
+	    saveImage = new BufferedImage(this.getWidth(), this.getHeight(),
+					   BufferedImage.TYPE_INT_RGB);
+	    // paint it
+	    Graphics gc = saveImage.getGraphics();
+	    paint(gc);
+
+	    float quality = 0.25f;
+	    com.sun.image.codec.jpeg.JPEGEncodeParam encodeParam = JPEGCodec.getDefaultJPEGEncodeParam(saveImage);
+	    encodeParam.setQuality(quality,false);
+
+	    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(file_out, encodeParam);
+	    encoder.encode(saveImage);
+	    System.out.println("Saved frame: " + filename);
+	    file_out.close();
+	}
+	catch(Exception ex)
+	    {System.out.print(ex.toString());}
+    }
+      
+
+
+	public void iResized(){
+		sizeScreen(this.getSize());
+	}
+	
+	public void mouseClicked(MouseEvent e) {
+	
+		Alignment align = aligns.currAlign;
+		int caretPos = this.getCaret().getMark();
+		
+		if (align.gapsSuppressed || !caretToNode.containsKey(caretPos))
+			return;
+			
+		int nodeI = caretToNode.get(caretPos);
+
+		Node v = align.L[nodeI];
+		v.setHighlight(!v.highlighted);
+		aligns.currAlign.buildSeqsAndCols(aligns.currAlign.gapsSuppressed, aligns.currAlign.colorScheme);
+		currPaintIndex = -2;
+		paint();
+    }
+    
+    public void mousePressed(MouseEvent e) {}
+    public void mouseReleased(MouseEvent e) {}
+    public void mouseEntered(MouseEvent e) {}
+    public void mouseExited(MouseEvent e) {}
+
+
+
+	
+    public void componentResized(ComponentEvent e) {
+		sizeScreen( e.getComponent().getSize() );
+    }
+
+    public void componentShown(ComponentEvent e) {};
+    public void componentHidden(ComponentEvent e) {};
+    public void componentMoved(ComponentEvent e) {};
+}
diff --git a/display/mad/Alignments.java b/display/mad/Alignments.java
new file mode 100644
index 0000000..4bcafc6
--- /dev/null
+++ b/display/mad/Alignments.java
@@ -0,0 +1,364 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for different accuracy measures was written by Robert Bradley.
+ */
+
+
+package mad;
+
+import java.util.Scanner;
+import java.util.*;
+import java.util.regex.*;
+import java.io.*;
+import java.net.*;
+
+/**
+ * Class Name:	Alignments
+ *
+ * Description: Acts as a wrapper for the DAG to communicate with viewer as if it held a list 
+ * 				of the different alignments.  Also parses and stores data from the log file. 
+ **/
+
+public class Alignments{
+	
+	AlignDAG aDag;
+	Alignment currAlign;
+	Alignment altAlign = null;
+	ProbabilityMatrices probMatrices;
+	int index;
+	int size;
+	int[] seqLengths;
+	String[] sequences;
+
+	public Double[] alignAccs;
+	public Double[] alignSPSs;
+	public Double[] alignPPVs;
+	public Double[] alignCerts;
+	public Double[] alignConss;
+
+        public Double[] alignGFs;
+
+	LinkedList<String> keys;
+	int[][] merges; // Merge is indexed so that the current merge will take you to the next alignment.
+	boolean suppressGaps;
+        int colorScheme;
+	
+	public Alignments(String seqPath, String guiPath, String probPath){
+		suppressGaps = true;
+		colorScheme = 0;
+		loadData(seqPath, guiPath, probPath);
+		makeAccArrays();
+	}
+	
+	public Alignments(String seqPath, String guiPath, String probPath, String altAlignPath){
+		this(seqPath, guiPath, probPath);
+		loadAltAlign(altAlignPath);
+	}
+
+	public int size(){
+		return this.size;
+	}
+	
+	private void loadAltAlign(String altAlignPath){
+		String[] altSeqs = new String[keys.size()];
+		String line;
+		BufferedReader br;
+		
+		try{
+			if (altAlignPath.startsWith("http://")){
+				br = new BufferedReader( new InputStreamReader( (new URL(altAlignPath)).openStream() ));	
+			}
+			else{
+				br = new BufferedReader( new FileReader(altAlignPath) );	
+			}
+			line = br.readLine();
+			while (line != null && line.length() > 0){
+				String key = line.substring(1);
+				int i = keys.indexOf(key);
+				
+				if (i == -1){
+					System.err.println("FATAL ERROR: Alternate alignment key '"+ key +"' does not match FSA alignment.");
+					System.exit(-1);
+				}
+				
+				StringBuffer seq = new StringBuffer("");
+				while ((line = br.readLine()) != null && line.length() > 0 && line.charAt(0) != '>')
+					seq.append(line);
+				altSeqs[i] = seq.toString();
+			}
+		} catch (IOException ioe){
+			ioe.printStackTrace();
+			System.exit(-1);
+		}
+				
+		AlignDAG altDag = new AlignDAG(keys, sequences, altSeqs, probMatrices);
+		this.altAlign = new Alignment(keys, sequences, altDag, suppressGaps, colorScheme);
+	}
+
+	private String firstWord(String s) {
+		int space_pos = s.indexOf(' ');
+		if (space_pos == -1) {
+			return s;
+		} else {
+			return s.substring(0, space_pos);
+		}
+	}
+	
+	private void loadData(String seqPath, String guiPath, String probPath){
+
+		keys = new LinkedList<String>();
+		LinkedList<String> seqs = new LinkedList<String>();
+		LinkedList<int[]> merges = new LinkedList<int[]>();
+		HashMap<String, Integer> initDAG = new HashMap<String, Integer>();
+		String line;
+		BufferedReader br;
+		Scanner scan;
+		
+		
+		String x;
+		String y;
+
+		int i=0;
+		
+		try{
+			if (seqPath.startsWith("http://")){
+				System.out.println("WEB");
+				br = new BufferedReader( new InputStreamReader( (new URL(seqPath)).openStream() ));	
+			}
+			else{
+				br = new BufferedReader( new FileReader(seqPath) );
+			}
+			String key = null;
+			StringBuffer seq = new StringBuffer("");
+			while (true) {
+				line = br.readLine();
+
+				// Check for end of previous sequence
+				if ((line == null || line.startsWith(">")) && key != null) {
+					// Only use the first word of title line as key
+					keys.add(firstWord(key.trim()));
+					String sequence = seq.toString();
+					sequence = sequence.replaceAll("\\s", "");   // remove whitespace
+					sequence = sequence.replaceAll("[-_.]", ""); // remove gaps
+					seqs.add(sequence);
+				}
+
+				// Process next line
+				if (line == null) {
+					// end of file
+					break;
+				} else if (line.startsWith(">")) {
+					// start a new sequence
+					key = line.substring(1);
+					seq.setLength(0);
+				} else {
+					// add to current sequence
+					seq.append(line);
+				}
+			}
+			
+		} catch (IOException ioe){
+			ioe.printStackTrace();
+			System.exit(-1);
+		} 
+		
+				
+		try{
+			if (guiPath.startsWith("http://")){
+				br = new BufferedReader( new InputStreamReader( (new URL(guiPath)).openStream() ));	
+			}
+			else{
+				br = new BufferedReader( new FileReader(guiPath) );
+			}
+			
+			// Skip blank lines and comments.		
+			while ((line = br.readLine()).length() == 0 || line.charAt(0) == ';')
+				continue;
+			
+			// Read nodes.
+			while(line.length() > 0 ){
+				if (line.charAt(0) == ';'){ // Skip comments
+					line = br.readLine();
+					continue;
+				}
+				
+				scan = new Scanner(line);
+				//				scan.findInLine("(\\d+):\\s[(](\\d+),\\s(\\d+)[)]\\s=>\\s(\\d+.\\d+|\\d+)");
+				scan.findInLine("(\\d+):\\s[(](\\d+),\\s(\\d+)[)]");
+		
+				
+     			MatchResult result = scan.match();
+     			i = new Integer(result.group(1));
+				x = result.group(2);
+				y = result.group(3);
+				initDAG.put(x + "." + y, i); // preserve 0-based indexing
+				line = br.readLine();
+
+			}
+			
+	
+			//Skip blank lines and comments
+			while ((line = br.readLine()).length() == 0 || line.charAt(0) == ';')
+				continue;
+			
+			// Read merges
+			while (line != null){
+				scan = new Scanner(line);
+				scan.findInLine("(\\d+)\\s->\\s(\\d+)");
+				MatchResult result = scan.match();
+				int[] merge = {new Integer(result.group(1)), new Integer(result.group(2))};
+				merges.add(merge);
+				line = br.readLine();
+			}
+				
+		} catch (IOException ioe){
+			ioe.printStackTrace();
+			System.exit(-1);
+		}
+				
+		// Read probabilities and set up matrix
+		
+		seqLengths = new int[seqs.size()];
+		Iterator<String> iter = seqs.iterator();
+		i=0;
+		while(iter.hasNext())
+			seqLengths[i++] = iter.next().length();
+		
+		probMatrices = new ProbabilityMatrices(seqLengths);
+		
+		int seq1, seq2;
+		int i1, i2;
+		double prob;
+		
+		
+		try{
+			if (probPath.startsWith("http://")){
+				br = new BufferedReader( new InputStreamReader( (new URL(probPath)).openStream() ));	
+			}
+			else{
+				br = new BufferedReader( new FileReader(probPath) );
+			}
+			while ((line = br.readLine()) != null){
+				if ( line.length() == 0 || line.charAt(0) == ';') // Skip comments and blanks
+					continue;
+				scan = new Scanner(line);
+				// cover case of scientific notation
+				scan.findInLine("[(](\\d+|-\\d+),\\s(\\d+|-\\d+)[)]\\s~\\s[(](\\d+|-\\d+),\\s(\\d+|-\\d+)[)]\\s=>\\s(\\d.\\d+|\\d+)\\*?[e|E]?(-\\d+)?");
+				MatchResult result = scan.match();
+			
+				seq1 = new Integer(result.group(1)).intValue();
+				i1 = new Integer(result.group(2)).intValue();
+				seq2 = new Integer(result.group(3)).intValue();
+				i2 = new Integer(result.group(4)).intValue();
+				prob = new Double(result.group(5)).doubleValue();
+				if (result.group(6) != null) {
+				    Integer exponent = new Integer((String) result.group(6));
+				    prob *= Math.pow(10, (double) exponent);
+				}
+				probMatrices.addElement(seq1, seq2, i1, i2, prob); // preserve 0-based indexing
+				
+				//double testProb = probMatrices.getElement(seq1, seq2, i1, i2);
+				//if (testProb != prob){
+				//	System.err.println("(" + seq1 + ", " + i1 + ") ~ (" + seq2 + ", " + i2 + ") => " + prob + "/" + testProb);
+				//	System.exit(-1);
+				//}
+			}
+		} catch (IOException ioe){
+			ioe.printStackTrace();
+			System.exit(-1);
+		}
+		
+		this.index = 0;
+		this.merges = merges.toArray(new int[0][0]);
+		this.size = this.merges.length+1;
+		this.sequences = seqs.toArray(new String[0]);
+		this.aDag = new AlignDAG(keys, sequences, initDAG, probMatrices);
+	}
+	
+
+    /// Calculate and store Accuracy, SPS, PPV, Certainty and Consistency for all alignments.
+    private void makeAccArrays(){
+	alignAccs = new Double[merges.length + 1];
+	alignSPSs = new Double[merges.length + 1];
+	alignPPVs = new Double[merges.length + 1];
+	alignCerts = new Double[merges.length + 1];
+	alignConss = new Double[merges.length + 1];
+	alignGFs = new Double[merges.length + 1];
+
+	alignAccs[0] = (Double) aDag.getAlignAccNorm();
+	alignSPSs[0] = (Double) aDag.getAlignSPSNorm();
+	alignPPVs[0] = (Double) aDag.getAlignPPVNorm();
+	alignCerts[0] = (Double) aDag.getAlignCertNorm();
+	alignConss[0] = (Double) aDag.getAlignConsNorm();
+	alignGFs[0] = (Double) aDag.getGapFactor();
+	
+	for (int i = 0; i < merges.length; i ++){
+	    next();
+	    alignAccs[i+1] = (Double) aDag.getAlignAccNorm();
+	    alignSPSs[i+1] = (Double) aDag.getAlignSPSNorm();
+	    alignPPVs[i+1] = (Double) aDag.getAlignPPVNorm();
+	    alignCerts[i+1] = (Double) aDag.getAlignCertNorm();
+	    alignConss[i+1] = (Double) aDag.getAlignConsNorm();
+	    alignGFs[i+1] = (Double) aDag.getGapFactor();
+	    //	    System.err.println ("i = " + i + "; acc = " + alignAccs[i+1] + "; sps = " + alignSPSs[i+1] + "; ppv = " + alignPPVs[i+1] + "; cert = " + alignCerts[i+1]);
+	}
+    }
+	
+	public Alignment get(int index){
+				
+		if (index == -1){ // -1 should only be request when an alternate alignment is available
+						  // otherwise the button is disabled
+			return this.altAlign;
+		}
+		
+		if (this.index == index && currAlign != null)
+			return this.currAlign;
+
+		while (this.index < index)
+			next();
+			
+		while (this.index > index)
+			previous();
+
+		currAlign = new Alignment(keys, sequences, aDag, suppressGaps, colorScheme);
+		System.gc();
+		return currAlign;
+	}
+	
+	// Merges with the current index and then increments it.
+	private void next(){
+		aDag.merge(merges[index][0], merges[index][1]);
+		index++;
+	}
+	
+	// Decrements the index and uses the last merge as a demerge.
+        // Tell AlignDAG::demerge about the next-to-last merge as well to lookup the previous gap factor.
+	private void previous(){
+		index --;
+		if (index > 0)
+		    aDag.demerge(merges[index][0], merges[index-1][0]);
+		else
+		    aDag.demerge(merges[index][0], -1);
+	}
+	
+	public void setGapSuppress(boolean val){
+		suppressGaps = val;
+		currAlign = null;
+		if (altAlign != null && altAlign.gapsSuppressed != suppressGaps)
+		    altAlign.buildSeqsAndCols(suppressGaps, colorScheme);
+	}
+
+    /// Set color scheme.
+    public void setColorScheme(int scheme){
+
+	aDag.setColorScheme (scheme);
+
+	this.colorScheme = scheme;
+	currAlign = null;
+	if (altAlign != null && altAlign.colorScheme != scheme)
+	    altAlign.buildSeqsAndCols(suppressGaps, scheme);
+    }
+
+}
diff --git a/display/mad/BatchDocument.java b/display/mad/BatchDocument.java
new file mode 100644
index 0000000..622be58
--- /dev/null
+++ b/display/mad/BatchDocument.java
@@ -0,0 +1,87 @@
+
+/*
+ *  Source code in this file is from
+ *  http://javatechniques.com/blog/faster-jtextpane-text-insertion-part-ii/
+ *  Copyright 2003-2007 - Philip Isenhour.
+ */
+
+
+package mad;
+
+import java.util.ArrayList;
+import javax.swing.text.Element;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.DefaultStyledDocument;
+
+/**
+ * DefaultDocument subclass that supports batching inserts.
+ */
+public class BatchDocument extends DefaultStyledDocument {
+    /**
+     * EOL tag that we re-use when creating ElementSpecs
+     */
+    private static final char[] EOL_ARRAY = { '\n' };
+
+    /**
+     * Batched ElementSpecs
+     */
+    private ArrayList<ElementSpec> batch = null;
+
+    public BatchDocument() {
+        batch = new ArrayList<ElementSpec>();
+    }
+
+    /**
+     * Adds a String (assumed to not contain linefeeds) for
+     * later batch insertion.
+     */
+    public void appendBatchString(String str,
+        AttributeSet a) {
+        // We could synchronize this if multiple threads
+        // would be in here. Since we're trying to boost speed,
+        // we'll leave it off for now.
+
+        // Make a copy of the attributes, since we will hang onto
+        // them indefinitely and the caller might change them
+        // before they are processed.
+        a = a.copyAttributes();
+        char[] chars = str.toCharArray();
+        batch.add(new ElementSpec(
+            a, ElementSpec.ContentType, chars, 0, str.length()));
+    }
+
+    /**
+     * Adds a linefeed for later batch processing
+     */
+    public void appendBatchLineFeed(AttributeSet a) {
+        // See sync notes above. In the interest of speed, this
+        // isn't synchronized.
+
+        // Add a spec with the linefeed characters
+        batch.add(new ElementSpec(
+                a, ElementSpec.ContentType, EOL_ARRAY, 0, 1));
+
+        // Then add attributes for element start/end tags. Ideally
+        // we'd get the attributes for the current position, but we
+        // don't know what those are yet if we have unprocessed
+        // batch inserts. Alternatives would be to get the last
+        // paragraph element (instead of the first), or to process
+        // any batch changes when a linefeed is inserted.
+        Element paragraph = getParagraphElement(0);
+        AttributeSet pattr = paragraph.getAttributes();
+        batch.add(new ElementSpec(null, ElementSpec.EndTagType));
+        batch.add(new ElementSpec(pattr, ElementSpec.StartTagType));
+    }
+
+    public void processBatchUpdates(int offs) throws
+        BadLocationException {
+        // As with insertBatchString, this could be synchronized if
+        // there was a chance multiple threads would be in here.
+        ElementSpec[] inserts = new ElementSpec[batch.size()];
+        batch.toArray(inserts);
+
+        // Process all of the inserts in bulk
+        super.insert(offs, inserts);
+    }
+}
diff --git a/display/mad/JpegImagesToMovie.java b/display/mad/JpegImagesToMovie.java
new file mode 100644
index 0000000..e751d0b
--- /dev/null
+++ b/display/mad/JpegImagesToMovie.java
@@ -0,0 +1,530 @@
+/*
+ * @(#)JpegImagesToMovie.java	1.3 01/03/13
+ *
+ * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
+ * modify and redistribute this software in source and binary code form,
+ * provided that i) this copyright notice and license appear on all copies of
+ * the software; and ii) Licensee does not utilize the software in a manner
+ * which is disparaging to Sun.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+ * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
+ * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
+ * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
+ * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
+ * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
+ * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
+ * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ * This software is not designed or intended for use in on-line control of
+ * aircraft, air traffic, aircraft navigation or aircraft communications; or in
+ * the design, construction, operation or maintenance of any nuclear
+ * facility. Licensee represents and warrants that it will not use or
+ * redistribute the Software for such purposes.
+ */
+
+
+package mad;
+
+import java.io.*;
+import java.util.*;
+import java.awt.Dimension;
+
+import javax.media.*;
+import javax.media.control.*;
+import javax.media.protocol.*;
+import javax.media.protocol.DataSource;
+import javax.media.datasink.*;
+import javax.media.format.VideoFormat;
+
+
+/**
+ * This program takes a list of JPEG image files and convert them into
+ * a QuickTime movie.
+ */
+public class JpegImagesToMovie implements ControllerListener, DataSinkListener {
+
+	public boolean doIt2(int width, int height, int frameRate, Vector inFiles, String outFile){
+			MediaLocator outML = createMediaLocator(outFile);
+			return doIt(width, height, frameRate, inFiles, outML);
+	}
+	
+    public boolean doIt(int width, int height, int frameRate, Vector inFiles, MediaLocator outML) {
+	ImageDataSource ids = new ImageDataSource(width, height, frameRate, inFiles);
+
+	Processor p;
+
+	try {
+	    System.err.println("- create processor for the image datasource ...");
+	    p = Manager.createProcessor(ids);
+	} catch (Exception e) {
+	    System.err.println("Yikes!  Cannot create a processor from the data source.");
+	    return false;
+	}
+
+	p.addControllerListener(this);
+
+	// Put the Processor into configured state so we can set
+	// some processing options on the processor.
+	p.configure();
+	if (!waitForState(p, p.Configured)) {
+	    System.err.println("Failed to configure the processor.");
+	    return false;
+	}
+
+	// Set the output content descriptor to QuickTime. 
+	p.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));
+
+	// Query for the processor for supported formats.
+	// Then set it on the processor.
+	TrackControl tcs[] = p.getTrackControls();
+	Format f[] = tcs[0].getSupportedFormats();
+	if (f == null || f.length <= 0) {
+	    System.err.println("The mux does not support the input format: " + tcs[0].getFormat());
+	    return false;
+	}
+
+	tcs[0].setFormat(f[0]);
+
+	System.err.println("Setting the track format to: " + f[0]);
+
+	// We are done with programming the processor.  Let's just
+	// realize it.
+	p.realize();
+	if (!waitForState(p, p.Realized)) {
+	    System.err.println("Failed to realize the processor.");
+	    return false;
+	}
+
+	// Now, we'll need to create a DataSink.
+	DataSink dsink;
+	if ((dsink = createDataSink(p, outML)) == null) {
+	    System.err.println("Failed to create a DataSink for the given output MediaLocator: " + outML);
+	    return false;
+	}
+
+	dsink.addDataSinkListener(this);
+	fileDone = false;
+
+	System.err.println("start processing...");
+
+	// OK, we can now start the actual transcoding.
+	try {
+	    p.start();
+	    dsink.start();
+	} catch (IOException e) {
+	    System.err.println("IO error during processing");
+	    return false;
+	}
+
+	// Wait for EndOfStream event.
+	waitForFileDone();
+
+	// Cleanup.
+	try {
+	    dsink.close();
+	} catch (Exception e) {}
+	p.removeControllerListener(this);
+
+	System.err.println("...done processing.");
+
+	return true;
+    }
+
+
+    /**
+     * Create the DataSink.
+     */
+    DataSink createDataSink(Processor p, MediaLocator outML) {
+
+	DataSource ds;
+
+	if ((ds = p.getDataOutput()) == null) {
+	    System.err.println("Something is really wrong: the processor does not have an output DataSource");
+	    return null;
+	}
+
+	DataSink dsink;
+
+	try {
+	    System.err.println("- create DataSink for: " + outML);
+	    dsink = Manager.createDataSink(ds, outML);
+	    dsink.open();
+	} catch (Exception e) {
+	    System.err.println("Cannot create the DataSink: " + e);
+	    return null;
+	}
+
+	return dsink;
+    }
+
+
+    Object waitSync = new Object();
+    boolean stateTransitionOK = true;
+
+    /**
+     * Block until the processor has transitioned to the given state.
+     * Return false if the transition failed.
+     */
+    boolean waitForState(Processor p, int state) {
+	synchronized (waitSync) {
+	    try {
+		while (p.getState() < state && stateTransitionOK)
+		    waitSync.wait();
+	    } catch (Exception e) {}
+	}
+	return stateTransitionOK;
+    }
+
+
+    /**
+     * Controller Listener.
+     */
+    public void controllerUpdate(ControllerEvent evt) {
+
+	if (evt instanceof ConfigureCompleteEvent ||
+	    evt instanceof RealizeCompleteEvent ||
+	    evt instanceof PrefetchCompleteEvent) {
+	    synchronized (waitSync) {
+		stateTransitionOK = true;
+		waitSync.notifyAll();
+	    }
+	} else if (evt instanceof ResourceUnavailableEvent) {
+	    synchronized (waitSync) {
+		stateTransitionOK = false;
+		waitSync.notifyAll();
+	    }
+	} else if (evt instanceof EndOfMediaEvent) {
+	    evt.getSourceController().stop();
+	    evt.getSourceController().close();
+	}
+    }
+
+
+    Object waitFileSync = new Object();
+    boolean fileDone = false;
+    boolean fileSuccess = true;
+
+    /**
+     * Block until file writing is done. 
+     */
+    boolean waitForFileDone() {
+	synchronized (waitFileSync) {
+	    try {
+		while (!fileDone)
+		    waitFileSync.wait();
+	    } catch (Exception e) {}
+	}
+	return fileSuccess;
+    }
+
+
+    /**
+     * Event handler for the file writer.
+     */
+    public void dataSinkUpdate(DataSinkEvent evt) {
+
+	if (evt instanceof EndOfStreamEvent) {
+	    synchronized (waitFileSync) {
+		fileDone = true;
+		waitFileSync.notifyAll();
+	    }
+	} else if (evt instanceof DataSinkErrorEvent) {
+	    synchronized (waitFileSync) {
+		fileDone = true;
+		fileSuccess = false;
+		waitFileSync.notifyAll();
+	    }
+	}
+    }
+
+
+    public static void main(String args[]) {
+
+	if (args.length == 0)
+	    prUsage();
+
+	// Parse the arguments.
+	int i = 0;
+	int width = -1, height = -1, frameRate = 1;
+	Vector<String> inputFiles = new Vector<String>();
+	String outputURL = null;
+
+	while (i < args.length) {
+
+	    if (args[i].equals("-w")) {
+		i++;
+		if (i >= args.length)
+		    prUsage();
+		width = new Integer(args[i]).intValue();
+	    } else if (args[i].equals("-h")) {
+		i++;
+		if (i >= args.length)
+		    prUsage();
+		height = new Integer(args[i]).intValue();
+	    } else if (args[i].equals("-f")) {
+		i++;
+		if (i >= args.length)
+		    prUsage();
+		frameRate = new Integer(args[i]).intValue();
+	    } else if (args[i].equals("-o")) {
+		i++;
+		if (i >= args.length)
+		    prUsage();
+		outputURL = args[i];
+	    } else {
+		inputFiles.addElement(args[i]);
+	    }
+	    i++;
+	}
+
+	if (outputURL == null || inputFiles.size() == 0)
+	    prUsage();
+
+	// Check for output file extension.
+	if (!outputURL.endsWith(".mov") && !outputURL.endsWith(".MOV")) {
+	    System.err.println("The output file extension should end with a .mov extension");
+	    prUsage();
+	}
+
+	if (width < 0 || height < 0) {
+	    System.err.println("Please specify the correct image size.");
+	    prUsage();
+	}
+
+	// Check the frame rate.
+	if (frameRate < 1)
+	    frameRate = 1;
+
+	// Generate the output media locators.
+	MediaLocator oml;
+
+	if ((oml = createMediaLocator(outputURL)) == null) {
+	    System.err.println("Cannot build media locator from: " + outputURL);
+	    System.exit(0);
+	}
+
+	JpegImagesToMovie imageToMovie = new JpegImagesToMovie();
+	imageToMovie.doIt(width, height, frameRate, inputFiles, oml);
+
+	System.exit(0);
+    }
+
+    static void prUsage() {
+	System.err.println("Usage: java JpegImagesToMovie -w <width> -h <height> -f <frame rate> -o <output URL> <input JPEG file 1> <input JPEG file 2> ...");
+	System.exit(-1);
+    }
+
+    /**
+     * Create a media locator from the given string.
+     */
+    static MediaLocator createMediaLocator(String url) {
+
+	MediaLocator ml;
+
+	if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
+	    return ml;
+
+	if (url.startsWith(File.separator)) {
+	    if ((ml = new MediaLocator("file:" + url)) != null)
+		return ml;
+	} else {
+	    String file = "file:" + System.getProperty("user.dir") + File.separator + url;
+	    if ((ml = new MediaLocator(file)) != null)
+		return ml;
+	}
+
+	return null;
+    }
+
+
+    ///////////////////////////////////////////////
+    //
+    // Inner classes.
+    ///////////////////////////////////////////////
+
+
+    /**
+     * A DataSource to read from a list of JPEG image files and
+     * turn that into a stream of JMF buffers.
+     * The DataSource is not seekable or positionable.
+     */
+    class ImageDataSource extends PullBufferDataSource {
+
+	ImageSourceStream streams[];
+
+	ImageDataSource(int width, int height, int frameRate, Vector images) {
+	    streams = new ImageSourceStream[1];
+	    streams[0] = new ImageSourceStream(width, height, frameRate, images);
+	}
+
+	public void setLocator(MediaLocator source) {
+	}
+
+	public MediaLocator getLocator() {
+	    return null;
+	}
+
+	/**
+	 * Content type is of RAW since we are sending buffers of video
+	 * frames without a container format.
+	 */
+	public String getContentType() {
+	    return ContentDescriptor.RAW;
+	}
+
+	public void connect() {
+	}
+
+	public void disconnect() {
+	}
+
+	public void start() {
+	}
+
+	public void stop() {
+	}
+
+	/**
+	 * Return the ImageSourceStreams.
+	 */
+	public PullBufferStream[] getStreams() {
+	    return streams;
+	}
+
+	/**
+	 * We could have derived the duration from the number of
+	 * frames and frame rate.  But for the purpose of this program,
+	 * it's not necessary.
+	 */
+	public Time getDuration() {
+	    return DURATION_UNKNOWN;
+	}
+
+	public Object[] getControls() {
+	    return new Object[0];
+	}
+
+	public Object getControl(String type) {
+	    return null;
+	}
+    }
+
+
+    /**
+     * The source stream to go along with ImageDataSource.
+     */
+    class ImageSourceStream implements PullBufferStream {
+
+	Vector images;
+	int width, height;
+	VideoFormat format;
+
+	int nextImage = 0;	// index of the next image to be read.
+	boolean ended = false;
+
+	public ImageSourceStream(int width, int height, int frameRate, Vector images) {
+	    this.width = width;
+	    this.height = height;
+	    this.images = images;
+
+	    format = new VideoFormat(VideoFormat.JPEG,
+				new Dimension(width, height),
+				Format.NOT_SPECIFIED,
+				Format.byteArray,
+				(float)frameRate);
+	}
+
+	/**
+	 * We should never need to block assuming data are read from files.
+	 */
+	public boolean willReadBlock() {
+	    return false;
+	}
+
+	/**
+	 * This is called from the Processor to read a frame worth
+	 * of video data.
+	 */
+ 	public void read(Buffer buf) throws IOException {
+
+	    // Check if we've finished all the frames.
+	    if (nextImage >= images.size()) {
+		// We are done.  Set EndOfMedia.
+		System.err.println("Done reading all images.");
+		buf.setEOM(true);
+		buf.setOffset(0);
+		buf.setLength(0);
+		ended = true;
+		return;
+	    }
+
+	    String imageFile = (String)images.elementAt(nextImage);
+	    nextImage++;
+
+	    System.err.println("  - reading image file: " + imageFile);
+
+	    // Open a random access file for the next image. 
+	    RandomAccessFile raFile;
+	    raFile = new RandomAccessFile(imageFile, "r");
+
+	    byte data[] = null;
+
+	    // Check the input buffer type & size.
+
+	    if (buf.getData() instanceof byte[])
+		data = (byte[])buf.getData();
+
+	    // Check to see the given buffer is big enough for the frame.
+	    if (data == null || data.length < raFile.length()) {
+		data = new byte[(int)raFile.length()];
+		buf.setData(data);
+	    }
+
+	    // Read the entire JPEG image from the file.
+	    raFile.readFully(data, 0, (int)raFile.length());
+
+	    System.err.println("    read " + raFile.length() + " bytes.");
+
+	    buf.setOffset(0);
+	    buf.setLength((int)raFile.length());
+	    buf.setFormat(format);
+	    buf.setFlags(buf.getFlags() | buf.FLAG_KEY_FRAME);
+
+	    // Close the random access file.
+	    raFile.close();
+	}
+
+	/**
+	 * Return the format of each video frame.  That will be JPEG.
+	 */
+	public Format getFormat() {
+	    return format;
+	}
+
+	public ContentDescriptor getContentDescriptor() {
+	    return new ContentDescriptor(ContentDescriptor.RAW);
+	}
+
+	public long getContentLength() {
+	    return 0;
+	}
+
+	public boolean endOfStream() {
+	    return ended;
+	}
+
+	public Object[] getControls() {
+	    return new Object[0];
+	}
+
+	public Object getControl(String type) {
+	    return null;
+	}
+    }
+}
diff --git a/display/mad/MAD.java b/display/mad/MAD.java
new file mode 100644
index 0000000..86ec5f8
--- /dev/null
+++ b/display/mad/MAD.java
@@ -0,0 +1,67 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot and Adam Roberts.
+ */
+
+package mad;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import java.awt.Dimension;
+
+public class MAD{
+	
+	public static void main(String[] args){
+		
+		System.out.print("Reading data and building structures...");
+		try {
+			Alignments aligns = null;
+			String fsaFile = "";
+			String altFile = "";
+			if (args.length == 1){
+				fsaFile = args[0];
+				aligns = new Alignments(fsaFile, fsaFile + ".gui", fsaFile + ".probs");
+				
+			} else if (args.length == 2){
+				fsaFile = args[0];
+				altFile = args[1];
+				aligns = new Alignments(fsaFile, fsaFile + ".gui", fsaFile + ".probs", altFile);
+			} else{
+				System.out.println("USAGE: java -jar MAD.jar sequencefile [alternatealignfile]");
+				System.exit(1);
+			}
+			
+			System.out.println("done");
+
+        	final JFrame frame = new JFrame("Multiple Alignment Display: " + args[0] + "  (FSA alignment)");
+        	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        	MadPanel panel = new MadPanel(frame, aligns, fsaFile, altFile);
+        	panel.setPreferredSize( new Dimension(900,700) );
+
+			JMenuBar menuBar = new JMenuBar();
+			JMenu fileMenu = new JMenu("File");
+			menuBar.add(fileMenu);
+			JMenuItem saveAsFasta = new JMenuItem( new SaveAsFastaAction(panel) );
+			JMenuItem saveAsTiff = new JMenuItem( new SaveAsTiffAction(panel) );
+			JMenuItem saveAsMov = new JMenuItem(new SaveAsMovAction(panel) );
+			fileMenu.add(saveAsFasta);
+			fileMenu.add(saveAsTiff);
+			fileMenu.add(saveAsMov);
+			frame.setJMenuBar(menuBar);
+
+
+        	//Display the window.
+        	frame.setContentPane(panel);
+        	frame.pack();
+        	frame.setVisible(true);
+        	
+        	
+		} catch (Exception ioe) {
+			ioe.printStackTrace();
+		}
+
+	}
+}
diff --git a/display/mad/MadApplet.java b/display/mad/MadApplet.java
new file mode 100644
index 0000000..5ae8f9b
--- /dev/null
+++ b/display/mad/MadApplet.java
@@ -0,0 +1,37 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ */
+
+package mad;
+
+import java.io.*;
+import java.util.*;
+import javax.swing.*;
+import java.applet.*;
+import java.awt.Dimension;
+
+public class MadApplet extends JApplet{
+	public void init() {
+	  	System.out.println("Applet initializing");
+		String fsaFile = getParameter("fsaFile");
+		Alignments aligns = new Alignments(fsaFile, fsaFile + ".gui", fsaFile + ".probs");
+	  	MadPanel panel = new MadPanel(aligns, fsaFile, "");
+		panel.setPreferredSize( new Dimension(900,700) );
+		getContentPane().add(panel);
+	}
+
+	public void start() {
+		System.out.println("Applet starting");
+	}
+	public void stop() {
+		System.out.println("Applet stopping");
+	}
+
+	public void destroy() {
+		System.out.println("Applet destroyed");
+	}
+
+	
+}
diff --git a/display/mad/MadPanel.java b/display/mad/MadPanel.java
new file mode 100644
index 0000000..0d97ceb
--- /dev/null
+++ b/display/mad/MadPanel.java
@@ -0,0 +1,792 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot and Adam Roberts.
+ *  Code for different accuracy measures was written by Robert Bradley.
+ */
+
+// to do:
+
+
+package mad;
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.NumberFormatter;
+import java.beans.*;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Vector;
+import java.util.Iterator;
+
+
+import java.io.File;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+
+import java.net.URL;
+
+
+public class MadPanel extends JPanel 
+    implements ChangeListener, PropertyChangeListener, ActionListener, ItemListener {
+
+    AlignmentPanel alignPanel;
+    JFormattedTextField indexField;
+    JLabel legLabel;
+    JFormattedTextField accField;
+
+    JLabel accLabel;
+    JLabel dAccLabel;
+
+    JLabel gfLabel;
+    JFormattedTextField gfField;
+
+    JSlider alignSlider;
+    JSlider zoomSlider;
+    Alignments aligns;
+    JButton nextButton;
+    JButton prevButton;
+    JButton startStopButton;
+    JButton altAlignButton;
+    JCheckBox gapSuppressCheck;
+    JFrame parent = null;
+    
+    JCheckBox coloredCheck;
+    JComboBox colorSchemes;
+    String[] colorSchemesList;
+    String[] colorSchemesLabels;
+    
+    String fsaPath, altPath;
+    
+    int maxSliderVal;
+    Map<Component,Boolean> ok2update;
+    Timer timer;
+    boolean frozen = true;
+    int delay = 100;
+
+    boolean inAlt = false;
+	
+
+    public MadPanel(JFrame parent, Alignments aligns, String fsaPath, String altPath){
+    	this(aligns, fsaPath, altPath);
+    	this.parent = parent;
+
+    }
+    public MadPanel(Alignments aligns, String fsaPath, String altPath) {
+
+	this.aligns = aligns;
+	this.fsaPath = fsaPath;
+	this.altPath = altPath;
+		
+	maxSliderVal = aligns.size()-1;
+
+	ok2update = new HashMap<Component,Boolean>();
+
+        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+
+	// set up animation timer
+	timer = new Timer(delay,this);
+	timer.setCoalesce(true);
+
+        //Create the label.
+        JLabel sliderLabel = new JLabel("Alignment: ", JLabel.CENTER);
+        sliderLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+
+        //Create the alignment number field 
+        java.text.NumberFormat intFormat = java.text.NumberFormat.getIntegerInstance();
+        NumberFormatter intFormatter = new NumberFormatter(intFormat);
+        intFormatter.setMinimum(new Integer(0));
+        intFormatter.setMaximum(new Integer(maxSliderVal));
+        indexField = new JFormattedTextField(intFormatter);
+        indexField.setColumns(4); //get some space
+        indexField.addPropertyChangeListener( this ); 
+	handleEnterKeyStroke( indexField );
+	ok2update.put(indexField,false);
+
+        accLabel = new JLabel("Accuracy: ", JLabel.CENTER);
+       	dAccLabel = new JLabel("\u0394 Accuracy: ", JLabel.CENTER);
+       	gfLabel = new JLabel("Gap Factor: ", JLabel.CENTER);
+
+        //Create the alignment acc field 
+        java.text.NumberFormat numFormat = java.text.NumberFormat.getNumberInstance();
+        NumberFormatter numFormatter = new NumberFormatter(numFormat);
+        numFormatter.setMinimum(new Float(0f));
+        numFormatter.setMaximum(new Float(Float.MAX_VALUE));
+        accField = new JFormattedTextField(numFormatter);
+        accField.setColumns(4); //get some space
+        accField.addPropertyChangeListener( this ); 
+	handleEnterKeyStroke( accField );
+	ok2update.put(accField,false);
+
+        //Create the alignment acc field 
+        java.text.NumberFormat numFormat2 = java.text.NumberFormat.getNumberInstance();
+        NumberFormatter numFormatter2 = new NumberFormatter(numFormat);
+        numFormatter2.setMinimum(new Float(0f));
+        numFormatter2.setMaximum(new Float(Float.MAX_VALUE));
+        gfField = new JFormattedTextField(numFormatter2);
+        gfField.setColumns(4); //get some space
+        gfField.addPropertyChangeListener( this ); 
+	handleEnterKeyStroke( gfField );
+	ok2update.put(gfField,false);
+
+	// create next button
+	nextButton = new JButton("Next");
+	nextButton.addActionListener(this);
+
+	startStopButton = new JButton("Start Animation");
+	startStopButton.addActionListener(this);
+
+	// create prev button
+	prevButton = new JButton("Prev");
+	prevButton.addActionListener(this);
+
+	// create alternate alignment button
+	altAlignButton = new JButton("Alt Alignment");
+	altAlignButton.addActionListener(this);
+	altAlignButton.setEnabled(aligns.altAlign != null);
+
+        //Create the sliders.
+        alignSlider = new JSlider(JSlider.HORIZONTAL, 0, maxSliderVal, 0);
+        alignSlider.addChangeListener(this);
+        zoomSlider = new JSlider(JSlider.VERTICAL, 0, 20, 10);
+        zoomSlider.addChangeListener(this);
+
+        //Turn on labels at major tick marks.
+        alignSlider.setMajorTickSpacing(calcTickSpacing(maxSliderVal));
+        alignSlider.setPaintTicks(true);
+        alignSlider.setPaintLabels(true);
+
+	//Create gap suppression checkbox
+	gapSuppressCheck = new JCheckBox("Gap Suppression", true);
+	gapSuppressCheck.addItemListener(this);
+
+        //Create the panel that displays the animation.
+        alignPanel = new AlignmentPanel(aligns,450,true);
+        alignPanel.setBorder(BorderFactory.createCompoundBorder(
+								BorderFactory.createLoweredBevelBorder(),
+								BorderFactory.createEmptyBorder(10,10,10,10)));
+
+	// set up scrolling
+	JScrollPane alignScroll = new JScrollPane(alignPanel);
+	alignScroll.setPreferredSize(new Dimension(500,800));
+	alignScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+	alignScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+	alignScroll.addComponentListener(alignPanel);
+
+	// Set up zoompanel
+	JLabel plusLabel = new JLabel("+", JLabel.CENTER);
+	plusLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+	JLabel minusLabel = new JLabel("-", JLabel.CENTER);
+	minusLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
+	JPanel zoomPanel = new JPanel();
+	zoomPanel.setLayout(new BoxLayout(zoomPanel, BoxLayout.Y_AXIS));
+	zoomPanel.add(plusLabel);
+	zoomPanel.add(zoomSlider);
+	zoomPanel.add(minusLabel);
+		
+	JPanel alignAndZoom = new JPanel(new BorderLayout());
+	alignAndZoom.add(zoomPanel,BorderLayout.LINE_START);
+	alignAndZoom.add(alignScroll,BorderLayout.CENTER);
+
+	// create colorin checkbox
+	coloredCheck = new JCheckBox("Coloring", true);
+	coloredCheck.addItemListener(this);
+
+	// set up color schemes	
+	colorSchemesList = new String[5];
+	colorSchemesList[0] = "Accuracy";
+	colorSchemesList[1] = "Sensitivity";
+	colorSchemesList[2] = "Specificity";
+	colorSchemesList[3] = "Certainty";
+	colorSchemesList[4] = "Consistency";
+
+	colorSchemesLabels = new String[5];
+	colorSchemesLabels[0] = "Low Accuracy                   High Accuracy";
+	colorSchemesLabels[1] = "Low Sensitivity               High Sensitivity";
+	colorSchemesLabels[2] = "Low Specificity               High Specificity";
+	colorSchemesLabels[3] = "Low Certainty                   High Certainty";
+	colorSchemesLabels[4] = "Low Consistency          High Consistency";
+
+	colorSchemes = new JComboBox(colorSchemesList);
+	colorSchemes.setSelectedIndex(0);
+	colorSchemes.addActionListener(this);
+
+	//Create legend
+	URL imgURL = getClass().getResource("legend.jpg");
+	ImageIcon legIcon = new ImageIcon(imgURL);
+	legLabel = new JLabel("Low Accuracy                   High Accuracy", legIcon, JLabel.CENTER);
+	legLabel.setVerticalTextPosition(JLabel.BOTTOM);
+	legLabel.setHorizontalTextPosition(JLabel.CENTER);
+	legLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
+
+        // Create a subpanel for the label and text field.
+        JPanel labelAndTextField = new JPanel(); //use FlowLayout
+	labelAndTextField.add(colorSchemes);
+	labelAndTextField.add(Box.createRigidArea(new Dimension(20,0)));
+	labelAndTextField.add(legLabel);
+	labelAndTextField.add(Box.createRigidArea(new Dimension(20,0)));
+	labelAndTextField.add(accLabel);
+	labelAndTextField.add(accField);
+	labelAndTextField.add(Box.createRigidArea(new Dimension(10,0)));
+	labelAndTextField.add(dAccLabel);
+	labelAndTextField.add(Box.createRigidArea(new Dimension(20,0)));
+	labelAndTextField.add(gfLabel);
+	labelAndTextField.add(gfField);
+	labelAndTextField.add(Box.createRigidArea(new Dimension(20,0)));
+        labelAndTextField.add(sliderLabel);
+        labelAndTextField.add(indexField);
+
+	JPanel controlPane = new JPanel();
+	controlPane.add(prevButton);
+	controlPane.add(startStopButton);
+	controlPane.add(nextButton);
+	controlPane.add(altAlignButton);
+	controlPane.add(coloredCheck);
+	controlPane.add(gapSuppressCheck);
+
+        // Put everything together.
+	// The order in which these are added CANNOT be changed without
+	// also changing the indexing in actionPerformed().
+        add(alignAndZoom);
+        add(Box.createRigidArea(new Dimension(0, 10)));
+        add(labelAndTextField);
+        add(alignSlider);
+        add(controlPane);
+        setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
+
+	update(maxSliderVal);
+    }
+
+    // Catch changes to sliders
+    public void stateChanged(ChangeEvent e) {
+    	
+        JSlider source = (JSlider)e.getSource();
+	if ( source == alignSlider && (boolean) ok2update.get(alignSlider)){
+	    update((int)alignSlider.getValue());
+	}
+	else if (source == zoomSlider){
+	    alignPanel.defaultFont = alignPanel.defaultFont.deriveFont(1 + (float)zoomSlider.getValue());
+	    alignPanel.iResized();
+	    //repaint();
+	}
+    }
+
+    // Changes the alignment frame
+    private void update(int index) {
+	Alignment align = aligns.get(index);
+	updatePicture(index);
+	ok2update.put(alignSlider, false);
+	alignSlider.setValue(index);
+	ok2update.put(alignSlider, true);
+	indexField.setText(Integer.toString(index));
+
+	// update accuracy field
+	accField.setText(getAccFieldString(align));
+	
+	// update delta accuracy field
+	dAccLabel.setText(getDeltaAccFieldString(align, index));
+
+	// update gap factor field
+	gfField.setText(getGapFactorFieldString(align, index));
+    }
+
+    /// Get value for the accuracy field (varies based on color scheme).
+    private String getAccFieldString(Alignment align){
+
+	// displayed value depends on the chosen color scheme
+	double accFieldValue = 0;
+	switch (align.colorScheme) {
+	case 0: // Accuracy
+	    accFieldValue = align.getAccNorm();
+	    break;
+	case 1: // SPS
+	    accFieldValue = align.getSPSNorm();
+	    break;
+	case 2: // PPV
+	    accFieldValue = align.getPPVNorm();
+	    break;
+	case 3: // Certainty
+	    accFieldValue = align.getCertNorm();
+	    break;
+	case 4: // Consistency
+	    accFieldValue = align.getConsNorm();
+	    break;
+	default:
+	    System.exit(1);
+	}
+
+	// test for undefined value
+	// (-1 is returned if undefined)
+	if (accFieldValue < 0)
+	    return "Undefined";
+	else {
+	    accFieldValue = Math.rint(accFieldValue*10000)/10000;
+	    return Double.toString(accFieldValue);
+	}
+
+    }
+
+    /// Get value for the delta accuracy field (varies based on color scheme).
+    /*
+     * @param index index of the alignment
+     * \return 0 if first alignment, N/A if alternate alignment and delta accuracy otherwise
+     */
+    private String getDeltaAccFieldString(Alignment align, int index){
+
+	// displayed value depends on the chosen color scheme
+	double delta = 0;
+	switch (align.colorScheme) {
+	case 0: // Accuracy
+	    delta = align.getDeltaAccNorm();
+	    break;
+	case 1: // SPS
+	    delta = align.getDeltaSPSNorm();
+	    break;
+	case 2: // PPV
+	    delta = align.getDeltaPPVNorm();
+	    break;
+	case 3: // Certainty
+	    delta = align.getDeltaCertNorm();
+	    break;
+	case 4: // Consistency
+	    delta = align.getDeltaConsNorm();
+	    break;
+	default:
+	    System.exit(1);
+	}
+
+	// handle case of first alignment
+	if (index == 0)
+	    delta = 0;
+
+	// now format nicely
+	NumberFormat formatter;			
+	if (delta < 0)
+	    formatter = new DecimalFormat("#0.0000");
+	else
+	    formatter = new DecimalFormat("  #0.0000");
+
+	String entry = "\u0394 Column " + colorSchemesList[align.colorScheme] + ": " + formatter.format(delta);
+
+	// handle case of alternate alignment
+	if (index == -1)
+	    entry = "\u0394 Column " + colorSchemesList[align.colorScheme] + ":    N/A     ";
+
+	return entry;
+    }
+
+    /// Get value for the gap factor field.
+    /*
+     * @param index index of the alignment
+     * \return Infinity if first alignment, N/A if alternate alignment and implicit gap factor otherwise
+     */
+    private String getGapFactorFieldString(Alignment align, int index){
+
+	double gf = align.getGapFactor();
+	gf = Math.rint(gf * 10)/10;
+
+	String entry;
+	// handle case of alternate alignment
+	if (index == -1)
+	    return "N/A";
+	// handle case of big gap factor
+	else if (gf > 100 || gf < 0)
+	    return ">100";
+	else
+	    return Double.toString(gf);
+
+    }
+
+    // Switch between alternate alignment and FSA alignment
+    private void toggleAltAlign(boolean toAlt){
+	if (toAlt){
+	    inAlt = true;
+
+	    Alignment align = aligns.get(-1);
+	    indexField.setText("ALT");
+	    updatePicture(-1);
+
+	    // update accuracy field
+	    accField.setText(getAccFieldString(align));
+
+	    // update delta accuracy field
+	    dAccLabel.setText(getDeltaAccFieldString(align, -1));
+
+	    // update gap factor field
+	    gfField.setText(getGapFactorFieldString(align, -1));
+
+	    altAlignButton.setText("FSA Alignment");
+	    if (parent != null)
+		parent.setTitle("Multiple Alignment Display: " + altPath + "  (Alternate alignment)");
+	} else{
+	    inAlt = false;
+
+	    update((int)alignSlider.getValue());
+	    altAlignButton.setText("Alt Alignment");
+	    if (parent != null)
+		parent.setTitle("Multiple Alignment Display: " + fsaPath + "  (FSA alignment)");
+	}
+
+	prevButton.setEnabled(!toAlt);
+	nextButton.setEnabled(!toAlt);
+	startStopButton.setEnabled(!toAlt);
+	accField.setEnabled(!toAlt);
+	gfField.setEnabled(!toAlt);
+	indexField.setEnabled(!toAlt);
+	alignSlider.setEnabled(!toAlt);
+	
+    }
+
+    // Catch changes to text boxes
+    public void propertyChange(PropertyChangeEvent e) {
+       	if (!"value".equals(e.getPropertyName())) 
+	    return;
+
+	// alignment index field
+	if ( e.getSource() == indexField && ok2update.get(indexField) ) {
+	    Number value = (Number)e.getNewValue();
+	    if (value != null) {
+		update(value.intValue());
+		ok2update.put(indexField,false);
+	    }
+	}
+
+	// accuracy field
+	else if ( e.getSource() == accField && ok2update.get(accField) ) {
+	    //	    Float acc = (Float) e.getNewValue();
+	    int index = -1;
+	    int scheme = colorSchemes.getSelectedIndex();
+	    switch (scheme) {
+	    case 0:
+		index = getIndexFromAcc ((Float)e.getNewValue());
+		break;
+	    case 1:
+		index = getIndexFromSPS ((Float)e.getNewValue());
+		break;
+	    case 2:
+		index = getIndexFromPPV ((Float)e.getNewValue());
+		break;
+	    case 3:
+		index = getIndexFromCert ((Float)e.getNewValue());
+		break;
+	    case 4:
+		index = getIndexFromCons ((Float)e.getNewValue());
+		break;
+	    default:
+		System.exit(1);
+	    }
+
+	    // if runs off the left, go to first alignment
+	    if (index < 0) {
+		update(0);
+		ok2update.put(accField, false);
+	    }
+	    // else go to the requested alignment
+	    else if (index >= 0 && index <= maxSliderVal) {
+		update(index);
+		ok2update.put(accField ,false);
+	    } 
+	}
+
+	// gap factor field
+	else if ( e.getSource() == gfField && (boolean) ok2update.get(gfField) ) {
+
+	    int index = getIndexFromGF ((Float)e.getNewValue());
+
+	    // if runs off the left, go to first alignment
+	    if (index < 0) {
+		update(0);
+		ok2update.put(gfField, false);
+	    }
+	    // else go to the requested alignment
+	    else if (index >= 0 && index <= maxSliderVal) {
+		update(index);
+		ok2update.put(gfField ,false);
+	    } 
+	}
+
+    }
+
+    // Catch button clicks and timer
+    public void actionPerformed(ActionEvent e) {
+
+	int curr = !inAlt ? (int)alignSlider.getValue() : -1;
+
+	// next alignment
+	if ( e.getSource() == nextButton) {
+	    if ( curr == maxSliderVal )
+		update(0);
+	    else
+		update(curr+1);
+	}
+
+	// timer
+	else if (e.getSource() == timer){
+	    if (curr == maxSliderVal ){
+		timer.stop();
+		frozen = true;
+		startStopButton.setText("Start Animation");
+	    }
+	    else
+		update(curr+1);		
+	}
+	// previous alignment
+	else if ( e.getSource() == prevButton ) {
+	    if ( curr == 0 )
+		update(maxSliderVal);
+	    else
+		update(curr-1);			
+	}
+	// start/stop animation
+	else if ( e.getSource() == startStopButton ) {
+	    if ( frozen ) {
+		if (curr == maxSliderVal)
+		    update(0);
+		timer.start();
+		startStopButton.setText("Stop Animation");
+		altAlignButton.setEnabled(false);
+	    } else {
+		timer.stop();
+		startStopButton.setText("Start Animation");
+		if (aligns.altAlign != null)
+		    altAlignButton.setEnabled(true);
+	    }
+	    frozen = !frozen;
+	}
+	// alternate alignment
+	else if ( e.getSource() == altAlignButton ) {
+	    toggleAltAlign(altAlignButton.getText() == "Alt Alignment");			
+	}
+	// color schemes
+	else if ( e.getSource() == colorSchemes ){
+
+	    JComboBox cb = (JComboBox)e.getSource();
+
+	    // get the integer index of the color scheme
+	    int scheme = cb.getSelectedIndex();
+
+	    // update the color scheme
+	    aligns.setColorScheme(scheme);
+
+	    // update the legend label
+	    legLabel.setText(colorSchemesLabels[scheme]);
+
+	    // update the accuracy field label
+	    accLabel.setText(colorSchemesList[scheme] + ": ");
+
+	    // to do: this needs to check whether in the alternate alignment;
+	    // currently uses curr, which is always the FSA alignment
+	    // (not updated properly for alternate alignment)
+
+	    // update accuracy field value
+	    // NB aligns.get(curr) returns the current Alignment object
+	    accField.setText(getAccFieldString(aligns.get(curr)));
+
+	    // update the delta accuracy label
+	    dAccLabel.setText(getDeltaAccFieldString(aligns.get(curr), curr));
+
+	    // update the gap factor label
+	    gfField.setText(getGapFactorFieldString(aligns.get(curr), curr));
+
+	    // redraw the panel
+	    alignPanel.iResized();
+	}
+
+    }
+
+    // Catch check box change
+    public void itemStateChanged(ItemEvent e) {
+	
+	Object source = e.getItemSelectable();
+
+	// colored
+	if (source == coloredCheck){
+	    if (e.getStateChange() == ItemEvent.DESELECTED) 
+		alignPanel.setColored(false);
+	    else
+		alignPanel.setColored(true);
+	    alignPanel.iResized();
+	}
+
+	// gap suppression
+	else if (source == gapSuppressCheck){
+	    if (e.getStateChange() == ItemEvent.DESELECTED) 
+		aligns.setGapSuppress(false);
+	    else
+		aligns.setGapSuppress(true);
+	    alignPanel.iResized();
+	    //repaint();
+	}
+	    
+    }
+
+
+	public void alignmentToMov(){
+		
+		// Get save path for movie file.
+		FileDialog chooseFile = new FileDialog(new Frame(), "Export as Quicktime Movie", FileDialog.SAVE);
+		chooseFile.setVisible(true);
+		String movFile = chooseFile.getFile();
+		if (movFile == null)
+			return;
+		if (!movFile.endsWith(".mov"))
+			movFile = movFile.concat(".mov");
+		String dirPath = chooseFile.getDirectory();
+		String movPath = dirPath + movFile;
+		
+		Vector<String> files = new Vector<String>();
+		String fName;
+			
+		
+		// Ceate JPEGs
+		for (int i = 0; i < aligns.size(); i++){
+			update(i);
+			fName = String.format(dirPath + "/%08d.jpg",i);
+			files.add(fName);
+			alignPanel.saveAsJPEG(fName);
+		}
+		
+		// Create movie
+		JpegImagesToMovie imageToMovie = new JpegImagesToMovie();
+		imageToMovie.doIt2(alignPanel.getWidth(), alignPanel.getHeight(), 5, files, movPath);
+
+		// Delete temporary JPEGs
+		Iterator iter = files.iterator();
+		while (iter.hasNext()){
+			fName = (String) iter.next();
+			(new File(fName)).delete();
+		}
+	}
+	
+    protected void updatePicture(int frameNum) {
+	alignPanel.setIndex(frameNum);
+    }
+
+    protected int calcTickSpacing(int val) {
+	return ((val/10) - (val%10));
+    }
+
+    /// Get index for the alignment with specified accuracy.
+    private int getIndexFromAcc(Float a) {
+	int index = -1;
+	double minDiff = (double) Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignAccs.length; i++){
+	    diff = Math.abs(aligns.alignAccs[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+    /// Get index for the alignment with specified SPS.
+    private int getIndexFromSPS(Float a) {
+	int index = -1;
+	double minDiff = Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignSPSs.length; i++){
+	    diff = Math.abs(aligns.alignSPSs[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+    /// Get index for the alignment with specified PPV.
+    private int getIndexFromPPV(Float a) {
+	int index = -1;
+	double minDiff = Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignPPVs.length; i++){
+	    diff = Math.abs(aligns.alignPPVs[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+    /// Get index for the alignment with specified Certainty.
+    private int getIndexFromCert(Float a) {
+	int index = -1;
+	double minDiff = Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignCerts.length; i++){
+	    diff = Math.abs(aligns.alignCerts[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+    /// Get index for the alignment with specified Consistency.
+    private int getIndexFromCons(Float a) {
+	int index = -1;
+	double minDiff = Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignConss.length; i++){
+	    diff = Math.abs(aligns.alignConss[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+    /// Get index for the alignment with specified gap factor.
+    private int getIndexFromGF(Float a) {
+	int index = -1;
+	double minDiff = Double.MAX_VALUE;
+	double diff;
+ 		
+	for (int i = 0; i < aligns.alignGFs.length; i++){
+	    diff = Math.abs(aligns.alignGFs[i].doubleValue() - a);
+	    if (diff < minDiff){
+		minDiff = diff;
+		index = i;
+	    }
+	}
+ 		
+	return index;
+    }
+
+
+	//React when the user presses Enter.
+	private void handleEnterKeyStroke( final JFormattedTextField field ) {
+        field.getInputMap().put(KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0), "check");
+        field.getActionMap().put("check", new AbstractAction() {
+            public void actionPerformed(ActionEvent e) {
+				//The text is invalid.
+                if (!field.isEditValid()) { 
+                    Toolkit.getDefaultToolkit().beep();
+                    field.selectAll();
+				//The text is valid, so use it.
+                } else try {
+					ok2update.put(field,true);
+                    field.commitEdit();     
+                } catch (java.text.ParseException exc) { }
+            }
+        });
+	}
+}
+
diff --git a/display/mad/Node.java b/display/mad/Node.java
new file mode 100644
index 0000000..4879953
--- /dev/null
+++ b/display/mad/Node.java
@@ -0,0 +1,618 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for different accuracy measures was written by Robert Bradley.
+ */
+
+
+// to do:
+
+
+package mad;
+
+import java.util.*;
+
+//import it.unimi.dsi.fastutil.objects.*;
+
+public class Node{
+    
+    private int[] seqVals;// Indices of position in each sequence contained in node
+    private char[] colors;
+    public int seqI; 		// If an initial node, what sequence I contain (useful for gap fills).
+    public int seqVal;
+    public int numSeqs;
+    
+    public double acc;
+    public double sps;
+    public double ppv;
+    public double cert;
+    public double cons;
+
+    public double accDenom;
+    public double spsDenom;
+    public double ppvDenom;
+    public double certDenom;
+    public double consDenom;
+
+    public double weightTgf;
+
+    public Node fwdEdge;
+    public boolean highlighted = false;
+
+    public int mergeOrder;
+
+    /* 
+     * 0 = Accuracy
+     * 1 = Sensitivity
+     * 2 = Specificity
+     * 3 = Certainty
+     * 4 = Consistency
+     */ 
+    public int colorScheme;
+
+    // Used for a merged node
+    public boolean isMerge;
+    public Node n1;
+    public Node n2;
+    
+    // Used for topological sort (DFS)
+    public int finishTime; 	
+    public boolean visited;   
+    
+    public ProbabilityMatrices pm; // allows access to probabilities to calculate accurcy
+    
+    public Node(int seqI, int seqVal, ProbabilityMatrices pm){
+        this.seqVal = seqVal;
+        this.seqI = seqI;
+        this.pm = pm;
+        this.isMerge = false;
+
+	this.acc = -1;
+	this.sps = -1;
+	this.ppv = -1;
+	this.cert = -1;
+	this.cons = -1;
+
+	this.accDenom = -1;
+	this.spsDenom = -1;
+	this.ppvDenom = -1;
+	this.certDenom = -1;
+	this.consDenom = -1;
+
+	this.weightTgf = -1;
+	this.mergeOrder = -1;
+
+     }
+         
+    public Node(int[] seqVals, int seqI, ProbabilityMatrices pm){
+        this.seqVals = seqVals;
+        this.seqI = seqI;
+        this.pm = pm;
+        this.isMerge = false;
+
+	this.acc = -1;
+	this.sps = -1;
+	this.ppv = -1;
+	this.cert = -1;
+	this.cons = -1;
+
+	this.accDenom = -1;
+	this.spsDenom = -1;
+	this.ppvDenom = -1;
+	this.certDenom = -1;
+	this.consDenom = -1;
+
+	this.weightTgf = -1;
+	this.mergeOrder = -1;
+
+     }
+    
+    public Node(Node n1, Node n2, int mergeOrder){
+
+        this.n1 = n1;
+        this.n2 = n2;
+        this.pm = n1.pm;
+        this.isMerge = true;
+
+	this.acc = -1;
+	this.sps = -1;
+	this.ppv = -1;
+	this.cert = -1;
+	this.cons = -1;
+
+	this.accDenom = -1;
+	this.spsDenom = -1;
+	this.ppvDenom = -1;
+	this.certDenom = -1;
+	this.consDenom = -1;
+
+	this.weightTgf = calcWeightTgf (n1, n2);
+	this.mergeOrder = mergeOrder;
+
+        mergeNodes();
+    }
+    
+  
+    private void mergeNodes(){
+// 		int[] s1 = n1.seqIndices;
+//     	int[] s2 = n2.seqIndices;
+//     		
+//     	seqIndices = new int[s1.length];
+//     	
+//     	//Merge columns.
+//     	for (int i = 0; i < s1.length; i++) {
+//     		if (s1[i] != -1 && s2[i] != -1)
+//     			System.out.println("Sanity Check Failed: Sequence has been overwritten.");
+//     			
+//     		if (s1[i] != -1)
+//     			seqIndices[i] = s1[i];
+//     		else if (s2[i] != -1)
+//     			seqIndices[i] = s2[i];
+//     		else
+//     			seqIndices[i] = -1;
+//     	}
+    	
+  
+  		//Merge highlighting
+  		this.highlighted = (n1.highlighted || n2.highlighted);
+  		
+    	//Merge edges
+    	//this.fEdges = new HashSet<Node>();
+    	//this.fEdges.addAll(n1.getFwdEdges());
+    	//this.fEdges.addAll(n2.getFwdEdges());   	
+    }
+    
+    public void setHighlight(boolean val){
+    	if (val == highlighted)
+    		return;
+    	
+    	if (isMerge){
+    		n1.setHighlight(val);
+    		n2.setHighlight(val);
+    	}
+    	
+    	highlighted = val;
+    	calcColorAccuracy();
+    }
+    
+    /// Calculate (updated) tgf weight for the merged column.
+    private double calcWeightTgf(Node n1, Node n2){
+	
+	// initialize
+	weightTgf = -1;
+	
+	int x,y;
+	double prob;
+
+	double pMatch = 0.;
+	double pGap = 0.;
+
+	int[] n1SeqIndices = n1.getSeqIndices();
+	int[] n2SeqIndices = n2.getSeqIndices();
+
+	for(int seq1=0; seq1 < pm.numSeqs; seq1++){
+
+	    x = n1SeqIndices[seq1];
+
+	    for (int seq2 = 0; seq2 < pm.numSeqs; seq2++){
+
+		// if we don't have probability information for the sequence pair seq1, seq2 then skip it
+		if ((seq1 == seq2) || !pm.matrixExists(seq1, seq2))
+		    continue;
+		
+		y = n2SeqIndices[seq2];
+
+		// only look at pairs of characters
+		if (x == -1 || y == -1)
+		    continue;
+
+		// increment pMatch
+		pMatch += pm.getElement(seq1,seq2,x,y);
+		// increment pGap
+		pGap += pm.getElement(seq1,seq2,x,-1);
+		pGap += pm.getElement(seq1,seq2,-1,y);
+
+	    }
+
+	}
+
+//	System.err.print ("n1: "); n1.output();
+//	System.err.print ("n2: "); n2.output();
+//	System.err.println ("  => pMatch = " + pMatch + "; pGap = " + pGap);
+
+	return 2 * pMatch / pGap;
+
+    }
+
+    /// Calculate accuracy metrics for the column and store desired coloration.
+    /*
+     * Coloration is encoded as an array of chars.
+     * \see getColors()
+     */
+    private void calcColorAccuracy(){
+	
+	// initialize
+	acc = 0;
+	sps = 0;
+	ppv = 0;
+	cert = 0;
+	cons = 0;
+
+	accDenom = 0;
+	spsDenom = 0;
+	ppvDenom = 0;
+	certDenom = 0;
+	consDenom = 0;
+
+	// coloration for each character or gap in column
+	// color scheme chosen based on this.colorScheme
+	Double[] colorAccs = new Double[pm.numSeqs];
+
+	double num;    // per-character numerator
+	double denom;  // per-character denominator (must be a double b/c takes non-integer values for SPS, Certainty and Consistency)
+
+	int x, y;      // sequence positions
+	double prob;   // probability (match or gap)
+
+	boolean hasMatch;  // are there at least two characters in the column?
+
+	int[] seqIndices = getSeqIndices(); // map from sequences to sequence positions in column
+	for(int seq1=0; seq1 < pm.numSeqs; seq1++){
+
+	    // initialize values
+	    num = 0;
+	    denom = 0;
+	    colorAccs[seq1] = (Double) 0.0;
+	    hasMatch = false;
+	
+	    x = seqIndices[seq1];
+
+	    for (int seq2 = 0; seq2 < pm.numSeqs; seq2++){
+
+		// if we don't have probability information for the sequence pair seq1, seq2 then skip it
+		if ((seq1 == seq2) || !pm.matrixExists(seq1, seq2))
+		    continue;
+		
+		y = seqIndices[seq2];
+
+		int multiplier = 0;
+		if (x != -1 && y != -1) {      // neither are gaps
+		    multiplier = 2;
+		    hasMatch = true;
+		}
+		else if (x != -1 || y != -1) { // exactly 1 is a gap
+		    multiplier = 1;
+		}
+		else {
+		    continue;
+		}
+		
+		prob = pm.getElement(seq1,seq2,x,y);
+
+		// everything contributes to accuracy
+		acc += multiplier * prob;
+		accDenom += multiplier;
+		if (colorScheme == 0) { // Accuracy
+		    num += multiplier * prob;
+		    denom += multiplier;
+		}
+
+		// certainty is colored for both character and gaps,
+		// but we only add to the full certainty calculation if 
+		// the currect position isn't a gap (otherwise we overcount the gap information)
+		if (colorScheme == 3) { // Certainty
+		    num += multiplier * prob;
+		    if (x != -1) // if x is not a gap, then use altmax_y P(x ~ y)
+			denom += multiplier * pm.getAltMaxProb(seq1,seq2,x,y);
+		    else         // if x is a gap, then use altmax_x P(x ~ y)
+			denom += multiplier * pm.getAltMaxProb(seq2,seq1,y,x);
+		}
+
+		// and for consistency
+		cons += multiplier * prob;
+		if (x != -1) // if x is not a gap, then use max_y P(x ~ y)
+		    consDenom += multiplier * pm.getMaxProb(seq1,seq2,x);
+		else         // if x is a gap, then use max_x P(x ~ y)
+		    consDenom += multiplier * pm.getMaxProb(seq2,seq1,y);
+		if (colorScheme == 4) { // Consistency
+		    num += multiplier * prob;
+		    if (x != -1) // if x is not a gap, then use max_y P(x ~ y)
+			denom += multiplier * pm.getMaxProb(seq1,seq2,x);
+		    else         // if x is a gap, then use max_x P(x ~ y)
+			denom += multiplier * pm.getMaxProb(seq2,seq1,y);
+		}
+
+		// in contrast, SPS and PPV aren't defined for gaps
+		if (x != -1) {
+
+		    // the numerator for SPS increases only if we're looking at aligned characters (y not a gap);
+		    // the denominator increases regardless
+		    //   (this is guaranteed by the (multiplier - 1) factor)
+		    sps += (multiplier - 1) * prob;
+		    spsDenom += pm.getSumProb(seq1,seq2,x);
+		    if (colorScheme == 1) { // SPS
+			num += (multiplier - 1) * prob;
+			denom += pm.getSumProb(seq1,seq2,x);
+		    }
+
+		    // only pairs of aligned characters contribute to PPV
+		    // (both x and y ungapped)
+		    if (y != -1) {
+			ppv += multiplier * prob;
+			ppvDenom += multiplier;
+			if (colorScheme == 2) { // PPV
+			    num += multiplier * prob;
+			    denom += multiplier;
+			}
+		    }
+
+		    // certainty
+		    cert += multiplier * prob;
+		    if (x != -1) // if x is not a gap, then use altmax_y P(x ~ y)
+			certDenom += multiplier * pm.getAltMaxProb(seq1,seq2,x,y);
+		    else         // if x is a gap, then use altmax_x P(x ~ y)
+			certDenom += multiplier * pm.getAltMaxProb(seq2,seq1,y,x);
+
+		}
+
+	    }
+
+	    // store value for this character or gap if it exists
+	    // (if the denominator is defined)
+	    if (denom > 0.0001) {
+
+		// sps and ppv are only defined if there is at least 1 match
+		if (colorScheme == 1 || colorScheme == 2) {
+		    if (hasMatch)
+			colorAccs[seq1] = (Double) SparseMatrix.saneProb (num / denom);
+		    else
+			colorAccs[seq1] = (Double) (-1.); // store (temporary) negative value
+		}
+
+		// certainty takes values in interval [0, 1/0.01], so it needs to be mapped to [0,1]
+		else if (colorScheme == 3)
+		    colorAccs[seq1] = (Double) SparseMatrix.saneProb (Node.normalizedCertainty (num / denom));
+
+		// otherwise just store the normalized value
+		else
+		    colorAccs[seq1] = (Double) SparseMatrix.saneProb (num / denom);
+
+	    }
+	    // if undefined, then store (temporary) negative value
+	    else {
+		colorAccs[seq1] = (Double) (-1.);
+	    }
+
+	}//Outer loop
+
+	// Generate color code array
+	colors = new char[seqIndices.length];
+	for (int i = 0; i < colors.length; i++){
+
+	    double c;
+
+	    // if highlighted
+	    if (highlighted) {
+		c = 65535.;
+	    }
+	    // if undefined
+	    else if (colorAccs[i].doubleValue() < 0.) {
+		c = 256.;
+	    }
+	    // else encode as integer in interval 0...255
+	    else {
+		c = Math.rint(colorAccs[i].doubleValue()*255);
+	    }
+
+	    // now store the value as a char
+	    // remember that 'char' acts as an unsigned short
+	    colors[i] = (char)c;
+	}
+
+    }
+  
+    /// Get unnormalized accuracy for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getAcc(){
+    	if (acc < 0)
+	    calcColorAccuracy();
+	return acc;
+    }
+
+    /// Get normalization for accuracy for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getAccDenom(){
+    	if (accDenom < 0)
+	    calcColorAccuracy();
+	return accDenom;
+    }
+
+    /// Get unnormalized SPS for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getSPS(){
+    	if (sps < 0)
+	    calcColorAccuracy();
+	return sps;
+    }
+
+    /// Get normalization for SPS for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getSPSDenom(){
+    	if (spsDenom < 0)
+	    calcColorAccuracy();
+	return spsDenom;
+    }
+
+    /// Get unnormalized PPV for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getPPV(){
+    	if (ppv < 0)
+	    calcColorAccuracy();
+	return ppv;
+    }
+
+    /// Get normalization for PPV for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getPPVDenom(){
+    	if (ppvDenom < 0)
+	    calcColorAccuracy();
+	return ppvDenom;
+    }
+  
+    /// Get unnormalized certainty for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getCert(){
+    	if (cert < 0)
+	    calcColorAccuracy();
+	return cert;
+    }
+
+    /// Get normalization for certainty for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getCertDenom(){
+    	if (certDenom < 0)
+	    calcColorAccuracy();
+	return certDenom;
+    }
+
+    /// Get unnormalized consistency for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getCons(){
+    	if (cons < 0)
+	    calcColorAccuracy();
+	return cons;
+    }
+
+    /// Get normalization for consistency for column.
+    /*
+     * Re-calculate if necessary.
+     */
+    public double getConsDenom(){
+    	if (consDenom < 0)
+	    calcColorAccuracy();
+	return consDenom;
+    }
+  
+    /// Get the tgf weight of the column.
+    public double getWeightTgf(){
+	if (weightTgf < 0)
+	    calcColorAccuracy();
+	return weightTgf;
+    }
+
+    public int[] getSeqIndices(){
+	if (seqVals != null)
+	    return seqVals;
+	int[] seqIndices = new int[pm.numSeqs];
+	Arrays.fill(seqIndices, -1);
+	return addSeqIndices(seqIndices);
+    }
+  	
+    // Recursive method that adds all of the children's sequence indices to the array.
+    public int[] addSeqIndices(int[] seqIndices){
+	if (!isMerge){
+	    seqIndices[seqI] = seqVal;
+	    return seqIndices;
+	}
+   		
+	seqIndices = n1.addSeqIndices(seqIndices);
+	seqIndices = n2.addSeqIndices(seqIndices);
+   		
+	return seqIndices;
+    }
+
+
+    /// Update color scheme for node.
+    /*
+     * Updates coloration.
+     * It is the responsibility of the parent object
+     * to call this function whenever the color scheme is updated globally.
+     */
+    public void setColorScheme(int scheme){
+	this.colorScheme = scheme;
+	calcColorAccuracy();
+    }
+
+    /// Return an array of chars, each char representing a color.
+    /*
+     * Chars act as unsigned shorts, taking values from 0 to 2^16.
+     * Colors are encoded as:
+     * 0...255 coloration for accuracy (=> 256 possible colors in total)
+     * 256 indicates highlighting
+     * 65,535 indicates undefined
+     *  (this value is 2^16 - 1)
+     */
+    public char[] getColors(){
+	if (colors == null)
+	    calcColorAccuracy();
+	return colors;
+    }
+   	
+    public Set<Node> getFwdEdges(){
+	Set<Node> fwdEdges = new HashSet<Node>();
+	return addFwdEdges(fwdEdges);
+    }	
+   	
+    // Recursive method that adds all of the children's edges to the set.
+    public Set<Node> addFwdEdges(Set<Node> fwdEdges){
+   		
+	if (isMerge && n1 != null){ // Alternate alignments have merges that w/o any child nodes
+	    n1.addFwdEdges(fwdEdges);
+	    n2.addFwdEdges(fwdEdges);
+	}
+	else if (fwdEdge != null){
+	    fwdEdges.add(fwdEdge);
+	}
+   		
+	return fwdEdges;
+    }
+    
+    public void output(){
+	StringBuffer s = new StringBuffer("");
+	s.append(finishTime + ": ");
+	int[] seqIndices = getSeqIndices();
+	for (int i = 0; i < seqIndices.length; i++)
+	    s.append("(" + i + ", " + seqIndices[i] + ") ~ ");
+    	
+    	System.out.println(s);
+    }
+    
+    /// Normalize a certainty value to interval [0,1].
+    /*
+     * @param c certainty in range [0, 1 / 0.01]
+     * Uses a logarithmic transform.
+     */
+    static double normalizedCertainty (double c) {
+
+	// if there was a better alternative, then return 0
+	if (c < 1.0)
+	    return 0;
+	// if it was 10 times better than the best alternative, then return 1
+	else if (c >= 5.0)
+	    return 1;
+	// else perform a logarithmic transform
+	else
+	    return Math.log (c) / Math.log (5.0);
+
+    }
+
+}
diff --git a/display/mad/ProbabilityMatrices.java b/display/mad/ProbabilityMatrices.java
new file mode 100644
index 0000000..a3895f7
--- /dev/null
+++ b/display/mad/ProbabilityMatrices.java
@@ -0,0 +1,169 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for calculating and storing the sum and max probabilities
+ *  was written by Robert Bradley.
+ */
+
+
+package mad;
+
+import java.util.*;
+
+public class ProbabilityMatrices{
+	int numSeqs;
+	int[] seqLengths;
+	int[][] index;
+	SparseMatrix[] matrices; 
+
+	public ProbabilityMatrices(int[] seqLengths){
+		this.seqLengths = seqLengths;
+		this.numSeqs = seqLengths.length;
+		this.matrices = new SparseMatrix[numSeqs*(numSeqs-1)/2];
+		buildIndex();
+	}
+	
+	private void buildIndex(){
+		int x = 0;
+		this.index = new int[numSeqs][numSeqs];
+		for (int i = 0; i < numSeqs; i++)
+			for (int j = i+1; j < numSeqs; j++){
+				this.index[i][j] = x;
+				this.index[j][i] = x++;
+			}
+	}
+	
+	public void addElement(int seq1, int seq2, int i1, int i2, double prob){
+		
+		//Handle gaps and index change from input file
+		if (i1 < 0)
+			i1 = seqLengths[seq1];
+		if (i2 < 0)
+			i2 = seqLengths[seq2];
+			
+		if (seq1 > seq2){
+			int temp = i1;
+			i1 = i2;
+			i2 = temp;
+		}
+				
+		if (!matrixExists(seq1, seq2))
+			addMatrix(seq1, seq2);
+		
+		matrices[getIndex(seq1,seq2)].put(i1, i2, prob);
+	}
+	
+	public double getElement(int seq1, int seq2, int i1, int i2){
+		
+		if (!matrixExists(seq1, seq2))
+			return 0.0;
+			
+		// Handle gaps
+		if (i1 < 0)
+			i1 = seqLengths[seq1];
+		if (i2 < 0)
+			i2 = seqLengths[seq2];
+		
+		if (seq1 > seq2){
+			int temp = i1;
+			i1 = i2;
+			i2 = temp;
+		}	
+		return matrices[getIndex(seq1,seq2)].get(i1, i2);
+	}
+
+    /// Get sum_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    public double getSumProb(int seq1, int seq2, int pos1){
+	
+	if (!matrixExists(seq1, seq2)) {
+	    System.err.println ("Probability matrix for sequences " + seq1 + " and " + seq2 + " does not exist.");
+	    System.exit(1);
+	}
+	
+	// no gaps
+	if (pos1 < 0) {
+	    System.err.println ("Sum probability is undefined for gaps; offending sequences are " + seq1 + " and " + seq2 + ".");
+	    System.exit(1);
+	}
+
+	if (seq1 < seq2)
+	    return matrices[getIndex(seq1,seq2)].getSumProbI(pos1);
+	else
+	    return matrices[getIndex(seq2,seq1)].getSumProbJ(pos1);
+
+    }
+
+    /// Get max_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    public double getMaxProb(int seq1, int seq2, int pos1){
+	
+	if (!matrixExists(seq1, seq2)) {
+	    System.err.println ("Probability matrix for sequences " + seq1 + " and " + seq2 + " does not exist.");
+	    System.exit(1);
+	}
+	
+	// no gaps
+	if (pos1 < 0) {
+	    System.err.println ("Max probability is undefined for gaps; offending sequences are " + seq1 + " and " + seq2 + ".");
+	    System.exit(1);
+	}
+
+	if (seq1 < seq2)
+	    return matrices[getIndex(seq1,seq2)].getMaxProbI(pos1);
+	else
+	    return matrices[getIndex(seq2,seq1)].getMaxProbJ(pos1);
+
+    }
+
+    /// Get altmax_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    public double getAltMaxProb(int seq1, int seq2, int pos1, int pos2){
+	
+	if (!matrixExists(seq1, seq2)) {
+	    System.err.println ("Probability matrix for sequences " + seq1 + " and " + seq2 + " does not exist.");
+	    System.exit(1);
+	}
+	
+	// handle gaps
+	if (pos1 < 0) {
+	    System.err.println ("Alt max probability is undefined for gaps in first sequence; offending sequences are " + seq1 + " and " + seq2 + ".");
+	    System.exit(1);
+	}
+	else if (pos2 < 0) {
+	    pos2 = seqLengths[seq2]; // convert to indexing used by SparseMatrix
+	}
+
+	if (seq1 < seq2) {
+	    return matrices[getIndex(seq1,seq2)].getAltMaxProbI(pos1,pos2);
+	}
+	else {
+	    return matrices[getIndex(seq2,seq1)].getAltMaxProbJ(pos2,pos1);
+	}
+
+    }
+
+
+	
+	private int getIndex(int seq1, int seq2){
+		return index[seq1][seq2];
+	}
+	
+	private void addMatrix(int seq1, int seq2){
+	
+		if (seq1 > seq2){
+			int temp = seq1;
+			seq1 = seq2;
+			seq2 = temp;
+		}
+		matrices[getIndex(seq1, seq2)] = new SparseMatrix(seqLengths[seq1]+1, seqLengths[seq2]+1);
+	}
+	
+	
+	public boolean matrixExists(int seq1, int seq2){
+		if (seq1 == seq2)
+			return false;
+		return matrices[getIndex(seq1, seq2)] != null;
+	}
+	
+
+	
+}
\ No newline at end of file
diff --git a/display/mad/PropertyChangeHandler.java b/display/mad/PropertyChangeHandler.java
new file mode 100644
index 0000000..b3dd843
--- /dev/null
+++ b/display/mad/PropertyChangeHandler.java
@@ -0,0 +1,37 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot.
+ */
+
+package mad;
+
+import java.util.*;
+import java.beans.*;
+
+
+public class PropertyChangeHandler {
+
+	private static PropertyChangeSupport pcs;
+	private static Object o;
+
+	static {
+		o = new Object();
+		pcs = new PropertyChangeSupport( o );
+	}
+
+	public static PropertyChangeSupport getPropertyChangeSupport() {
+		return pcs;
+	}
+
+	public static void firePropertyChange(String id, Object oldValue, Object newValue) {
+		try {
+			PropertyChangeIDs.valueOf(id);
+		} catch (IllegalArgumentException ex) {
+			System.err.println("Illegal PropertyChangeEvent ID: " + id + "   ignoring!");
+			return;
+		}
+		PropertyChangeEvent e = new PropertyChangeEvent(pcs, id, oldValue, newValue);
+		pcs.firePropertyChange(e);
+	}
+}
diff --git a/display/mad/PropertyChangeIDs.java b/display/mad/PropertyChangeIDs.java
new file mode 100644
index 0000000..6a339f6
--- /dev/null
+++ b/display/mad/PropertyChangeIDs.java
@@ -0,0 +1,11 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot.
+ */
+
+package mad;
+
+public enum PropertyChangeIDs {
+	CHANGE_ALIGNMENT,
+}
diff --git a/display/mad/SaveAsFastaAction.java b/display/mad/SaveAsFastaAction.java
new file mode 100644
index 0000000..f1c4469
--- /dev/null
+++ b/display/mad/SaveAsFastaAction.java
@@ -0,0 +1,59 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Michael Smoot and Adam Roberts.
+ */
+
+package mad;
+
+import java.util.*;
+import java.beans.*;
+import java.io.*;
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.Component;
+
+
+public class SaveAsFastaAction extends AbstractAction implements PropertyChangeListener {
+
+	Alignments aligns;
+	MadPanel parent;
+	JFileChooser fc;
+	
+	SaveAsFastaAction(MadPanel parent ) {
+		super("Save as Multi-FASTA");
+		this.parent = parent;
+		fc = new JFileChooser();
+		PropertyChangeHandler.getPropertyChangeSupport()
+		                     .addPropertyChangeListener(PropertyChangeIDs.CHANGE_ALIGNMENT.toString(), this);
+		aligns =  parent.aligns;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		Alignment a = aligns.get(aligns.index);
+		System.out.print ("Saving as Multi-FASTA file...");
+		if ( a != null ) {
+			try {
+				int returnVal = fc.showSaveDialog(parent);
+				if (returnVal == JFileChooser.APPROVE_OPTION) {
+					File file = fc.getSelectedFile();
+					FileWriter fw = new FileWriter(file);
+					String mfa = a.toMultiFasta();
+					fw.write(mfa,0,mfa.length());
+					fw.close();
+					System.out.println ("done");
+				}
+			} catch (Exception ioe) {
+				JOptionPane.showMessageDialog(parent,
+				                              "Failed to save Multi-FASTA file:\n\n" + ioe.getMessage(),
+				                              "Error saving file.",
+				                              JOptionPane.ERROR_MESSAGE);
+				ioe.printStackTrace();
+			}
+		} else
+			System.err.println("No alignment found.");
+			
+	}
+
+	public void propertyChange(PropertyChangeEvent e) {}
+}
diff --git a/display/mad/SaveAsMovAction.java b/display/mad/SaveAsMovAction.java
new file mode 100644
index 0000000..ea9b07b
--- /dev/null
+++ b/display/mad/SaveAsMovAction.java
@@ -0,0 +1,31 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ */
+
+
+package mad;
+
+import java.util.*;
+import java.beans.*;
+import java.io.*;
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.*;
+
+
+public class SaveAsMovAction extends AbstractAction {
+
+	MadPanel parent;
+	
+	SaveAsMovAction(MadPanel parent ) {
+		super("Export as Quicktime Movie");
+		this.parent = parent;
+	}
+
+	public void actionPerformed(ActionEvent e) {
+		this.parent.alignmentToMov();	
+	}
+
+}
diff --git a/display/mad/SaveAsTiffAction.java b/display/mad/SaveAsTiffAction.java
new file mode 100644
index 0000000..27b0ba5
--- /dev/null
+++ b/display/mad/SaveAsTiffAction.java
@@ -0,0 +1,53 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Robert Bradley.
+ */
+
+package mad;
+
+import java.util.*;
+import java.beans.*;
+import java.io.*;
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.Component;
+
+public class SaveAsTiffAction extends AbstractAction implements PropertyChangeListener {
+
+    AlignmentPanel parentAlignPanel;
+    MadPanel parent;
+    JFileChooser fc;
+	
+    SaveAsTiffAction(MadPanel parent ) {
+	super("Save as TIFF file");
+	this.parent = parent;
+	fc = new JFileChooser();
+	PropertyChangeHandler.getPropertyChangeSupport()
+	    .addPropertyChangeListener(PropertyChangeIDs.CHANGE_ALIGNMENT.toString(), this);
+	parentAlignPanel =  parent.alignPanel;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+
+	System.out.print("Saving as TIFF image...");
+
+	try {
+	    int returnVal = fc.showSaveDialog(parent);
+	    if (returnVal == JFileChooser.APPROVE_OPTION) {
+		File file = fc.getSelectedFile();
+		parentAlignPanel.saveAsTiff (file.getPath());
+		System.out.println("done");
+	    }
+	} catch (Exception ioe) {
+	    JOptionPane.showMessageDialog(parent,
+					  "Failed to save TIFF file:\n\n" + ioe.getMessage(),
+					  "Error saving file.",
+					  JOptionPane.ERROR_MESSAGE);
+	    ioe.printStackTrace();
+	}
+	
+    }
+
+    public void propertyChange(PropertyChangeEvent e) {}
+}
diff --git a/display/mad/SparseMatrix.java b/display/mad/SparseMatrix.java
new file mode 100644
index 0000000..683e123
--- /dev/null
+++ b/display/mad/SparseMatrix.java
@@ -0,0 +1,257 @@
+
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Adam Roberts.
+ *  Code for calculating and storing the sum and max probabilities
+ *  was written by Robert Bradley.
+ */
+
+
+package mad;
+
+//import it.unimi.dsi.fastutil.ints.*;
+import java.util.*;
+import java.lang.Math.*;
+
+public class SparseMatrix{
+	
+    private int length, width;
+    private Vector<Double> values;
+    private Map<Integer, Integer> indexMap;
+
+    private Double[] sumProbI;
+    private Double[][] maxProbI;
+
+    private Double[] sumProbJ;
+    private Double[][] maxProbJ;
+
+    public SparseMatrix(int length, int width){
+	this.length = length; // length == length of first sequence + 1
+	this.width = width;   // width == length of second sequence + 1
+
+	indexMap = new HashMap<Integer, Integer>();
+	values = new Vector<Double>(100, 10);
+
+	sumProbI = new Double[length-1];
+	maxProbI = new Double[length-1][2];
+
+	sumProbJ = new Double[width-1];
+	maxProbJ = new Double[width-1][2];
+
+    }
+    
+    public void put(int i, int j, double e){
+	int index = j*length+i;
+
+	if (indexMap.containsKey(index)){
+	    System.err.println("SANITY CHECK FAILED:  Matrix index repeated (i = " + i + ", j = " + j + ", index = " + index + ")");
+	    System.exit(-1);
+	}
+	
+	// check that the probability is valid
+	e = SparseMatrix.saneProb (e);
+
+	indexMap.put(index, values.size());
+	values.addElement(e);
+
+	// Note that max is over all possible positions in the other sequence, including gapped.
+	// The below check over single indices ensures that the possibility of gaps
+	// in the other sequence are properly taken into account when finding the max (and alternate max).
+
+	// first sequence
+	if (i < length-1) { // i == (length - 1) corresponds to first sequence gapped
+                            //   (NB sequence position indices are 0-based)
+
+	    // if max prob undefined, store new value
+	    if (maxProbI[i][0] == null) {
+		maxProbI[i][0] = (Double) e;
+	    }
+
+	    // if new max, then store new value and update alternate max
+	    else if (maxProbI[i][0].doubleValue() < e) {
+		maxProbI[i][1] = maxProbI[i][0];
+		maxProbI[i][0] = (Double) e;
+	    }
+
+	    // if new alternate max b/c alternate max is undefined
+	    else if (maxProbI[i][1] == null) {
+		maxProbI[i][1] = (Double) e;
+	    }
+
+	    // if new alternate max
+	    else if (maxProbI[i][1].doubleValue() < e) {
+		maxProbI[i][1] = (Double) e;
+	    }
+
+	}
+
+	// second sequence
+	if (j < width-1) { // j == (width - 1) corresponds to second sequence gapped
+
+	    // if max prob undefined, store new value
+	    // and initialize alternate max
+	    if (maxProbJ[j][0] == null) {
+		maxProbJ[j][0] = (Double) e;
+	    }
+
+	    // if new max, then store new value and update alternate max
+	    else if (maxProbJ[j][0].doubleValue() < e) {
+		maxProbJ[j][1] = maxProbJ[j][0];
+		maxProbJ[j][0] = (Double) e;
+	    }
+
+	    // if new alternate max b/c alternate max is undefined
+	    else if (maxProbJ[j][1] == null) {
+		maxProbJ[j][1] = (Double) e;
+	    }
+
+	    // if new alternate max
+	    else if (maxProbJ[j][1].doubleValue() < e) {
+		maxProbJ[j][1] = (Double) e;
+	    }
+
+	}
+
+	// sum is only over possible aligned character pairs
+	// (if gaps are included then all sums be 1. b/c they're normalized probability distributions)
+	if ((i < length-1) && (j < width-1)) {
+
+	    if (sumProbI[i] == null)
+		sumProbI[i] = (Double) e;
+	    else
+		sumProbI[i] += (Double) e;
+
+	    if (sumProbJ[j] == null)
+		sumProbJ[j] = (Double) e;
+	    else
+		sumProbJ[j] += (Double) e;
+
+	}
+
+    }
+    
+    public double get(int i, int j){
+	int index = j*length+i;
+	if (!indexMap.containsKey(index))
+	    return 0.0;
+	return SparseMatrix.saneProb (values.get(indexMap.get(index)));
+    }
+    
+    /// Get sum_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    /*
+     * Cover the case of no entry for a match probability > 0.01.
+     */
+    public double getSumProbI(int pos){
+	if (sumProbI[pos] == null) // cover case of no input data (no match prob above FSA's threshold)
+	    return 0.01;
+	return SparseMatrix.saneProb (sumProbI[pos]);
+    }
+
+    /// Get sum_pos1 P((seq1, pos1) ~ (seq2, pos2)).
+    /*
+     * Cover the case of no entry for a match probability > 0.01.
+     */
+    public double getSumProbJ(int pos){
+	if (sumProbJ[pos] == null) // cover case of no input data (no match prob above FSA's threshold)
+	    return 0.01;
+	return SparseMatrix.saneProb (sumProbJ[pos]);
+    }
+
+    /// Get max_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    public double getMaxProbI(int pos){
+	// sanity check
+	if (maxProbI[pos][0] == null) {
+	    System.err.println ("A max prob is null; this should never happen!");
+	    System.exit(1);
+	}
+	return SparseMatrix.saneProb (maxProbI[pos][0]);
+    }
+
+    /// Get altmax_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+    /*
+     * \return second-best probability, or 0.01 if undefined
+     * Minimum value of 0.01 is due to the inherent coarse-graining
+     * of the probability reported by FSA.
+     */
+    public double getAltMaxProbI(int pos1, int pos2){
+
+	// sanity check
+	if (maxProbI[pos1][0] == null) {
+	    System.err.println ("A max prob is null; this should never happen!");
+	    System.exit(1);
+	}
+
+	// get probability to determine best alternate
+	double prob = get(pos1,pos2);
+
+	// if prob is the max, then return the second-best alternate
+	if (Math.abs (prob - maxProbI[pos1][0].doubleValue()) < 0.0001) {
+	    if (maxProbI[pos1][1] != null)
+		return SparseMatrix.saneProb (maxProbI[pos1][1]);
+	    else
+		return 0.01;
+	}
+	// else return the max
+	else
+	    return SparseMatrix.saneProb (maxProbI[pos1][0]);
+
+    }
+
+    /// Get altmax_pos1 P((seq1, pos1) ~ (seq2, pos2)).
+    /*
+     * \return second-best probability, or 0.01 if undefined
+     * Minimum value of 0.01 is due to the inherent coarse-graining
+     * of the probability reported by FSA.
+     */
+    public double getAltMaxProbJ(int pos1, int pos2){
+
+	// sanity check
+	if (maxProbJ[pos2][0] == null) {
+	    System.err.println ("A max prob is null; this should never happen!");
+	    System.exit(1);
+	}
+
+	// get probability to determine best alternate
+	double prob = get(pos1,pos2);
+
+	// if prob is the max, then return the second-best alternate
+	if (Math.abs (prob - maxProbJ[pos2][0].doubleValue()) < 0.0001) {
+	    if (maxProbJ[pos2][1] != null)
+		return SparseMatrix.saneProb (maxProbJ[pos2][1]);
+	    else
+		return 0.01;
+	}
+	// else return the max
+	else
+	    return SparseMatrix.saneProb (maxProbJ[pos2][0]);
+
+    }
+
+    /// Get max_pos1 P((seq1, pos1) ~ (seq2, pos2)).
+    public double getMaxProbJ(int pos){
+
+	// sanity check
+	if (maxProbJ[pos][0] == null) {
+	    System.err.println ("A max prob is null; this should never happen!");
+	    System.exit(1);
+	}
+
+	return SparseMatrix.saneProb (maxProbJ[pos][0]);
+    }
+
+    /// Bounds-checking for a valid probability.
+    static double saneProb (double p) {
+	if (p < -0.0001 || p > 1.0001) {
+	    System.err.println("Error: probability " + p + " is out of bounds.");
+	    System.exit(1);
+	}
+	p = (p < -0.0001) ? 0. : p;
+	p = (p > 1.0001) ? 1.0 : p;
+	return p;	
+    }
+
+    static double saneProb (Double p) {
+	return saneProb (p.doubleValue());
+    }
+
+}
\ No newline at end of file
diff --git a/display/mad/legend.jpg b/display/mad/legend.jpg
new file mode 100644
index 0000000..86972bc
Binary files /dev/null and b/display/mad/legend.jpg differ
diff --git a/display/mad/manifest.mf b/display/mad/manifest.mf
new file mode 100644
index 0000000..93b0654
--- /dev/null
+++ b/display/mad/manifest.mf
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Created-By: 1.6.0 (Sun Microsystems Inc.)
+Class-Path: JMF-2.1.1e/lib/jmf.jar jai-1_1_3/lib/jai_codec.jar jai-1_1_3/lib/jai_core.jar
+Main-Class: mad.MAD
diff --git a/display/mad/manifest.mf.in b/display/mad/manifest.mf.in
new file mode 100644
index 0000000..1804577
--- /dev/null
+++ b/display/mad/manifest.mf.in
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Created-By: 1.6.0 (Sun Microsystems Inc.)
+Class-Path: JMF-2.1.1e/lib/jmf.jar jai-1_1_3/lib/jai_codec.jar jai-1_1_3/lib/jai_core.jar
+Main-Class: @MAD_MAIN_CLASS@
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..de7be8a
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,23 @@
+EXTRA_DIST = \
+	README \
+	RV12.BBS12030.fasta \
+	RV12.BBS12030.fasta.gui \
+	RV12.BBS12030.fasta.probs \
+	RV12.BBS12030.mfa \
+	RV12.BBS12030.reference.mfa \
+	RV12.BBS12030.reference.stock \
+	RV12.BBS12030.stock \
+	U5.aln1.fasta \
+	U5.aln1.fasta.gui \
+	U5.aln1.fasta.probs \
+	U5.aln1.mfa \
+	U5.aln1.reference.mfa \
+	U5.aln1.reference.stock \
+	U5.aln1.stock \
+	tRNA.aln1.fasta \
+	tRNA.aln1.fasta.gui \
+	tRNA.aln1.fasta.probs \
+	tRNA.aln1.mfa \
+	tRNA.aln1.reference.mfa \
+	tRNA.aln1.reference.stock \
+	tRNA.aln1.stock
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 0000000..0f89184
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,431 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = examples
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am README
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+	README \
+	RV12.BBS12030.fasta \
+	RV12.BBS12030.fasta.gui \
+	RV12.BBS12030.fasta.probs \
+	RV12.BBS12030.mfa \
+	RV12.BBS12030.reference.mfa \
+	RV12.BBS12030.reference.stock \
+	RV12.BBS12030.stock \
+	U5.aln1.fasta \
+	U5.aln1.fasta.gui \
+	U5.aln1.fasta.probs \
+	U5.aln1.mfa \
+	U5.aln1.reference.mfa \
+	U5.aln1.reference.stock \
+	U5.aln1.stock \
+	tRNA.aln1.fasta \
+	tRNA.aln1.fasta.gui \
+	tRNA.aln1.fasta.probs \
+	tRNA.aln1.mfa \
+	tRNA.aln1.reference.mfa \
+	tRNA.aln1.reference.stock \
+	tRNA.aln1.stock
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign examples/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+	ctags-am distclean distclean-generic distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/examples/README b/examples/README
new file mode 100644
index 0000000..836b246
--- /dev/null
+++ b/examples/README
@@ -0,0 +1,36 @@
+
+Guide to sequence and alignment files:
+.fasta file is the unaligned sequences
+.reference.{mfa,stock} is the reference alignment
+.{mfa,stock} is the alignment produced by FSA run with the options
+	      --noindel2 (for only 1 set of indel states)
+	      --refinement 0 (for no iterative refinement)
+
+Origins of sequence and alignment files in example/:
+
+****************************
+BRalibaseII:
+****************************
+
+tRNA.aln1
+U5.aln1
+
+References:
+1. Gardner PP, Wilm A & Washietl S (2005) A benchmark of multiple sequence alignment programs upon structural RNAs. Nucleic Acids Research. 33(8):2433-2439.Supp. Mat.
+
+
+****************************
+Balibase:
+****************************
+
+RV12.BBS12030
+
+References:
+1. Thompson JD, Plewniak F, Poch O. BAliBASE: a benchmark alignment database for the evaluation of multiple alignment programs.
+Bioinformatics. 1999 Jan;15(1):87-8. 
+
+2. Thompson JD, Plewniak F, Poch O. A comprehensive comparison of multiple sequence alignment programs.
+Nucleic Acids Res. 1999 Jul 1;27(13):2682-90
+
+3. Bahr A, Thompson JD, Thierry JC, Poch O. BAliBASE (Benchmark Alignment dataBASE): enhancements for repeats, transmembrane sequences and circular permutations.
+Nucleic Acids Res. 2001 Jan 1;29(1):323-6.
diff --git a/examples/RV12.BBS12030.fasta b/examples/RV12.BBS12030.fasta
new file mode 100644
index 0000000..c8a25e6
--- /dev/null
+++ b/examples/RV12.BBS12030.fasta
@@ -0,0 +1,36 @@
+>POL_MPMV
+APQQCAEPITWKSDEPVWVDQWPLTNDKLAAAQQLVQEQLEAGHITESSS
+PWNTPIFVIKKKSGKWRLLQDLRAVNATMVLMGALQPGLPSPVAIPQGYL
+KIIIDLKDCFFSIPLHPSDQKRFAFSLPSTNFKEPMQRFQWKVLPQGMAN
+SPTLCQKYVATAIHKVRHAWKQMYIIHYMDDILIAGKDGQQVLQCFDQLK
+QELTAAGLHIAPEKVQLQDPYTYLGFELNGPKI
+>POL_BIV06
+HTEKIEPLPVKVRGPGPKVPQWPLTKEKYQALKEIVKDLLAEGKISEAAW
+DNPYNTPVFVIKKKGTGRWRMLMDFRELNKITVKGQEFSTGLPYPPGIKE
+CEHLTAIDIKDAYFTIPLHEDFRPFTAFSVVPVNREGPIERFQWNVLPQG
+WVCSPAIYQTTTQKIIENIKKSHPDVMLYQYMDDLLIGSNRDDHKQIVQE
+IRDKLGSYGFKTPDEKVQEERVKWIGFELTPKKW
+>POL_CAEVC
+LEEKRIPITKVKLKEGCTGPHVPQWPLTEEKLKGLTEIIDKLVEEGKLGK
+APPHWTCNTPIFCIKKKSGKWRMLIDFRELNKQTEDLTEAQLGLPHPGGL
+QKKKHVTILDIGDAYFTIPLYEPYREYTCFTLLSPNNLGPCKRYYWKVLP
+QGWKLSPSVYQFTMQEILEDWIQQHPEIQFGIYMDDIYIGSDLEIKKHRE
+IVKDLANYIAQYGFTLPEEKRQKGYPAKWLGFELHPQTW
+>1bqm_A
+PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKI
+GPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGL
+KKKKSVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYNVLP
+QGWKGSPAIFQSSMTKILEPFKKQNPDIVIYQYMDDLYVGSDLEIGQHRT
+KIEELRQHLLRWGLTTPDKKHQKEPPFLWMGYELHPDKW
+>1d0e_A
+LAVRQAPLIIPLKATSTPVSIKQYPMSQEARLGIKPHIQRLLDQGILVPC
+QSPWNTPLLPVKKPGTNDYRPVQDLREVNKRVEDIHPTVPNPYNLLSGLP
+PSHQWYTVLDLKDAFFCLRLHPTSQPLFAFEWRDPEMGISGQLTWTRLPQ
+GFKNSPTLFDEALHRDLADFRIQHPDLILLQYVDDLLLAATSELDCQQGT
+RALLQTLGNLGYRASAKKAQICQKQVKYLGYLLKEGQR
+>POL_RSVP
+VALHLAIPLKWKPDHTPVWIDQWPLPEGKLVALTQLVEKELQLGHIEPSL
+SCWNTPVFVIRKASGSYRLLHDLRAVNAKLVPFGAVQQGAPVLSALPRGW
+PLMVLDLKDCFFSIPLAEQDREAFAFTLPSVNNQAPARRFQWKVLPQGMT
+CSPTICQLVVGQVLEPLRLKHPSLCMLHYMDDLLLAASSHDGLEAAGEEV
+ISTLERAGFTISPDKVQREPGVQYLGYKLGSTYV
diff --git a/examples/RV12.BBS12030.fasta.gui b/examples/RV12.BBS12030.fasta.gui
new file mode 100644
index 0000000..b10a55c
--- /dev/null
+++ b/examples/RV12.BBS12030.fasta.gui
@@ -0,0 +1,2599 @@
+; Initial DAG
+; Format is:
+;   column: (sequence, position)
+; sequence is 0-based and position is 0-based
+
+0: (0, 0)
+1: (1, 0)
+2: (2, 0)
+3: (3, 0)
+4: (4, 0)
+5: (5, 0)
+6: (0, 1)
+7: (1, 1)
+8: (2, 1)
+9: (3, 1)
+10: (4, 1)
+11: (5, 1)
+12: (0, 2)
+13: (1, 2)
+14: (2, 2)
+15: (3, 2)
+16: (4, 2)
+17: (5, 2)
+18: (0, 3)
+19: (1, 3)
+20: (2, 3)
+21: (3, 3)
+22: (4, 3)
+23: (5, 3)
+24: (0, 4)
+25: (1, 4)
+26: (2, 4)
+27: (3, 4)
+28: (4, 4)
+29: (5, 4)
+30: (0, 5)
+31: (1, 5)
+32: (2, 5)
+33: (3, 5)
+34: (4, 5)
+35: (5, 5)
+36: (0, 6)
+37: (1, 6)
+38: (2, 6)
+39: (3, 6)
+40: (4, 6)
+41: (5, 6)
+42: (0, 7)
+43: (1, 7)
+44: (2, 7)
+45: (3, 7)
+46: (4, 7)
+47: (5, 7)
+48: (0, 8)
+49: (1, 8)
+50: (2, 8)
+51: (3, 8)
+52: (4, 8)
+53: (5, 8)
+54: (0, 9)
+55: (1, 9)
+56: (2, 9)
+57: (3, 9)
+58: (4, 9)
+59: (5, 9)
+60: (0, 10)
+61: (1, 10)
+62: (2, 10)
+63: (3, 10)
+64: (4, 10)
+65: (5, 10)
+66: (0, 11)
+67: (1, 11)
+68: (2, 11)
+69: (3, 11)
+70: (4, 11)
+71: (5, 11)
+72: (0, 12)
+73: (1, 12)
+74: (2, 12)
+75: (3, 12)
+76: (4, 12)
+77: (5, 12)
+78: (0, 13)
+79: (1, 13)
+80: (2, 13)
+81: (3, 13)
+82: (4, 13)
+83: (5, 13)
+84: (0, 14)
+85: (1, 14)
+86: (2, 14)
+87: (3, 14)
+88: (4, 14)
+89: (5, 14)
+90: (0, 15)
+91: (1, 15)
+92: (2, 15)
+93: (3, 15)
+94: (4, 15)
+95: (5, 15)
+96: (0, 16)
+97: (1, 16)
+98: (2, 16)
+99: (3, 16)
+100: (4, 16)
+101: (5, 16)
+102: (0, 17)
+103: (1, 17)
+104: (2, 17)
+105: (3, 17)
+106: (4, 17)
+107: (5, 17)
+108: (0, 18)
+109: (1, 18)
+110: (2, 18)
+111: (3, 18)
+112: (4, 18)
+113: (5, 18)
+114: (0, 19)
+115: (1, 19)
+116: (2, 19)
+117: (3, 19)
+118: (4, 19)
+119: (5, 19)
+120: (0, 20)
+121: (1, 20)
+122: (2, 20)
+123: (3, 20)
+124: (4, 20)
+125: (5, 20)
+126: (0, 21)
+127: (1, 21)
+128: (2, 21)
+129: (3, 21)
+130: (4, 21)
+131: (5, 21)
+132: (0, 22)
+133: (1, 22)
+134: (2, 22)
+135: (3, 22)
+136: (4, 22)
+137: (5, 22)
+138: (0, 23)
+139: (1, 23)
+140: (2, 23)
+141: (3, 23)
+142: (4, 23)
+143: (5, 23)
+144: (0, 24)
+145: (1, 24)
+146: (2, 24)
+147: (3, 24)
+148: (4, 24)
+149: (5, 24)
+150: (0, 25)
+151: (1, 25)
+152: (2, 25)
+153: (3, 25)
+154: (4, 25)
+155: (5, 25)
+156: (0, 26)
+157: (1, 26)
+158: (2, 26)
+159: (3, 26)
+160: (4, 26)
+161: (5, 26)
+162: (0, 27)
+163: (1, 27)
+164: (2, 27)
+165: (3, 27)
+166: (4, 27)
+167: (5, 27)
+168: (0, 28)
+169: (1, 28)
+170: (2, 28)
+171: (3, 28)
+172: (4, 28)
+173: (5, 28)
+174: (0, 29)
+175: (1, 29)
+176: (2, 29)
+177: (3, 29)
+178: (4, 29)
+179: (5, 29)
+180: (0, 30)
+181: (1, 30)
+182: (2, 30)
+183: (3, 30)
+184: (4, 30)
+185: (5, 30)
+186: (0, 31)
+187: (1, 31)
+188: (2, 31)
+189: (3, 31)
+190: (4, 31)
+191: (5, 31)
+192: (0, 32)
+193: (1, 32)
+194: (2, 32)
+195: (3, 32)
+196: (4, 32)
+197: (5, 32)
+198: (0, 33)
+199: (1, 33)
+200: (2, 33)
+201: (3, 33)
+202: (4, 33)
+203: (5, 33)
+204: (0, 34)
+205: (1, 34)
+206: (2, 34)
+207: (3, 34)
+208: (4, 34)
+209: (5, 34)
+210: (0, 35)
+211: (1, 35)
+212: (2, 35)
+213: (3, 35)
+214: (4, 35)
+215: (5, 35)
+216: (0, 36)
+217: (1, 36)
+218: (2, 36)
+219: (3, 36)
+220: (4, 36)
+221: (5, 36)
+222: (0, 37)
+223: (1, 37)
+224: (2, 37)
+225: (3, 37)
+226: (4, 37)
+227: (5, 37)
+228: (0, 38)
+229: (1, 38)
+230: (2, 38)
+231: (3, 38)
+232: (4, 38)
+233: (5, 38)
+234: (0, 39)
+235: (1, 39)
+236: (2, 39)
+237: (3, 39)
+238: (4, 39)
+239: (5, 39)
+240: (0, 40)
+241: (1, 40)
+242: (2, 40)
+243: (3, 40)
+244: (4, 40)
+245: (5, 40)
+246: (0, 41)
+247: (1, 41)
+248: (2, 41)
+249: (3, 41)
+250: (4, 41)
+251: (5, 41)
+252: (0, 42)
+253: (1, 42)
+254: (2, 42)
+255: (3, 42)
+256: (4, 42)
+257: (5, 42)
+258: (0, 43)
+259: (1, 43)
+260: (2, 43)
+261: (3, 43)
+262: (4, 43)
+263: (5, 43)
+264: (0, 44)
+265: (1, 44)
+266: (2, 44)
+267: (3, 44)
+268: (4, 44)
+269: (5, 44)
+270: (0, 45)
+271: (1, 45)
+272: (2, 45)
+273: (3, 45)
+274: (4, 45)
+275: (5, 45)
+276: (0, 46)
+277: (1, 46)
+278: (2, 46)
+279: (3, 46)
+280: (4, 46)
+281: (5, 46)
+282: (0, 47)
+283: (1, 47)
+284: (2, 47)
+285: (3, 47)
+286: (4, 47)
+287: (5, 47)
+288: (0, 48)
+289: (1, 48)
+290: (2, 48)
+291: (3, 48)
+292: (4, 48)
+293: (5, 48)
+294: (0, 49)
+295: (1, 49)
+296: (2, 49)
+297: (3, 49)
+298: (4, 49)
+299: (5, 49)
+300: (0, 50)
+301: (1, 50)
+302: (2, 50)
+303: (3, 50)
+304: (4, 50)
+305: (5, 50)
+306: (0, 51)
+307: (1, 51)
+308: (2, 51)
+309: (3, 51)
+310: (4, 51)
+311: (5, 51)
+312: (0, 52)
+313: (1, 52)
+314: (2, 52)
+315: (3, 52)
+316: (4, 52)
+317: (5, 52)
+318: (0, 53)
+319: (1, 53)
+320: (2, 53)
+321: (3, 53)
+322: (4, 53)
+323: (5, 53)
+324: (0, 54)
+325: (1, 54)
+326: (2, 54)
+327: (3, 54)
+328: (4, 54)
+329: (5, 54)
+330: (0, 55)
+331: (1, 55)
+332: (2, 55)
+333: (3, 55)
+334: (4, 55)
+335: (5, 55)
+336: (0, 56)
+337: (1, 56)
+338: (2, 56)
+339: (3, 56)
+340: (4, 56)
+341: (5, 56)
+342: (0, 57)
+343: (1, 57)
+344: (2, 57)
+345: (3, 57)
+346: (4, 57)
+347: (5, 57)
+348: (0, 58)
+349: (1, 58)
+350: (2, 58)
+351: (3, 58)
+352: (4, 58)
+353: (5, 58)
+354: (0, 59)
+355: (1, 59)
+356: (2, 59)
+357: (3, 59)
+358: (4, 59)
+359: (5, 59)
+360: (0, 60)
+361: (1, 60)
+362: (2, 60)
+363: (3, 60)
+364: (4, 60)
+365: (5, 60)
+366: (0, 61)
+367: (1, 61)
+368: (2, 61)
+369: (3, 61)
+370: (4, 61)
+371: (5, 61)
+372: (0, 62)
+373: (1, 62)
+374: (2, 62)
+375: (3, 62)
+376: (4, 62)
+377: (5, 62)
+378: (0, 63)
+379: (1, 63)
+380: (2, 63)
+381: (3, 63)
+382: (4, 63)
+383: (5, 63)
+384: (0, 64)
+385: (1, 64)
+386: (2, 64)
+387: (3, 64)
+388: (4, 64)
+389: (5, 64)
+390: (0, 65)
+391: (1, 65)
+392: (2, 65)
+393: (3, 65)
+394: (4, 65)
+395: (5, 65)
+396: (0, 66)
+397: (1, 66)
+398: (2, 66)
+399: (3, 66)
+400: (4, 66)
+401: (5, 66)
+402: (0, 67)
+403: (1, 67)
+404: (2, 67)
+405: (3, 67)
+406: (4, 67)
+407: (5, 67)
+408: (0, 68)
+409: (1, 68)
+410: (2, 68)
+411: (3, 68)
+412: (4, 68)
+413: (5, 68)
+414: (0, 69)
+415: (1, 69)
+416: (2, 69)
+417: (3, 69)
+418: (4, 69)
+419: (5, 69)
+420: (0, 70)
+421: (1, 70)
+422: (2, 70)
+423: (3, 70)
+424: (4, 70)
+425: (5, 70)
+426: (0, 71)
+427: (1, 71)
+428: (2, 71)
+429: (3, 71)
+430: (4, 71)
+431: (5, 71)
+432: (0, 72)
+433: (1, 72)
+434: (2, 72)
+435: (3, 72)
+436: (4, 72)
+437: (5, 72)
+438: (0, 73)
+439: (1, 73)
+440: (2, 73)
+441: (3, 73)
+442: (4, 73)
+443: (5, 73)
+444: (0, 74)
+445: (1, 74)
+446: (2, 74)
+447: (3, 74)
+448: (4, 74)
+449: (5, 74)
+450: (0, 75)
+451: (1, 75)
+452: (2, 75)
+453: (3, 75)
+454: (4, 75)
+455: (5, 75)
+456: (0, 76)
+457: (1, 76)
+458: (2, 76)
+459: (3, 76)
+460: (4, 76)
+461: (5, 76)
+462: (0, 77)
+463: (1, 77)
+464: (2, 77)
+465: (3, 77)
+466: (4, 77)
+467: (5, 77)
+468: (0, 78)
+469: (1, 78)
+470: (2, 78)
+471: (3, 78)
+472: (4, 78)
+473: (5, 78)
+474: (0, 79)
+475: (1, 79)
+476: (2, 79)
+477: (3, 79)
+478: (4, 79)
+479: (5, 79)
+480: (0, 80)
+481: (1, 80)
+482: (2, 80)
+483: (3, 80)
+484: (4, 80)
+485: (5, 80)
+486: (0, 81)
+487: (1, 81)
+488: (2, 81)
+489: (3, 81)
+490: (4, 81)
+491: (5, 81)
+492: (0, 82)
+493: (1, 82)
+494: (2, 82)
+495: (3, 82)
+496: (4, 82)
+497: (5, 82)
+498: (0, 83)
+499: (1, 83)
+500: (2, 83)
+501: (3, 83)
+502: (4, 83)
+503: (5, 83)
+504: (0, 84)
+505: (1, 84)
+506: (2, 84)
+507: (3, 84)
+508: (4, 84)
+509: (5, 84)
+510: (0, 85)
+511: (1, 85)
+512: (2, 85)
+513: (3, 85)
+514: (4, 85)
+515: (5, 85)
+516: (0, 86)
+517: (1, 86)
+518: (2, 86)
+519: (3, 86)
+520: (4, 86)
+521: (5, 86)
+522: (0, 87)
+523: (1, 87)
+524: (2, 87)
+525: (3, 87)
+526: (4, 87)
+527: (5, 87)
+528: (0, 88)
+529: (1, 88)
+530: (2, 88)
+531: (3, 88)
+532: (4, 88)
+533: (5, 88)
+534: (0, 89)
+535: (1, 89)
+536: (2, 89)
+537: (3, 89)
+538: (4, 89)
+539: (5, 89)
+540: (0, 90)
+541: (1, 90)
+542: (2, 90)
+543: (3, 90)
+544: (4, 90)
+545: (5, 90)
+546: (0, 91)
+547: (1, 91)
+548: (2, 91)
+549: (3, 91)
+550: (4, 91)
+551: (5, 91)
+552: (0, 92)
+553: (1, 92)
+554: (2, 92)
+555: (3, 92)
+556: (4, 92)
+557: (5, 92)
+558: (0, 93)
+559: (1, 93)
+560: (2, 93)
+561: (3, 93)
+562: (4, 93)
+563: (5, 93)
+564: (0, 94)
+565: (1, 94)
+566: (2, 94)
+567: (3, 94)
+568: (4, 94)
+569: (5, 94)
+570: (0, 95)
+571: (1, 95)
+572: (2, 95)
+573: (3, 95)
+574: (4, 95)
+575: (5, 95)
+576: (0, 96)
+577: (1, 96)
+578: (2, 96)
+579: (3, 96)
+580: (4, 96)
+581: (5, 96)
+582: (0, 97)
+583: (1, 97)
+584: (2, 97)
+585: (3, 97)
+586: (4, 97)
+587: (5, 97)
+588: (0, 98)
+589: (1, 98)
+590: (2, 98)
+591: (3, 98)
+592: (4, 98)
+593: (5, 98)
+594: (0, 99)
+595: (1, 99)
+596: (2, 99)
+597: (3, 99)
+598: (4, 99)
+599: (5, 99)
+600: (0, 100)
+601: (1, 100)
+602: (2, 100)
+603: (3, 100)
+604: (4, 100)
+605: (5, 100)
+606: (0, 101)
+607: (1, 101)
+608: (2, 101)
+609: (3, 101)
+610: (4, 101)
+611: (5, 101)
+612: (0, 102)
+613: (1, 102)
+614: (2, 102)
+615: (3, 102)
+616: (4, 102)
+617: (5, 102)
+618: (0, 103)
+619: (1, 103)
+620: (2, 103)
+621: (3, 103)
+622: (4, 103)
+623: (5, 103)
+624: (0, 104)
+625: (1, 104)
+626: (2, 104)
+627: (3, 104)
+628: (4, 104)
+629: (5, 104)
+630: (0, 105)
+631: (1, 105)
+632: (2, 105)
+633: (3, 105)
+634: (4, 105)
+635: (5, 105)
+636: (0, 106)
+637: (1, 106)
+638: (2, 106)
+639: (3, 106)
+640: (4, 106)
+641: (5, 106)
+642: (0, 107)
+643: (1, 107)
+644: (2, 107)
+645: (3, 107)
+646: (4, 107)
+647: (5, 107)
+648: (0, 108)
+649: (1, 108)
+650: (2, 108)
+651: (3, 108)
+652: (4, 108)
+653: (5, 108)
+654: (0, 109)
+655: (1, 109)
+656: (2, 109)
+657: (3, 109)
+658: (4, 109)
+659: (5, 109)
+660: (0, 110)
+661: (1, 110)
+662: (2, 110)
+663: (3, 110)
+664: (4, 110)
+665: (5, 110)
+666: (0, 111)
+667: (1, 111)
+668: (2, 111)
+669: (3, 111)
+670: (4, 111)
+671: (5, 111)
+672: (0, 112)
+673: (1, 112)
+674: (2, 112)
+675: (3, 112)
+676: (4, 112)
+677: (5, 112)
+678: (0, 113)
+679: (1, 113)
+680: (2, 113)
+681: (3, 113)
+682: (4, 113)
+683: (5, 113)
+684: (0, 114)
+685: (1, 114)
+686: (2, 114)
+687: (3, 114)
+688: (4, 114)
+689: (5, 114)
+690: (0, 115)
+691: (1, 115)
+692: (2, 115)
+693: (3, 115)
+694: (4, 115)
+695: (5, 115)
+696: (0, 116)
+697: (1, 116)
+698: (2, 116)
+699: (3, 116)
+700: (4, 116)
+701: (5, 116)
+702: (0, 117)
+703: (1, 117)
+704: (2, 117)
+705: (3, 117)
+706: (4, 117)
+707: (5, 117)
+708: (0, 118)
+709: (1, 118)
+710: (2, 118)
+711: (3, 118)
+712: (4, 118)
+713: (5, 118)
+714: (0, 119)
+715: (1, 119)
+716: (2, 119)
+717: (3, 119)
+718: (4, 119)
+719: (5, 119)
+720: (0, 120)
+721: (1, 120)
+722: (2, 120)
+723: (3, 120)
+724: (4, 120)
+725: (5, 120)
+726: (0, 121)
+727: (1, 121)
+728: (2, 121)
+729: (3, 121)
+730: (4, 121)
+731: (5, 121)
+732: (0, 122)
+733: (1, 122)
+734: (2, 122)
+735: (3, 122)
+736: (4, 122)
+737: (5, 122)
+738: (0, 123)
+739: (1, 123)
+740: (2, 123)
+741: (3, 123)
+742: (4, 123)
+743: (5, 123)
+744: (0, 124)
+745: (1, 124)
+746: (2, 124)
+747: (3, 124)
+748: (4, 124)
+749: (5, 124)
+750: (0, 125)
+751: (1, 125)
+752: (2, 125)
+753: (3, 125)
+754: (4, 125)
+755: (5, 125)
+756: (0, 126)
+757: (1, 126)
+758: (2, 126)
+759: (3, 126)
+760: (4, 126)
+761: (5, 126)
+762: (0, 127)
+763: (1, 127)
+764: (2, 127)
+765: (3, 127)
+766: (4, 127)
+767: (5, 127)
+768: (0, 128)
+769: (1, 128)
+770: (2, 128)
+771: (3, 128)
+772: (4, 128)
+773: (5, 128)
+774: (0, 129)
+775: (1, 129)
+776: (2, 129)
+777: (3, 129)
+778: (4, 129)
+779: (5, 129)
+780: (0, 130)
+781: (1, 130)
+782: (2, 130)
+783: (3, 130)
+784: (4, 130)
+785: (5, 130)
+786: (0, 131)
+787: (1, 131)
+788: (2, 131)
+789: (3, 131)
+790: (4, 131)
+791: (5, 131)
+792: (0, 132)
+793: (1, 132)
+794: (2, 132)
+795: (3, 132)
+796: (4, 132)
+797: (5, 132)
+798: (0, 133)
+799: (1, 133)
+800: (2, 133)
+801: (3, 133)
+802: (4, 133)
+803: (5, 133)
+804: (0, 134)
+805: (1, 134)
+806: (2, 134)
+807: (3, 134)
+808: (4, 134)
+809: (5, 134)
+810: (0, 135)
+811: (1, 135)
+812: (2, 135)
+813: (3, 135)
+814: (4, 135)
+815: (5, 135)
+816: (0, 136)
+817: (1, 136)
+818: (2, 136)
+819: (3, 136)
+820: (4, 136)
+821: (5, 136)
+822: (0, 137)
+823: (1, 137)
+824: (2, 137)
+825: (3, 137)
+826: (4, 137)
+827: (5, 137)
+828: (0, 138)
+829: (1, 138)
+830: (2, 138)
+831: (3, 138)
+832: (4, 138)
+833: (5, 138)
+834: (0, 139)
+835: (1, 139)
+836: (2, 139)
+837: (3, 139)
+838: (4, 139)
+839: (5, 139)
+840: (0, 140)
+841: (1, 140)
+842: (2, 140)
+843: (3, 140)
+844: (4, 140)
+845: (5, 140)
+846: (0, 141)
+847: (1, 141)
+848: (2, 141)
+849: (3, 141)
+850: (4, 141)
+851: (5, 141)
+852: (0, 142)
+853: (1, 142)
+854: (2, 142)
+855: (3, 142)
+856: (4, 142)
+857: (5, 142)
+858: (0, 143)
+859: (1, 143)
+860: (2, 143)
+861: (3, 143)
+862: (4, 143)
+863: (5, 143)
+864: (0, 144)
+865: (1, 144)
+866: (2, 144)
+867: (3, 144)
+868: (4, 144)
+869: (5, 144)
+870: (0, 145)
+871: (1, 145)
+872: (2, 145)
+873: (3, 145)
+874: (4, 145)
+875: (5, 145)
+876: (0, 146)
+877: (1, 146)
+878: (2, 146)
+879: (3, 146)
+880: (4, 146)
+881: (5, 146)
+882: (0, 147)
+883: (1, 147)
+884: (2, 147)
+885: (3, 147)
+886: (4, 147)
+887: (5, 147)
+888: (0, 148)
+889: (1, 148)
+890: (2, 148)
+891: (3, 148)
+892: (4, 148)
+893: (5, 148)
+894: (0, 149)
+895: (1, 149)
+896: (2, 149)
+897: (3, 149)
+898: (4, 149)
+899: (5, 149)
+900: (0, 150)
+901: (1, 150)
+902: (2, 150)
+903: (3, 150)
+904: (4, 150)
+905: (5, 150)
+906: (0, 151)
+907: (1, 151)
+908: (2, 151)
+909: (3, 151)
+910: (4, 151)
+911: (5, 151)
+912: (0, 152)
+913: (1, 152)
+914: (2, 152)
+915: (3, 152)
+916: (4, 152)
+917: (5, 152)
+918: (0, 153)
+919: (1, 153)
+920: (2, 153)
+921: (3, 153)
+922: (4, 153)
+923: (5, 153)
+924: (0, 154)
+925: (1, 154)
+926: (2, 154)
+927: (3, 154)
+928: (4, 154)
+929: (5, 154)
+930: (0, 155)
+931: (1, 155)
+932: (2, 155)
+933: (3, 155)
+934: (4, 155)
+935: (5, 155)
+936: (0, 156)
+937: (1, 156)
+938: (2, 156)
+939: (3, 156)
+940: (4, 156)
+941: (5, 156)
+942: (0, 157)
+943: (1, 157)
+944: (2, 157)
+945: (3, 157)
+946: (4, 157)
+947: (5, 157)
+948: (0, 158)
+949: (1, 158)
+950: (2, 158)
+951: (3, 158)
+952: (4, 158)
+953: (5, 158)
+954: (0, 159)
+955: (1, 159)
+956: (2, 159)
+957: (3, 159)
+958: (4, 159)
+959: (5, 159)
+960: (0, 160)
+961: (1, 160)
+962: (2, 160)
+963: (3, 160)
+964: (4, 160)
+965: (5, 160)
+966: (0, 161)
+967: (1, 161)
+968: (2, 161)
+969: (3, 161)
+970: (4, 161)
+971: (5, 161)
+972: (0, 162)
+973: (1, 162)
+974: (2, 162)
+975: (3, 162)
+976: (4, 162)
+977: (5, 162)
+978: (0, 163)
+979: (1, 163)
+980: (2, 163)
+981: (3, 163)
+982: (4, 163)
+983: (5, 163)
+984: (0, 164)
+985: (1, 164)
+986: (2, 164)
+987: (3, 164)
+988: (4, 164)
+989: (5, 164)
+990: (0, 165)
+991: (1, 165)
+992: (2, 165)
+993: (3, 165)
+994: (4, 165)
+995: (5, 165)
+996: (0, 166)
+997: (1, 166)
+998: (2, 166)
+999: (3, 166)
+1000: (4, 166)
+1001: (5, 166)
+1002: (0, 167)
+1003: (1, 167)
+1004: (2, 167)
+1005: (3, 167)
+1006: (4, 167)
+1007: (5, 167)
+1008: (0, 168)
+1009: (1, 168)
+1010: (2, 168)
+1011: (3, 168)
+1012: (4, 168)
+1013: (5, 168)
+1014: (0, 169)
+1015: (1, 169)
+1016: (2, 169)
+1017: (3, 169)
+1018: (4, 169)
+1019: (5, 169)
+1020: (0, 170)
+1021: (1, 170)
+1022: (2, 170)
+1023: (3, 170)
+1024: (4, 170)
+1025: (5, 170)
+1026: (0, 171)
+1027: (1, 171)
+1028: (2, 171)
+1029: (3, 171)
+1030: (4, 171)
+1031: (5, 171)
+1032: (0, 172)
+1033: (1, 172)
+1034: (2, 172)
+1035: (3, 172)
+1036: (4, 172)
+1037: (5, 172)
+1038: (0, 173)
+1039: (1, 173)
+1040: (2, 173)
+1041: (3, 173)
+1042: (4, 173)
+1043: (5, 173)
+1044: (0, 174)
+1045: (1, 174)
+1046: (2, 174)
+1047: (3, 174)
+1048: (4, 174)
+1049: (5, 174)
+1050: (0, 175)
+1051: (1, 175)
+1052: (2, 175)
+1053: (3, 175)
+1054: (4, 175)
+1055: (5, 175)
+1056: (0, 176)
+1057: (1, 176)
+1058: (2, 176)
+1059: (3, 176)
+1060: (4, 176)
+1061: (5, 176)
+1062: (0, 177)
+1063: (1, 177)
+1064: (2, 177)
+1065: (3, 177)
+1066: (4, 177)
+1067: (5, 177)
+1068: (0, 178)
+1069: (1, 178)
+1070: (2, 178)
+1071: (3, 178)
+1072: (4, 178)
+1073: (5, 178)
+1074: (0, 179)
+1075: (1, 179)
+1076: (2, 179)
+1077: (3, 179)
+1078: (4, 179)
+1079: (5, 179)
+1080: (0, 180)
+1081: (1, 180)
+1082: (2, 180)
+1083: (3, 180)
+1084: (4, 180)
+1085: (5, 180)
+1086: (0, 181)
+1087: (1, 181)
+1088: (2, 181)
+1089: (3, 181)
+1090: (4, 181)
+1091: (5, 181)
+1092: (0, 182)
+1093: (1, 182)
+1094: (2, 182)
+1095: (3, 182)
+1096: (4, 182)
+1097: (5, 182)
+1098: (0, 183)
+1099: (1, 183)
+1100: (2, 183)
+1101: (3, 183)
+1102: (4, 183)
+1103: (5, 183)
+1104: (0, 184)
+1105: (1, 184)
+1106: (2, 184)
+1107: (3, 184)
+1108: (4, 184)
+1109: (5, 184)
+1110: (0, 185)
+1111: (1, 185)
+1112: (2, 185)
+1113: (3, 185)
+1114: (4, 185)
+1115: (5, 185)
+1116: (0, 186)
+1117: (1, 186)
+1118: (2, 186)
+1119: (3, 186)
+1120: (4, 186)
+1121: (5, 186)
+1122: (0, 187)
+1123: (1, 187)
+1124: (2, 187)
+1125: (3, 187)
+1126: (4, 187)
+1127: (5, 187)
+1128: (0, 188)
+1129: (1, 188)
+1130: (2, 188)
+1131: (3, 188)
+1132: (4, 188)
+1133: (5, 188)
+1134: (0, 189)
+1135: (1, 189)
+1136: (2, 189)
+1137: (3, 189)
+1138: (4, 189)
+1139: (5, 189)
+1140: (0, 190)
+1141: (1, 190)
+1142: (2, 190)
+1143: (3, 190)
+1144: (4, 190)
+1145: (5, 190)
+1146: (0, 191)
+1147: (1, 191)
+1148: (2, 191)
+1149: (3, 191)
+1150: (4, 191)
+1151: (5, 191)
+1152: (0, 192)
+1153: (1, 192)
+1154: (2, 192)
+1155: (3, 192)
+1156: (4, 192)
+1157: (5, 192)
+1158: (0, 193)
+1159: (1, 193)
+1160: (2, 193)
+1161: (3, 193)
+1162: (4, 193)
+1163: (5, 193)
+1164: (0, 194)
+1165: (1, 194)
+1166: (2, 194)
+1167: (3, 194)
+1168: (4, 194)
+1169: (5, 194)
+1170: (0, 195)
+1171: (1, 195)
+1172: (2, 195)
+1173: (3, 195)
+1174: (4, 195)
+1175: (5, 195)
+1176: (0, 196)
+1177: (1, 196)
+1178: (2, 196)
+1179: (3, 196)
+1180: (4, 196)
+1181: (5, 196)
+1182: (0, 197)
+1183: (1, 197)
+1184: (2, 197)
+1185: (3, 197)
+1186: (4, 197)
+1187: (5, 197)
+1188: (0, 198)
+1189: (1, 198)
+1190: (2, 198)
+1191: (3, 198)
+1192: (4, 198)
+1193: (5, 198)
+1194: (0, 199)
+1195: (1, 199)
+1196: (2, 199)
+1197: (3, 199)
+1198: (4, 199)
+1199: (5, 199)
+1200: (0, 200)
+1201: (1, 200)
+1202: (2, 200)
+1203: (3, 200)
+1204: (4, 200)
+1205: (5, 200)
+1206: (0, 201)
+1207: (1, 201)
+1208: (2, 201)
+1209: (3, 201)
+1210: (4, 201)
+1211: (5, 201)
+1212: (0, 202)
+1213: (1, 202)
+1214: (2, 202)
+1215: (3, 202)
+1216: (4, 202)
+1217: (5, 202)
+1218: (0, 203)
+1219: (1, 203)
+1220: (2, 203)
+1221: (3, 203)
+1222: (4, 203)
+1223: (5, 203)
+1224: (0, 204)
+1225: (1, 204)
+1226: (2, 204)
+1227: (3, 204)
+1228: (4, 204)
+1229: (5, 204)
+1230: (0, 205)
+1231: (1, 205)
+1232: (2, 205)
+1233: (3, 205)
+1234: (4, 205)
+1235: (5, 205)
+1236: (0, 206)
+1237: (1, 206)
+1238: (2, 206)
+1239: (3, 206)
+1240: (4, 206)
+1241: (5, 206)
+1242: (0, 207)
+1243: (1, 207)
+1244: (2, 207)
+1245: (3, 207)
+1246: (4, 207)
+1247: (5, 207)
+1248: (0, 208)
+1249: (1, 208)
+1250: (2, 208)
+1251: (3, 208)
+1252: (4, 208)
+1253: (5, 208)
+1254: (0, 209)
+1255: (1, 209)
+1256: (2, 209)
+1257: (3, 209)
+1258: (4, 209)
+1259: (5, 209)
+1260: (0, 210)
+1261: (1, 210)
+1262: (2, 210)
+1263: (3, 210)
+1264: (4, 210)
+1265: (5, 210)
+1266: (0, 211)
+1267: (1, 211)
+1268: (2, 211)
+1269: (3, 211)
+1270: (4, 211)
+1271: (5, 211)
+1272: (0, 212)
+1273: (1, 212)
+1274: (2, 212)
+1275: (3, 212)
+1276: (4, 212)
+1277: (5, 212)
+1278: (0, 213)
+1279: (1, 213)
+1280: (2, 213)
+1281: (3, 213)
+1282: (4, 213)
+1283: (5, 213)
+1284: (0, 214)
+1285: (1, 214)
+1286: (2, 214)
+1287: (3, 214)
+1288: (4, 214)
+1289: (5, 214)
+1290: (0, 215)
+1291: (1, 215)
+1292: (2, 215)
+1293: (3, 215)
+1294: (4, 215)
+1295: (5, 215)
+1296: (0, 216)
+1297: (1, 216)
+1298: (2, 216)
+1299: (3, 216)
+1300: (4, 216)
+1301: (5, 216)
+1302: (0, 217)
+1303: (1, 217)
+1304: (2, 217)
+1305: (3, 217)
+1306: (4, 217)
+1307: (5, 217)
+1308: (0, 218)
+1309: (1, 218)
+1310: (2, 218)
+1311: (3, 218)
+1312: (4, 218)
+1313: (5, 218)
+1314: (0, 219)
+1315: (1, 219)
+1316: (2, 219)
+1317: (3, 219)
+1318: (4, 219)
+1319: (5, 219)
+1320: (0, 220)
+1321: (1, 220)
+1322: (2, 220)
+1323: (3, 220)
+1324: (4, 220)
+1325: (5, 220)
+1326: (0, 221)
+1327: (1, 221)
+1328: (2, 221)
+1329: (3, 221)
+1330: (4, 221)
+1331: (5, 221)
+1332: (0, 222)
+1333: (1, 222)
+1334: (2, 222)
+1335: (3, 222)
+1336: (4, 222)
+1337: (5, 222)
+1338: (0, 223)
+1339: (1, 223)
+1340: (2, 223)
+1341: (3, 223)
+1342: (4, 223)
+1343: (5, 223)
+1344: (0, 224)
+1345: (1, 224)
+1346: (2, 224)
+1347: (3, 224)
+1348: (4, 224)
+1349: (5, 224)
+1350: (0, 225)
+1351: (1, 225)
+1352: (2, 225)
+1353: (3, 225)
+1354: (4, 225)
+1355: (5, 225)
+1356: (0, 226)
+1357: (1, 226)
+1358: (2, 226)
+1359: (3, 226)
+1360: (4, 226)
+1361: (5, 226)
+1362: (0, 227)
+1363: (1, 227)
+1364: (2, 227)
+1365: (3, 227)
+1366: (4, 227)
+1367: (5, 227)
+1368: (0, 228)
+1369: (1, 228)
+1370: (2, 228)
+1371: (3, 228)
+1372: (4, 228)
+1373: (5, 228)
+1374: (0, 229)
+1375: (1, 229)
+1376: (2, 229)
+1377: (3, 229)
+1378: (4, 229)
+1379: (5, 229)
+1380: (0, 230)
+1381: (1, 230)
+1382: (2, 230)
+1383: (3, 230)
+1384: (4, 230)
+1385: (5, 230)
+1386: (0, 231)
+1387: (1, 231)
+1388: (2, 231)
+1389: (3, 231)
+1390: (4, 231)
+1391: (5, 231)
+1392: (0, 232)
+1393: (1, 232)
+1394: (2, 232)
+1395: (3, 232)
+1396: (4, 232)
+1397: (5, 232)
+1398: (1, 233)
+1399: (2, 233)
+1400: (3, 233)
+1401: (4, 233)
+1402: (5, 233)
+1403: (2, 234)
+1404: (3, 234)
+1405: (4, 234)
+1406: (2, 235)
+1407: (3, 235)
+1408: (4, 235)
+1409: (2, 236)
+1410: (3, 236)
+1411: (4, 236)
+1412: (2, 237)
+1413: (3, 237)
+1414: (4, 237)
+1415: (2, 238)
+1416: (3, 238)
+
+; Merges (added edges)
+; Format is:
+;   source_column -> dest_column
+; (new accuracy is source_column_accuracy + dest_column_accuracy + accuracy_change)
+; (note that all accuracies are unnormalized)
+
+120 -> 131
+1357 -> 1388
+126 -> 137
+750 -> 761
+756 -> 767
+1266 -> 1277
+1344 -> 1355
+762 -> 773
+1062 -> 1073
+1068 -> 1079
+768 -> 779
+846 -> 857
+906 -> 917
+918 -> 929
+924 -> 935
+923 -> 912
+852 -> 863
+870 -> 881
+882 -> 893
+887 -> 876
+858 -> 869
+875 -> 864
+828 -> 839
+834 -> 845
+851 -> 840
+306 -> 317
+312 -> 323
+390 -> 401
+630 -> 641
+654 -> 665
+660 -> 671
+678 -> 689
+666 -> 677
+683 -> 672
+636 -> 647
+642 -> 653
+659 -> 648
+396 -> 407
+420 -> 431
+426 -> 437
+432 -> 443
+318 -> 329
+324 -> 335
+330 -> 341
+336 -> 347
+889 -> 902
+895 -> 908
+1272 -> 1283
+755 -> 744
+450 -> 461
+1067 -> 1056
+1074 -> 1085
+635 -> 624
+438 -> 449
+455 -> 444
+378 -> 389
+132 -> 143
+258 -> 269
+1350 -> 1361
+425 -> 414
+395 -> 384
+402 -> 413
+342 -> 353
+1278 -> 1289
+1080 -> 1091
+911 -> 900
+573 -> 572
+749 -> 738
+419 -> 408
+263 -> 252
+133 -> 147
+1349 -> 1338
+1271 -> 1260
+1149 -> 1148
+459 -> 458
+576 -> 587
+146 -> 141
+896 -> 883
+804 -> 815
+833 -> 822
+125 -> 114
+1137 -> 1136
+1155 -> 1154
+1143 -> 1142
+555 -> 554
+561 -> 560
+567 -> 566
+477 -> 476
+465 -> 464
+348 -> 359
+445 -> 459
+774 -> 785
+582 -> 593
+498 -> 509
+319 -> 333
+325 -> 339
+1404 -> 1403
+1395 -> 1394
+1400 -> 1399
+915 -> 914
+657 -> 656
+669 -> 668
+675 -> 674
+681 -> 680
+579 -> 578
+483 -> 482
+471 -> 470
+453 -> 452
+158 -> 153
+503 -> 492
+133 -> 152
+581 -> 570
+383 -> 372
+1265 -> 1254
+1382 -> 1383
+1119 -> 1118
+1125 -> 1124
+1131 -> 1130
+777 -> 776
+759 -> 758
+663 -> 662
+549 -> 548
+743 -> 732
+138 -> 149
+456 -> 467
+204 -> 215
+889 -> 903
+1416 -> 1415
+1161 -> 1160
+771 -> 770
+504 -> 515
+210 -> 221
+146 -> 127
+895 -> 909
+727 -> 741
+451 -> 465
+897 -> 896
+765 -> 764
+687 -> 686
+693 -> 692
+684 -> 695
+865 -> 879
+337 -> 351
+327 -> 313
+345 -> 331
+1284 -> 1295
+1113 -> 1112
+827 -> 816
+164 -> 159
+711 -> 710
+821 -> 810
+780 -> 791
+453 -> 439
+1407 -> 1406
+1107 -> 1106
+747 -> 746
+409 -> 423
+888 -> 899
+834 -> 853
+1275 -> 1274
+753 -> 752
+1259 -> 1248
+905 -> 894
+699 -> 698
+116 -> 111
+697 -> 711
+343 -> 357
+891 -> 890
+705 -> 704
+543 -> 542
+1416 -> 1398
+1253 -> 1242
+809 -> 798
+1081 -> 1095
+873 -> 859
+354 -> 365
+168 -> 179
+457 -> 471
+1087 -> 1101
+846 -> 878
+651 -> 650
+173 -> 162
+1045 -> 1059
+1356 -> 1367
+182 -> 177
+188 -> 183
+1089 -> 1075
+939 -> 938
+639 -> 638
+803 -> 792
+194 -> 189
+510 -> 521
+679 -> 693
+140 -> 135
+871 -> 885
+687 -> 673
+1167 -> 1166
+170 -> 165
+377 -> 366
+681 -> 667
+797 -> 786
+489 -> 488
+200 -> 195
+176 -> 171
+371 -> 360
+930 -> 941
+1377 -> 1376
+597 -> 596
+462 -> 473
+1247 -> 1236
+931 -> 945
+645 -> 644
+513 -> 512
+463 -> 477
+705 -> 691
+139 -> 158
+951 -> 950
+591 -> 590
+699 -> 685
+349 -> 363
+259 -> 273
+585 -> 584
+122 -> 117
+783 -> 782
+209 -> 198
+1363 -> 1395
+633 -> 632
+501 -> 500
+264 -> 275
+897 -> 875
+1053 -> 1039
+265 -> 279
+1005 -> 1004
+1061 -> 1050
+999 -> 998
+957 -> 956
+507 -> 506
+1343 -> 1332
+234 -> 245
+257 -> 246
+1083 -> 1069
+735 -> 721
+218 -> 213
+852 -> 884
+272 -> 267
+206 -> 201
+128 -> 123
+495 -> 494
+1185 -> 1184
+110 -> 105
+251 -> 240
+216 -> 227
+306 -> 322
+390 -> 422
+396 -> 428
+943 -> 957
+643 -> 657
+891 -> 877
+1371 -> 1370
+901 -> 915
+870 -> 889
+47 -> 42
+963 -> 962
+921 -> 920
+447 -> 446
+144 -> 155
+1269 -> 1268
+537 -> 536
+134 -> 129
+468 -> 479
+981 -> 980
+174 -> 185
+933 -> 932
+819 -> 818
+212 -> 207
+717 -> 716
+497 -> 486
+321 -> 307
+847 -> 828
+813 -> 812
+311 -> 300
+312 -> 328
+474 -> 485
+222 -> 233
+239 -> 228
+1362 -> 1373
+553 -> 567
+415 -> 429
+356 -> 337
+469 -> 483
+203 -> 192
+1413 -> 1412
+854 -> 855
+575 -> 564
+1011 -> 1010
+675 -> 661
+1410 -> 1409
+180 -> 191
+167 -> 156
+516 -> 527
+872 -> 851
+1382 -> 1344
+161 -> 150
+751 -> 765
+757 -> 771
+53 -> 48
+763 -> 777
+531 -> 530
+993 -> 992
+491 -> 480
+1249 -> 1275
+1290 -> 1301
+1299 -> 1298
+703 -> 717
+1086 -> 1097
+1350 -> 1389
+759 -> 745
+727 -> 740
+733 -> 747
+1281 -> 1280
+197 -> 186
+927 -> 926
+441 -> 440
+649 -> 663
+378 -> 410
+1046 -> 1047
+837 -> 836
+690 -> 724
+987 -> 986
+416 -> 395
+305 -> 294
+834 -> 867
+1369 -> 1400
+421 -> 434
+1093 -> 1107
+588 -> 599
+522 -> 533
+1055 -> 1044
+271 -> 285
+1173 -> 1172
+860 -> 861
+951 -> 937
+972 -> 983
+1350 -> 1357
+1179 -> 1178
+627 -> 626
+795 -> 762
+978 -> 989
+642 -> 676
+870 -> 898
+729 -> 715
+1191 -> 1190
+939 -> 925
+1049 -> 1038
+1052 -> 1053
+629 -> 618
+753 -> 739
+975 -> 974
+723 -> 722
+336 -> 368
+669 -> 655
+224 -> 219
+969 -> 968
+949 -> 963
+990 -> 1001
+996 -> 1007
+1092 -> 1103
+995 -> 984
+1054 -> 1045
+1043 -> 1032
+145 -> 164
+977 -> 966
+936 -> 947
+944 -> 931
+1381 -> 1407
+891 -> 858
+1255 -> 1281
+719 -> 708
+705 -> 683
+621 -> 620
+603 -> 602
+825 -> 824
+41 -> 36
+1100 -> 1087
+519 -> 518
+448 -> 426
+696 -> 707
+1329 -> 1328
+1404 -> 1375
+831 -> 830
+971 -> 960
+948 -> 959
+699 -> 666
+447 -> 433
+561 -> 547
+965 -> 954
+421 -> 435
+1017 -> 1016
+133 -> 132
+1241 -> 1230
+702 -> 713
+1041 -> 1040
+737 -> 726
+906 -> 934
+355 -> 369
+272 -> 253
+1287 -> 1286
+953 -> 942
+615 -> 614
+872 -> 873
+609 -> 608
+525 -> 524
+35 -> 30
+849 -> 848
+5 -> 0
+887 -> 904
+843 -> 842
+361 -> 375
+1305 -> 1304
+1077 -> 1063
+714 -> 725
+789 -> 756
+731 -> 720
+723 -> 709
+659 -> 682
+1402 -> 1392
+282 -> 293
+559 -> 573
+887 -> 895
+404 -> 383
+1051 -> 1065
+1263 -> 1262
+270 -> 281
+1090 -> 1081
+1293 -> 1292
+1335 -> 1334
+1037 -> 1026
+266 -> 261
+441 -> 427
+623 -> 612
+92 -> 87
+299 -> 288
+350 -> 345
+734 -> 735
+287 -> 276
+104 -> 99
+728 -> 729
+199 -> 218
+871 -> 852
+670 -> 636
+1015 -> 1029
+1323 -> 1322
+119 -> 108
+1021 -> 1035
+1317 -> 1316
+296 -> 291
+451 -> 432
+1227 -> 1226
+865 -> 846
+29 -> 24
+98 -> 93
+1351 -> 1378
+259 -> 278
+1311 -> 1310
+569 -> 558
+1071 -> 1057
+1022 -> 1023
+442 -> 420
+23 -> 18
+11 -> 6
+140 -> 121
+1099 -> 1113
+1048 -> 1031
+807 -> 806
+985 -> 999
+230 -> 225
+17 -> 12
+675 -> 642
+801 -> 800
+1098 -> 1109
+841 -> 854
+991 -> 1005
+625 -> 639
+1002 -> 1013
+1413 -> 1393
+1372 -> 1345
+783 -> 750
+860 -> 847
+1068 -> 1096
+59 -> 54
+187 -> 206
+1042 -> 1025
+367 -> 381
+126 -> 142
+163 -> 182
+1337 -> 1326
+659 -> 681
+1410 -> 1387
+1008 -> 1019
+679 -> 660
+212 -> 193
+617 -> 606
+933 -> 919
+651 -> 637
+1221 -> 1220
+176 -> 157
+817 -> 831
+823 -> 837
+342 -> 374
+451 -> 454
+1074 -> 1102
+348 -> 380
+170 -> 151
+633 -> 619
+362 -> 343
+654 -> 688
+993 -> 979
+417 -> 403
+1397 -> 1386
+834 -> 866
+236 -> 231
+928 -> 911
+1365 -> 1364
+1046 -> 1033
+200 -> 181
+315 -> 301
+594 -> 605
+1257 -> 1256
+1269 -> 1243
+645 -> 631
+1080 -> 1108
+242 -> 237
+1251 -> 1250
+373 -> 387
+1207 -> 1233
+611 -> 600
+1368 -> 1379
+248 -> 243
+1331 -> 1320
+1391 -> 1380
+1084 -> 1089
+169 -> 188
+1245 -> 1244
+1385 -> 1374
+1341 -> 1340
+528 -> 539
+302 -> 297
+555 -> 541
+923 -> 940
+1239 -> 1238
+379 -> 393
+1296 -> 1307
+260 -> 255
+314 -> 309
+1215 -> 1214
+1235 -> 1224
+475 -> 489
+534 -> 545
+254 -> 249
+308 -> 303
+1353 -> 1352
+1359 -> 1358
+194 -> 175
+939 -> 906
+1302 -> 1313
+1356 -> 1363
+354 -> 386
+445 -> 448
+318 -> 334
+136 -> 120
+1366 -> 1339
+678 -> 697
+1105 -> 1119
+1104 -> 1115
+583 -> 597
+955 -> 969
+398 -> 377
+1229 -> 1218
+205 -> 224
+789 -> 788
+65 -> 60
+392 -> 371
+388 -> 385
+1347 -> 1346
+892 -> 897
+627 -> 613
+565 -> 579
+997 -> 1011
+1377 -> 1349
+438 -> 457
+1223 -> 1212
+1325 -> 1314
+1319 -> 1308
+1197 -> 1196
+687 -> 654
+591 -> 577
+987 -> 973
+669 -> 670
+133 -> 148
+1209 -> 1208
+882 -> 910
+1052 -> 1048
+961 -> 975
+801 -> 768
+540 -> 551
+113 -> 102
+453 -> 442
+933 -> 928
+138 -> 139
+841 -> 833
+981 -> 967
+664 -> 630
+563 -> 552
+1100 -> 1068
+557 -> 546
+585 -> 571
+411 -> 397
+266 -> 247
+1203 -> 1202
+825 -> 811
+86 -> 81
+415 -> 418
+344 -> 325
+922 -> 905
+405 -> 391
+679 -> 694
+1263 -> 1237
+265 -> 284
+1111 -> 1125
+455 -> 463
+658 -> 643
+916 -> 921
+649 -> 664
+1273 -> 1299
+1217 -> 1206
+794 -> 795
+362 -> 330
+75 -> 71
+211 -> 230
+923 -> 944
+1090 -> 1062
+409 -> 412
+316 -> 311
+774 -> 807
+927 -> 913
+436 -> 425
+882 -> 901
+799 -> 813
+1261 -> 1287
+1371 -> 1343
+1117 -> 1131
+1211 -> 1200
+916 -> 888
+819 -> 805
+134 -> 115
+356 -> 324
+126 -> 146
+1246 -> 1231
+621 -> 607
+438 -> 460
+1293 -> 1267
+918 -> 951
+3 -> 1
+1205 -> 1194
+528 -> 561
+763 -> 755
+260 -> 241
+555 -> 522
+804 -> 823
+534 -> 553
+849 -> 835
+1199 -> 1188
+843 -> 829
+128 -> 109
+684 -> 703
+1064 -> 1051
+27 -> 25
+1362 -> 1369
+589 -> 603
+229 -> 248
+1046 -> 1042
+927 -> 922
+849 -> 827
+1110 -> 1121
+1225 -> 1251
+1003 -> 1017
+1193 -> 1182
+254 -> 235
+843 -> 821
+549 -> 516
+310 -> 305
+595 -> 609
+21 -> 19
+615 -> 601
+916 -> 907
+9 -> 7
+1187 -> 1176
+130 -> 125
+450 -> 469
+1083 -> 1078
+924 -> 943
+799 -> 780
+783 -> 769
+15 -> 13
+543 -> 510
+1041 -> 1027
+356 -> 340
+918 -> 946
+1245 -> 1219
+419 -> 441
+1086 -> 1114
+33 -> 31
+1227 -> 1201
+1350 -> 1384
+1077 -> 1072
+699 -> 700
+217 -> 236
+263 -> 268
+1071 -> 1066
+242 -> 223
+658 -> 635
+4 -> 2
+455 -> 466
+1249 -> 1247
+1207 -> 1232
+112 -> 107
+145 -> 144
+1239 -> 1213
+364 -> 361
+74 -> 69
+481 -> 495
+1360 -> 1333
+292 -> 287
+336 -> 349
+930 -> 949
+1279 -> 1305
+421 -> 402
+447 -> 436
+1221 -> 1195
+1181 -> 1170
+1034 -> 1021
+304 -> 299
+124 -> 119
+1123 -> 1137
+1116 -> 1127
+298 -> 282
+1058 -> 1054
+415 -> 396
+1094 -> 1090
+1351 -> 1382
+1365 -> 1337
+370 -> 367
+358 -> 355
+1175 -> 1164
+1022 -> 1009
+271 -> 290
+1074 -> 1093
+487 -> 501
+1092 -> 1120
+1028 -> 1015
+138 -> 154
+886 -> 891
+170 -> 161
+1060 -> 1043
+706 -> 705
+701 -> 723
+122 -> 103
+540 -> 559
+924 -> 952
+1122 -> 1133
+424 -> 421
+1169 -> 1158
+286 -> 270
+419 -> 430
+1084 -> 1067
+1012 -> 1003
+258 -> 274
+277 -> 296
+376 -> 373
+1098 -> 1126
+1128 -> 1139
+1163 -> 1152
+1157 -> 1146
+1134 -> 1145
+280 -> 264
+1253 -> 1255
+417 -> 406
+1151 -> 1140
+774 -> 793
+1041 -> 1036
+106 -> 101
+749 -> 772
+1022 -> 1018
+557 -> 565
+350 -> 318
+68 -> 63
+450 -> 472
+1006 -> 997
+1080 -> 1099
+1359 -> 1331
+817 -> 809
+797 -> 819
+712 -> 678
+283 -> 302
+382 -> 379
+537 -> 504
+825 -> 803
+775 -> 789
+1215 -> 1189
+517 -> 531
+118 -> 113
+549 -> 535
+262 -> 257
+493 -> 507
+718 -> 684
+167 -> 176
+388 -> 399
+519 -> 497
+1368 -> 1404
+652 -> 651
+140 -> 136
+563 -> 585
+394 -> 405
+1058 -> 1037
+1083 -> 1061
+1024 -> 996
+411 -> 400
+1285 -> 1311
+250 -> 234
+513 -> 499
+936 -> 955
+1240 -> 1223
+525 -> 511
+256 -> 251
+569 -> 591
+1356 -> 1390
+1077 -> 1055
+714 -> 748
+1000 -> 991
+1034 -> 1030
+930 -> 958
+1362 -> 1396
+1071 -> 1049
+409 -> 390
+338 -> 319
+116 -> 97
+575 -> 583
+1246 -> 1229
+1064 -> 1060
+1269 -> 1241
+731 -> 754
+1353 -> 1325
+173 -> 163
+1354 -> 1327
+1234 -> 1217
+543 -> 529
+1296 -> 1335
+1022 -> 990
+953 -> 961
+794 -> 781
+39 -> 37
+766 -> 743
+1302 -> 1341
+1024 -> 1028
+801 -> 787
+1413 -> 1397
+1329 -> 1290
+1006 -> 978
+1104 -> 1132
+1012 -> 995
+332 -> 327
+1279 -> 1266
+985 -> 977
+1416 -> 1402
+1000 -> 972
+45 -> 43
+1008 -> 1041
+346 -> 362
+742 -> 719
+1347 -> 1319
+749 -> 757
+51 -> 49
+948 -> 981
+1385 -> 1381
+10 -> 8
+1034 -> 1002
+1410 -> 1391
+1052 -> 1020
+1317 -> 1278
+244 -> 239
+1209 -> 1183
+987 -> 982
+1263 -> 1235
+690 -> 701
+936 -> 964
+160 -> 145
+493 -> 474
+112 -> 96
+993 -> 971
+1088 -> 1084
+238 -> 222
+880 -> 871
+232 -> 216
+1046 -> 1014
+1071 -> 1070
+760 -> 737
+537 -> 523
+953 -> 970
+289 -> 308
+1323 -> 1284
+167 -> 172
+487 -> 468
+1076 -> 1077
+948 -> 976
+763 -> 778
+326 -> 321
+696 -> 730
+987 -> 965
+314 -> 295
+352 -> 336
+733 -> 714
+1228 -> 1211
+1082 -> 1083
+513 -> 491
+1291 -> 1317
+1416 -> 1414
+1411 -> 1413
+1285 -> 1272
+104 -> 95
+1282 -> 1265
+993 -> 988
+456 -> 475
+481 -> 462
+994 -> 985
+727 -> 742
+753 -> 731
+1368 -> 1401
+696 -> 728
+505 -> 519
+734 -> 736
+320 -> 315
+517 -> 498
+203 -> 212
+734 -> 702
+205 -> 220
+760 -> 759
+645 -> 646
+1110 -> 1138
+214 -> 199
+1271 -> 1288
+344 -> 312
+92 -> 83
+1276 -> 1259
+80 -> 76
+202 -> 187
+62 -> 57
+166 -> 170
+98 -> 89
+226 -> 210
+203 -> 208
+1385 -> 1405
+1408 -> 1410
+16 -> 14
+652 -> 629
+581 -> 589
+86 -> 77
+525 -> 503
+874 -> 865
+576 -> 595
+1372 -> 1377
+1323 -> 1297
+1129 -> 1143
+196 -> 180
+202 -> 197
+1203 -> 1177
+184 -> 168
+364 -> 348
+868 -> 872
+766 -> 751
+209 -> 214
+22 -> 20
+633 -> 611
+627 -> 594
+1150 -> 1122
+1222 -> 1205
+28 -> 26
+110 -> 106
+617 -> 625
+190 -> 174
+1144 -> 1116
+1249 -> 1264
+184 -> 169
+34 -> 32
+178 -> 173
+40 -> 38
+1216 -> 1199
+582 -> 615
+645 -> 623
+196 -> 200
+66 -> 61
+1159 -> 1185
+104 -> 100
+1261 -> 1276
+1197 -> 1171
+1366 -> 1371
+1270 -> 1253
+272 -> 263
+74 -> 70
+358 -> 342
+1191 -> 1165
+205 -> 204
+621 -> 588
+1163 -> 1180
+1174 -> 1157
+1271 -> 1273
+266 -> 262
+1175 -> 1192
+190 -> 194
+65 -> 55
+1210 -> 1193
+1086 -> 1105
+1168 -> 1151
+1348 -> 1321
+1204 -> 1187
+1228 -> 1239
+1303 -> 1329
+1216 -> 1227
+134 -> 130
+259 -> 258
+1186 -> 1169
+1092 -> 1111
+1293 -> 1282
+260 -> 256
+254 -> 250
+1198 -> 1181
+1222 -> 1207
+1128 -> 1156
+456 -> 478
+1279 -> 1294
+265 -> 280
+1098 -> 1117
+1285 -> 1300
+1342 -> 1315
+1291 -> 1306
+72 -> 67
+90 -> 85
+417 -> 416
+244 -> 229
+84 -> 79
+78 -> 73
+68 -> 64
+1365 -> 1360
+783 -> 784
+1221 -> 1210
+128 -> 124
+10 -> 9
+59 -> 51
+1234 -> 1245
+640 -> 617
+862 -> 834
+211 -> 226
+40 -> 39
+98 -> 94
+22 -> 21
+411 -> 378
+16 -> 15
+238 -> 242
+232 -> 217
+1162 -> 1134
+46 -> 45
+34 -> 33
+80 -> 75
+110 -> 91
+62 -> 58
+1168 -> 1153
+1225 -> 1240
+1258 -> 1269
+1323 -> 1312
+856 -> 860
+1257 -> 1246
+370 -> 354
+4 -> 3
+1215 -> 1204
+481 -> 484
+376 -> 392
+775 -> 790
+86 -> 82
+88 -> 92
+534 -> 538
+394 -> 404
+1359 -> 1354
+28 -> 27
+1303 -> 1318
+122 -> 118
+1135 -> 1149
+11 -> 10
+1336 -> 1309
+68 -> 66
+528 -> 532
+1104 -> 1123
+17 -> 16
+326 -> 310
+1263 -> 1252
+1110 -> 1129
+557 -> 550
+540 -> 544
+46 -> 44
+74 -> 72
+794 -> 796
+23 -> 22
+1186 -> 1197
+271 -> 286
+487 -> 490
+1144 -> 1135
+801 -> 802
+774 -> 808
+116 -> 112
+634 -> 633
+80 -> 78
+1175 -> 1203
+1209 -> 1198
+850 -> 841
+277 -> 292
+1147 -> 1128
+1141 -> 1150
+5 -> 4
+817 -> 826
+1336 -> 1302
+1353 -> 1348
+382 -> 398
+1191 -> 1163
+843 -> 838
+1159 -> 1174
+832 -> 804
+496 -> 493
+1179 -> 1168
+283 -> 298
+555 -> 526
+1347 -> 1342
+316 -> 332
+338 -> 306
+29 -> 28
+1141 -> 1155
+1161 -> 1147
+502 -> 513
+799 -> 814
+1324 -> 1296
+52 -> 47
+844 -> 849
+65 -> 62
+1162 -> 1167
+53 -> 50
+628 -> 627
+59 -> 56
+84 -> 86
+35 -> 34
+556 -> 563
+797 -> 820
+304 -> 289
+586 -> 569
+46 -> 41
+622 -> 621
+508 -> 505
+549 -> 520
+575 -> 592
+543 -> 514
+104 -> 90
+581 -> 598
+616 -> 582
+604 -> 576
diff --git a/examples/RV12.BBS12030.fasta.probs b/examples/RV12.BBS12030.fasta.probs
new file mode 100644
index 0000000..5f32d8a
--- /dev/null
+++ b/examples/RV12.BBS12030.fasta.probs
@@ -0,0 +1,12627 @@
+; Sparse posterior probability matrix for sequences 0 and 1
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (1, 0) => 0.89986
+(0, 1) ~ (1, 0) => 0.0901648
+(0, 1) ~ (1, 1) => 0.763527
+(0, 2) ~ (1, 1) => 0.223249
+(0, 2) ~ (1, 2) => 0.66554
+(0, 3) ~ (1, 2) => 0.32216
+(0, 3) ~ (1, 3) => 0.566657
+(0, 4) ~ (1, 3) => 0.420167
+(0, 4) ~ (1, 4) => 0.348624
+(0, 5) ~ (1, 4) => 0.636536
+(0, 5) ~ (1, 5) => 0.13273
+(0, 5) ~ (1, 6) => 0.0285437
+(0, 6) ~ (1, 5) => 0.836738
+(0, 6) ~ (1, 6) => 0.0620544
+(0, 6) ~ (1, 7) => 0.0598981
+(0, 7) ~ (1, 6) => 0.87152
+(0, 7) ~ (1, 8) => 0.1194
+(0, 8) ~ (1, 7) => 0.869057
+(0, 8) ~ (1, 9) => 0.127402
+(0, 9) ~ (1, 8) => 0.861457
+(0, 9) ~ (1, 10) => 0.132766
+(0, 10) ~ (1, 9) => 0.855653
+(0, 10) ~ (1, 11) => 0.13784
+(0, 11) ~ (1, 10) => 0.849625
+(0, 11) ~ (1, 12) => 0.142508
+(0, 12) ~ (1, 11) => 0.815944
+(0, 12) ~ (1, 12) => 0.0276572
+(0, 12) ~ (1, 13) => 0.150591
+(0, 13) ~ (1, 12) => 0.782076
+(0, 13) ~ (1, 13) => 0.0518783
+(0, 13) ~ (1, 14) => 0.157371
+(0, 14) ~ (1, 13) => 0.752851
+(0, 14) ~ (1, 14) => 0.0760803
+(0, 14) ~ (1, 15) => 0.162424
+(0, 15) ~ (1, 14) => 0.728604
+(0, 15) ~ (1, 15) => 0.0958991
+(0, 15) ~ (1, 16) => 0.16695
+(0, 16) ~ (1, 15) => 0.407686
+(0, 16) ~ (1, 16) => 0.411177
+(0, 16) ~ (1, 17) => 0.107603
+(0, 17) ~ (1, 16) => 0.228637
+(0, 17) ~ (1, 17) => 0.651948
+(0, 17) ~ (1, 18) => 0.025584
+(0, 18) ~ (1, 17) => 0.0237921
+(0, 18) ~ (1, 18) => 0.943645
+(0, 18) ~ (1, 19) => 0.0117118
+(0, 19) ~ (1, 19) => 0.97949
+(0, 20) ~ (1, 20) => 0.997798
+(0, 21) ~ (1, 21) => 0.999964
+(0, 22) ~ (1, 22) => 0.999993
+(0, 23) ~ (1, 23) => 0.99998
+(0, 24) ~ (1, 24) => 0.99988
+(0, 25) ~ (1, 25) => 0.999589
+(0, 26) ~ (1, 26) => 0.999548
+(0, 27) ~ (1, 27) => 0.999611
+(0, 28) ~ (1, 28) => 0.998805
+(0, 29) ~ (1, 29) => 0.997862
+(0, 30) ~ (1, 30) => 0.997611
+(0, 31) ~ (1, 31) => 0.997352
+(0, 32) ~ (1, 32) => 0.998013
+(0, 33) ~ (1, 33) => 0.998607
+(0, 34) ~ (1, 34) => 0.999066
+(0, 35) ~ (1, 35) => 0.999166
+(0, 36) ~ (1, 36) => 0.998037
+(0, 37) ~ (1, 37) => 0.997197
+(0, 38) ~ (1, 38) => 0.996661
+(0, 39) ~ (1, 39) => 0.99736
+(0, 40) ~ (1, 40) => 0.99737
+(0, 41) ~ (1, 41) => 0.997629
+(0, 42) ~ (1, 42) => 0.999505
+(0, 43) ~ (1, 43) => 0.999097
+(0, 44) ~ (1, 44) => 0.998495
+(0, 45) ~ (1, 45) => 0.984006
+(0, 45) ~ (1, 47) => 0.0133551
+(0, 46) ~ (1, 46) => 0.955807
+(0, 46) ~ (1, 48) => 0.0364919
+(0, 47) ~ (1, 47) => 0.855012
+(0, 47) ~ (1, 48) => 0.0194927
+(0, 47) ~ (1, 49) => 0.119346
+(0, 48) ~ (1, 48) => 0.591986
+(0, 48) ~ (1, 49) => 0.0162982
+(0, 48) ~ (1, 50) => 0.382829
+(0, 49) ~ (1, 49) => 0.18099
+(0, 49) ~ (1, 50) => 0.0172235
+(0, 49) ~ (1, 51) => 0.795034
+(0, 50) ~ (1, 50) => 0.0125432
+(0, 50) ~ (1, 52) => 0.985908
+(0, 51) ~ (1, 53) => 0.99801
+(0, 52) ~ (1, 54) => 0.999877
+(0, 53) ~ (1, 55) => 0.999978
+(0, 54) ~ (1, 56) => 0.999984
+(0, 55) ~ (1, 57) => 0.999917
+(0, 56) ~ (1, 58) => 0.999684
+(0, 57) ~ (1, 59) => 0.996121
+(0, 58) ~ (1, 60) => 0.989716
+(0, 59) ~ (1, 61) => 0.909098
+(0, 59) ~ (1, 62) => 0.0895553
+(0, 60) ~ (1, 62) => 0.82865
+(0, 60) ~ (1, 63) => 0.169068
+(0, 61) ~ (1, 63) => 0.748562
+(0, 61) ~ (1, 64) => 0.248703
+(0, 62) ~ (1, 64) => 0.219225
+(0, 62) ~ (1, 65) => 0.777294
+(0, 63) ~ (1, 65) => 0.0288552
+(0, 63) ~ (1, 66) => 0.968397
+(0, 64) ~ (1, 67) => 0.991767
+(0, 65) ~ (1, 68) => 0.999785
+(0, 66) ~ (1, 69) => 0.999959
+(0, 67) ~ (1, 70) => 0.999645
+(0, 68) ~ (1, 71) => 0.999529
+(0, 69) ~ (1, 72) => 0.999584
+(0, 70) ~ (1, 73) => 0.999902
+(0, 71) ~ (1, 74) => 0.999942
+(0, 72) ~ (1, 75) => 0.999946
+(0, 73) ~ (1, 76) => 0.999794
+(0, 74) ~ (1, 77) => 0.999675
+(0, 75) ~ (1, 78) => 0.999007
+(0, 76) ~ (1, 79) => 0.981745
+(0, 77) ~ (1, 79) => 0.0119672
+(0, 77) ~ (1, 80) => 0.966108
+(0, 78) ~ (1, 80) => 0.0221349
+(0, 78) ~ (1, 81) => 0.961193
+(0, 79) ~ (1, 81) => 0.0262796
+(0, 79) ~ (1, 82) => 0.957397
+(0, 80) ~ (1, 82) => 0.0330955
+(0, 80) ~ (1, 83) => 0.938467
+(0, 81) ~ (1, 83) => 0.0521752
+(0, 81) ~ (1, 84) => 0.928304
+(0, 82) ~ (1, 84) => 0.0632947
+(0, 82) ~ (1, 85) => 0.929046
+(0, 83) ~ (1, 85) => 0.0347337
+(0, 83) ~ (1, 86) => 0.960032
+(0, 84) ~ (1, 86) => 0.0123726
+(0, 84) ~ (1, 87) => 0.983973
+(0, 85) ~ (1, 88) => 0.991948
+(0, 86) ~ (1, 89) => 0.995131
+(0, 87) ~ (1, 90) => 0.999474
+(0, 88) ~ (1, 91) => 0.999927
+(0, 89) ~ (1, 92) => 0.999782
+(0, 90) ~ (1, 93) => 0.997797
+(0, 91) ~ (1, 94) => 0.996803
+(0, 92) ~ (1, 95) => 0.995126
+(0, 93) ~ (1, 96) => 0.994351
+(0, 94) ~ (1, 97) => 0.992259
+(0, 95) ~ (1, 98) => 0.963007
+(0, 95) ~ (1, 99) => 0.0229394
+(0, 96) ~ (1, 98) => 0.0109689
+(0, 96) ~ (1, 99) => 0.944609
+(0, 96) ~ (1, 100) => 0.0358478
+(0, 97) ~ (1, 99) => 0.0146147
+(0, 97) ~ (1, 100) => 0.885341
+(0, 97) ~ (1, 101) => 0.081701
+(0, 98) ~ (1, 100) => 0.026206
+(0, 98) ~ (1, 101) => 0.814957
+(0, 98) ~ (1, 102) => 0.143989
+(0, 99) ~ (1, 101) => 0.0302855
+(0, 99) ~ (1, 102) => 0.798267
+(0, 99) ~ (1, 103) => 0.154841
+(0, 100) ~ (1, 102) => 0.0337123
+(0, 100) ~ (1, 103) => 0.799999
+(0, 100) ~ (1, 104) => 0.127588
+(0, 101) ~ (1, 103) => 0.0320211
+(0, 101) ~ (1, 104) => 0.832705
+(0, 101) ~ (1, 105) => 0.0858481
+(0, 102) ~ (1, 104) => 0.0171666
+(0, 102) ~ (1, 105) => 0.890861
+(0, 102) ~ (1, 106) => 0.0441244
+(0, 103) ~ (1, 106) => 0.95103
+(0, 104) ~ (1, 107) => 0.997753
+(0, 105) ~ (1, 108) => 0.999529
+(0, 106) ~ (1, 109) => 0.999925
+(0, 107) ~ (1, 110) => 0.999982
+(0, 108) ~ (1, 111) => 0.999952
+(0, 109) ~ (1, 112) => 0.999905
+(0, 110) ~ (1, 113) => 0.99992
+(0, 111) ~ (1, 114) => 0.99996
+(0, 112) ~ (1, 115) => 0.999976
+(0, 113) ~ (1, 116) => 0.999982
+(0, 114) ~ (1, 117) => 0.999794
+(0, 115) ~ (1, 118) => 0.998263
+(0, 116) ~ (1, 119) => 0.957666
+(0, 117) ~ (1, 119) => 0.0396389
+(0, 117) ~ (1, 120) => 0.916317
+(0, 118) ~ (1, 120) => 0.079775
+(0, 118) ~ (1, 121) => 0.911768
+(0, 119) ~ (1, 121) => 0.0764868
+(0, 119) ~ (1, 122) => 0.911401
+(0, 120) ~ (1, 122) => 0.0824834
+(0, 120) ~ (1, 123) => 0.907496
+(0, 121) ~ (1, 123) => 0.0851558
+(0, 121) ~ (1, 124) => 0.900234
+(0, 122) ~ (1, 124) => 0.0925551
+(0, 122) ~ (1, 125) => 0.905522
+(0, 123) ~ (1, 125) => 0.0165443
+(0, 123) ~ (1, 126) => 0.983043
+(0, 124) ~ (1, 127) => 0.999155
+(0, 125) ~ (1, 128) => 0.9992
+(0, 126) ~ (1, 129) => 0.994038
+(0, 127) ~ (1, 130) => 0.988902
+(0, 128) ~ (1, 131) => 0.988926
+(0, 129) ~ (1, 132) => 0.994843
+(0, 130) ~ (1, 133) => 0.998442
+(0, 131) ~ (1, 134) => 0.99075
+(0, 132) ~ (1, 135) => 0.990016
+(0, 133) ~ (1, 136) => 0.991062
+(0, 134) ~ (1, 137) => 0.999256
+(0, 135) ~ (1, 138) => 0.999737
+(0, 136) ~ (1, 139) => 0.999897
+(0, 137) ~ (1, 140) => 0.999975
+(0, 138) ~ (1, 141) => 0.999998
+(0, 139) ~ (1, 142) => 0.999999
+(0, 140) ~ (1, 143) => 0.999992
+(0, 141) ~ (1, 144) => 0.999962
+(0, 142) ~ (1, 145) => 0.999948
+(0, 143) ~ (1, 146) => 0.999968
+(0, 144) ~ (1, 147) => 0.999994
+(0, 145) ~ (1, 148) => 0.999992
+(0, 146) ~ (1, 149) => 0.999958
+(0, 147) ~ (1, 150) => 0.999411
+(0, 148) ~ (1, 151) => 0.999232
+(0, 149) ~ (1, 152) => 0.99941
+(0, 150) ~ (1, 153) => 0.999824
+(0, 151) ~ (1, 154) => 0.999936
+(0, 152) ~ (1, 155) => 0.999733
+(0, 153) ~ (1, 156) => 0.999554
+(0, 154) ~ (1, 157) => 0.999387
+(0, 155) ~ (1, 158) => 0.999133
+(0, 156) ~ (1, 159) => 0.996898
+(0, 157) ~ (1, 160) => 0.994502
+(0, 158) ~ (1, 161) => 0.993165
+(0, 159) ~ (1, 162) => 0.993092
+(0, 160) ~ (1, 163) => 0.993472
+(0, 161) ~ (1, 164) => 0.995053
+(0, 162) ~ (1, 165) => 0.997151
+(0, 163) ~ (1, 166) => 0.997662
+(0, 164) ~ (1, 167) => 0.997914
+(0, 165) ~ (1, 168) => 0.998867
+(0, 166) ~ (1, 169) => 0.998422
+(0, 167) ~ (1, 170) => 0.99797
+(0, 168) ~ (1, 171) => 0.998112
+(0, 169) ~ (1, 172) => 0.998082
+(0, 170) ~ (1, 173) => 0.997326
+(0, 171) ~ (1, 174) => 0.996704
+(0, 172) ~ (1, 175) => 0.994489
+(0, 173) ~ (1, 176) => 0.992809
+(0, 174) ~ (1, 177) => 0.994191
+(0, 175) ~ (1, 178) => 0.994731
+(0, 176) ~ (1, 179) => 0.997462
+(0, 177) ~ (1, 180) => 0.999688
+(0, 178) ~ (1, 181) => 0.999938
+(0, 179) ~ (1, 182) => 0.998343
+(0, 180) ~ (1, 183) => 0.996774
+(0, 181) ~ (1, 184) => 0.955323
+(0, 182) ~ (1, 184) => 0.0412435
+(0, 182) ~ (1, 185) => 0.926103
+(0, 183) ~ (1, 185) => 0.0672819
+(0, 183) ~ (1, 186) => 0.879701
+(0, 183) ~ (1, 187) => 0.0135791
+(0, 184) ~ (1, 186) => 0.105123
+(0, 184) ~ (1, 187) => 0.590665
+(0, 184) ~ (1, 188) => 0.110689
+(0, 184) ~ (1, 189) => 0.0121664
+(0, 185) ~ (1, 187) => 0.283092
+(0, 185) ~ (1, 188) => 0.448533
+(0, 185) ~ (1, 189) => 0.198462
+(0, 185) ~ (1, 190) => 0.0371411
+(0, 186) ~ (1, 188) => 0.299401
+(0, 186) ~ (1, 189) => 0.281772
+(0, 186) ~ (1, 190) => 0.270462
+(0, 186) ~ (1, 191) => 0.114133
+(0, 187) ~ (1, 189) => 0.316976
+(0, 187) ~ (1, 190) => 0.180498
+(0, 187) ~ (1, 191) => 0.277852
+(0, 187) ~ (1, 192) => 0.188208
+(0, 188) ~ (1, 190) => 0.33704
+(0, 188) ~ (1, 191) => 0.137804
+(0, 188) ~ (1, 192) => 0.228958
+(0, 188) ~ (1, 193) => 0.207168
+(0, 189) ~ (1, 191) => 0.380007
+(0, 189) ~ (1, 192) => 0.121588
+(0, 189) ~ (1, 193) => 0.199134
+(0, 189) ~ (1, 194) => 0.226222
+(0, 190) ~ (1, 192) => 0.427224
+(0, 190) ~ (1, 193) => 0.102048
+(0, 190) ~ (1, 194) => 0.148625
+(0, 190) ~ (1, 195) => 0.247372
+(0, 191) ~ (1, 193) => 0.46187
+(0, 191) ~ (1, 194) => 0.059552
+(0, 191) ~ (1, 195) => 0.0348289
+(0, 191) ~ (1, 196) => 0.247228
+(0, 192) ~ (1, 194) => 0.534345
+(0, 192) ~ (1, 196) => 0.027454
+(0, 192) ~ (1, 197) => 0.233477
+(0, 193) ~ (1, 195) => 0.701222
+(0, 193) ~ (1, 197) => 0.012185
+(0, 193) ~ (1, 198) => 0.207691
+(0, 194) ~ (1, 196) => 0.716232
+(0, 194) ~ (1, 199) => 0.0298545
+(0, 195) ~ (1, 197) => 0.74629
+(0, 195) ~ (1, 200) => 0.0126273
+(0, 196) ~ (1, 198) => 0.782822
+(0, 197) ~ (1, 199) => 0.955678
+(0, 198) ~ (1, 200) => 0.979821
+(0, 199) ~ (1, 201) => 0.98912
+(0, 200) ~ (1, 202) => 0.991518
+(0, 201) ~ (1, 203) => 0.994707
+(0, 202) ~ (1, 204) => 0.99691
+(0, 203) ~ (1, 205) => 0.996252
+(0, 204) ~ (1, 206) => 0.996681
+(0, 205) ~ (1, 207) => 0.997704
+(0, 206) ~ (1, 208) => 0.999451
+(0, 207) ~ (1, 209) => 0.998695
+(0, 208) ~ (1, 210) => 0.99611
+(0, 209) ~ (1, 211) => 0.989077
+(0, 210) ~ (1, 212) => 0.983429
+(0, 211) ~ (1, 212) => 0.0151349
+(0, 211) ~ (1, 213) => 0.983655
+(0, 212) ~ (1, 214) => 0.991641
+(0, 213) ~ (1, 215) => 0.992954
+(0, 214) ~ (1, 216) => 0.988114
+(0, 215) ~ (1, 217) => 0.951903
+(0, 216) ~ (1, 217) => 0.0378741
+(0, 216) ~ (1, 218) => 0.441162
+(0, 217) ~ (1, 218) => 0.542396
+(0, 217) ~ (1, 219) => 0.334715
+(0, 218) ~ (1, 218) => 0.0112233
+(0, 218) ~ (1, 219) => 0.648809
+(0, 218) ~ (1, 220) => 0.212576
+(0, 219) ~ (1, 220) => 0.772227
+(0, 219) ~ (1, 221) => 0.109443
+(0, 220) ~ (1, 221) => 0.879386
+(0, 220) ~ (1, 222) => 0.0374198
+(0, 221) ~ (1, 222) => 0.954372
+(0, 222) ~ (1, 223) => 0.992936
+(0, 223) ~ (1, 224) => 0.998152
+(0, 224) ~ (1, 225) => 0.999938
+(0, 225) ~ (1, 226) => 0.999991
+(0, 226) ~ (1, 227) => 0.999935
+(0, 227) ~ (1, 228) => 0.999265
+(0, 228) ~ (1, 229) => 0.98897
+(0, 229) ~ (1, 229) => 0.0105571
+(0, 229) ~ (1, 230) => 0.978965
+(0, 230) ~ (1, 230) => 0.020106
+(0, 230) ~ (1, 231) => 0.978905
+(0, 231) ~ (1, 231) => 0.0130771
+(0, 231) ~ (1, 232) => 0.98667
+(0, 232) ~ (1, 233) => 0.994388
+
+; gap posteriors
+(0, 0) ~ (1, -1) => 0.10014
+(0, 1) ~ (1, -1) => 0.146309
+(0, 2) ~ (1, -1) => 0.111212
+(0, 3) ~ (1, -1) => 0.111183
+(0, 4) ~ (1, -1) => 0.231209
+(0, 5) ~ (1, -1) => 0.20219
+(0, 6) ~ (1, -1) => 0.0413098
+(0, 7) ~ (1, -1) => 0.00907975
+(0, 8) ~ (1, -1) => 0.00354095
+(0, 9) ~ (1, -1) => 0.00577657
+(0, 10) ~ (1, -1) => 0.00650714
+(0, 11) ~ (1, -1) => 0.00786735
+(0, 12) ~ (1, -1) => 0.00580733
+(0, 13) ~ (1, -1) => 0.00867404
+(0, 14) ~ (1, -1) => 0.00864452
+(0, 15) ~ (1, -1) => 0.00854623
+(0, 16) ~ (1, -1) => 0.0735349
+(0, 17) ~ (1, -1) => 0.0938304
+(0, 18) ~ (1, -1) => 0.0208514
+(0, 19) ~ (1, -1) => 0.0205101
+(0, 20) ~ (1, -1) => 0.00220186
+(0, 21) ~ (1, -1) => 0.0001
+(0, 22) ~ (1, -1) => 0.0001
+(0, 23) ~ (1, -1) => 0.0001
+(0, 24) ~ (1, -1) => 0.000120163
+(0, 25) ~ (1, -1) => 0.000410736
+(0, 26) ~ (1, -1) => 0.000452399
+(0, 27) ~ (1, -1) => 0.000389159
+(0, 28) ~ (1, -1) => 0.00119466
+(0, 29) ~ (1, -1) => 0.0021382
+(0, 30) ~ (1, -1) => 0.00238943
+(0, 31) ~ (1, -1) => 0.0026477
+(0, 32) ~ (1, -1) => 0.00198716
+(0, 33) ~ (1, -1) => 0.00139296
+(0, 34) ~ (1, -1) => 0.000933647
+(0, 35) ~ (1, -1) => 0.00083369
+(0, 36) ~ (1, -1) => 0.00196308
+(0, 37) ~ (1, -1) => 0.00280279
+(0, 38) ~ (1, -1) => 0.00333869
+(0, 39) ~ (1, -1) => 0.00263965
+(0, 40) ~ (1, -1) => 0.00263011
+(0, 41) ~ (1, -1) => 0.00237125
+(0, 42) ~ (1, -1) => 0.000494719
+(0, 43) ~ (1, -1) => 0.00090313
+(0, 44) ~ (1, -1) => 0.0015046
+(0, 45) ~ (1, -1) => 0.00263894
+(0, 46) ~ (1, -1) => 0.00770151
+(0, 47) ~ (1, -1) => 0.00614866
+(0, 48) ~ (1, -1) => 0.00888637
+(0, 49) ~ (1, -1) => 0.00675267
+(0, 50) ~ (1, -1) => 0.00154907
+(0, 51) ~ (1, -1) => 0.00199014
+(0, 52) ~ (1, -1) => 0.000123322
+(0, 53) ~ (1, -1) => 0.0001
+(0, 54) ~ (1, -1) => 0.0001
+(0, 55) ~ (1, -1) => 0.0001
+(0, 56) ~ (1, -1) => 0.000316441
+(0, 57) ~ (1, -1) => 0.00387931
+(0, 58) ~ (1, -1) => 0.0102841
+(0, 59) ~ (1, -1) => 0.00134643
+(0, 60) ~ (1, -1) => 0.00228235
+(0, 61) ~ (1, -1) => 0.0027348
+(0, 62) ~ (1, -1) => 0.00348157
+(0, 63) ~ (1, -1) => 0.00274771
+(0, 64) ~ (1, -1) => 0.00823337
+(0, 65) ~ (1, -1) => 0.000215173
+(0, 66) ~ (1, -1) => 0.0001
+(0, 67) ~ (1, -1) => 0.000354707
+(0, 68) ~ (1, -1) => 0.000471473
+(0, 69) ~ (1, -1) => 0.000415862
+(0, 70) ~ (1, -1) => 0.0001
+(0, 71) ~ (1, -1) => 0.0001
+(0, 72) ~ (1, -1) => 0.0001
+(0, 73) ~ (1, -1) => 0.000205636
+(0, 74) ~ (1, -1) => 0.000324786
+(0, 75) ~ (1, -1) => 0.000992835
+(0, 76) ~ (1, -1) => 0.0182546
+(0, 77) ~ (1, -1) => 0.0219248
+(0, 78) ~ (1, -1) => 0.0166726
+(0, 79) ~ (1, -1) => 0.0163233
+(0, 80) ~ (1, -1) => 0.028438
+(0, 81) ~ (1, -1) => 0.019521
+(0, 82) ~ (1, -1) => 0.0076592
+(0, 83) ~ (1, -1) => 0.00523466
+(0, 84) ~ (1, -1) => 0.00365406
+(0, 85) ~ (1, -1) => 0.00805235
+(0, 86) ~ (1, -1) => 0.0048694
+(0, 87) ~ (1, -1) => 0.000526488
+(0, 88) ~ (1, -1) => 0.0001
+(0, 89) ~ (1, -1) => 0.000217736
+(0, 90) ~ (1, -1) => 0.00220287
+(0, 91) ~ (1, -1) => 0.00319672
+(0, 92) ~ (1, -1) => 0.00487357
+(0, 93) ~ (1, -1) => 0.00564867
+(0, 94) ~ (1, -1) => 0.0077408
+(0, 95) ~ (1, -1) => 0.014054
+(0, 96) ~ (1, -1) => 0.00857422
+(0, 97) ~ (1, -1) => 0.0183429
+(0, 98) ~ (1, -1) => 0.0148479
+(0, 99) ~ (1, -1) => 0.0166062
+(0, 100) ~ (1, -1) => 0.0387008
+(0, 101) ~ (1, -1) => 0.0494262
+(0, 102) ~ (1, -1) => 0.0478482
+(0, 103) ~ (1, -1) => 0.0489703
+(0, 104) ~ (1, -1) => 0.0022471
+(0, 105) ~ (1, -1) => 0.000470698
+(0, 106) ~ (1, -1) => 0.0001
+(0, 107) ~ (1, -1) => 0.0001
+(0, 108) ~ (1, -1) => 0.0001
+(0, 109) ~ (1, -1) => 0.0001
+(0, 110) ~ (1, -1) => 0.0001
+(0, 111) ~ (1, -1) => 0.0001
+(0, 112) ~ (1, -1) => 0.0001
+(0, 113) ~ (1, -1) => 0.0001
+(0, 114) ~ (1, -1) => 0.00020647
+(0, 115) ~ (1, -1) => 0.00173736
+(0, 116) ~ (1, -1) => 0.0423336
+(0, 117) ~ (1, -1) => 0.0440441
+(0, 118) ~ (1, -1) => 0.00845748
+(0, 119) ~ (1, -1) => 0.0121118
+(0, 120) ~ (1, -1) => 0.0100206
+(0, 121) ~ (1, -1) => 0.0146102
+(0, 122) ~ (1, -1) => 0.00192297
+(0, 123) ~ (1, -1) => 0.00041312
+(0, 124) ~ (1, -1) => 0.000845373
+(0, 125) ~ (1, -1) => 0.000799775
+(0, 126) ~ (1, -1) => 0.00596184
+(0, 127) ~ (1, -1) => 0.0110984
+(0, 128) ~ (1, -1) => 0.0110739
+(0, 129) ~ (1, -1) => 0.00515676
+(0, 130) ~ (1, -1) => 0.0015583
+(0, 131) ~ (1, -1) => 0.00924969
+(0, 132) ~ (1, -1) => 0.00998437
+(0, 133) ~ (1, -1) => 0.00893778
+(0, 134) ~ (1, -1) => 0.000743985
+(0, 135) ~ (1, -1) => 0.000263393
+(0, 136) ~ (1, -1) => 0.000102758
+(0, 137) ~ (1, -1) => 0.0001
+(0, 138) ~ (1, -1) => 0.0001
+(0, 139) ~ (1, -1) => 0.0001
+(0, 140) ~ (1, -1) => 0.0001
+(0, 141) ~ (1, -1) => 0.0001
+(0, 142) ~ (1, -1) => 0.0001
+(0, 143) ~ (1, -1) => 0.0001
+(0, 144) ~ (1, -1) => 0.0001
+(0, 145) ~ (1, -1) => 0.0001
+(0, 146) ~ (1, -1) => 0.0001
+(0, 147) ~ (1, -1) => 0.000588715
+(0, 148) ~ (1, -1) => 0.000768244
+(0, 149) ~ (1, -1) => 0.000590444
+(0, 150) ~ (1, -1) => 0.000175655
+(0, 151) ~ (1, -1) => 0.0001
+(0, 152) ~ (1, -1) => 0.000267088
+(0, 153) ~ (1, -1) => 0.00044632
+(0, 154) ~ (1, -1) => 0.000612974
+(0, 155) ~ (1, -1) => 0.000867426
+(0, 156) ~ (1, -1) => 0.00310183
+(0, 157) ~ (1, -1) => 0.00549775
+(0, 158) ~ (1, -1) => 0.00683546
+(0, 159) ~ (1, -1) => 0.00690812
+(0, 160) ~ (1, -1) => 0.00652766
+(0, 161) ~ (1, -1) => 0.00494701
+(0, 162) ~ (1, -1) => 0.0028494
+(0, 163) ~ (1, -1) => 0.00233835
+(0, 164) ~ (1, -1) => 0.00208575
+(0, 165) ~ (1, -1) => 0.00113332
+(0, 166) ~ (1, -1) => 0.00157809
+(0, 167) ~ (1, -1) => 0.0020299
+(0, 168) ~ (1, -1) => 0.00188786
+(0, 169) ~ (1, -1) => 0.0019179
+(0, 170) ~ (1, -1) => 0.00267404
+(0, 171) ~ (1, -1) => 0.00329608
+(0, 172) ~ (1, -1) => 0.00551105
+(0, 173) ~ (1, -1) => 0.00719106
+(0, 174) ~ (1, -1) => 0.00580871
+(0, 175) ~ (1, -1) => 0.00526905
+(0, 176) ~ (1, -1) => 0.00253832
+(0, 177) ~ (1, -1) => 0.000311613
+(0, 178) ~ (1, -1) => 0.0001
+(0, 179) ~ (1, -1) => 0.00165713
+(0, 180) ~ (1, -1) => 0.00322604
+(0, 181) ~ (1, -1) => 0.0446772
+(0, 182) ~ (1, -1) => 0.0326536
+(0, 183) ~ (1, -1) => 0.0394381
+(0, 184) ~ (1, -1) => 0.181356
+(0, 185) ~ (1, -1) => 0.0327724
+(0, 186) ~ (1, -1) => 0.0342316
+(0, 187) ~ (1, -1) => 0.0364658
+(0, 188) ~ (1, -1) => 0.0890302
+(0, 189) ~ (1, -1) => 0.0730489
+(0, 190) ~ (1, -1) => 0.0747308
+(0, 191) ~ (1, -1) => 0.196521
+(0, 192) ~ (1, -1) => 0.204724
+(0, 193) ~ (1, -1) => 0.0789018
+(0, 194) ~ (1, -1) => 0.253913
+(0, 195) ~ (1, -1) => 0.241083
+(0, 196) ~ (1, -1) => 0.217178
+(0, 197) ~ (1, -1) => 0.0443221
+(0, 198) ~ (1, -1) => 0.0201795
+(0, 199) ~ (1, -1) => 0.0108798
+(0, 200) ~ (1, -1) => 0.00848156
+(0, 201) ~ (1, -1) => 0.00529325
+(0, 202) ~ (1, -1) => 0.00308996
+(0, 203) ~ (1, -1) => 0.00374812
+(0, 204) ~ (1, -1) => 0.00331867
+(0, 205) ~ (1, -1) => 0.00229561
+(0, 206) ~ (1, -1) => 0.00054878
+(0, 207) ~ (1, -1) => 0.00130475
+(0, 208) ~ (1, -1) => 0.0038898
+(0, 209) ~ (1, -1) => 0.0109231
+(0, 210) ~ (1, -1) => 0.0165706
+(0, 211) ~ (1, -1) => 0.00121051
+(0, 212) ~ (1, -1) => 0.00835872
+(0, 213) ~ (1, -1) => 0.00704634
+(0, 214) ~ (1, -1) => 0.0118859
+(0, 215) ~ (1, -1) => 0.0480969
+(0, 216) ~ (1, -1) => 0.520964
+(0, 217) ~ (1, -1) => 0.122889
+(0, 218) ~ (1, -1) => 0.127392
+(0, 219) ~ (1, -1) => 0.11833
+(0, 220) ~ (1, -1) => 0.0831937
+(0, 221) ~ (1, -1) => 0.0456284
+(0, 222) ~ (1, -1) => 0.00706357
+(0, 223) ~ (1, -1) => 0.00184834
+(0, 224) ~ (1, -1) => 0.0001
+(0, 225) ~ (1, -1) => 0.0001
+(0, 226) ~ (1, -1) => 0.0001
+(0, 227) ~ (1, -1) => 0.000734568
+(0, 228) ~ (1, -1) => 0.0110296
+(0, 229) ~ (1, -1) => 0.0104784
+(0, 230) ~ (1, -1) => 0.000988483
+(0, 231) ~ (1, -1) => 0.000252426
+(0, 232) ~ (1, -1) => 0.00561154
+
+(0, -1) ~ (1, 0) => 0.00997552
+(0, -1) ~ (1, 1) => 0.0132247
+(0, -1) ~ (1, 2) => 0.0123008
+(0, -1) ~ (1, 3) => 0.0131763
+(0, -1) ~ (1, 4) => 0.0148393
+(0, -1) ~ (1, 5) => 0.0305325
+(0, -1) ~ (1, 6) => 0.0378817
+(0, -1) ~ (1, 7) => 0.0710449
+(0, -1) ~ (1, 8) => 0.0191429
+(0, -1) ~ (1, 9) => 0.0169454
+(0, -1) ~ (1, 10) => 0.0176087
+(0, -1) ~ (1, 11) => 0.0462157
+(0, -1) ~ (1, 12) => 0.0477588
+(0, -1) ~ (1, 13) => 0.0446793
+(0, -1) ~ (1, 14) => 0.037944
+(0, -1) ~ (1, 15) => 0.333991
+(0, -1) ~ (1, 16) => 0.193235
+(0, -1) ~ (1, 17) => 0.216657
+(0, -1) ~ (1, 18) => 0.0307713
+(0, -1) ~ (1, 19) => 0.0087983
+(0, -1) ~ (1, 20) => 0.00220186
+(0, -1) ~ (1, 21) => 0.0001
+(0, -1) ~ (1, 22) => 0.0001
+(0, -1) ~ (1, 23) => 0.0001
+(0, -1) ~ (1, 24) => 0.000120163
+(0, -1) ~ (1, 25) => 0.000410736
+(0, -1) ~ (1, 26) => 0.000452399
+(0, -1) ~ (1, 27) => 0.000389159
+(0, -1) ~ (1, 28) => 0.00119466
+(0, -1) ~ (1, 29) => 0.0021382
+(0, -1) ~ (1, 30) => 0.00238943
+(0, -1) ~ (1, 31) => 0.0026477
+(0, -1) ~ (1, 32) => 0.00198716
+(0, -1) ~ (1, 33) => 0.00139296
+(0, -1) ~ (1, 34) => 0.000933647
+(0, -1) ~ (1, 35) => 0.00083369
+(0, -1) ~ (1, 36) => 0.00196308
+(0, -1) ~ (1, 37) => 0.00280279
+(0, -1) ~ (1, 38) => 0.00333869
+(0, -1) ~ (1, 39) => 0.00263965
+(0, -1) ~ (1, 40) => 0.00263011
+(0, -1) ~ (1, 41) => 0.00237125
+(0, -1) ~ (1, 42) => 0.000494719
+(0, -1) ~ (1, 43) => 0.00090313
+(0, -1) ~ (1, 44) => 0.0015046
+(0, -1) ~ (1, 45) => 0.015994
+(0, -1) ~ (1, 46) => 0.0441934
+(0, -1) ~ (1, 47) => 0.131633
+(0, -1) ~ (1, 48) => 0.352029
+(0, -1) ~ (1, 49) => 0.683366
+(0, -1) ~ (1, 50) => 0.587404
+(0, -1) ~ (1, 51) => 0.204966
+(0, -1) ~ (1, 52) => 0.0140923
+(0, -1) ~ (1, 53) => 0.00199014
+(0, -1) ~ (1, 54) => 0.000123322
+(0, -1) ~ (1, 55) => 0.0001
+(0, -1) ~ (1, 56) => 0.0001
+(0, -1) ~ (1, 57) => 0.0001
+(0, -1) ~ (1, 58) => 0.000316441
+(0, -1) ~ (1, 59) => 0.00387931
+(0, -1) ~ (1, 60) => 0.0102841
+(0, -1) ~ (1, 61) => 0.0909017
+(0, -1) ~ (1, 62) => 0.081795
+(0, -1) ~ (1, 63) => 0.0823697
+(0, -1) ~ (1, 64) => 0.532072
+(0, -1) ~ (1, 65) => 0.193851
+(0, -1) ~ (1, 66) => 0.0316029
+(0, -1) ~ (1, 67) => 0.00823337
+(0, -1) ~ (1, 68) => 0.000215173
+(0, -1) ~ (1, 69) => 0.0001
+(0, -1) ~ (1, 70) => 0.000354707
+(0, -1) ~ (1, 71) => 0.000471473
+(0, -1) ~ (1, 72) => 0.000415862
+(0, -1) ~ (1, 73) => 0.0001
+(0, -1) ~ (1, 74) => 0.0001
+(0, -1) ~ (1, 75) => 0.0001
+(0, -1) ~ (1, 76) => 0.000205636
+(0, -1) ~ (1, 77) => 0.000324786
+(0, -1) ~ (1, 78) => 0.000992835
+(0, -1) ~ (1, 79) => 0.00628748
+(0, -1) ~ (1, 80) => 0.0117571
+(0, -1) ~ (1, 81) => 0.0125278
+(0, -1) ~ (1, 82) => 0.00950738
+(0, -1) ~ (1, 83) => 0.00935825
+(0, -1) ~ (1, 84) => 0.00840153
+(0, -1) ~ (1, 85) => 0.0362202
+(0, -1) ~ (1, 86) => 0.0275958
+(0, -1) ~ (1, 87) => 0.0160266
+(0, -1) ~ (1, 88) => 0.00805235
+(0, -1) ~ (1, 89) => 0.0048694
+(0, -1) ~ (1, 90) => 0.000526488
+(0, -1) ~ (1, 91) => 0.0001
+(0, -1) ~ (1, 92) => 0.000217736
+(0, -1) ~ (1, 93) => 0.00220287
+(0, -1) ~ (1, 94) => 0.00319672
+(0, -1) ~ (1, 95) => 0.00487357
+(0, -1) ~ (1, 96) => 0.00564867
+(0, -1) ~ (1, 97) => 0.0077408
+(0, -1) ~ (1, 98) => 0.0260246
+(0, -1) ~ (1, 99) => 0.0178368
+(0, -1) ~ (1, 100) => 0.052605
+(0, -1) ~ (1, 101) => 0.0730563
+(0, -1) ~ (1, 102) => 0.0240318
+(0, -1) ~ (1, 103) => 0.0131384
+(0, -1) ~ (1, 104) => 0.022541
+(0, -1) ~ (1, 105) => 0.0232911
+(0, -1) ~ (1, 106) => 0.00484586
+(0, -1) ~ (1, 107) => 0.0022471
+(0, -1) ~ (1, 108) => 0.000470698
+(0, -1) ~ (1, 109) => 0.0001
+(0, -1) ~ (1, 110) => 0.0001
+(0, -1) ~ (1, 111) => 0.0001
+(0, -1) ~ (1, 112) => 0.0001
+(0, -1) ~ (1, 113) => 0.0001
+(0, -1) ~ (1, 114) => 0.0001
+(0, -1) ~ (1, 115) => 0.0001
+(0, -1) ~ (1, 116) => 0.0001
+(0, -1) ~ (1, 117) => 0.00020647
+(0, -1) ~ (1, 118) => 0.00173736
+(0, -1) ~ (1, 119) => 0.00269475
+(0, -1) ~ (1, 120) => 0.00390804
+(0, -1) ~ (1, 121) => 0.0117457
+(0, -1) ~ (1, 122) => 0.00611517
+(0, -1) ~ (1, 123) => 0.00734827
+(0, -1) ~ (1, 124) => 0.00721081
+(0, -1) ~ (1, 125) => 0.0779338
+(0, -1) ~ (1, 126) => 0.0169574
+(0, -1) ~ (1, 127) => 0.000845373
+(0, -1) ~ (1, 128) => 0.000799775
+(0, -1) ~ (1, 129) => 0.00596184
+(0, -1) ~ (1, 130) => 0.0110984
+(0, -1) ~ (1, 131) => 0.0110739
+(0, -1) ~ (1, 132) => 0.00515676
+(0, -1) ~ (1, 133) => 0.0015583
+(0, -1) ~ (1, 134) => 0.00924969
+(0, -1) ~ (1, 135) => 0.00998437
+(0, -1) ~ (1, 136) => 0.00893778
+(0, -1) ~ (1, 137) => 0.000743985
+(0, -1) ~ (1, 138) => 0.000263393
+(0, -1) ~ (1, 139) => 0.000102758
+(0, -1) ~ (1, 140) => 0.0001
+(0, -1) ~ (1, 141) => 0.0001
+(0, -1) ~ (1, 142) => 0.0001
+(0, -1) ~ (1, 143) => 0.0001
+(0, -1) ~ (1, 144) => 0.0001
+(0, -1) ~ (1, 145) => 0.0001
+(0, -1) ~ (1, 146) => 0.0001
+(0, -1) ~ (1, 147) => 0.0001
+(0, -1) ~ (1, 148) => 0.0001
+(0, -1) ~ (1, 149) => 0.0001
+(0, -1) ~ (1, 150) => 0.000588715
+(0, -1) ~ (1, 151) => 0.000768244
+(0, -1) ~ (1, 152) => 0.000590444
+(0, -1) ~ (1, 153) => 0.000175655
+(0, -1) ~ (1, 154) => 0.0001
+(0, -1) ~ (1, 155) => 0.000267088
+(0, -1) ~ (1, 156) => 0.00044632
+(0, -1) ~ (1, 157) => 0.000612974
+(0, -1) ~ (1, 158) => 0.000867426
+(0, -1) ~ (1, 159) => 0.00310183
+(0, -1) ~ (1, 160) => 0.00549775
+(0, -1) ~ (1, 161) => 0.00683546
+(0, -1) ~ (1, 162) => 0.00690812
+(0, -1) ~ (1, 163) => 0.00652766
+(0, -1) ~ (1, 164) => 0.00494701
+(0, -1) ~ (1, 165) => 0.0028494
+(0, -1) ~ (1, 166) => 0.00233835
+(0, -1) ~ (1, 167) => 0.00208575
+(0, -1) ~ (1, 168) => 0.00113332
+(0, -1) ~ (1, 169) => 0.00157809
+(0, -1) ~ (1, 170) => 0.0020299
+(0, -1) ~ (1, 171) => 0.00188786
+(0, -1) ~ (1, 172) => 0.0019179
+(0, -1) ~ (1, 173) => 0.00267404
+(0, -1) ~ (1, 174) => 0.00329608
+(0, -1) ~ (1, 175) => 0.00551105
+(0, -1) ~ (1, 176) => 0.00719106
+(0, -1) ~ (1, 177) => 0.00580871
+(0, -1) ~ (1, 178) => 0.00526905
+(0, -1) ~ (1, 179) => 0.00253832
+(0, -1) ~ (1, 180) => 0.000311613
+(0, -1) ~ (1, 181) => 0.0001
+(0, -1) ~ (1, 182) => 0.00165713
+(0, -1) ~ (1, 183) => 0.00322604
+(0, -1) ~ (1, 184) => 0.00343365
+(0, -1) ~ (1, 185) => 0.00661527
+(0, -1) ~ (1, 186) => 0.0151756
+(0, -1) ~ (1, 187) => 0.112665
+(0, -1) ~ (1, 188) => 0.141377
+(0, -1) ~ (1, 189) => 0.190624
+(0, -1) ~ (1, 190) => 0.174859
+(0, -1) ~ (1, 191) => 0.0902042
+(0, -1) ~ (1, 192) => 0.0340222
+(0, -1) ~ (1, 193) => 0.0297794
+(0, -1) ~ (1, 194) => 0.031256
+(0, -1) ~ (1, 195) => 0.0165769
+(0, -1) ~ (1, 196) => 0.00908566
+(0, -1) ~ (1, 197) => 0.00804824
+(0, -1) ~ (1, 198) => 0.00948673
+(0, -1) ~ (1, 199) => 0.0144676
+(0, -1) ~ (1, 200) => 0.00755221
+(0, -1) ~ (1, 201) => 0.0108798
+(0, -1) ~ (1, 202) => 0.00848156
+(0, -1) ~ (1, 203) => 0.00529325
+(0, -1) ~ (1, 204) => 0.00308996
+(0, -1) ~ (1, 205) => 0.00374812
+(0, -1) ~ (1, 206) => 0.00331867
+(0, -1) ~ (1, 207) => 0.00229561
+(0, -1) ~ (1, 208) => 0.00054878
+(0, -1) ~ (1, 209) => 0.00130475
+(0, -1) ~ (1, 210) => 0.0038898
+(0, -1) ~ (1, 211) => 0.0109231
+(0, -1) ~ (1, 212) => 0.00143566
+(0, -1) ~ (1, 213) => 0.0163454
+(0, -1) ~ (1, 214) => 0.00835872
+(0, -1) ~ (1, 215) => 0.00704634
+(0, -1) ~ (1, 216) => 0.0118859
+(0, -1) ~ (1, 217) => 0.0102228
+(0, -1) ~ (1, 218) => 0.00521811
+(0, -1) ~ (1, 219) => 0.0164766
+(0, -1) ~ (1, 220) => 0.0151965
+(0, -1) ~ (1, 221) => 0.0111705
+(0, -1) ~ (1, 222) => 0.00820863
+(0, -1) ~ (1, 223) => 0.00706357
+(0, -1) ~ (1, 224) => 0.00184834
+(0, -1) ~ (1, 225) => 0.0001
+(0, -1) ~ (1, 226) => 0.0001
+(0, -1) ~ (1, 227) => 0.0001
+(0, -1) ~ (1, 228) => 0.000734568
+(0, -1) ~ (1, 229) => 0.000472467
+(0, -1) ~ (1, 230) => 0.00092946
+(0, -1) ~ (1, 231) => 0.00801743
+(0, -1) ~ (1, 232) => 0.0133295
+(0, -1) ~ (1, 233) => 0.00561154
+
+; Sparse posterior probability matrix for sequences 0 and 2
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (2, 0) => 0.983607
+(0, 1) ~ (2, 0) => 0.0128121
+(0, 1) ~ (2, 1) => 0.962194
+(0, 2) ~ (2, 1) => 0.0319362
+(0, 2) ~ (2, 2) => 0.952387
+(0, 3) ~ (2, 2) => 0.0397051
+(0, 3) ~ (2, 3) => 0.941118
+(0, 4) ~ (2, 3) => 0.0474095
+(0, 4) ~ (2, 4) => 0.918483
+(0, 5) ~ (2, 4) => 0.0645879
+(0, 5) ~ (2, 5) => 0.897614
+(0, 6) ~ (2, 5) => 0.0811618
+(0, 6) ~ (2, 6) => 0.855541
+(0, 7) ~ (2, 6) => 0.120507
+(0, 7) ~ (2, 7) => 0.846589
+(0, 7) ~ (2, 9) => 0.0104856
+(0, 8) ~ (2, 7) => 0.122328
+(0, 8) ~ (2, 8) => 0.8438
+(0, 8) ~ (2, 10) => 0.0127542
+(0, 9) ~ (2, 8) => 0.114622
+(0, 9) ~ (2, 9) => 0.847883
+(0, 9) ~ (2, 11) => 0.0134658
+(0, 10) ~ (2, 9) => 0.0605391
+(0, 10) ~ (2, 10) => 0.881439
+(0, 10) ~ (2, 12) => 0.0171103
+(0, 10) ~ (2, 13) => 0.0125936
+(0, 10) ~ (2, 14) => 0.0111072
+(0, 11) ~ (2, 10) => 0.031585
+(0, 11) ~ (2, 11) => 0.891644
+(0, 11) ~ (2, 13) => 0.0189395
+(0, 11) ~ (2, 14) => 0.0215229
+(0, 11) ~ (2, 15) => 0.0178301
+(0, 12) ~ (2, 11) => 0.0239857
+(0, 12) ~ (2, 12) => 0.868108
+(0, 12) ~ (2, 14) => 0.0149805
+(0, 12) ~ (2, 15) => 0.0352955
+(0, 12) ~ (2, 16) => 0.0333216
+(0, 13) ~ (2, 12) => 0.0189655
+(0, 13) ~ (2, 13) => 0.859822
+(0, 13) ~ (2, 15) => 0.0119852
+(0, 13) ~ (2, 16) => 0.0438492
+(0, 13) ~ (2, 17) => 0.0386053
+(0, 14) ~ (2, 13) => 0.0167482
+(0, 14) ~ (2, 14) => 0.838576
+(0, 14) ~ (2, 17) => 0.0742632
+(0, 14) ~ (2, 18) => 0.0418754
+(0, 15) ~ (2, 14) => 0.0116211
+(0, 15) ~ (2, 15) => 0.661587
+(0, 15) ~ (2, 18) => 0.237612
+(0, 15) ~ (2, 19) => 0.0607021
+(0, 16) ~ (2, 16) => 0.506643
+(0, 16) ~ (2, 19) => 0.407144
+(0, 16) ~ (2, 20) => 0.0234943
+(0, 17) ~ (2, 17) => 0.066981
+(0, 17) ~ (2, 20) => 0.899752
+(0, 18) ~ (2, 21) => 0.981772
+(0, 19) ~ (2, 22) => 0.990562
+(0, 20) ~ (2, 23) => 0.998385
+(0, 21) ~ (2, 24) => 0.999906
+(0, 22) ~ (2, 25) => 0.999966
+(0, 23) ~ (2, 26) => 0.999995
+(0, 24) ~ (2, 27) => 0.999989
+(0, 25) ~ (2, 28) => 0.999961
+(0, 26) ~ (2, 29) => 0.999959
+(0, 27) ~ (2, 30) => 0.999974
+(0, 28) ~ (2, 31) => 0.999941
+(0, 29) ~ (2, 32) => 0.999726
+(0, 30) ~ (2, 33) => 0.999598
+(0, 31) ~ (2, 34) => 0.999502
+(0, 32) ~ (2, 35) => 0.999544
+(0, 33) ~ (2, 36) => 0.999636
+(0, 34) ~ (2, 37) => 0.999678
+(0, 35) ~ (2, 38) => 0.999686
+(0, 36) ~ (2, 39) => 0.999548
+(0, 37) ~ (2, 40) => 0.99943
+(0, 38) ~ (2, 41) => 0.99935
+(0, 39) ~ (2, 42) => 0.999456
+(0, 40) ~ (2, 43) => 0.999735
+(0, 41) ~ (2, 44) => 0.999696
+(0, 42) ~ (2, 45) => 0.999676
+(0, 43) ~ (2, 46) => 0.998698
+(0, 44) ~ (2, 47) => 0.99722
+(0, 45) ~ (2, 48) => 0.986571
+(0, 46) ~ (2, 49) => 0.979398
+(0, 46) ~ (2, 51) => 0.0134602
+(0, 47) ~ (2, 50) => 0.964226
+(0, 47) ~ (2, 52) => 0.0211103
+(0, 48) ~ (2, 51) => 0.94148
+(0, 48) ~ (2, 53) => 0.0361107
+(0, 49) ~ (2, 51) => 0.0150438
+(0, 49) ~ (2, 52) => 0.922469
+(0, 49) ~ (2, 54) => 0.0491523
+(0, 50) ~ (2, 52) => 0.0202728
+(0, 50) ~ (2, 53) => 0.902038
+(0, 50) ~ (2, 55) => 0.0700271
+(0, 51) ~ (2, 53) => 0.0159468
+(0, 51) ~ (2, 54) => 0.894513
+(0, 51) ~ (2, 56) => 0.0852831
+(0, 52) ~ (2, 55) => 0.0583747
+(0, 52) ~ (2, 57) => 0.939657
+(0, 53) ~ (2, 58) => 0.992086
+(0, 54) ~ (2, 59) => 0.999671
+(0, 55) ~ (2, 60) => 0.999953
+(0, 56) ~ (2, 61) => 0.999995
+(0, 57) ~ (2, 62) => 0.999988
+(0, 58) ~ (2, 63) => 0.999988
+(0, 59) ~ (2, 64) => 0.999984
+(0, 60) ~ (2, 65) => 0.999979
+(0, 61) ~ (2, 66) => 0.999985
+(0, 62) ~ (2, 67) => 0.999997
+(0, 63) ~ (2, 68) => 0.999999
+(0, 64) ~ (2, 69) => 0.999999
+(0, 65) ~ (2, 70) => 1
+(0, 66) ~ (2, 71) => 0.999997
+(0, 67) ~ (2, 72) => 0.999954
+(0, 68) ~ (2, 73) => 0.999937
+(0, 69) ~ (2, 74) => 0.999938
+(0, 70) ~ (2, 75) => 0.999982
+(0, 71) ~ (2, 76) => 0.999987
+(0, 72) ~ (2, 77) => 0.99999
+(0, 73) ~ (2, 78) => 0.999972
+(0, 74) ~ (2, 79) => 0.999959
+(0, 75) ~ (2, 80) => 0.999896
+(0, 76) ~ (2, 81) => 0.998635
+(0, 77) ~ (2, 82) => 0.997509
+(0, 78) ~ (2, 83) => 0.997173
+(0, 79) ~ (2, 84) => 0.996852
+(0, 80) ~ (2, 85) => 0.996148
+(0, 81) ~ (2, 86) => 0.996439
+(0, 82) ~ (2, 87) => 0.99678
+(0, 83) ~ (2, 88) => 0.997148
+(0, 84) ~ (2, 89) => 0.997419
+(0, 85) ~ (2, 90) => 0.999462
+(0, 86) ~ (2, 91) => 0.999604
+(0, 87) ~ (2, 92) => 0.999941
+(0, 88) ~ (2, 93) => 0.999956
+(0, 89) ~ (2, 94) => 0.999875
+(0, 90) ~ (2, 95) => 0.998996
+(0, 91) ~ (2, 96) => 0.998122
+(0, 92) ~ (2, 97) => 0.995935
+(0, 93) ~ (2, 98) => 0.995108
+(0, 94) ~ (2, 99) => 0.99414
+(0, 95) ~ (2, 100) => 0.988342
+(0, 96) ~ (2, 101) => 0.984411
+(0, 97) ~ (2, 102) => 0.979584
+(0, 98) ~ (2, 103) => 0.975227
+(0, 98) ~ (2, 104) => 0.0118768
+(0, 99) ~ (2, 104) => 0.974553
+(0, 99) ~ (2, 105) => 0.0119954
+(0, 100) ~ (2, 105) => 0.975549
+(0, 101) ~ (2, 106) => 0.982397
+(0, 102) ~ (2, 107) => 0.990699
+(0, 103) ~ (2, 108) => 0.99547
+(0, 104) ~ (2, 109) => 0.999744
+(0, 105) ~ (2, 110) => 0.999895
+(0, 106) ~ (2, 111) => 0.99994
+(0, 107) ~ (2, 112) => 0.999984
+(0, 108) ~ (2, 113) => 0.999991
+(0, 109) ~ (2, 114) => 0.99999
+(0, 110) ~ (2, 115) => 0.999991
+(0, 111) ~ (2, 116) => 0.999995
+(0, 112) ~ (2, 117) => 0.999996
+(0, 113) ~ (2, 118) => 0.999985
+(0, 114) ~ (2, 119) => 0.999822
+(0, 115) ~ (2, 120) => 0.998808
+(0, 116) ~ (2, 121) => 0.997296
+(0, 117) ~ (2, 122) => 0.996766
+(0, 118) ~ (2, 123) => 0.996641
+(0, 119) ~ (2, 124) => 0.996893
+(0, 120) ~ (2, 125) => 0.996959
+(0, 121) ~ (2, 126) => 0.997183
+(0, 122) ~ (2, 127) => 0.99786
+(0, 123) ~ (2, 128) => 0.999298
+(0, 124) ~ (2, 129) => 0.99991
+(0, 125) ~ (2, 130) => 0.999943
+(0, 126) ~ (2, 131) => 0.999868
+(0, 127) ~ (2, 132) => 0.999768
+(0, 128) ~ (2, 133) => 0.999793
+(0, 129) ~ (2, 134) => 0.999694
+(0, 130) ~ (2, 135) => 0.999625
+(0, 131) ~ (2, 136) => 0.99944
+(0, 132) ~ (2, 137) => 0.99943
+(0, 133) ~ (2, 138) => 0.999652
+(0, 134) ~ (2, 139) => 0.99994
+(0, 135) ~ (2, 140) => 0.999961
+(0, 136) ~ (2, 141) => 0.999971
+(0, 137) ~ (2, 142) => 0.999986
+(0, 138) ~ (2, 143) => 0.999963
+(0, 139) ~ (2, 144) => 0.999959
+(0, 140) ~ (2, 145) => 0.999993
+(0, 141) ~ (2, 146) => 0.999998
+(0, 142) ~ (2, 147) => 0.999997
+(0, 143) ~ (2, 148) => 0.999997
+(0, 144) ~ (2, 149) => 0.999999
+(0, 145) ~ (2, 150) => 0.999998
+(0, 146) ~ (2, 151) => 0.999987
+(0, 147) ~ (2, 152) => 0.999871
+(0, 148) ~ (2, 153) => 0.999746
+(0, 149) ~ (2, 154) => 0.999733
+(0, 150) ~ (2, 155) => 0.999916
+(0, 151) ~ (2, 156) => 0.999962
+(0, 152) ~ (2, 157) => 0.999871
+(0, 153) ~ (2, 158) => 0.999633
+(0, 154) ~ (2, 159) => 0.999079
+(0, 155) ~ (2, 160) => 0.998255
+(0, 156) ~ (2, 161) => 0.993442
+(0, 157) ~ (2, 162) => 0.992499
+(0, 158) ~ (2, 163) => 0.992344
+(0, 159) ~ (2, 164) => 0.992016
+(0, 160) ~ (2, 165) => 0.991732
+(0, 161) ~ (2, 166) => 0.991858
+(0, 162) ~ (2, 167) => 0.992201
+(0, 163) ~ (2, 168) => 0.991425
+(0, 164) ~ (2, 169) => 0.99029
+(0, 165) ~ (2, 170) => 0.987755
+(0, 166) ~ (2, 171) => 0.986861
+(0, 167) ~ (2, 172) => 0.986994
+(0, 168) ~ (2, 173) => 0.987454
+(0, 169) ~ (2, 174) => 0.988138
+(0, 170) ~ (2, 175) => 0.989027
+(0, 171) ~ (2, 176) => 0.98925
+(0, 172) ~ (2, 177) => 0.989455
+(0, 173) ~ (2, 178) => 0.9887
+(0, 174) ~ (2, 179) => 0.989995
+(0, 175) ~ (2, 180) => 0.990789
+(0, 176) ~ (2, 181) => 0.992202
+(0, 177) ~ (2, 182) => 0.999129
+(0, 178) ~ (2, 183) => 0.999911
+(0, 179) ~ (2, 184) => 0.999581
+(0, 180) ~ (2, 185) => 0.999084
+(0, 181) ~ (2, 186) => 0.988496
+(0, 182) ~ (2, 187) => 0.953219
+(0, 182) ~ (2, 188) => 0.011222
+(0, 183) ~ (2, 187) => 0.0309581
+(0, 183) ~ (2, 188) => 0.910198
+(0, 183) ~ (2, 189) => 0.015096
+(0, 184) ~ (2, 188) => 0.063015
+(0, 184) ~ (2, 189) => 0.681409
+(0, 184) ~ (2, 190) => 0.0691852
+(0, 184) ~ (2, 193) => 0.0161878
+(0, 185) ~ (2, 189) => 0.213417
+(0, 185) ~ (2, 190) => 0.583851
+(0, 185) ~ (2, 191) => 0.118771
+(0, 185) ~ (2, 194) => 0.0246532
+(0, 186) ~ (2, 190) => 0.231169
+(0, 186) ~ (2, 191) => 0.424571
+(0, 186) ~ (2, 192) => 0.202593
+(0, 186) ~ (2, 195) => 0.0667658
+(0, 187) ~ (2, 190) => 0.0151276
+(0, 187) ~ (2, 191) => 0.24593
+(0, 187) ~ (2, 192) => 0.215124
+(0, 187) ~ (2, 193) => 0.387406
+(0, 187) ~ (2, 196) => 0.0734905
+(0, 188) ~ (2, 191) => 0.0204526
+(0, 188) ~ (2, 192) => 0.203744
+(0, 188) ~ (2, 193) => 0.185169
+(0, 188) ~ (2, 194) => 0.437372
+(0, 188) ~ (2, 197) => 0.0781191
+(0, 189) ~ (2, 192) => 0.0351806
+(0, 189) ~ (2, 193) => 0.150887
+(0, 189) ~ (2, 194) => 0.103764
+(0, 189) ~ (2, 195) => 0.56183
+(0, 189) ~ (2, 197) => 0.0106668
+(0, 189) ~ (2, 198) => 0.0821699
+(0, 190) ~ (2, 193) => 0.0417367
+(0, 190) ~ (2, 194) => 0.0709281
+(0, 190) ~ (2, 195) => 0.0762573
+(0, 190) ~ (2, 196) => 0.663308
+(0, 190) ~ (2, 198) => 0.0105526
+(0, 190) ~ (2, 199) => 0.0818701
+(0, 191) ~ (2, 194) => 0.0446032
+(0, 191) ~ (2, 195) => 0.0437612
+(0, 191) ~ (2, 196) => 0.0474161
+(0, 191) ~ (2, 197) => 0.720848
+(0, 191) ~ (2, 200) => 0.0795003
+(0, 192) ~ (2, 194) => 0.0108244
+(0, 192) ~ (2, 195) => 0.0387856
+(0, 192) ~ (2, 196) => 0.0291392
+(0, 192) ~ (2, 197) => 0.0320127
+(0, 192) ~ (2, 198) => 0.762645
+(0, 192) ~ (2, 201) => 0.0689563
+(0, 193) ~ (2, 195) => 0.0100998
+(0, 193) ~ (2, 196) => 0.0354724
+(0, 193) ~ (2, 197) => 0.018905
+(0, 193) ~ (2, 198) => 0.0188927
+(0, 193) ~ (2, 199) => 0.806473
+(0, 193) ~ (2, 202) => 0.049258
+(0, 194) ~ (2, 197) => 0.0326149
+(0, 194) ~ (2, 200) => 0.83823
+(0, 194) ~ (2, 203) => 0.0125828
+(0, 195) ~ (2, 198) => 0.02926
+(0, 195) ~ (2, 201) => 0.865463
+(0, 196) ~ (2, 199) => 0.0285537
+(0, 196) ~ (2, 202) => 0.894063
+(0, 197) ~ (2, 200) => 0.0252415
+(0, 197) ~ (2, 203) => 0.935606
+(0, 198) ~ (2, 201) => 0.0242767
+(0, 198) ~ (2, 204) => 0.948484
+(0, 199) ~ (2, 202) => 0.0238855
+(0, 199) ~ (2, 205) => 0.951111
+(0, 200) ~ (2, 203) => 0.0203246
+(0, 200) ~ (2, 206) => 0.955336
+(0, 201) ~ (2, 204) => 0.0141161
+(0, 201) ~ (2, 207) => 0.962499
+(0, 202) ~ (2, 208) => 0.975351
+(0, 203) ~ (2, 209) => 0.981655
+(0, 204) ~ (2, 210) => 0.986373
+(0, 205) ~ (2, 211) => 0.991767
+(0, 206) ~ (2, 212) => 0.998725
+(0, 207) ~ (2, 213) => 0.999224
+(0, 208) ~ (2, 214) => 0.99932
+(0, 209) ~ (2, 215) => 0.999438
+(0, 210) ~ (2, 216) => 0.998833
+(0, 211) ~ (2, 217) => 0.998889
+(0, 212) ~ (2, 218) => 0.999326
+(0, 213) ~ (2, 219) => 0.999669
+(0, 214) ~ (2, 220) => 0.999595
+(0, 215) ~ (2, 221) => 0.999469
+(0, 216) ~ (2, 222) => 0.999058
+(0, 217) ~ (2, 223) => 0.998999
+(0, 218) ~ (2, 224) => 0.999173
+(0, 219) ~ (2, 225) => 0.999688
+(0, 220) ~ (2, 226) => 0.999683
+(0, 221) ~ (2, 227) => 0.999805
+(0, 222) ~ (2, 228) => 0.999937
+(0, 223) ~ (2, 229) => 0.999991
+(0, 224) ~ (2, 230) => 0.999999
+(0, 225) ~ (2, 231) => 1
+(0, 226) ~ (2, 232) => 0.999993
+(0, 227) ~ (2, 233) => 0.999937
+(0, 228) ~ (2, 234) => 0.999155
+(0, 229) ~ (2, 235) => 0.996956
+(0, 230) ~ (2, 236) => 0.996809
+(0, 231) ~ (2, 237) => 0.997297
+(0, 232) ~ (2, 238) => 0.998014
+
+; gap posteriors
+(0, 0) ~ (2, -1) => 0.0163932
+(0, 1) ~ (2, -1) => 0.0249941
+(0, 2) ~ (2, -1) => 0.0156772
+(0, 3) ~ (2, -1) => 0.0191768
+(0, 4) ~ (2, -1) => 0.0341071
+(0, 5) ~ (2, -1) => 0.0377984
+(0, 6) ~ (2, -1) => 0.0632976
+(0, 7) ~ (2, -1) => 0.0224177
+(0, 8) ~ (2, -1) => 0.0211184
+(0, 9) ~ (2, -1) => 0.0240292
+(0, 10) ~ (2, -1) => 0.0172112
+(0, 11) ~ (2, -1) => 0.0184786
+(0, 12) ~ (2, -1) => 0.0243085
+(0, 13) ~ (2, -1) => 0.0267729
+(0, 14) ~ (2, -1) => 0.028537
+(0, 15) ~ (2, -1) => 0.028478
+(0, 16) ~ (2, -1) => 0.0627189
+(0, 17) ~ (2, -1) => 0.0332673
+(0, 18) ~ (2, -1) => 0.0182276
+(0, 19) ~ (2, -1) => 0.00943756
+(0, 20) ~ (2, -1) => 0.00161451
+(0, 21) ~ (2, -1) => 0.0001
+(0, 22) ~ (2, -1) => 0.0001
+(0, 23) ~ (2, -1) => 0.0001
+(0, 24) ~ (2, -1) => 0.0001
+(0, 25) ~ (2, -1) => 0.0001
+(0, 26) ~ (2, -1) => 0.0001
+(0, 27) ~ (2, -1) => 0.0001
+(0, 28) ~ (2, -1) => 0.0001
+(0, 29) ~ (2, -1) => 0.000273824
+(0, 30) ~ (2, -1) => 0.000401914
+(0, 31) ~ (2, -1) => 0.000497699
+(0, 32) ~ (2, -1) => 0.000455797
+(0, 33) ~ (2, -1) => 0.000364482
+(0, 34) ~ (2, -1) => 0.000322104
+(0, 35) ~ (2, -1) => 0.000314415
+(0, 36) ~ (2, -1) => 0.000451982
+(0, 37) ~ (2, -1) => 0.000570059
+(0, 38) ~ (2, -1) => 0.000649989
+(0, 39) ~ (2, -1) => 0.000543773
+(0, 40) ~ (2, -1) => 0.000265121
+(0, 41) ~ (2, -1) => 0.000303626
+(0, 42) ~ (2, -1) => 0.000324249
+(0, 43) ~ (2, -1) => 0.00130188
+(0, 44) ~ (2, -1) => 0.00278038
+(0, 45) ~ (2, -1) => 0.0134289
+(0, 46) ~ (2, -1) => 0.00714164
+(0, 47) ~ (2, -1) => 0.0146641
+(0, 48) ~ (2, -1) => 0.022409
+(0, 49) ~ (2, -1) => 0.0133352
+(0, 50) ~ (2, -1) => 0.00766244
+(0, 51) ~ (2, -1) => 0.00425665
+(0, 52) ~ (2, -1) => 0.00196797
+(0, 53) ~ (2, -1) => 0.00791413
+(0, 54) ~ (2, -1) => 0.000329316
+(0, 55) ~ (2, -1) => 0.0001
+(0, 56) ~ (2, -1) => 0.0001
+(0, 57) ~ (2, -1) => 0.0001
+(0, 58) ~ (2, -1) => 0.0001
+(0, 59) ~ (2, -1) => 0.0001
+(0, 60) ~ (2, -1) => 0.0001
+(0, 61) ~ (2, -1) => 0.0001
+(0, 62) ~ (2, -1) => 0.0001
+(0, 63) ~ (2, -1) => 0.0001
+(0, 64) ~ (2, -1) => 0.0001
+(0, 65) ~ (2, -1) => 0.0001
+(0, 66) ~ (2, -1) => 0.0001
+(0, 67) ~ (2, -1) => 0.0001
+(0, 68) ~ (2, -1) => 0.0001
+(0, 69) ~ (2, -1) => 0.0001
+(0, 70) ~ (2, -1) => 0.0001
+(0, 71) ~ (2, -1) => 0.0001
+(0, 72) ~ (2, -1) => 0.0001
+(0, 73) ~ (2, -1) => 0.0001
+(0, 74) ~ (2, -1) => 0.0001
+(0, 75) ~ (2, -1) => 0.00010407
+(0, 76) ~ (2, -1) => 0.00136471
+(0, 77) ~ (2, -1) => 0.00249064
+(0, 78) ~ (2, -1) => 0.00282675
+(0, 79) ~ (2, -1) => 0.00314844
+(0, 80) ~ (2, -1) => 0.00385171
+(0, 81) ~ (2, -1) => 0.00356066
+(0, 82) ~ (2, -1) => 0.0032205
+(0, 83) ~ (2, -1) => 0.00285214
+(0, 84) ~ (2, -1) => 0.00258136
+(0, 85) ~ (2, -1) => 0.000537813
+(0, 86) ~ (2, -1) => 0.000395596
+(0, 87) ~ (2, -1) => 0.0001
+(0, 88) ~ (2, -1) => 0.0001
+(0, 89) ~ (2, -1) => 0.000125289
+(0, 90) ~ (2, -1) => 0.00100362
+(0, 91) ~ (2, -1) => 0.00187784
+(0, 92) ~ (2, -1) => 0.0040645
+(0, 93) ~ (2, -1) => 0.00489247
+(0, 94) ~ (2, -1) => 0.00585985
+(0, 95) ~ (2, -1) => 0.0116577
+(0, 96) ~ (2, -1) => 0.0155891
+(0, 97) ~ (2, -1) => 0.0204161
+(0, 98) ~ (2, -1) => 0.0128961
+(0, 99) ~ (2, -1) => 0.0134518
+(0, 100) ~ (2, -1) => 0.0244514
+(0, 101) ~ (2, -1) => 0.0176026
+(0, 102) ~ (2, -1) => 0.00930136
+(0, 103) ~ (2, -1) => 0.00452977
+(0, 104) ~ (2, -1) => 0.000255823
+(0, 105) ~ (2, -1) => 0.000105441
+(0, 106) ~ (2, -1) => 0.0001
+(0, 107) ~ (2, -1) => 0.0001
+(0, 108) ~ (2, -1) => 0.0001
+(0, 109) ~ (2, -1) => 0.0001
+(0, 110) ~ (2, -1) => 0.0001
+(0, 111) ~ (2, -1) => 0.0001
+(0, 112) ~ (2, -1) => 0.0001
+(0, 113) ~ (2, -1) => 0.0001
+(0, 114) ~ (2, -1) => 0.000178277
+(0, 115) ~ (2, -1) => 0.00119191
+(0, 116) ~ (2, -1) => 0.00270385
+(0, 117) ~ (2, -1) => 0.00323367
+(0, 118) ~ (2, -1) => 0.00335908
+(0, 119) ~ (2, -1) => 0.00310689
+(0, 120) ~ (2, -1) => 0.00304073
+(0, 121) ~ (2, -1) => 0.00281745
+(0, 122) ~ (2, -1) => 0.00214016
+(0, 123) ~ (2, -1) => 0.000702262
+(0, 124) ~ (2, -1) => 0.0001
+(0, 125) ~ (2, -1) => 0.0001
+(0, 126) ~ (2, -1) => 0.000132024
+(0, 127) ~ (2, -1) => 0.000231624
+(0, 128) ~ (2, -1) => 0.000206947
+(0, 129) ~ (2, -1) => 0.000305951
+(0, 130) ~ (2, -1) => 0.000375211
+(0, 131) ~ (2, -1) => 0.000559568
+(0, 132) ~ (2, -1) => 0.000570238
+(0, 133) ~ (2, -1) => 0.000347853
+(0, 134) ~ (2, -1) => 0.0001
+(0, 135) ~ (2, -1) => 0.0001
+(0, 136) ~ (2, -1) => 0.0001
+(0, 137) ~ (2, -1) => 0.0001
+(0, 138) ~ (2, -1) => 0.0001
+(0, 139) ~ (2, -1) => 0.0001
+(0, 140) ~ (2, -1) => 0.0001
+(0, 141) ~ (2, -1) => 0.0001
+(0, 142) ~ (2, -1) => 0.0001
+(0, 143) ~ (2, -1) => 0.0001
+(0, 144) ~ (2, -1) => 0.0001
+(0, 145) ~ (2, -1) => 0.0001
+(0, 146) ~ (2, -1) => 0.0001
+(0, 147) ~ (2, -1) => 0.000129044
+(0, 148) ~ (2, -1) => 0.000253975
+(0, 149) ~ (2, -1) => 0.000267029
+(0, 150) ~ (2, -1) => 0.0001
+(0, 151) ~ (2, -1) => 0.0001
+(0, 152) ~ (2, -1) => 0.000129104
+(0, 153) ~ (2, -1) => 0.000366747
+(0, 154) ~ (2, -1) => 0.000921428
+(0, 155) ~ (2, -1) => 0.00174505
+(0, 156) ~ (2, -1) => 0.0065583
+(0, 157) ~ (2, -1) => 0.0075013
+(0, 158) ~ (2, -1) => 0.0076564
+(0, 159) ~ (2, -1) => 0.00798392
+(0, 160) ~ (2, -1) => 0.00826848
+(0, 161) ~ (2, -1) => 0.00814223
+(0, 162) ~ (2, -1) => 0.00779921
+(0, 163) ~ (2, -1) => 0.00857532
+(0, 164) ~ (2, -1) => 0.00970978
+(0, 165) ~ (2, -1) => 0.0122453
+(0, 166) ~ (2, -1) => 0.0131392
+(0, 167) ~ (2, -1) => 0.0130062
+(0, 168) ~ (2, -1) => 0.012546
+(0, 169) ~ (2, -1) => 0.0118616
+(0, 170) ~ (2, -1) => 0.0109733
+(0, 171) ~ (2, -1) => 0.0107499
+(0, 172) ~ (2, -1) => 0.0105447
+(0, 173) ~ (2, -1) => 0.0113001
+(0, 174) ~ (2, -1) => 0.0100055
+(0, 175) ~ (2, -1) => 0.0092113
+(0, 176) ~ (2, -1) => 0.00779849
+(0, 177) ~ (2, -1) => 0.000871122
+(0, 178) ~ (2, -1) => 0.0001
+(0, 179) ~ (2, -1) => 0.000418842
+(0, 180) ~ (2, -1) => 0.000915647
+(0, 181) ~ (2, -1) => 0.0115041
+(0, 182) ~ (2, -1) => 0.0355589
+(0, 183) ~ (2, -1) => 0.0437483
+(0, 184) ~ (2, -1) => 0.170203
+(0, 185) ~ (2, -1) => 0.0593081
+(0, 186) ~ (2, -1) => 0.0749021
+(0, 187) ~ (2, -1) => 0.0629224
+(0, 188) ~ (2, -1) => 0.0751439
+(0, 189) ~ (2, -1) => 0.0555011
+(0, 190) ~ (2, -1) => 0.0553475
+(0, 191) ~ (2, -1) => 0.063871
+(0, 192) ~ (2, -1) => 0.057637
+(0, 193) ~ (2, -1) => 0.0608994
+(0, 194) ~ (2, -1) => 0.116572
+(0, 195) ~ (2, -1) => 0.105277
+(0, 196) ~ (2, -1) => 0.0773835
+(0, 197) ~ (2, -1) => 0.0391524
+(0, 198) ~ (2, -1) => 0.0272396
+(0, 199) ~ (2, -1) => 0.025003
+(0, 200) ~ (2, -1) => 0.0243393
+(0, 201) ~ (2, -1) => 0.0233846
+(0, 202) ~ (2, -1) => 0.024649
+(0, 203) ~ (2, -1) => 0.0183448
+(0, 204) ~ (2, -1) => 0.0136271
+(0, 205) ~ (2, -1) => 0.00823325
+(0, 206) ~ (2, -1) => 0.0012747
+(0, 207) ~ (2, -1) => 0.000776112
+(0, 208) ~ (2, -1) => 0.000680208
+(0, 209) ~ (2, -1) => 0.000561833
+(0, 210) ~ (2, -1) => 0.00116718
+(0, 211) ~ (2, -1) => 0.00111145
+(0, 212) ~ (2, -1) => 0.000674307
+(0, 213) ~ (2, -1) => 0.000330806
+(0, 214) ~ (2, -1) => 0.000405371
+(0, 215) ~ (2, -1) => 0.000531256
+(0, 216) ~ (2, -1) => 0.000941575
+(0, 217) ~ (2, -1) => 0.00100148
+(0, 218) ~ (2, -1) => 0.000826597
+(0, 219) ~ (2, -1) => 0.000311911
+(0, 220) ~ (2, -1) => 0.000317156
+(0, 221) ~ (2, -1) => 0.000195444
+(0, 222) ~ (2, -1) => 0.0001
+(0, 223) ~ (2, -1) => 0.0001
+(0, 224) ~ (2, -1) => 0.0001
+(0, 225) ~ (2, -1) => 0.0001
+(0, 226) ~ (2, -1) => 0.0001
+(0, 227) ~ (2, -1) => 0.0001
+(0, 228) ~ (2, -1) => 0.000845432
+(0, 229) ~ (2, -1) => 0.00304359
+(0, 230) ~ (2, -1) => 0.00319093
+(0, 231) ~ (2, -1) => 0.00270259
+(0, 232) ~ (2, -1) => 0.00198627
+
+(0, -1) ~ (2, 0) => 0.00358114
+(0, -1) ~ (2, 1) => 0.00587003
+(0, -1) ~ (2, 2) => 0.00790827
+(0, -1) ~ (2, 3) => 0.0114724
+(0, -1) ~ (2, 4) => 0.0169288
+(0, -1) ~ (2, 5) => 0.0212245
+(0, -1) ~ (2, 6) => 0.023952
+(0, -1) ~ (2, 7) => 0.0310831
+(0, -1) ~ (2, 8) => 0.0415779
+(0, -1) ~ (2, 9) => 0.0810926
+(0, -1) ~ (2, 10) => 0.0742222
+(0, -1) ~ (2, 11) => 0.0709047
+(0, -1) ~ (2, 12) => 0.0958161
+(0, -1) ~ (2, 13) => 0.0918968
+(0, -1) ~ (2, 14) => 0.102192
+(0, -1) ~ (2, 15) => 0.273302
+(0, -1) ~ (2, 16) => 0.416186
+(0, -1) ~ (2, 17) => 0.82015
+(0, -1) ~ (2, 18) => 0.720513
+(0, -1) ~ (2, 19) => 0.532154
+(0, -1) ~ (2, 20) => 0.076754
+(0, -1) ~ (2, 21) => 0.0182276
+(0, -1) ~ (2, 22) => 0.00943756
+(0, -1) ~ (2, 23) => 0.00161451
+(0, -1) ~ (2, 24) => 0.0001
+(0, -1) ~ (2, 25) => 0.0001
+(0, -1) ~ (2, 26) => 0.0001
+(0, -1) ~ (2, 27) => 0.0001
+(0, -1) ~ (2, 28) => 0.0001
+(0, -1) ~ (2, 29) => 0.0001
+(0, -1) ~ (2, 30) => 0.0001
+(0, -1) ~ (2, 31) => 0.0001
+(0, -1) ~ (2, 32) => 0.000273824
+(0, -1) ~ (2, 33) => 0.000401914
+(0, -1) ~ (2, 34) => 0.000497699
+(0, -1) ~ (2, 35) => 0.000455797
+(0, -1) ~ (2, 36) => 0.000364482
+(0, -1) ~ (2, 37) => 0.000322104
+(0, -1) ~ (2, 38) => 0.000314415
+(0, -1) ~ (2, 39) => 0.000451982
+(0, -1) ~ (2, 40) => 0.000570059
+(0, -1) ~ (2, 41) => 0.000649989
+(0, -1) ~ (2, 42) => 0.000543773
+(0, -1) ~ (2, 43) => 0.000265121
+(0, -1) ~ (2, 44) => 0.000303626
+(0, -1) ~ (2, 45) => 0.000324249
+(0, -1) ~ (2, 46) => 0.00130188
+(0, -1) ~ (2, 47) => 0.00278038
+(0, -1) ~ (2, 48) => 0.0134289
+(0, -1) ~ (2, 49) => 0.0206019
+(0, -1) ~ (2, 50) => 0.0357744
+(0, -1) ~ (2, 51) => 0.0300157
+(0, -1) ~ (2, 52) => 0.0361483
+(0, -1) ~ (2, 53) => 0.0459048
+(0, -1) ~ (2, 54) => 0.0563343
+(0, -1) ~ (2, 55) => 0.871598
+(0, -1) ~ (2, 56) => 0.914717
+(0, -1) ~ (2, 57) => 0.0603427
+(0, -1) ~ (2, 58) => 0.00791413
+(0, -1) ~ (2, 59) => 0.000329316
+(0, -1) ~ (2, 60) => 0.0001
+(0, -1) ~ (2, 61) => 0.0001
+(0, -1) ~ (2, 62) => 0.0001
+(0, -1) ~ (2, 63) => 0.0001
+(0, -1) ~ (2, 64) => 0.0001
+(0, -1) ~ (2, 65) => 0.0001
+(0, -1) ~ (2, 66) => 0.0001
+(0, -1) ~ (2, 67) => 0.0001
+(0, -1) ~ (2, 68) => 0.0001
+(0, -1) ~ (2, 69) => 0.0001
+(0, -1) ~ (2, 70) => 0.0001
+(0, -1) ~ (2, 71) => 0.0001
+(0, -1) ~ (2, 72) => 0.0001
+(0, -1) ~ (2, 73) => 0.0001
+(0, -1) ~ (2, 74) => 0.0001
+(0, -1) ~ (2, 75) => 0.0001
+(0, -1) ~ (2, 76) => 0.0001
+(0, -1) ~ (2, 77) => 0.0001
+(0, -1) ~ (2, 78) => 0.0001
+(0, -1) ~ (2, 79) => 0.0001
+(0, -1) ~ (2, 80) => 0.00010407
+(0, -1) ~ (2, 81) => 0.00136471
+(0, -1) ~ (2, 82) => 0.00249064
+(0, -1) ~ (2, 83) => 0.00282675
+(0, -1) ~ (2, 84) => 0.00314844
+(0, -1) ~ (2, 85) => 0.00385171
+(0, -1) ~ (2, 86) => 0.00356066
+(0, -1) ~ (2, 87) => 0.0032205
+(0, -1) ~ (2, 88) => 0.00285214
+(0, -1) ~ (2, 89) => 0.00258136
+(0, -1) ~ (2, 90) => 0.000537813
+(0, -1) ~ (2, 91) => 0.000395596
+(0, -1) ~ (2, 92) => 0.0001
+(0, -1) ~ (2, 93) => 0.0001
+(0, -1) ~ (2, 94) => 0.000125289
+(0, -1) ~ (2, 95) => 0.00100362
+(0, -1) ~ (2, 96) => 0.00187784
+(0, -1) ~ (2, 97) => 0.0040645
+(0, -1) ~ (2, 98) => 0.00489247
+(0, -1) ~ (2, 99) => 0.00585985
+(0, -1) ~ (2, 100) => 0.0116577
+(0, -1) ~ (2, 101) => 0.0155891
+(0, -1) ~ (2, 102) => 0.0204161
+(0, -1) ~ (2, 103) => 0.0247729
+(0, -1) ~ (2, 104) => 0.0135704
+(0, -1) ~ (2, 105) => 0.0124559
+(0, -1) ~ (2, 106) => 0.0176026
+(0, -1) ~ (2, 107) => 0.00930136
+(0, -1) ~ (2, 108) => 0.00452977
+(0, -1) ~ (2, 109) => 0.000255823
+(0, -1) ~ (2, 110) => 0.000105441
+(0, -1) ~ (2, 111) => 0.0001
+(0, -1) ~ (2, 112) => 0.0001
+(0, -1) ~ (2, 113) => 0.0001
+(0, -1) ~ (2, 114) => 0.0001
+(0, -1) ~ (2, 115) => 0.0001
+(0, -1) ~ (2, 116) => 0.0001
+(0, -1) ~ (2, 117) => 0.0001
+(0, -1) ~ (2, 118) => 0.0001
+(0, -1) ~ (2, 119) => 0.000178277
+(0, -1) ~ (2, 120) => 0.00119191
+(0, -1) ~ (2, 121) => 0.00270385
+(0, -1) ~ (2, 122) => 0.00323367
+(0, -1) ~ (2, 123) => 0.00335908
+(0, -1) ~ (2, 124) => 0.00310689
+(0, -1) ~ (2, 125) => 0.00304073
+(0, -1) ~ (2, 126) => 0.00281745
+(0, -1) ~ (2, 127) => 0.00214016
+(0, -1) ~ (2, 128) => 0.000702262
+(0, -1) ~ (2, 129) => 0.0001
+(0, -1) ~ (2, 130) => 0.0001
+(0, -1) ~ (2, 131) => 0.000132024
+(0, -1) ~ (2, 132) => 0.000231624
+(0, -1) ~ (2, 133) => 0.000206947
+(0, -1) ~ (2, 134) => 0.000305951
+(0, -1) ~ (2, 135) => 0.000375211
+(0, -1) ~ (2, 136) => 0.000559568
+(0, -1) ~ (2, 137) => 0.000570238
+(0, -1) ~ (2, 138) => 0.000347853
+(0, -1) ~ (2, 139) => 0.0001
+(0, -1) ~ (2, 140) => 0.0001
+(0, -1) ~ (2, 141) => 0.0001
+(0, -1) ~ (2, 142) => 0.0001
+(0, -1) ~ (2, 143) => 0.0001
+(0, -1) ~ (2, 144) => 0.0001
+(0, -1) ~ (2, 145) => 0.0001
+(0, -1) ~ (2, 146) => 0.0001
+(0, -1) ~ (2, 147) => 0.0001
+(0, -1) ~ (2, 148) => 0.0001
+(0, -1) ~ (2, 149) => 0.0001
+(0, -1) ~ (2, 150) => 0.0001
+(0, -1) ~ (2, 151) => 0.0001
+(0, -1) ~ (2, 152) => 0.000129044
+(0, -1) ~ (2, 153) => 0.000253975
+(0, -1) ~ (2, 154) => 0.000267029
+(0, -1) ~ (2, 155) => 0.0001
+(0, -1) ~ (2, 156) => 0.0001
+(0, -1) ~ (2, 157) => 0.000129104
+(0, -1) ~ (2, 158) => 0.000366747
+(0, -1) ~ (2, 159) => 0.000921428
+(0, -1) ~ (2, 160) => 0.00174505
+(0, -1) ~ (2, 161) => 0.0065583
+(0, -1) ~ (2, 162) => 0.0075013
+(0, -1) ~ (2, 163) => 0.0076564
+(0, -1) ~ (2, 164) => 0.00798392
+(0, -1) ~ (2, 165) => 0.00826848
+(0, -1) ~ (2, 166) => 0.00814223
+(0, -1) ~ (2, 167) => 0.00779921
+(0, -1) ~ (2, 168) => 0.00857532
+(0, -1) ~ (2, 169) => 0.00970978
+(0, -1) ~ (2, 170) => 0.0122453
+(0, -1) ~ (2, 171) => 0.0131392
+(0, -1) ~ (2, 172) => 0.0130062
+(0, -1) ~ (2, 173) => 0.012546
+(0, -1) ~ (2, 174) => 0.0118616
+(0, -1) ~ (2, 175) => 0.0109733
+(0, -1) ~ (2, 176) => 0.0107499
+(0, -1) ~ (2, 177) => 0.0105447
+(0, -1) ~ (2, 178) => 0.0113001
+(0, -1) ~ (2, 179) => 0.0100055
+(0, -1) ~ (2, 180) => 0.0092113
+(0, -1) ~ (2, 181) => 0.00779849
+(0, -1) ~ (2, 182) => 0.000871122
+(0, -1) ~ (2, 183) => 0.0001
+(0, -1) ~ (2, 184) => 0.000418842
+(0, -1) ~ (2, 185) => 0.000915647
+(0, -1) ~ (2, 186) => 0.0115041
+(0, -1) ~ (2, 187) => 0.0158229
+(0, -1) ~ (2, 188) => 0.0155655
+(0, -1) ~ (2, 189) => 0.0900781
+(0, -1) ~ (2, 190) => 0.100668
+(0, -1) ~ (2, 191) => 0.190276
+(0, -1) ~ (2, 192) => 0.343359
+(0, -1) ~ (2, 193) => 0.218613
+(0, -1) ~ (2, 194) => 0.307855
+(0, -1) ~ (2, 195) => 0.2025
+(0, -1) ~ (2, 196) => 0.151174
+(0, -1) ~ (2, 197) => 0.106833
+(0, -1) ~ (2, 198) => 0.09648
+(0, -1) ~ (2, 199) => 0.0831036
+(0, -1) ~ (2, 200) => 0.0570283
+(0, -1) ~ (2, 201) => 0.0413042
+(0, -1) ~ (2, 202) => 0.0327936
+(0, -1) ~ (2, 203) => 0.0314865
+(0, -1) ~ (2, 204) => 0.0374002
+(0, -1) ~ (2, 205) => 0.0488885
+(0, -1) ~ (2, 206) => 0.044664
+(0, -1) ~ (2, 207) => 0.0375007
+(0, -1) ~ (2, 208) => 0.024649
+(0, -1) ~ (2, 209) => 0.0183448
+(0, -1) ~ (2, 210) => 0.0136271
+(0, -1) ~ (2, 211) => 0.00823325
+(0, -1) ~ (2, 212) => 0.0012747
+(0, -1) ~ (2, 213) => 0.000776112
+(0, -1) ~ (2, 214) => 0.000680208
+(0, -1) ~ (2, 215) => 0.000561833
+(0, -1) ~ (2, 216) => 0.00116718
+(0, -1) ~ (2, 217) => 0.00111145
+(0, -1) ~ (2, 218) => 0.000674307
+(0, -1) ~ (2, 219) => 0.000330806
+(0, -1) ~ (2, 220) => 0.000405371
+(0, -1) ~ (2, 221) => 0.000531256
+(0, -1) ~ (2, 222) => 0.000941575
+(0, -1) ~ (2, 223) => 0.00100148
+(0, -1) ~ (2, 224) => 0.000826597
+(0, -1) ~ (2, 225) => 0.000311911
+(0, -1) ~ (2, 226) => 0.000317156
+(0, -1) ~ (2, 227) => 0.000195444
+(0, -1) ~ (2, 228) => 0.0001
+(0, -1) ~ (2, 229) => 0.0001
+(0, -1) ~ (2, 230) => 0.0001
+(0, -1) ~ (2, 231) => 0.0001
+(0, -1) ~ (2, 232) => 0.0001
+(0, -1) ~ (2, 233) => 0.0001
+(0, -1) ~ (2, 234) => 0.000845432
+(0, -1) ~ (2, 235) => 0.00304359
+(0, -1) ~ (2, 236) => 0.00319093
+(0, -1) ~ (2, 237) => 0.00270259
+(0, -1) ~ (2, 238) => 0.00198627
+
+; Sparse posterior probability matrix for sequences 0 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (3, 0) => 0.514813
+(0, 0) ~ (3, 1) => 0.0267797
+(0, 0) ~ (3, 2) => 0.1484
+(0, 0) ~ (3, 3) => 0.0100961
+(0, 1) ~ (3, 0) => 0.293745
+(0, 1) ~ (3, 1) => 0.382295
+(0, 1) ~ (3, 2) => 0.0428307
+(0, 1) ~ (3, 3) => 0.227108
+(0, 1) ~ (3, 4) => 0.020482
+(0, 2) ~ (3, 1) => 0.309294
+(0, 2) ~ (3, 2) => 0.344229
+(0, 2) ~ (3, 3) => 0.0475929
+(0, 2) ~ (3, 4) => 0.208346
+(0, 2) ~ (3, 5) => 0.0453192
+(0, 3) ~ (3, 2) => 0.323826
+(0, 3) ~ (3, 3) => 0.304373
+(0, 3) ~ (3, 4) => 0.0637306
+(0, 3) ~ (3, 5) => 0.204256
+(0, 3) ~ (3, 6) => 0.0514972
+(0, 4) ~ (3, 3) => 0.33791
+(0, 4) ~ (3, 4) => 0.272916
+(0, 4) ~ (3, 5) => 0.0802968
+(0, 4) ~ (3, 6) => 0.151937
+(0, 4) ~ (3, 7) => 0.0569922
+(0, 5) ~ (3, 4) => 0.359347
+(0, 5) ~ (3, 5) => 0.203911
+(0, 5) ~ (3, 6) => 0.180431
+(0, 5) ~ (3, 7) => 0.129578
+(0, 5) ~ (3, 8) => 0.0595082
+(0, 6) ~ (3, 5) => 0.376834
+(0, 6) ~ (3, 6) => 0.134624
+(0, 6) ~ (3, 7) => 0.270089
+(0, 6) ~ (3, 8) => 0.059676
+(0, 6) ~ (3, 9) => 0.070046
+(0, 7) ~ (3, 6) => 0.310302
+(0, 7) ~ (3, 7) => 0.0199317
+(0, 7) ~ (3, 8) => 0.509028
+(0, 7) ~ (3, 9) => 0.0397365
+(0, 7) ~ (3, 10) => 0.0953032
+(0, 8) ~ (3, 7) => 0.303682
+(0, 8) ~ (3, 9) => 0.517125
+(0, 8) ~ (3, 10) => 0.024616
+(0, 8) ~ (3, 11) => 0.132073
+(0, 9) ~ (3, 8) => 0.29235
+(0, 9) ~ (3, 10) => 0.511032
+(0, 9) ~ (3, 11) => 0.0258647
+(0, 9) ~ (3, 12) => 0.148107
+(0, 10) ~ (3, 9) => 0.282905
+(0, 10) ~ (3, 11) => 0.503508
+(0, 10) ~ (3, 12) => 0.028719
+(0, 10) ~ (3, 13) => 0.163121
+(0, 11) ~ (3, 10) => 0.266261
+(0, 11) ~ (3, 12) => 0.489795
+(0, 11) ~ (3, 13) => 0.0363559
+(0, 11) ~ (3, 14) => 0.189513
+(0, 12) ~ (3, 11) => 0.17955
+(0, 12) ~ (3, 13) => 0.368414
+(0, 12) ~ (3, 14) => 0.074291
+(0, 12) ~ (3, 15) => 0.345575
+(0, 13) ~ (3, 12) => 0.10648
+(0, 13) ~ (3, 14) => 0.142597
+(0, 13) ~ (3, 15) => 0.0961825
+(0, 13) ~ (3, 16) => 0.613809
+(0, 14) ~ (3, 12) => 0.0206354
+(0, 14) ~ (3, 13) => 0.0753847
+(0, 14) ~ (3, 15) => 0.065411
+(0, 14) ~ (3, 16) => 0.184391
+(0, 14) ~ (3, 17) => 0.620348
+(0, 15) ~ (3, 13) => 0.0274866
+(0, 15) ~ (3, 14) => 0.055961
+(0, 15) ~ (3, 16) => 0.0436467
+(0, 15) ~ (3, 17) => 0.224346
+(0, 15) ~ (3, 18) => 0.619655
+(0, 16) ~ (3, 14) => 0.0208178
+(0, 16) ~ (3, 15) => 0.0416291
+(0, 16) ~ (3, 17) => 0.0250435
+(0, 16) ~ (3, 18) => 0.277239
+(0, 16) ~ (3, 19) => 0.380961
+(0, 17) ~ (3, 15) => 0.0175353
+(0, 17) ~ (3, 16) => 0.0129838
+(0, 17) ~ (3, 18) => 0.0149752
+(0, 17) ~ (3, 19) => 0.554923
+(0, 17) ~ (3, 20) => 0.0818338
+(0, 18) ~ (3, 20) => 0.900597
+(0, 18) ~ (3, 21) => 0.0323831
+(0, 19) ~ (3, 21) => 0.959243
+(0, 20) ~ (3, 22) => 0.994815
+(0, 21) ~ (3, 23) => 0.999918
+(0, 22) ~ (3, 24) => 0.999994
+(0, 23) ~ (3, 25) => 0.999988
+(0, 24) ~ (3, 26) => 0.999936
+(0, 25) ~ (3, 27) => 0.999753
+(0, 26) ~ (3, 28) => 0.999716
+(0, 27) ~ (3, 29) => 0.999748
+(0, 28) ~ (3, 30) => 0.999147
+(0, 29) ~ (3, 31) => 0.997694
+(0, 30) ~ (3, 32) => 0.997105
+(0, 31) ~ (3, 33) => 0.995592
+(0, 32) ~ (3, 34) => 0.995535
+(0, 33) ~ (3, 35) => 0.996566
+(0, 34) ~ (3, 36) => 0.99685
+(0, 35) ~ (3, 37) => 0.99653
+(0, 36) ~ (3, 38) => 0.995223
+(0, 37) ~ (3, 39) => 0.993722
+(0, 38) ~ (3, 40) => 0.987608
+(0, 39) ~ (3, 41) => 0.985913
+(0, 40) ~ (3, 42) => 0.987189
+(0, 41) ~ (3, 43) => 0.991909
+(0, 42) ~ (3, 44) => 0.996245
+(0, 43) ~ (3, 45) => 0.990441
+(0, 44) ~ (3, 46) => 0.983726
+(0, 45) ~ (3, 47) => 0.920085
+(0, 45) ~ (3, 49) => 0.0626211
+(0, 46) ~ (3, 48) => 0.726134
+(0, 46) ~ (3, 50) => 0.242387
+(0, 47) ~ (3, 49) => 0.324821
+(0, 47) ~ (3, 50) => 0.0222893
+(0, 47) ~ (3, 51) => 0.624472
+(0, 47) ~ (3, 52) => 0.0101649
+(0, 48) ~ (3, 50) => 0.198142
+(0, 48) ~ (3, 51) => 0.0178333
+(0, 48) ~ (3, 52) => 0.758879
+(0, 49) ~ (3, 51) => 0.0823622
+(0, 49) ~ (3, 53) => 0.894614
+(0, 50) ~ (3, 54) => 0.989894
+(0, 51) ~ (3, 55) => 0.998903
+(0, 52) ~ (3, 56) => 0.999891
+(0, 53) ~ (3, 57) => 0.999981
+(0, 54) ~ (3, 58) => 0.999977
+(0, 55) ~ (3, 59) => 0.999728
+(0, 56) ~ (3, 60) => 0.99886
+(0, 57) ~ (3, 61) => 0.973886
+(0, 57) ~ (3, 62) => 0.0257788
+(0, 58) ~ (3, 62) => 0.965748
+(0, 58) ~ (3, 63) => 0.0337701
+(0, 59) ~ (3, 63) => 0.862898
+(0, 59) ~ (3, 64) => 0.136007
+(0, 60) ~ (3, 64) => 0.7602
+(0, 60) ~ (3, 65) => 0.238096
+(0, 61) ~ (3, 65) => 0.657848
+(0, 61) ~ (3, 66) => 0.340352
+(0, 62) ~ (3, 66) => 0.168717
+(0, 62) ~ (3, 67) => 0.829581
+(0, 63) ~ (3, 67) => 0.0911778
+(0, 63) ~ (3, 68) => 0.907216
+(0, 64) ~ (3, 68) => 0.0169918
+(0, 64) ~ (3, 69) => 0.982688
+(0, 65) ~ (3, 70) => 0.999768
+(0, 66) ~ (3, 71) => 0.999758
+(0, 67) ~ (3, 72) => 0.998631
+(0, 68) ~ (3, 73) => 0.998603
+(0, 69) ~ (3, 74) => 0.99885
+(0, 70) ~ (3, 75) => 0.999803
+(0, 71) ~ (3, 76) => 0.99992
+(0, 72) ~ (3, 77) => 0.999954
+(0, 73) ~ (3, 78) => 0.999862
+(0, 74) ~ (3, 79) => 0.999792
+(0, 75) ~ (3, 80) => 0.999387
+(0, 76) ~ (3, 81) => 0.991378
+(0, 77) ~ (3, 82) => 0.980662
+(0, 77) ~ (3, 83) => 0.0168353
+(0, 78) ~ (3, 83) => 0.978418
+(0, 78) ~ (3, 84) => 0.0168635
+(0, 79) ~ (3, 84) => 0.977064
+(0, 79) ~ (3, 85) => 0.0158169
+(0, 80) ~ (3, 85) => 0.976706
+(0, 80) ~ (3, 86) => 0.0167812
+(0, 81) ~ (3, 86) => 0.978793
+(0, 81) ~ (3, 87) => 0.0156804
+(0, 82) ~ (3, 87) => 0.980733
+(0, 83) ~ (3, 88) => 0.989764
+(0, 84) ~ (3, 89) => 0.994745
+(0, 85) ~ (3, 90) => 0.99903
+(0, 86) ~ (3, 91) => 0.999285
+(0, 87) ~ (3, 92) => 0.999861
+(0, 88) ~ (3, 93) => 0.999874
+(0, 89) ~ (3, 94) => 0.999823
+(0, 90) ~ (3, 95) => 0.999397
+(0, 91) ~ (3, 96) => 0.998983
+(0, 92) ~ (3, 97) => 0.997115
+(0, 93) ~ (3, 98) => 0.995936
+(0, 94) ~ (3, 99) => 0.994726
+(0, 95) ~ (3, 100) => 0.984092
+(0, 96) ~ (3, 101) => 0.97506
+(0, 96) ~ (3, 102) => 0.0123873
+(0, 97) ~ (3, 102) => 0.963228
+(0, 97) ~ (3, 103) => 0.017366
+(0, 98) ~ (3, 103) => 0.952933
+(0, 98) ~ (3, 104) => 0.0220295
+(0, 99) ~ (3, 104) => 0.947447
+(0, 99) ~ (3, 105) => 0.0251221
+(0, 100) ~ (3, 104) => 0.0104867
+(0, 100) ~ (3, 105) => 0.94829
+(0, 100) ~ (3, 106) => 0.021518
+(0, 101) ~ (3, 105) => 0.0105598
+(0, 101) ~ (3, 106) => 0.961473
+(0, 101) ~ (3, 107) => 0.0147668
+(0, 102) ~ (3, 107) => 0.978764
+(0, 103) ~ (3, 108) => 0.989581
+(0, 104) ~ (3, 109) => 0.999403
+(0, 105) ~ (3, 110) => 0.999714
+(0, 106) ~ (3, 111) => 0.99982
+(0, 107) ~ (3, 112) => 0.999952
+(0, 108) ~ (3, 113) => 0.999964
+(0, 109) ~ (3, 114) => 0.999948
+(0, 110) ~ (3, 115) => 0.99996
+(0, 111) ~ (3, 116) => 0.999988
+(0, 112) ~ (3, 117) => 0.999959
+(0, 113) ~ (3, 118) => 0.999852
+(0, 114) ~ (3, 119) => 0.99902
+(0, 115) ~ (3, 120) => 0.992036
+(0, 116) ~ (3, 121) => 0.986692
+(0, 117) ~ (3, 121) => 0.0103366
+(0, 117) ~ (3, 122) => 0.981732
+(0, 118) ~ (3, 122) => 0.0152999
+(0, 118) ~ (3, 123) => 0.981632
+(0, 119) ~ (3, 124) => 0.988605
+(0, 120) ~ (3, 125) => 0.989909
+(0, 121) ~ (3, 126) => 0.989303
+(0, 122) ~ (3, 127) => 0.990573
+(0, 123) ~ (3, 128) => 0.998255
+(0, 124) ~ (3, 129) => 0.999882
+(0, 125) ~ (3, 130) => 0.999947
+(0, 126) ~ (3, 131) => 0.999967
+(0, 127) ~ (3, 132) => 0.999982
+(0, 128) ~ (3, 133) => 0.999925
+(0, 129) ~ (3, 134) => 0.999744
+(0, 130) ~ (3, 135) => 0.999566
+(0, 131) ~ (3, 136) => 0.998649
+(0, 132) ~ (3, 137) => 0.997995
+(0, 133) ~ (3, 138) => 0.998048
+(0, 134) ~ (3, 139) => 0.999437
+(0, 135) ~ (3, 140) => 0.998906
+(0, 136) ~ (3, 141) => 0.999
+(0, 137) ~ (3, 142) => 0.999824
+(0, 138) ~ (3, 143) => 0.999966
+(0, 139) ~ (3, 144) => 0.999985
+(0, 140) ~ (3, 145) => 0.999963
+(0, 141) ~ (3, 146) => 0.999949
+(0, 142) ~ (3, 147) => 0.999965
+(0, 143) ~ (3, 148) => 0.999979
+(0, 144) ~ (3, 149) => 0.999996
+(0, 145) ~ (3, 150) => 0.999993
+(0, 146) ~ (3, 151) => 0.999965
+(0, 147) ~ (3, 152) => 0.999752
+(0, 148) ~ (3, 153) => 0.999428
+(0, 149) ~ (3, 154) => 0.999456
+(0, 150) ~ (3, 155) => 0.999845
+(0, 151) ~ (3, 156) => 0.999944
+(0, 152) ~ (3, 157) => 0.99973
+(0, 153) ~ (3, 158) => 0.999514
+(0, 154) ~ (3, 159) => 0.99923
+(0, 155) ~ (3, 160) => 0.99896
+(0, 156) ~ (3, 161) => 0.996036
+(0, 157) ~ (3, 162) => 0.993818
+(0, 158) ~ (3, 163) => 0.992366
+(0, 159) ~ (3, 164) => 0.988917
+(0, 160) ~ (3, 165) => 0.988574
+(0, 161) ~ (3, 166) => 0.989602
+(0, 162) ~ (3, 167) => 0.991049
+(0, 163) ~ (3, 168) => 0.992011
+(0, 164) ~ (3, 169) => 0.991864
+(0, 165) ~ (3, 170) => 0.992366
+(0, 166) ~ (3, 171) => 0.992853
+(0, 167) ~ (3, 172) => 0.992473
+(0, 168) ~ (3, 173) => 0.99269
+(0, 169) ~ (3, 174) => 0.993218
+(0, 170) ~ (3, 175) => 0.994006
+(0, 171) ~ (3, 176) => 0.995384
+(0, 172) ~ (3, 177) => 0.996321
+(0, 173) ~ (3, 178) => 0.99567
+(0, 174) ~ (3, 179) => 0.996102
+(0, 175) ~ (3, 180) => 0.99605
+(0, 176) ~ (3, 181) => 0.997943
+(0, 177) ~ (3, 182) => 0.999641
+(0, 178) ~ (3, 183) => 0.999857
+(0, 179) ~ (3, 184) => 0.995955
+(0, 180) ~ (3, 185) => 0.992007
+(0, 181) ~ (3, 186) => 0.891649
+(0, 182) ~ (3, 186) => 0.105279
+(0, 182) ~ (3, 187) => 0.816319
+(0, 183) ~ (3, 187) => 0.171694
+(0, 183) ~ (3, 188) => 0.713917
+(0, 183) ~ (3, 189) => 0.0109857
+(0, 184) ~ (3, 188) => 0.270236
+(0, 184) ~ (3, 189) => 0.463727
+(0, 184) ~ (3, 190) => 0.0377497
+(0, 185) ~ (3, 189) => 0.48348
+(0, 185) ~ (3, 190) => 0.386296
+(0, 185) ~ (3, 191) => 0.0613418
+(0, 185) ~ (3, 192) => 0.0237557
+(0, 186) ~ (3, 190) => 0.506434
+(0, 186) ~ (3, 191) => 0.267725
+(0, 186) ~ (3, 192) => 0.102257
+(0, 186) ~ (3, 193) => 0.0759969
+(0, 187) ~ (3, 191) => 0.525267
+(0, 187) ~ (3, 192) => 0.131927
+(0, 187) ~ (3, 193) => 0.192942
+(0, 187) ~ (3, 194) => 0.124363
+(0, 188) ~ (3, 192) => 0.298726
+(0, 188) ~ (3, 193) => 0.0744224
+(0, 188) ~ (3, 194) => 0.218894
+(0, 188) ~ (3, 195) => 0.372883
+(0, 189) ~ (3, 192) => 0.0212
+(0, 189) ~ (3, 193) => 0.232901
+(0, 189) ~ (3, 194) => 0.0367877
+(0, 189) ~ (3, 195) => 0.307823
+(0, 189) ~ (3, 196) => 0.361461
+(0, 190) ~ (3, 193) => 0.0264794
+(0, 190) ~ (3, 194) => 0.0499937
+(0, 190) ~ (3, 195) => 0.0105654
+(0, 190) ~ (3, 196) => 0.533805
+(0, 190) ~ (3, 197) => 0.33825
+(0, 191) ~ (3, 194) => 0.0315484
+(0, 191) ~ (3, 195) => 0.0355312
+(0, 191) ~ (3, 197) => 0.571763
+(0, 191) ~ (3, 198) => 0.283779
+(0, 192) ~ (3, 195) => 0.0295944
+(0, 192) ~ (3, 196) => 0.0287529
+(0, 192) ~ (3, 198) => 0.632966
+(0, 192) ~ (3, 199) => 0.19588
+(0, 193) ~ (3, 196) => 0.0303312
+(0, 193) ~ (3, 197) => 0.0247499
+(0, 193) ~ (3, 199) => 0.728508
+(0, 193) ~ (3, 200) => 0.166706
+(0, 194) ~ (3, 197) => 0.0227545
+(0, 194) ~ (3, 198) => 0.0173771
+(0, 194) ~ (3, 200) => 0.779059
+(0, 194) ~ (3, 201) => 0.10118
+(0, 195) ~ (3, 198) => 0.0113913
+(0, 195) ~ (3, 199) => 0.0104827
+(0, 195) ~ (3, 201) => 0.868535
+(0, 195) ~ (3, 202) => 0.0226979
+(0, 196) ~ (3, 202) => 0.963224
+(0, 196) ~ (3, 203) => 0.0116733
+(0, 197) ~ (3, 203) => 0.9825
+(0, 198) ~ (3, 204) => 0.996081
+(0, 199) ~ (3, 205) => 0.998199
+(0, 200) ~ (3, 206) => 0.9988
+(0, 201) ~ (3, 207) => 0.998619
+(0, 202) ~ (3, 208) => 0.998287
+(0, 203) ~ (3, 209) => 0.997418
+(0, 204) ~ (3, 210) => 0.997371
+(0, 205) ~ (3, 211) => 0.998104
+(0, 206) ~ (3, 212) => 0.999518
+(0, 207) ~ (3, 213) => 0.998676
+(0, 208) ~ (3, 214) => 0.991467
+(0, 209) ~ (3, 215) => 0.982737
+(0, 210) ~ (3, 215) => 0.0162395
+(0, 210) ~ (3, 216) => 0.975531
+(0, 211) ~ (3, 216) => 0.0233495
+(0, 211) ~ (3, 217) => 0.975447
+(0, 212) ~ (3, 217) => 0.01827
+(0, 212) ~ (3, 218) => 0.981042
+(0, 213) ~ (3, 218) => 0.0132324
+(0, 213) ~ (3, 219) => 0.986376
+(0, 214) ~ (3, 220) => 0.991385
+(0, 215) ~ (3, 221) => 0.994184
+(0, 216) ~ (3, 222) => 0.993976
+(0, 217) ~ (3, 223) => 0.994804
+(0, 218) ~ (3, 224) => 0.995643
+(0, 219) ~ (3, 225) => 0.997593
+(0, 220) ~ (3, 226) => 0.999293
+(0, 221) ~ (3, 227) => 0.999359
+(0, 222) ~ (3, 228) => 0.999674
+(0, 223) ~ (3, 229) => 0.99986
+(0, 224) ~ (3, 230) => 0.999988
+(0, 225) ~ (3, 231) => 0.999991
+(0, 226) ~ (3, 232) => 0.999982
+(0, 227) ~ (3, 233) => 0.999898
+(0, 228) ~ (3, 234) => 0.998763
+(0, 229) ~ (3, 235) => 0.995801
+(0, 230) ~ (3, 236) => 0.995812
+(0, 231) ~ (3, 237) => 0.998729
+(0, 232) ~ (3, 238) => 0.999385
+
+; gap posteriors
+(0, 0) ~ (3, -1) => 0.299911
+(0, 1) ~ (3, -1) => 0.0335389
+(0, 2) ~ (3, -1) => 0.045219
+(0, 3) ~ (3, -1) => 0.0523184
+(0, 4) ~ (3, -1) => 0.0999478
+(0, 5) ~ (3, -1) => 0.0672246
+(0, 6) ~ (3, -1) => 0.0887307
+(0, 7) ~ (3, -1) => 0.0256978
+(0, 8) ~ (3, -1) => 0.0225036
+(0, 9) ~ (3, -1) => 0.0226464
+(0, 10) ~ (3, -1) => 0.021748
+(0, 11) ~ (3, -1) => 0.0180745
+(0, 12) ~ (3, -1) => 0.0321702
+(0, 13) ~ (3, -1) => 0.0409312
+(0, 14) ~ (3, -1) => 0.0338302
+(0, 15) ~ (3, -1) => 0.0289053
+(0, 16) ~ (3, -1) => 0.25431
+(0, 17) ~ (3, -1) => 0.317749
+(0, 18) ~ (3, -1) => 0.0670201
+(0, 19) ~ (3, -1) => 0.0407566
+(0, 20) ~ (3, -1) => 0.00518495
+(0, 21) ~ (3, -1) => 0.0001
+(0, 22) ~ (3, -1) => 0.0001
+(0, 23) ~ (3, -1) => 0.0001
+(0, 24) ~ (3, -1) => 0.0001
+(0, 25) ~ (3, -1) => 0.000247002
+(0, 26) ~ (3, -1) => 0.000283778
+(0, 27) ~ (3, -1) => 0.00025177
+(0, 28) ~ (3, -1) => 0.000852585
+(0, 29) ~ (3, -1) => 0.00230551
+(0, 30) ~ (3, -1) => 0.00289476
+(0, 31) ~ (3, -1) => 0.00440848
+(0, 32) ~ (3, -1) => 0.00446504
+(0, 33) ~ (3, -1) => 0.0034337
+(0, 34) ~ (3, -1) => 0.00314951
+(0, 35) ~ (3, -1) => 0.0034703
+(0, 36) ~ (3, -1) => 0.00477743
+(0, 37) ~ (3, -1) => 0.0062775
+(0, 38) ~ (3, -1) => 0.0123917
+(0, 39) ~ (3, -1) => 0.0140868
+(0, 40) ~ (3, -1) => 0.0128109
+(0, 41) ~ (3, -1) => 0.00809103
+(0, 42) ~ (3, -1) => 0.00375515
+(0, 43) ~ (3, -1) => 0.00955874
+(0, 44) ~ (3, -1) => 0.0162743
+(0, 45) ~ (3, -1) => 0.0172939
+(0, 46) ~ (3, -1) => 0.031479
+(0, 47) ~ (3, -1) => 0.0182534
+(0, 48) ~ (3, -1) => 0.0251459
+(0, 49) ~ (3, -1) => 0.0230238
+(0, 50) ~ (3, -1) => 0.0101058
+(0, 51) ~ (3, -1) => 0.00109684
+(0, 52) ~ (3, -1) => 0.000108957
+(0, 53) ~ (3, -1) => 0.0001
+(0, 54) ~ (3, -1) => 0.0001
+(0, 55) ~ (3, -1) => 0.000271738
+(0, 56) ~ (3, -1) => 0.00114018
+(0, 57) ~ (3, -1) => 0.000335172
+(0, 58) ~ (3, -1) => 0.000481941
+(0, 59) ~ (3, -1) => 0.00109492
+(0, 60) ~ (3, -1) => 0.00170398
+(0, 61) ~ (3, -1) => 0.00180039
+(0, 62) ~ (3, -1) => 0.00170177
+(0, 63) ~ (3, -1) => 0.00160569
+(0, 64) ~ (3, -1) => 0.000319839
+(0, 65) ~ (3, -1) => 0.000231981
+(0, 66) ~ (3, -1) => 0.000241816
+(0, 67) ~ (3, -1) => 0.00136942
+(0, 68) ~ (3, -1) => 0.00139678
+(0, 69) ~ (3, -1) => 0.00114995
+(0, 70) ~ (3, -1) => 0.000196815
+(0, 71) ~ (3, -1) => 0.0001
+(0, 72) ~ (3, -1) => 0.0001
+(0, 73) ~ (3, -1) => 0.000138104
+(0, 74) ~ (3, -1) => 0.000207782
+(0, 75) ~ (3, -1) => 0.000612855
+(0, 76) ~ (3, -1) => 0.00862223
+(0, 77) ~ (3, -1) => 0.00250255
+(0, 78) ~ (3, -1) => 0.00471883
+(0, 79) ~ (3, -1) => 0.00711954
+(0, 80) ~ (3, -1) => 0.0065129
+(0, 81) ~ (3, -1) => 0.00552634
+(0, 82) ~ (3, -1) => 0.0192668
+(0, 83) ~ (3, -1) => 0.0102357
+(0, 84) ~ (3, -1) => 0.00525498
+(0, 85) ~ (3, -1) => 0.000969648
+(0, 86) ~ (3, -1) => 0.000715375
+(0, 87) ~ (3, -1) => 0.000139475
+(0, 88) ~ (3, -1) => 0.000125647
+(0, 89) ~ (3, -1) => 0.000176549
+(0, 90) ~ (3, -1) => 0.000603199
+(0, 91) ~ (3, -1) => 0.00101727
+(0, 92) ~ (3, -1) => 0.00288451
+(0, 93) ~ (3, -1) => 0.00406379
+(0, 94) ~ (3, -1) => 0.00527382
+(0, 95) ~ (3, -1) => 0.0159079
+(0, 96) ~ (3, -1) => 0.0125526
+(0, 97) ~ (3, -1) => 0.0194059
+(0, 98) ~ (3, -1) => 0.0250372
+(0, 99) ~ (3, -1) => 0.0274304
+(0, 100) ~ (3, -1) => 0.0197054
+(0, 101) ~ (3, -1) => 0.0132006
+(0, 102) ~ (3, -1) => 0.0212355
+(0, 103) ~ (3, -1) => 0.0104192
+(0, 104) ~ (3, -1) => 0.000597477
+(0, 105) ~ (3, -1) => 0.000286162
+(0, 106) ~ (3, -1) => 0.000180185
+(0, 107) ~ (3, -1) => 0.0001
+(0, 108) ~ (3, -1) => 0.0001
+(0, 109) ~ (3, -1) => 0.0001
+(0, 110) ~ (3, -1) => 0.0001
+(0, 111) ~ (3, -1) => 0.0001
+(0, 112) ~ (3, -1) => 0.0001
+(0, 113) ~ (3, -1) => 0.000148177
+(0, 114) ~ (3, -1) => 0.000979722
+(0, 115) ~ (3, -1) => 0.00796402
+(0, 116) ~ (3, -1) => 0.0133081
+(0, 117) ~ (3, -1) => 0.00793123
+(0, 118) ~ (3, -1) => 0.00306761
+(0, 119) ~ (3, -1) => 0.0113949
+(0, 120) ~ (3, -1) => 0.0100909
+(0, 121) ~ (3, -1) => 0.0106972
+(0, 122) ~ (3, -1) => 0.00942659
+(0, 123) ~ (3, -1) => 0.00174463
+(0, 124) ~ (3, -1) => 0.00011754
+(0, 125) ~ (3, -1) => 0.0001
+(0, 126) ~ (3, -1) => 0.0001
+(0, 127) ~ (3, -1) => 0.0001
+(0, 128) ~ (3, -1) => 0.0001
+(0, 129) ~ (3, -1) => 0.000256002
+(0, 130) ~ (3, -1) => 0.000433981
+(0, 131) ~ (3, -1) => 0.00135058
+(0, 132) ~ (3, -1) => 0.00200474
+(0, 133) ~ (3, -1) => 0.00195152
+(0, 134) ~ (3, -1) => 0.000562847
+(0, 135) ~ (3, -1) => 0.00109446
+(0, 136) ~ (3, -1) => 0.000999689
+(0, 137) ~ (3, -1) => 0.000176072
+(0, 138) ~ (3, -1) => 0.0001
+(0, 139) ~ (3, -1) => 0.0001
+(0, 140) ~ (3, -1) => 0.0001
+(0, 141) ~ (3, -1) => 0.0001
+(0, 142) ~ (3, -1) => 0.0001
+(0, 143) ~ (3, -1) => 0.0001
+(0, 144) ~ (3, -1) => 0.0001
+(0, 145) ~ (3, -1) => 0.0001
+(0, 146) ~ (3, -1) => 0.0001
+(0, 147) ~ (3, -1) => 0.000247717
+(0, 148) ~ (3, -1) => 0.000572026
+(0, 149) ~ (3, -1) => 0.000543773
+(0, 150) ~ (3, -1) => 0.000154614
+(0, 151) ~ (3, -1) => 0.0001
+(0, 152) ~ (3, -1) => 0.000269771
+(0, 153) ~ (3, -1) => 0.000485778
+(0, 154) ~ (3, -1) => 0.00077045
+(0, 155) ~ (3, -1) => 0.00104022
+(0, 156) ~ (3, -1) => 0.00396353
+(0, 157) ~ (3, -1) => 0.00618249
+(0, 158) ~ (3, -1) => 0.0076341
+(0, 159) ~ (3, -1) => 0.0110826
+(0, 160) ~ (3, -1) => 0.0114257
+(0, 161) ~ (3, -1) => 0.0103984
+(0, 162) ~ (3, -1) => 0.00895095
+(0, 163) ~ (3, -1) => 0.00798911
+(0, 164) ~ (3, -1) => 0.00813627
+(0, 165) ~ (3, -1) => 0.00763363
+(0, 166) ~ (3, -1) => 0.00714725
+(0, 167) ~ (3, -1) => 0.00752735
+(0, 168) ~ (3, -1) => 0.00730968
+(0, 169) ~ (3, -1) => 0.00678241
+(0, 170) ~ (3, -1) => 0.0059936
+(0, 171) ~ (3, -1) => 0.0046162
+(0, 172) ~ (3, -1) => 0.00367928
+(0, 173) ~ (3, -1) => 0.00432962
+(0, 174) ~ (3, -1) => 0.00389832
+(0, 175) ~ (3, -1) => 0.0039497
+(0, 176) ~ (3, -1) => 0.00205708
+(0, 177) ~ (3, -1) => 0.000359237
+(0, 178) ~ (3, -1) => 0.000143349
+(0, 179) ~ (3, -1) => 0.00404489
+(0, 180) ~ (3, -1) => 0.00799346
+(0, 181) ~ (3, -1) => 0.108351
+(0, 182) ~ (3, -1) => 0.0784019
+(0, 183) ~ (3, -1) => 0.103403
+(0, 184) ~ (3, -1) => 0.228287
+(0, 185) ~ (3, -1) => 0.0451264
+(0, 186) ~ (3, -1) => 0.0475877
+(0, 187) ~ (3, -1) => 0.0255018
+(0, 188) ~ (3, -1) => 0.0350746
+(0, 189) ~ (3, -1) => 0.039827
+(0, 190) ~ (3, -1) => 0.0409064
+(0, 191) ~ (3, -1) => 0.0773785
+(0, 192) ~ (3, -1) => 0.112807
+(0, 193) ~ (3, -1) => 0.0497052
+(0, 194) ~ (3, -1) => 0.0796297
+(0, 195) ~ (3, -1) => 0.0868927
+(0, 196) ~ (3, -1) => 0.0251031
+(0, 197) ~ (3, -1) => 0.0175004
+(0, 198) ~ (3, -1) => 0.00391871
+(0, 199) ~ (3, -1) => 0.00180066
+(0, 200) ~ (3, -1) => 0.00120038
+(0, 201) ~ (3, -1) => 0.00138146
+(0, 202) ~ (3, -1) => 0.0017128
+(0, 203) ~ (3, -1) => 0.00258249
+(0, 204) ~ (3, -1) => 0.00262886
+(0, 205) ~ (3, -1) => 0.00189644
+(0, 206) ~ (3, -1) => 0.000482321
+(0, 207) ~ (3, -1) => 0.00132352
+(0, 208) ~ (3, -1) => 0.0085327
+(0, 209) ~ (3, -1) => 0.0172632
+(0, 210) ~ (3, -1) => 0.00822937
+(0, 211) ~ (3, -1) => 0.00120306
+(0, 212) ~ (3, -1) => 0.000687659
+(0, 213) ~ (3, -1) => 0.000391662
+(0, 214) ~ (3, -1) => 0.00861484
+(0, 215) ~ (3, -1) => 0.00581557
+(0, 216) ~ (3, -1) => 0.00602382
+(0, 217) ~ (3, -1) => 0.00519574
+(0, 218) ~ (3, -1) => 0.00435698
+(0, 219) ~ (3, -1) => 0.00240713
+(0, 220) ~ (3, -1) => 0.000707388
+(0, 221) ~ (3, -1) => 0.000640929
+(0, 222) ~ (3, -1) => 0.000326097
+(0, 223) ~ (3, -1) => 0.000139892
+(0, 224) ~ (3, -1) => 0.0001
+(0, 225) ~ (3, -1) => 0.0001
+(0, 226) ~ (3, -1) => 0.0001
+(0, 227) ~ (3, -1) => 0.000102341
+(0, 228) ~ (3, -1) => 0.00123703
+(0, 229) ~ (3, -1) => 0.00419861
+(0, 230) ~ (3, -1) => 0.00418806
+(0, 231) ~ (3, -1) => 0.00127113
+(0, 232) ~ (3, -1) => 0.00061518
+
+(0, -1) ~ (3, 0) => 0.191442
+(0, -1) ~ (3, 1) => 0.281631
+(0, -1) ~ (3, 2) => 0.140715
+(0, -1) ~ (3, 3) => 0.0729202
+(0, -1) ~ (3, 4) => 0.0751782
+(0, -1) ~ (3, 5) => 0.0893828
+(0, -1) ~ (3, 6) => 0.171209
+(0, -1) ~ (3, 7) => 0.219727
+(0, -1) ~ (3, 8) => 0.0794379
+(0, -1) ~ (3, 9) => 0.0901879
+(0, -1) ~ (3, 10) => 0.102788
+(0, -1) ~ (3, 11) => 0.159004
+(0, -1) ~ (3, 12) => 0.206263
+(0, -1) ~ (3, 13) => 0.329238
+(0, -1) ~ (3, 14) => 0.51682
+(0, -1) ~ (3, 15) => 0.433667
+(0, -1) ~ (3, 16) => 0.145169
+(0, -1) ~ (3, 17) => 0.130263
+(0, -1) ~ (3, 18) => 0.0881311
+(0, -1) ~ (3, 19) => 0.0641164
+(0, -1) ~ (3, 20) => 0.0175695
+(0, -1) ~ (3, 21) => 0.00837344
+(0, -1) ~ (3, 22) => 0.00518495
+(0, -1) ~ (3, 23) => 0.0001
+(0, -1) ~ (3, 24) => 0.0001
+(0, -1) ~ (3, 25) => 0.0001
+(0, -1) ~ (3, 26) => 0.0001
+(0, -1) ~ (3, 27) => 0.000247002
+(0, -1) ~ (3, 28) => 0.000283778
+(0, -1) ~ (3, 29) => 0.00025177
+(0, -1) ~ (3, 30) => 0.000852585
+(0, -1) ~ (3, 31) => 0.00230551
+(0, -1) ~ (3, 32) => 0.00289476
+(0, -1) ~ (3, 33) => 0.00440848
+(0, -1) ~ (3, 34) => 0.00446504
+(0, -1) ~ (3, 35) => 0.0034337
+(0, -1) ~ (3, 36) => 0.00314951
+(0, -1) ~ (3, 37) => 0.0034703
+(0, -1) ~ (3, 38) => 0.00477743
+(0, -1) ~ (3, 39) => 0.0062775
+(0, -1) ~ (3, 40) => 0.0123917
+(0, -1) ~ (3, 41) => 0.0140868
+(0, -1) ~ (3, 42) => 0.0128109
+(0, -1) ~ (3, 43) => 0.00809103
+(0, -1) ~ (3, 44) => 0.00375515
+(0, -1) ~ (3, 45) => 0.00955874
+(0, -1) ~ (3, 46) => 0.0162743
+(0, -1) ~ (3, 47) => 0.079915
+(0, -1) ~ (3, 48) => 0.273866
+(0, -1) ~ (3, 49) => 0.612558
+(0, -1) ~ (3, 50) => 0.537183
+(0, -1) ~ (3, 51) => 0.275333
+(0, -1) ~ (3, 52) => 0.230956
+(0, -1) ~ (3, 53) => 0.105386
+(0, -1) ~ (3, 54) => 0.0101058
+(0, -1) ~ (3, 55) => 0.00109684
+(0, -1) ~ (3, 56) => 0.000108957
+(0, -1) ~ (3, 57) => 0.0001
+(0, -1) ~ (3, 58) => 0.0001
+(0, -1) ~ (3, 59) => 0.000271738
+(0, -1) ~ (3, 60) => 0.00114018
+(0, -1) ~ (3, 61) => 0.026114
+(0, -1) ~ (3, 62) => 0.00847322
+(0, -1) ~ (3, 63) => 0.103332
+(0, -1) ~ (3, 64) => 0.103793
+(0, -1) ~ (3, 65) => 0.104057
+(0, -1) ~ (3, 66) => 0.490931
+(0, -1) ~ (3, 67) => 0.0792408
+(0, -1) ~ (3, 68) => 0.0757917
+(0, -1) ~ (3, 69) => 0.0173117
+(0, -1) ~ (3, 70) => 0.000231981
+(0, -1) ~ (3, 71) => 0.000241816
+(0, -1) ~ (3, 72) => 0.00136942
+(0, -1) ~ (3, 73) => 0.00139678
+(0, -1) ~ (3, 74) => 0.00114995
+(0, -1) ~ (3, 75) => 0.000196815
+(0, -1) ~ (3, 76) => 0.0001
+(0, -1) ~ (3, 77) => 0.0001
+(0, -1) ~ (3, 78) => 0.000138104
+(0, -1) ~ (3, 79) => 0.000207782
+(0, -1) ~ (3, 80) => 0.000612855
+(0, -1) ~ (3, 81) => 0.00862223
+(0, -1) ~ (3, 82) => 0.0193379
+(0, -1) ~ (3, 83) => 0.00474697
+(0, -1) ~ (3, 84) => 0.006073
+(0, -1) ~ (3, 85) => 0.00747716
+(0, -1) ~ (3, 86) => 0.00442553
+(0, -1) ~ (3, 87) => 0.00358641
+(0, -1) ~ (3, 88) => 0.0102357
+(0, -1) ~ (3, 89) => 0.00525498
+(0, -1) ~ (3, 90) => 0.000969648
+(0, -1) ~ (3, 91) => 0.000715375
+(0, -1) ~ (3, 92) => 0.000139475
+(0, -1) ~ (3, 93) => 0.000125647
+(0, -1) ~ (3, 94) => 0.000176549
+(0, -1) ~ (3, 95) => 0.000603199
+(0, -1) ~ (3, 96) => 0.00101727
+(0, -1) ~ (3, 97) => 0.00288451
+(0, -1) ~ (3, 98) => 0.00406379
+(0, -1) ~ (3, 99) => 0.00527382
+(0, -1) ~ (3, 100) => 0.0159079
+(0, -1) ~ (3, 101) => 0.0249399
+(0, -1) ~ (3, 102) => 0.0243845
+(0, -1) ~ (3, 103) => 0.0297008
+(0, -1) ~ (3, 104) => 0.0200363
+(0, -1) ~ (3, 105) => 0.0160283
+(0, -1) ~ (3, 106) => 0.0170091
+(0, -1) ~ (3, 107) => 0.00646871
+(0, -1) ~ (3, 108) => 0.0104192
+(0, -1) ~ (3, 109) => 0.000597477
+(0, -1) ~ (3, 110) => 0.000286162
+(0, -1) ~ (3, 111) => 0.000180185
+(0, -1) ~ (3, 112) => 0.0001
+(0, -1) ~ (3, 113) => 0.0001
+(0, -1) ~ (3, 114) => 0.0001
+(0, -1) ~ (3, 115) => 0.0001
+(0, -1) ~ (3, 116) => 0.0001
+(0, -1) ~ (3, 117) => 0.0001
+(0, -1) ~ (3, 118) => 0.000148177
+(0, -1) ~ (3, 119) => 0.000979722
+(0, -1) ~ (3, 120) => 0.00796402
+(0, -1) ~ (3, 121) => 0.00297155
+(0, -1) ~ (3, 122) => 0.00296788
+(0, -1) ~ (3, 123) => 0.0183675
+(0, -1) ~ (3, 124) => 0.0113949
+(0, -1) ~ (3, 125) => 0.0100909
+(0, -1) ~ (3, 126) => 0.0106972
+(0, -1) ~ (3, 127) => 0.00942659
+(0, -1) ~ (3, 128) => 0.00174463
+(0, -1) ~ (3, 129) => 0.00011754
+(0, -1) ~ (3, 130) => 0.0001
+(0, -1) ~ (3, 131) => 0.0001
+(0, -1) ~ (3, 132) => 0.0001
+(0, -1) ~ (3, 133) => 0.0001
+(0, -1) ~ (3, 134) => 0.000256002
+(0, -1) ~ (3, 135) => 0.000433981
+(0, -1) ~ (3, 136) => 0.00135058
+(0, -1) ~ (3, 137) => 0.00200474
+(0, -1) ~ (3, 138) => 0.00195152
+(0, -1) ~ (3, 139) => 0.000562847
+(0, -1) ~ (3, 140) => 0.00109446
+(0, -1) ~ (3, 141) => 0.000999689
+(0, -1) ~ (3, 142) => 0.000176072
+(0, -1) ~ (3, 143) => 0.0001
+(0, -1) ~ (3, 144) => 0.0001
+(0, -1) ~ (3, 145) => 0.0001
+(0, -1) ~ (3, 146) => 0.0001
+(0, -1) ~ (3, 147) => 0.0001
+(0, -1) ~ (3, 148) => 0.0001
+(0, -1) ~ (3, 149) => 0.0001
+(0, -1) ~ (3, 150) => 0.0001
+(0, -1) ~ (3, 151) => 0.0001
+(0, -1) ~ (3, 152) => 0.000247717
+(0, -1) ~ (3, 153) => 0.000572026
+(0, -1) ~ (3, 154) => 0.000543773
+(0, -1) ~ (3, 155) => 0.000154614
+(0, -1) ~ (3, 156) => 0.0001
+(0, -1) ~ (3, 157) => 0.000269771
+(0, -1) ~ (3, 158) => 0.000485778
+(0, -1) ~ (3, 159) => 0.00077045
+(0, -1) ~ (3, 160) => 0.00104022
+(0, -1) ~ (3, 161) => 0.00396353
+(0, -1) ~ (3, 162) => 0.00618249
+(0, -1) ~ (3, 163) => 0.0076341
+(0, -1) ~ (3, 164) => 0.0110826
+(0, -1) ~ (3, 165) => 0.0114257
+(0, -1) ~ (3, 166) => 0.0103984
+(0, -1) ~ (3, 167) => 0.00895095
+(0, -1) ~ (3, 168) => 0.00798911
+(0, -1) ~ (3, 169) => 0.00813627
+(0, -1) ~ (3, 170) => 0.00763363
+(0, -1) ~ (3, 171) => 0.00714725
+(0, -1) ~ (3, 172) => 0.00752735
+(0, -1) ~ (3, 173) => 0.00730968
+(0, -1) ~ (3, 174) => 0.00678241
+(0, -1) ~ (3, 175) => 0.0059936
+(0, -1) ~ (3, 176) => 0.0046162
+(0, -1) ~ (3, 177) => 0.00367928
+(0, -1) ~ (3, 178) => 0.00432962
+(0, -1) ~ (3, 179) => 0.00389832
+(0, -1) ~ (3, 180) => 0.0039497
+(0, -1) ~ (3, 181) => 0.00205708
+(0, -1) ~ (3, 182) => 0.000359237
+(0, -1) ~ (3, 183) => 0.000143349
+(0, -1) ~ (3, 184) => 0.00404489
+(0, -1) ~ (3, 185) => 0.00799346
+(0, -1) ~ (3, 186) => 0.00307188
+(0, -1) ~ (3, 187) => 0.0119864
+(0, -1) ~ (3, 188) => 0.0158472
+(0, -1) ~ (3, 189) => 0.0418065
+(0, -1) ~ (3, 190) => 0.0695207
+(0, -1) ~ (3, 191) => 0.145666
+(0, -1) ~ (3, 192) => 0.422135
+(0, -1) ~ (3, 193) => 0.397259
+(0, -1) ~ (3, 194) => 0.538414
+(0, -1) ~ (3, 195) => 0.243603
+(0, -1) ~ (3, 196) => 0.0456492
+(0, -1) ~ (3, 197) => 0.0424827
+(0, -1) ~ (3, 198) => 0.0544871
+(0, -1) ~ (3, 199) => 0.0651293
+(0, -1) ~ (3, 200) => 0.0542351
+(0, -1) ~ (3, 201) => 0.0302851
+(0, -1) ~ (3, 202) => 0.0140786
+(0, -1) ~ (3, 203) => 0.00582707
+(0, -1) ~ (3, 204) => 0.00391871
+(0, -1) ~ (3, 205) => 0.00180066
+(0, -1) ~ (3, 206) => 0.00120038
+(0, -1) ~ (3, 207) => 0.00138146
+(0, -1) ~ (3, 208) => 0.0017128
+(0, -1) ~ (3, 209) => 0.00258249
+(0, -1) ~ (3, 210) => 0.00262886
+(0, -1) ~ (3, 211) => 0.00189644
+(0, -1) ~ (3, 212) => 0.000482321
+(0, -1) ~ (3, 213) => 0.00132352
+(0, -1) ~ (3, 214) => 0.0085327
+(0, -1) ~ (3, 215) => 0.00102372
+(0, -1) ~ (3, 216) => 0.00111929
+(0, -1) ~ (3, 217) => 0.00628258
+(0, -1) ~ (3, 218) => 0.00572532
+(0, -1) ~ (3, 219) => 0.013624
+(0, -1) ~ (3, 220) => 0.00861484
+(0, -1) ~ (3, 221) => 0.00581557
+(0, -1) ~ (3, 222) => 0.00602382
+(0, -1) ~ (3, 223) => 0.00519574
+(0, -1) ~ (3, 224) => 0.00435698
+(0, -1) ~ (3, 225) => 0.00240713
+(0, -1) ~ (3, 226) => 0.000707388
+(0, -1) ~ (3, 227) => 0.000640929
+(0, -1) ~ (3, 228) => 0.000326097
+(0, -1) ~ (3, 229) => 0.000139892
+(0, -1) ~ (3, 230) => 0.0001
+(0, -1) ~ (3, 231) => 0.0001
+(0, -1) ~ (3, 232) => 0.0001
+(0, -1) ~ (3, 233) => 0.000102341
+(0, -1) ~ (3, 234) => 0.00123703
+(0, -1) ~ (3, 235) => 0.00419861
+(0, -1) ~ (3, 236) => 0.00418806
+(0, -1) ~ (3, 237) => 0.00127113
+(0, -1) ~ (3, 238) => 0.00061518
+
+; Sparse posterior probability matrix for sequences 0 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (4, 0) => 0.354707
+(0, 0) ~ (4, 1) => 0.629218
+(0, 1) ~ (4, 1) => 0.256812
+(0, 1) ~ (4, 2) => 0.718143
+(0, 2) ~ (4, 2) => 0.163972
+(0, 2) ~ (4, 3) => 0.806587
+(0, 3) ~ (4, 3) => 0.133315
+(0, 3) ~ (4, 4) => 0.833635
+(0, 4) ~ (4, 3) => 0.0111244
+(0, 4) ~ (4, 4) => 0.113585
+(0, 4) ~ (4, 5) => 0.824777
+(0, 4) ~ (4, 7) => 0.0180062
+(0, 5) ~ (4, 4) => 0.0210531
+(0, 5) ~ (4, 5) => 0.113333
+(0, 5) ~ (4, 6) => 0.782572
+(0, 5) ~ (4, 8) => 0.049947
+(0, 6) ~ (4, 5) => 0.0304084
+(0, 6) ~ (4, 6) => 0.0973225
+(0, 6) ~ (4, 7) => 0.761439
+(0, 6) ~ (4, 9) => 0.0802125
+(0, 7) ~ (4, 6) => 0.047
+(0, 7) ~ (4, 7) => 0.0740586
+(0, 7) ~ (4, 8) => 0.736611
+(0, 7) ~ (4, 10) => 0.129892
+(0, 8) ~ (4, 7) => 0.0404603
+(0, 8) ~ (4, 8) => 0.06842
+(0, 8) ~ (4, 9) => 0.747139
+(0, 8) ~ (4, 11) => 0.12982
+(0, 9) ~ (4, 8) => 0.0290991
+(0, 9) ~ (4, 9) => 0.0502129
+(0, 9) ~ (4, 10) => 0.737374
+(0, 9) ~ (4, 11) => 0.0432329
+(0, 9) ~ (4, 12) => 0.119025
+(0, 10) ~ (4, 9) => 0.0177761
+(0, 10) ~ (4, 10) => 0.0314942
+(0, 10) ~ (4, 11) => 0.724339
+(0, 10) ~ (4, 12) => 0.0951032
+(0, 10) ~ (4, 13) => 0.0913556
+(0, 11) ~ (4, 10) => 0.0108091
+(0, 11) ~ (4, 11) => 0.0129869
+(0, 11) ~ (4, 12) => 0.691418
+(0, 11) ~ (4, 13) => 0.184418
+(0, 11) ~ (4, 14) => 0.0819864
+(0, 12) ~ (4, 13) => 0.451135
+(0, 12) ~ (4, 14) => 0.446391
+(0, 12) ~ (4, 15) => 0.081854
+(0, 13) ~ (4, 14) => 0.265206
+(0, 13) ~ (4, 15) => 0.642639
+(0, 13) ~ (4, 16) => 0.0484948
+(0, 14) ~ (4, 15) => 0.145788
+(0, 14) ~ (4, 16) => 0.798659
+(0, 15) ~ (4, 16) => 0.0136699
+(0, 15) ~ (4, 17) => 0.979698
+(0, 16) ~ (4, 18) => 0.994347
+(0, 17) ~ (4, 19) => 0.996042
+(0, 18) ~ (4, 20) => 0.998719
+(0, 19) ~ (4, 21) => 0.999326
+(0, 20) ~ (4, 22) => 0.999889
+(0, 21) ~ (4, 23) => 0.99998
+(0, 22) ~ (4, 24) => 0.999935
+(0, 23) ~ (4, 25) => 0.998635
+(0, 24) ~ (4, 26) => 0.993509
+(0, 25) ~ (4, 27) => 0.980705
+(0, 25) ~ (4, 28) => 0.0157649
+(0, 26) ~ (4, 28) => 0.971262
+(0, 26) ~ (4, 29) => 0.0238278
+(0, 27) ~ (4, 29) => 0.942026
+(0, 27) ~ (4, 30) => 0.0504982
+(0, 28) ~ (4, 30) => 0.931229
+(0, 28) ~ (4, 31) => 0.0595547
+(0, 29) ~ (4, 31) => 0.930442
+(0, 29) ~ (4, 32) => 0.0538183
+(0, 30) ~ (4, 32) => 0.936814
+(0, 30) ~ (4, 33) => 0.0473468
+(0, 31) ~ (4, 33) => 0.942758
+(0, 31) ~ (4, 34) => 0.0407755
+(0, 32) ~ (4, 34) => 0.948934
+(0, 32) ~ (4, 35) => 0.0366851
+(0, 33) ~ (4, 35) => 0.951926
+(0, 33) ~ (4, 36) => 0.0339196
+(0, 34) ~ (4, 36) => 0.957529
+(0, 34) ~ (4, 37) => 0.0160545
+(0, 35) ~ (4, 37) => 0.979373
+(0, 36) ~ (4, 38) => 0.992057
+(0, 37) ~ (4, 39) => 0.992238
+(0, 38) ~ (4, 40) => 0.993692
+(0, 39) ~ (4, 41) => 0.99697
+(0, 40) ~ (4, 42) => 0.998066
+(0, 41) ~ (4, 43) => 0.998598
+(0, 42) ~ (4, 44) => 0.999513
+(0, 43) ~ (4, 45) => 0.998858
+(0, 44) ~ (4, 46) => 0.998823
+(0, 45) ~ (4, 47) => 0.998865
+(0, 46) ~ (4, 48) => 0.998958
+(0, 47) ~ (4, 49) => 0.999047
+(0, 48) ~ (4, 50) => 0.999194
+(0, 49) ~ (4, 51) => 0.999636
+(0, 50) ~ (4, 52) => 0.999967
+(0, 51) ~ (4, 53) => 0.999999
+(0, 52) ~ (4, 54) => 0.999996
+(0, 53) ~ (4, 55) => 0.999952
+(0, 54) ~ (4, 56) => 0.999647
+(0, 55) ~ (4, 57) => 0.993112
+(0, 56) ~ (4, 58) => 0.985969
+(0, 56) ~ (4, 59) => 0.0113468
+(0, 57) ~ (4, 59) => 0.94107
+(0, 57) ~ (4, 60) => 0.0552703
+(0, 58) ~ (4, 60) => 0.934184
+(0, 58) ~ (4, 61) => 0.0600308
+(0, 59) ~ (4, 61) => 0.877643
+(0, 59) ~ (4, 62) => 0.103937
+(0, 60) ~ (4, 61) => 0.0175604
+(0, 60) ~ (4, 62) => 0.820564
+(0, 60) ~ (4, 63) => 0.147513
+(0, 61) ~ (4, 62) => 0.0299267
+(0, 61) ~ (4, 63) => 0.577562
+(0, 61) ~ (4, 64) => 0.37645
+(0, 62) ~ (4, 63) => 0.0375248
+(0, 62) ~ (4, 64) => 0.274215
+(0, 62) ~ (4, 65) => 0.669317
+(0, 63) ~ (4, 64) => 0.048323
+(0, 63) ~ (4, 65) => 0.169105
+(0, 63) ~ (4, 66) => 0.776689
+(0, 64) ~ (4, 65) => 0.0273583
+(0, 64) ~ (4, 66) => 0.0767054
+(0, 64) ~ (4, 67) => 0.893058
+(0, 65) ~ (4, 68) => 0.9933
+(0, 66) ~ (4, 69) => 0.99874
+(0, 67) ~ (4, 70) => 0.998802
+(0, 68) ~ (4, 71) => 0.999447
+(0, 69) ~ (4, 72) => 0.999942
+(0, 70) ~ (4, 73) => 0.999989
+(0, 71) ~ (4, 74) => 0.99998
+(0, 72) ~ (4, 75) => 0.999927
+(0, 73) ~ (4, 76) => 0.999331
+(0, 74) ~ (4, 77) => 0.998704
+(0, 75) ~ (4, 78) => 0.996007
+(0, 76) ~ (4, 79) => 0.91435
+(0, 77) ~ (4, 80) => 0.775753
+(0, 78) ~ (4, 80) => 0.0122599
+(0, 78) ~ (4, 81) => 0.564706
+(0, 79) ~ (4, 79) => 0.0636952
+(0, 79) ~ (4, 80) => 0.0129337
+(0, 79) ~ (4, 81) => 0.020785
+(0, 79) ~ (4, 82) => 0.354809
+(0, 80) ~ (4, 80) => 0.188461
+(0, 80) ~ (4, 81) => 0.0119514
+(0, 80) ~ (4, 82) => 0.012775
+(0, 80) ~ (4, 83) => 0.195949
+(0, 81) ~ (4, 81) => 0.390785
+(0, 81) ~ (4, 82) => 0.0108336
+(0, 81) ~ (4, 84) => 0.109923
+(0, 82) ~ (4, 82) => 0.600286
+(0, 82) ~ (4, 83) => 0.0118349
+(0, 82) ~ (4, 85) => 0.0324213
+(0, 83) ~ (4, 83) => 0.763221
+(0, 84) ~ (4, 84) => 0.866735
+(0, 85) ~ (4, 85) => 0.955159
+(0, 86) ~ (4, 86) => 0.985982
+(0, 87) ~ (4, 87) => 0.987828
+(0, 88) ~ (4, 88) => 0.988695
+(0, 89) ~ (4, 89) => 0.988984
+(0, 90) ~ (4, 90) => 0.986859
+(0, 91) ~ (4, 91) => 0.983696
+(0, 92) ~ (4, 92) => 0.930817
+(0, 92) ~ (4, 96) => 0.0294705
+(0, 93) ~ (4, 93) => 0.865977
+(0, 93) ~ (4, 97) => 0.0773831
+(0, 93) ~ (4, 98) => 0.0214042
+(0, 94) ~ (4, 94) => 0.830071
+(0, 94) ~ (4, 98) => 0.101393
+(0, 94) ~ (4, 99) => 0.0359639
+(0, 95) ~ (4, 95) => 0.671641
+(0, 95) ~ (4, 99) => 0.110074
+(0, 95) ~ (4, 100) => 0.184659
+(0, 95) ~ (4, 101) => 0.0136525
+(0, 96) ~ (4, 96) => 0.658944
+(0, 96) ~ (4, 100) => 0.0864994
+(0, 96) ~ (4, 101) => 0.19955
+(0, 96) ~ (4, 102) => 0.0223239
+(0, 96) ~ (4, 103) => 0.0195866
+(0, 97) ~ (4, 97) => 0.650024
+(0, 97) ~ (4, 101) => 0.0805842
+(0, 97) ~ (4, 102) => 0.21043
+(0, 97) ~ (4, 103) => 0.0244918
+(0, 97) ~ (4, 104) => 0.0191353
+(0, 98) ~ (4, 98) => 0.498083
+(0, 98) ~ (4, 102) => 0.0756801
+(0, 98) ~ (4, 103) => 0.29691
+(0, 98) ~ (4, 104) => 0.0566669
+(0, 98) ~ (4, 105) => 0.0310399
+(0, 99) ~ (4, 98) => 0.0191128
+(0, 99) ~ (4, 99) => 0.321096
+(0, 99) ~ (4, 102) => 0.0153483
+(0, 99) ~ (4, 103) => 0.0508688
+(0, 99) ~ (4, 104) => 0.466185
+(0, 99) ~ (4, 105) => 0.0602934
+(0, 99) ~ (4, 106) => 0.0116941
+(0, 100) ~ (4, 99) => 0.0156632
+(0, 100) ~ (4, 100) => 0.221321
+(0, 100) ~ (4, 101) => 0.0125015
+(0, 100) ~ (4, 102) => 0.0107059
+(0, 100) ~ (4, 103) => 0.0211461
+(0, 100) ~ (4, 104) => 0.0340524
+(0, 100) ~ (4, 105) => 0.582069
+(0, 100) ~ (4, 106) => 0.0552365
+(0, 101) ~ (4, 101) => 0.0721322
+(0, 101) ~ (4, 102) => 0.010731
+(0, 101) ~ (4, 104) => 0.0141961
+(0, 101) ~ (4, 105) => 0.0193284
+(0, 101) ~ (4, 106) => 0.798507
+(0, 101) ~ (4, 107) => 0.0398774
+(0, 102) ~ (4, 102) => 0.0200074
+(0, 102) ~ (4, 107) => 0.920313
+(0, 102) ~ (4, 108) => 0.0205614
+(0, 103) ~ (4, 108) => 0.968586
+(0, 104) ~ (4, 109) => 0.998705
+(0, 105) ~ (4, 110) => 0.999803
+(0, 106) ~ (4, 111) => 0.999968
+(0, 107) ~ (4, 112) => 0.99999
+(0, 108) ~ (4, 113) => 0.999988
+(0, 109) ~ (4, 114) => 0.999972
+(0, 110) ~ (4, 115) => 0.999964
+(0, 111) ~ (4, 116) => 0.999901
+(0, 112) ~ (4, 117) => 0.999844
+(0, 113) ~ (4, 118) => 0.99985
+(0, 114) ~ (4, 119) => 0.99993
+(0, 115) ~ (4, 120) => 0.999991
+(0, 116) ~ (4, 121) => 0.999968
+(0, 117) ~ (4, 122) => 0.999706
+(0, 118) ~ (4, 123) => 0.999647
+(0, 119) ~ (4, 124) => 0.999787
+(0, 120) ~ (4, 125) => 0.999593
+(0, 121) ~ (4, 126) => 0.999366
+(0, 122) ~ (4, 127) => 0.999405
+(0, 123) ~ (4, 128) => 0.999025
+(0, 124) ~ (4, 129) => 0.997704
+(0, 125) ~ (4, 130) => 0.977299
+(0, 126) ~ (4, 131) => 0.958921
+(0, 126) ~ (4, 133) => 0.0167028
+(0, 127) ~ (4, 132) => 0.930713
+(0, 127) ~ (4, 134) => 0.0368153
+(0, 128) ~ (4, 133) => 0.92254
+(0, 128) ~ (4, 135) => 0.0367939
+(0, 129) ~ (4, 134) => 0.912811
+(0, 129) ~ (4, 136) => 0.0372567
+(0, 130) ~ (4, 135) => 0.90547
+(0, 130) ~ (4, 137) => 0.0350622
+(0, 131) ~ (4, 131) => 0.0154992
+(0, 131) ~ (4, 136) => 0.890265
+(0, 131) ~ (4, 138) => 0.03291
+(0, 132) ~ (4, 132) => 0.0198253
+(0, 132) ~ (4, 136) => 0.0169624
+(0, 132) ~ (4, 137) => 0.842209
+(0, 132) ~ (4, 139) => 0.029257
+(0, 133) ~ (4, 133) => 0.0207697
+(0, 133) ~ (4, 137) => 0.0606403
+(0, 133) ~ (4, 138) => 0.793511
+(0, 133) ~ (4, 140) => 0.0227596
+(0, 134) ~ (4, 134) => 0.0209826
+(0, 134) ~ (4, 135) => 0.0126298
+(0, 134) ~ (4, 138) => 0.106325
+(0, 134) ~ (4, 139) => 0.752801
+(0, 134) ~ (4, 141) => 0.0139538
+(0, 135) ~ (4, 136) => 0.0208468
+(0, 135) ~ (4, 138) => 0.0113268
+(0, 135) ~ (4, 139) => 0.159509
+(0, 135) ~ (4, 140) => 0.673104
+(0, 135) ~ (4, 142) => 0.010867
+(0, 136) ~ (4, 137) => 0.0125595
+(0, 136) ~ (4, 140) => 0.263672
+(0, 136) ~ (4, 141) => 0.594236
+(0, 137) ~ (4, 141) => 0.3743
+(0, 137) ~ (4, 142) => 0.212308
+(0, 138) ~ (4, 142) => 0.76754
+(0, 138) ~ (4, 143) => 0.0815242
+(0, 139) ~ (4, 143) => 0.906928
+(0, 140) ~ (4, 144) => 0.99733
+(0, 141) ~ (4, 145) => 0.998185
+(0, 142) ~ (4, 146) => 0.998506
+(0, 143) ~ (4, 147) => 0.999606
+(0, 144) ~ (4, 148) => 0.999979
+(0, 145) ~ (4, 149) => 0.999994
+(0, 146) ~ (4, 150) => 0.999983
+(0, 147) ~ (4, 151) => 0.999923
+(0, 148) ~ (4, 152) => 0.999919
+(0, 149) ~ (4, 153) => 0.999982
+(0, 150) ~ (4, 154) => 0.999991
+(0, 151) ~ (4, 155) => 0.999991
+(0, 152) ~ (4, 156) => 0.999944
+(0, 153) ~ (4, 157) => 0.99968
+(0, 154) ~ (4, 158) => 0.998694
+(0, 155) ~ (4, 159) => 0.997013
+(0, 156) ~ (4, 160) => 0.99447
+(0, 157) ~ (4, 161) => 0.990829
+(0, 158) ~ (4, 162) => 0.989638
+(0, 159) ~ (4, 163) => 0.988182
+(0, 160) ~ (4, 164) => 0.988005
+(0, 161) ~ (4, 165) => 0.988211
+(0, 162) ~ (4, 166) => 0.989651
+(0, 163) ~ (4, 167) => 0.989557
+(0, 164) ~ (4, 168) => 0.990485
+(0, 165) ~ (4, 169) => 0.993264
+(0, 166) ~ (4, 170) => 0.994604
+(0, 167) ~ (4, 171) => 0.993256
+(0, 168) ~ (4, 172) => 0.993328
+(0, 169) ~ (4, 173) => 0.993929
+(0, 170) ~ (4, 174) => 0.996268
+(0, 171) ~ (4, 175) => 0.998114
+(0, 172) ~ (4, 176) => 0.998047
+(0, 173) ~ (4, 177) => 0.997531
+(0, 174) ~ (4, 178) => 0.99809
+(0, 175) ~ (4, 179) => 0.998782
+(0, 176) ~ (4, 180) => 0.999556
+(0, 177) ~ (4, 181) => 0.999933
+(0, 178) ~ (4, 182) => 0.999976
+(0, 179) ~ (4, 183) => 0.999972
+(0, 180) ~ (4, 184) => 0.999965
+(0, 181) ~ (4, 185) => 0.999715
+(0, 182) ~ (4, 186) => 0.999505
+(0, 183) ~ (4, 187) => 0.999226
+(0, 184) ~ (4, 188) => 0.998127
+(0, 185) ~ (4, 189) => 0.995163
+(0, 186) ~ (4, 190) => 0.988568
+(0, 187) ~ (4, 191) => 0.975911
+(0, 187) ~ (4, 194) => 0.0186323
+(0, 188) ~ (4, 192) => 0.972092
+(0, 188) ~ (4, 195) => 0.0200044
+(0, 189) ~ (4, 193) => 0.969961
+(0, 189) ~ (4, 196) => 0.0210085
+(0, 190) ~ (4, 194) => 0.970959
+(0, 190) ~ (4, 197) => 0.018539
+(0, 191) ~ (4, 195) => 0.972131
+(0, 191) ~ (4, 198) => 0.01543
+(0, 192) ~ (4, 196) => 0.972235
+(0, 192) ~ (4, 199) => 0.0144208
+(0, 193) ~ (4, 197) => 0.976311
+(0, 193) ~ (4, 200) => 0.0139808
+(0, 194) ~ (4, 198) => 0.978401
+(0, 194) ~ (4, 201) => 0.0127553
+(0, 195) ~ (4, 199) => 0.978723
+(0, 196) ~ (4, 200) => 0.978795
+(0, 197) ~ (4, 201) => 0.980948
+(0, 198) ~ (4, 202) => 0.989939
+(0, 199) ~ (4, 203) => 0.992226
+(0, 200) ~ (4, 204) => 0.994785
+(0, 201) ~ (4, 205) => 0.994913
+(0, 202) ~ (4, 206) => 0.995607
+(0, 203) ~ (4, 207) => 0.993698
+(0, 204) ~ (4, 208) => 0.992856
+(0, 205) ~ (4, 209) => 0.993044
+(0, 206) ~ (4, 210) => 0.994342
+(0, 207) ~ (4, 211) => 0.985456
+(0, 208) ~ (4, 212) => 0.979197
+(0, 209) ~ (4, 212) => 0.0125869
+(0, 209) ~ (4, 213) => 0.974895
+(0, 210) ~ (4, 213) => 0.0158078
+(0, 210) ~ (4, 214) => 0.971333
+(0, 211) ~ (4, 214) => 0.0150241
+(0, 211) ~ (4, 215) => 0.970893
+(0, 212) ~ (4, 215) => 0.0126545
+(0, 212) ~ (4, 216) => 0.973379
+(0, 213) ~ (4, 217) => 0.97544
+(0, 214) ~ (4, 218) => 0.970342
+(0, 214) ~ (4, 219) => 0.015412
+(0, 215) ~ (4, 219) => 0.960623
+(0, 215) ~ (4, 220) => 0.0263461
+(0, 216) ~ (4, 220) => 0.821666
+(0, 216) ~ (4, 221) => 0.165677
+(0, 217) ~ (4, 221) => 0.277747
+(0, 217) ~ (4, 222) => 0.704585
+(0, 218) ~ (4, 222) => 0.229325
+(0, 218) ~ (4, 223) => 0.751362
+(0, 219) ~ (4, 223) => 0.166657
+(0, 219) ~ (4, 224) => 0.813925
+(0, 220) ~ (4, 224) => 0.10476
+(0, 220) ~ (4, 225) => 0.883187
+(0, 221) ~ (4, 225) => 0.0587038
+(0, 221) ~ (4, 226) => 0.934513
+(0, 222) ~ (4, 227) => 0.995447
+(0, 223) ~ (4, 228) => 0.999285
+(0, 224) ~ (4, 229) => 0.999911
+(0, 225) ~ (4, 230) => 0.999557
+(0, 226) ~ (4, 231) => 0.998202
+(0, 227) ~ (4, 232) => 0.997516
+(0, 228) ~ (4, 233) => 0.98851
+(0, 228) ~ (4, 234) => 0.0102478
+(0, 229) ~ (4, 234) => 0.98152
+(0, 229) ~ (4, 235) => 0.0167049
+(0, 230) ~ (4, 235) => 0.981232
+(0, 230) ~ (4, 236) => 0.0129216
+(0, 231) ~ (4, 236) => 0.985454
+(0, 231) ~ (4, 237) => 0.0114117
+(0, 232) ~ (4, 237) => 0.987806
+
+; gap posteriors
+(0, 0) ~ (4, -1) => 0.0160754
+(0, 1) ~ (4, -1) => 0.0250445
+(0, 2) ~ (4, -1) => 0.0294403
+(0, 3) ~ (4, -1) => 0.03305
+(0, 4) ~ (4, -1) => 0.0325083
+(0, 5) ~ (4, -1) => 0.0330957
+(0, 6) ~ (4, -1) => 0.0306173
+(0, 7) ~ (4, -1) => 0.0124388
+(0, 8) ~ (4, -1) => 0.0141609
+(0, 9) ~ (4, -1) => 0.0210556
+(0, 10) ~ (4, -1) => 0.0399323
+(0, 11) ~ (4, -1) => 0.0183816
+(0, 12) ~ (4, -1) => 0.02062
+(0, 13) ~ (4, -1) => 0.0436606
+(0, 14) ~ (4, -1) => 0.0555535
+(0, 15) ~ (4, -1) => 0.00663173
+(0, 16) ~ (4, -1) => 0.00565344
+(0, 17) ~ (4, -1) => 0.00395775
+(0, 18) ~ (4, -1) => 0.00128055
+(0, 19) ~ (4, -1) => 0.000674188
+(0, 20) ~ (4, -1) => 0.000110507
+(0, 21) ~ (4, -1) => 0.0001
+(0, 22) ~ (4, -1) => 0.0001
+(0, 23) ~ (4, -1) => 0.00136548
+(0, 24) ~ (4, -1) => 0.0064913
+(0, 25) ~ (4, -1) => 0.00352961
+(0, 26) ~ (4, -1) => 0.00491052
+(0, 27) ~ (4, -1) => 0.00747562
+(0, 28) ~ (4, -1) => 0.00921609
+(0, 29) ~ (4, -1) => 0.0157399
+(0, 30) ~ (4, -1) => 0.0158393
+(0, 31) ~ (4, -1) => 0.0164661
+(0, 32) ~ (4, -1) => 0.0143806
+(0, 33) ~ (4, -1) => 0.0141544
+(0, 34) ~ (4, -1) => 0.0264163
+(0, 35) ~ (4, -1) => 0.0206273
+(0, 36) ~ (4, -1) => 0.00794303
+(0, 37) ~ (4, -1) => 0.00776219
+(0, 38) ~ (4, -1) => 0.0063082
+(0, 39) ~ (4, -1) => 0.00302976
+(0, 40) ~ (4, -1) => 0.00193411
+(0, 41) ~ (4, -1) => 0.00140154
+(0, 42) ~ (4, -1) => 0.000486851
+(0, 43) ~ (4, -1) => 0.0011422
+(0, 44) ~ (4, -1) => 0.00117666
+(0, 45) ~ (4, -1) => 0.00113469
+(0, 46) ~ (4, -1) => 0.00104165
+(0, 47) ~ (4, -1) => 0.00095284
+(0, 48) ~ (4, -1) => 0.000806451
+(0, 49) ~ (4, -1) => 0.000363767
+(0, 50) ~ (4, -1) => 0.0001
+(0, 51) ~ (4, -1) => 0.0001
+(0, 52) ~ (4, -1) => 0.0001
+(0, 53) ~ (4, -1) => 0.0001
+(0, 54) ~ (4, -1) => 0.000353396
+(0, 55) ~ (4, -1) => 0.00688815
+(0, 56) ~ (4, -1) => 0.00268397
+(0, 57) ~ (4, -1) => 0.00365977
+(0, 58) ~ (4, -1) => 0.00578496
+(0, 59) ~ (4, -1) => 0.01842
+(0, 60) ~ (4, -1) => 0.0143628
+(0, 61) ~ (4, -1) => 0.0160607
+(0, 62) ~ (4, -1) => 0.0189435
+(0, 63) ~ (4, -1) => 0.00588328
+(0, 64) ~ (4, -1) => 0.00287867
+(0, 65) ~ (4, -1) => 0.00670028
+(0, 66) ~ (4, -1) => 0.0012604
+(0, 67) ~ (4, -1) => 0.0011977
+(0, 68) ~ (4, -1) => 0.000553012
+(0, 69) ~ (4, -1) => 0.0001
+(0, 70) ~ (4, -1) => 0.0001
+(0, 71) ~ (4, -1) => 0.0001
+(0, 72) ~ (4, -1) => 0.0001
+(0, 73) ~ (4, -1) => 0.000669003
+(0, 74) ~ (4, -1) => 0.00129616
+(0, 75) ~ (4, -1) => 0.00399309
+(0, 76) ~ (4, -1) => 0.0856501
+(0, 77) ~ (4, -1) => 0.224247
+(0, 78) ~ (4, -1) => 0.423034
+(0, 79) ~ (4, -1) => 0.547777
+(0, 80) ~ (4, -1) => 0.590863
+(0, 81) ~ (4, -1) => 0.488458
+(0, 82) ~ (4, -1) => 0.355458
+(0, 83) ~ (4, -1) => 0.236779
+(0, 84) ~ (4, -1) => 0.133265
+(0, 85) ~ (4, -1) => 0.0448415
+(0, 86) ~ (4, -1) => 0.0140181
+(0, 87) ~ (4, -1) => 0.0121716
+(0, 88) ~ (4, -1) => 0.011305
+(0, 89) ~ (4, -1) => 0.0110158
+(0, 90) ~ (4, -1) => 0.0131413
+(0, 91) ~ (4, -1) => 0.0163044
+(0, 92) ~ (4, -1) => 0.0397121
+(0, 93) ~ (4, -1) => 0.0352361
+(0, 94) ~ (4, -1) => 0.0325723
+(0, 95) ~ (4, -1) => 0.0199742
+(0, 96) ~ (4, -1) => 0.013097
+(0, 97) ~ (4, -1) => 0.0153352
+(0, 98) ~ (4, -1) => 0.0416196
+(0, 99) ~ (4, -1) => 0.0554018
+(0, 100) ~ (4, -1) => 0.0473047
+(0, 101) ~ (4, -1) => 0.0452282
+(0, 102) ~ (4, -1) => 0.0391182
+(0, 103) ~ (4, -1) => 0.0314136
+(0, 104) ~ (4, -1) => 0.00129521
+(0, 105) ~ (4, -1) => 0.000197172
+(0, 106) ~ (4, -1) => 0.0001
+(0, 107) ~ (4, -1) => 0.0001
+(0, 108) ~ (4, -1) => 0.0001
+(0, 109) ~ (4, -1) => 0.0001
+(0, 110) ~ (4, -1) => 0.0001
+(0, 111) ~ (4, -1) => 0.0001
+(0, 112) ~ (4, -1) => 0.000155985
+(0, 113) ~ (4, -1) => 0.000149667
+(0, 114) ~ (4, -1) => 0.0001
+(0, 115) ~ (4, -1) => 0.0001
+(0, 116) ~ (4, -1) => 0.0001
+(0, 117) ~ (4, -1) => 0.000293672
+(0, 118) ~ (4, -1) => 0.000352561
+(0, 119) ~ (4, -1) => 0.000213325
+(0, 120) ~ (4, -1) => 0.000407279
+(0, 121) ~ (4, -1) => 0.000633597
+(0, 122) ~ (4, -1) => 0.000595212
+(0, 123) ~ (4, -1) => 0.000975251
+(0, 124) ~ (4, -1) => 0.00229573
+(0, 125) ~ (4, -1) => 0.0227012
+(0, 126) ~ (4, -1) => 0.0243762
+(0, 127) ~ (4, -1) => 0.0324719
+(0, 128) ~ (4, -1) => 0.0406665
+(0, 129) ~ (4, -1) => 0.0499325
+(0, 130) ~ (4, -1) => 0.0594681
+(0, 131) ~ (4, -1) => 0.0613254
+(0, 132) ~ (4, -1) => 0.0917463
+(0, 133) ~ (4, -1) => 0.10232
+(0, 134) ~ (4, -1) => 0.0933086
+(0, 135) ~ (4, -1) => 0.124346
+(0, 136) ~ (4, -1) => 0.129533
+(0, 137) ~ (4, -1) => 0.413392
+(0, 138) ~ (4, -1) => 0.150936
+(0, 139) ~ (4, -1) => 0.0930717
+(0, 140) ~ (4, -1) => 0.00266963
+(0, 141) ~ (4, -1) => 0.00181472
+(0, 142) ~ (4, -1) => 0.00149387
+(0, 143) ~ (4, -1) => 0.00039351
+(0, 144) ~ (4, -1) => 0.0001
+(0, 145) ~ (4, -1) => 0.0001
+(0, 146) ~ (4, -1) => 0.0001
+(0, 147) ~ (4, -1) => 0.0001
+(0, 148) ~ (4, -1) => 0.0001
+(0, 149) ~ (4, -1) => 0.0001
+(0, 150) ~ (4, -1) => 0.0001
+(0, 151) ~ (4, -1) => 0.0001
+(0, 152) ~ (4, -1) => 0.0001
+(0, 153) ~ (4, -1) => 0.000319719
+(0, 154) ~ (4, -1) => 0.0013063
+(0, 155) ~ (4, -1) => 0.00298697
+(0, 156) ~ (4, -1) => 0.00552952
+(0, 157) ~ (4, -1) => 0.00917131
+(0, 158) ~ (4, -1) => 0.0103619
+(0, 159) ~ (4, -1) => 0.0118175
+(0, 160) ~ (4, -1) => 0.0119948
+(0, 161) ~ (4, -1) => 0.0117887
+(0, 162) ~ (4, -1) => 0.0103491
+(0, 163) ~ (4, -1) => 0.0104428
+(0, 164) ~ (4, -1) => 0.00951463
+(0, 165) ~ (4, -1) => 0.00673634
+(0, 166) ~ (4, -1) => 0.00539619
+(0, 167) ~ (4, -1) => 0.00674355
+(0, 168) ~ (4, -1) => 0.00667179
+(0, 169) ~ (4, -1) => 0.00607073
+(0, 170) ~ (4, -1) => 0.00373232
+(0, 171) ~ (4, -1) => 0.00188553
+(0, 172) ~ (4, -1) => 0.00195307
+(0, 173) ~ (4, -1) => 0.002469
+(0, 174) ~ (4, -1) => 0.00190991
+(0, 175) ~ (4, -1) => 0.00121814
+(0, 176) ~ (4, -1) => 0.000444174
+(0, 177) ~ (4, -1) => 0.0001
+(0, 178) ~ (4, -1) => 0.0001
+(0, 179) ~ (4, -1) => 0.0001
+(0, 180) ~ (4, -1) => 0.0001
+(0, 181) ~ (4, -1) => 0.000285149
+(0, 182) ~ (4, -1) => 0.000494838
+(0, 183) ~ (4, -1) => 0.000773668
+(0, 184) ~ (4, -1) => 0.00187337
+(0, 185) ~ (4, -1) => 0.00483721
+(0, 186) ~ (4, -1) => 0.0114324
+(0, 187) ~ (4, -1) => 0.00545685
+(0, 188) ~ (4, -1) => 0.00790314
+(0, 189) ~ (4, -1) => 0.00903091
+(0, 190) ~ (4, -1) => 0.0105018
+(0, 191) ~ (4, -1) => 0.0124387
+(0, 192) ~ (4, -1) => 0.0133445
+(0, 193) ~ (4, -1) => 0.00970776
+(0, 194) ~ (4, -1) => 0.008844
+(0, 195) ~ (4, -1) => 0.0212765
+(0, 196) ~ (4, -1) => 0.021205
+(0, 197) ~ (4, -1) => 0.019052
+(0, 198) ~ (4, -1) => 0.0100607
+(0, 199) ~ (4, -1) => 0.00777411
+(0, 200) ~ (4, -1) => 0.00521457
+(0, 201) ~ (4, -1) => 0.00508708
+(0, 202) ~ (4, -1) => 0.00439292
+(0, 203) ~ (4, -1) => 0.00630236
+(0, 204) ~ (4, -1) => 0.00714415
+(0, 205) ~ (4, -1) => 0.0069564
+(0, 206) ~ (4, -1) => 0.00565755
+(0, 207) ~ (4, -1) => 0.0145437
+(0, 208) ~ (4, -1) => 0.0208026
+(0, 209) ~ (4, -1) => 0.0125183
+(0, 210) ~ (4, -1) => 0.0128592
+(0, 211) ~ (4, -1) => 0.0140827
+(0, 212) ~ (4, -1) => 0.0139662
+(0, 213) ~ (4, -1) => 0.0245598
+(0, 214) ~ (4, -1) => 0.0142461
+(0, 215) ~ (4, -1) => 0.0130305
+(0, 216) ~ (4, -1) => 0.0126568
+(0, 217) ~ (4, -1) => 0.0176681
+(0, 218) ~ (4, -1) => 0.0193133
+(0, 219) ~ (4, -1) => 0.0194183
+(0, 220) ~ (4, -1) => 0.012053
+(0, 221) ~ (4, -1) => 0.00678289
+(0, 222) ~ (4, -1) => 0.00455266
+(0, 223) ~ (4, -1) => 0.000714719
+(0, 224) ~ (4, -1) => 0.0001
+(0, 225) ~ (4, -1) => 0.000442564
+(0, 226) ~ (4, -1) => 0.00179833
+(0, 227) ~ (4, -1) => 0.00248355
+(0, 228) ~ (4, -1) => 0.0012424
+(0, 229) ~ (4, -1) => 0.00177518
+(0, 230) ~ (4, -1) => 0.00584641
+(0, 231) ~ (4, -1) => 0.00313416
+(0, 232) ~ (4, -1) => 0.0121936
+
+(0, -1) ~ (4, 0) => 0.645293
+(0, -1) ~ (4, 1) => 0.11397
+(0, -1) ~ (4, 2) => 0.117884
+(0, -1) ~ (4, 3) => 0.0489734
+(0, -1) ~ (4, 4) => 0.0317273
+(0, -1) ~ (4, 5) => 0.0314825
+(0, -1) ~ (4, 6) => 0.0731058
+(0, -1) ~ (4, 7) => 0.106036
+(0, -1) ~ (4, 8) => 0.115923
+(0, -1) ~ (4, 9) => 0.104659
+(0, -1) ~ (4, 10) => 0.0904308
+(0, -1) ~ (4, 11) => 0.0896218
+(0, -1) ~ (4, 12) => 0.094453
+(0, -1) ~ (4, 13) => 0.273092
+(0, -1) ~ (4, 14) => 0.206417
+(0, -1) ~ (4, 15) => 0.129719
+(0, -1) ~ (4, 16) => 0.139176
+(0, -1) ~ (4, 17) => 0.0203016
+(0, -1) ~ (4, 18) => 0.00565344
+(0, -1) ~ (4, 19) => 0.00395775
+(0, -1) ~ (4, 20) => 0.00128055
+(0, -1) ~ (4, 21) => 0.000674188
+(0, -1) ~ (4, 22) => 0.000110507
+(0, -1) ~ (4, 23) => 0.0001
+(0, -1) ~ (4, 24) => 0.0001
+(0, -1) ~ (4, 25) => 0.00136548
+(0, -1) ~ (4, 26) => 0.0064913
+(0, -1) ~ (4, 27) => 0.0192945
+(0, -1) ~ (4, 28) => 0.0129734
+(0, -1) ~ (4, 29) => 0.0341461
+(0, -1) ~ (4, 30) => 0.0182726
+(0, -1) ~ (4, 31) => 0.0100034
+(0, -1) ~ (4, 32) => 0.00936776
+(0, -1) ~ (4, 33) => 0.00989491
+(0, -1) ~ (4, 34) => 0.0102901
+(0, -1) ~ (4, 35) => 0.0113889
+(0, -1) ~ (4, 36) => 0.00855112
+(0, -1) ~ (4, 37) => 0.00457281
+(0, -1) ~ (4, 38) => 0.00794303
+(0, -1) ~ (4, 39) => 0.00776219
+(0, -1) ~ (4, 40) => 0.0063082
+(0, -1) ~ (4, 41) => 0.00302976
+(0, -1) ~ (4, 42) => 0.00193411
+(0, -1) ~ (4, 43) => 0.00140154
+(0, -1) ~ (4, 44) => 0.000486851
+(0, -1) ~ (4, 45) => 0.0011422
+(0, -1) ~ (4, 46) => 0.00117666
+(0, -1) ~ (4, 47) => 0.00113469
+(0, -1) ~ (4, 48) => 0.00104165
+(0, -1) ~ (4, 49) => 0.00095284
+(0, -1) ~ (4, 50) => 0.000806451
+(0, -1) ~ (4, 51) => 0.000363767
+(0, -1) ~ (4, 52) => 0.0001
+(0, -1) ~ (4, 53) => 0.0001
+(0, -1) ~ (4, 54) => 0.0001
+(0, -1) ~ (4, 55) => 0.0001
+(0, -1) ~ (4, 56) => 0.000353396
+(0, -1) ~ (4, 57) => 0.00688815
+(0, -1) ~ (4, 58) => 0.0140308
+(0, -1) ~ (4, 59) => 0.0475833
+(0, -1) ~ (4, 60) => 0.0105454
+(0, -1) ~ (4, 61) => 0.0447659
+(0, -1) ~ (4, 62) => 0.045572
+(0, -1) ~ (4, 63) => 0.2374
+(0, -1) ~ (4, 64) => 0.301012
+(0, -1) ~ (4, 65) => 0.13422
+(0, -1) ~ (4, 66) => 0.146606
+(0, -1) ~ (4, 67) => 0.106942
+(0, -1) ~ (4, 68) => 0.00670028
+(0, -1) ~ (4, 69) => 0.0012604
+(0, -1) ~ (4, 70) => 0.0011977
+(0, -1) ~ (4, 71) => 0.000553012
+(0, -1) ~ (4, 72) => 0.0001
+(0, -1) ~ (4, 73) => 0.0001
+(0, -1) ~ (4, 74) => 0.0001
+(0, -1) ~ (4, 75) => 0.0001
+(0, -1) ~ (4, 76) => 0.000669003
+(0, -1) ~ (4, 77) => 0.00129616
+(0, -1) ~ (4, 78) => 0.00399309
+(0, -1) ~ (4, 79) => 0.0219549
+(0, -1) ~ (4, 80) => 0.0105922
+(0, -1) ~ (4, 81) => 0.0117723
+(0, -1) ~ (4, 82) => 0.0212967
+(0, -1) ~ (4, 83) => 0.0289944
+(0, -1) ~ (4, 84) => 0.0233412
+(0, -1) ~ (4, 85) => 0.0124202
+(0, -1) ~ (4, 86) => 0.0140181
+(0, -1) ~ (4, 87) => 0.0121716
+(0, -1) ~ (4, 88) => 0.011305
+(0, -1) ~ (4, 89) => 0.0110158
+(0, -1) ~ (4, 90) => 0.0131413
+(0, -1) ~ (4, 91) => 0.0163044
+(0, -1) ~ (4, 92) => 0.0691826
+(0, -1) ~ (4, 93) => 0.134023
+(0, -1) ~ (4, 94) => 0.169929
+(0, -1) ~ (4, 95) => 0.328359
+(0, -1) ~ (4, 96) => 0.311586
+(0, -1) ~ (4, 97) => 0.272593
+(0, -1) ~ (4, 98) => 0.360006
+(0, -1) ~ (4, 99) => 0.517203
+(0, -1) ~ (4, 100) => 0.507521
+(0, -1) ~ (4, 101) => 0.62158
+(0, -1) ~ (4, 102) => 0.634773
+(0, -1) ~ (4, 103) => 0.586997
+(0, -1) ~ (4, 104) => 0.409765
+(0, -1) ~ (4, 105) => 0.307269
+(0, -1) ~ (4, 106) => 0.134563
+(0, -1) ~ (4, 107) => 0.0398096
+(0, -1) ~ (4, 108) => 0.0108522
+(0, -1) ~ (4, 109) => 0.00129521
+(0, -1) ~ (4, 110) => 0.000197172
+(0, -1) ~ (4, 111) => 0.0001
+(0, -1) ~ (4, 112) => 0.0001
+(0, -1) ~ (4, 113) => 0.0001
+(0, -1) ~ (4, 114) => 0.0001
+(0, -1) ~ (4, 115) => 0.0001
+(0, -1) ~ (4, 116) => 0.0001
+(0, -1) ~ (4, 117) => 0.000155985
+(0, -1) ~ (4, 118) => 0.000149667
+(0, -1) ~ (4, 119) => 0.0001
+(0, -1) ~ (4, 120) => 0.0001
+(0, -1) ~ (4, 121) => 0.0001
+(0, -1) ~ (4, 122) => 0.000293672
+(0, -1) ~ (4, 123) => 0.000352561
+(0, -1) ~ (4, 124) => 0.000213325
+(0, -1) ~ (4, 125) => 0.000407279
+(0, -1) ~ (4, 126) => 0.000633597
+(0, -1) ~ (4, 127) => 0.000595212
+(0, -1) ~ (4, 128) => 0.000975251
+(0, -1) ~ (4, 129) => 0.00229573
+(0, -1) ~ (4, 130) => 0.0227012
+(0, -1) ~ (4, 131) => 0.0255798
+(0, -1) ~ (4, 132) => 0.0494619
+(0, -1) ~ (4, 133) => 0.039988
+(0, -1) ~ (4, 134) => 0.0293914
+(0, -1) ~ (4, 135) => 0.0451066
+(0, -1) ~ (4, 136) => 0.0346686
+(0, -1) ~ (4, 137) => 0.049529
+(0, -1) ~ (4, 138) => 0.0559277
+(0, -1) ~ (4, 139) => 0.0584328
+(0, -1) ~ (4, 140) => 0.0404646
+(0, -1) ~ (4, 141) => 0.0175101
+(0, -1) ~ (4, 142) => 0.00928527
+(0, -1) ~ (4, 143) => 0.0115475
+(0, -1) ~ (4, 144) => 0.00266963
+(0, -1) ~ (4, 145) => 0.00181472
+(0, -1) ~ (4, 146) => 0.00149387
+(0, -1) ~ (4, 147) => 0.00039351
+(0, -1) ~ (4, 148) => 0.0001
+(0, -1) ~ (4, 149) => 0.0001
+(0, -1) ~ (4, 150) => 0.0001
+(0, -1) ~ (4, 151) => 0.0001
+(0, -1) ~ (4, 152) => 0.0001
+(0, -1) ~ (4, 153) => 0.0001
+(0, -1) ~ (4, 154) => 0.0001
+(0, -1) ~ (4, 155) => 0.0001
+(0, -1) ~ (4, 156) => 0.0001
+(0, -1) ~ (4, 157) => 0.000319719
+(0, -1) ~ (4, 158) => 0.0013063
+(0, -1) ~ (4, 159) => 0.00298697
+(0, -1) ~ (4, 160) => 0.00552952
+(0, -1) ~ (4, 161) => 0.00917131
+(0, -1) ~ (4, 162) => 0.0103619
+(0, -1) ~ (4, 163) => 0.0118175
+(0, -1) ~ (4, 164) => 0.0119948
+(0, -1) ~ (4, 165) => 0.0117887
+(0, -1) ~ (4, 166) => 0.0103491
+(0, -1) ~ (4, 167) => 0.0104428
+(0, -1) ~ (4, 168) => 0.00951463
+(0, -1) ~ (4, 169) => 0.00673634
+(0, -1) ~ (4, 170) => 0.00539619
+(0, -1) ~ (4, 171) => 0.00674355
+(0, -1) ~ (4, 172) => 0.00667179
+(0, -1) ~ (4, 173) => 0.00607073
+(0, -1) ~ (4, 174) => 0.00373232
+(0, -1) ~ (4, 175) => 0.00188553
+(0, -1) ~ (4, 176) => 0.00195307
+(0, -1) ~ (4, 177) => 0.002469
+(0, -1) ~ (4, 178) => 0.00190991
+(0, -1) ~ (4, 179) => 0.00121814
+(0, -1) ~ (4, 180) => 0.000444174
+(0, -1) ~ (4, 181) => 0.0001
+(0, -1) ~ (4, 182) => 0.0001
+(0, -1) ~ (4, 183) => 0.0001
+(0, -1) ~ (4, 184) => 0.0001
+(0, -1) ~ (4, 185) => 0.000285149
+(0, -1) ~ (4, 186) => 0.000494838
+(0, -1) ~ (4, 187) => 0.000773668
+(0, -1) ~ (4, 188) => 0.00187337
+(0, -1) ~ (4, 189) => 0.00483721
+(0, -1) ~ (4, 190) => 0.0114324
+(0, -1) ~ (4, 191) => 0.0240892
+(0, -1) ~ (4, 192) => 0.0279076
+(0, -1) ~ (4, 193) => 0.0300394
+(0, -1) ~ (4, 194) => 0.0104085
+(0, -1) ~ (4, 195) => 0.00786436
+(0, -1) ~ (4, 196) => 0.00675684
+(0, -1) ~ (4, 197) => 0.00514954
+(0, -1) ~ (4, 198) => 0.00616926
+(0, -1) ~ (4, 199) => 0.00685573
+(0, -1) ~ (4, 200) => 0.0072242
+(0, -1) ~ (4, 201) => 0.00629675
+(0, -1) ~ (4, 202) => 0.0100607
+(0, -1) ~ (4, 203) => 0.00777411
+(0, -1) ~ (4, 204) => 0.00521457
+(0, -1) ~ (4, 205) => 0.00508708
+(0, -1) ~ (4, 206) => 0.00439292
+(0, -1) ~ (4, 207) => 0.00630236
+(0, -1) ~ (4, 208) => 0.00714415
+(0, -1) ~ (4, 209) => 0.0069564
+(0, -1) ~ (4, 210) => 0.00565755
+(0, -1) ~ (4, 211) => 0.0145437
+(0, -1) ~ (4, 212) => 0.00821571
+(0, -1) ~ (4, 213) => 0.00929741
+(0, -1) ~ (4, 214) => 0.0136429
+(0, -1) ~ (4, 215) => 0.0164522
+(0, -1) ~ (4, 216) => 0.0266207
+(0, -1) ~ (4, 217) => 0.0245598
+(0, -1) ~ (4, 218) => 0.0296581
+(0, -1) ~ (4, 219) => 0.0239646
+(0, -1) ~ (4, 220) => 0.151988
+(0, -1) ~ (4, 221) => 0.556576
+(0, -1) ~ (4, 222) => 0.0660902
+(0, -1) ~ (4, 223) => 0.0819809
+(0, -1) ~ (4, 224) => 0.0813152
+(0, -1) ~ (4, 225) => 0.0581095
+(0, -1) ~ (4, 226) => 0.0654867
+(0, -1) ~ (4, 227) => 0.00455266
+(0, -1) ~ (4, 228) => 0.000714719
+(0, -1) ~ (4, 229) => 0.0001
+(0, -1) ~ (4, 230) => 0.000442564
+(0, -1) ~ (4, 231) => 0.00179833
+(0, -1) ~ (4, 232) => 0.00248355
+(0, -1) ~ (4, 233) => 0.0114902
+(0, -1) ~ (4, 234) => 0.00823236
+(0, -1) ~ (4, 235) => 0.0020631
+(0, -1) ~ (4, 236) => 0.00162429
+(0, -1) ~ (4, 237) => 0.000781894
+
+; Sparse posterior probability matrix for sequences 0 and 5
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (5, 0) => 0.99998
+(0, 1) ~ (5, 1) => 0.99997
+(0, 2) ~ (5, 2) => 0.999967
+(0, 3) ~ (5, 3) => 0.99997
+(0, 4) ~ (5, 4) => 0.999972
+(0, 5) ~ (5, 5) => 0.99998
+(0, 6) ~ (5, 6) => 0.999984
+(0, 7) ~ (5, 7) => 0.999995
+(0, 8) ~ (5, 8) => 0.999993
+(0, 9) ~ (5, 9) => 0.999963
+(0, 10) ~ (5, 10) => 0.999885
+(0, 11) ~ (5, 11) => 0.992982
+(0, 12) ~ (5, 12) => 0.956823
+(0, 12) ~ (5, 13) => 0.042909
+(0, 13) ~ (5, 13) => 0.92784
+(0, 13) ~ (5, 14) => 0.0718188
+(0, 14) ~ (5, 14) => 0.536412
+(0, 14) ~ (5, 15) => 0.46326
+(0, 15) ~ (5, 15) => 0.0416179
+(0, 15) ~ (5, 16) => 0.958288
+(0, 16) ~ (5, 17) => 0.995469
+(0, 17) ~ (5, 18) => 0.999854
+(0, 18) ~ (5, 19) => 0.999974
+(0, 19) ~ (5, 20) => 1
+(0, 20) ~ (5, 21) => 1
+(0, 21) ~ (5, 22) => 1
+(0, 22) ~ (5, 23) => 1
+(0, 23) ~ (5, 24) => 0.999999
+(0, 24) ~ (5, 25) => 0.999995
+(0, 25) ~ (5, 26) => 0.999993
+(0, 26) ~ (5, 27) => 0.999993
+(0, 27) ~ (5, 28) => 0.999998
+(0, 28) ~ (5, 29) => 0.999998
+(0, 29) ~ (5, 30) => 0.999995
+(0, 30) ~ (5, 31) => 0.999993
+(0, 31) ~ (5, 32) => 0.999992
+(0, 32) ~ (5, 33) => 0.999994
+(0, 33) ~ (5, 34) => 0.999997
+(0, 34) ~ (5, 35) => 0.999999
+(0, 35) ~ (5, 36) => 0.999999
+(0, 36) ~ (5, 37) => 0.999996
+(0, 37) ~ (5, 38) => 0.999994
+(0, 38) ~ (5, 39) => 0.999994
+(0, 39) ~ (5, 40) => 0.999996
+(0, 40) ~ (5, 41) => 0.999996
+(0, 41) ~ (5, 42) => 0.999996
+(0, 42) ~ (5, 43) => 1
+(0, 43) ~ (5, 44) => 1
+(0, 44) ~ (5, 45) => 0.999997
+(0, 45) ~ (5, 46) => 0.999978
+(0, 46) ~ (5, 47) => 0.999975
+(0, 47) ~ (5, 48) => 0.999979
+(0, 48) ~ (5, 49) => 0.999976
+(0, 49) ~ (5, 50) => 0.999991
+(0, 50) ~ (5, 51) => 0.999994
+(0, 51) ~ (5, 52) => 1
+(0, 52) ~ (5, 53) => 1
+(0, 53) ~ (5, 54) => 1
+(0, 54) ~ (5, 55) => 1
+(0, 55) ~ (5, 56) => 1
+(0, 56) ~ (5, 57) => 1
+(0, 57) ~ (5, 58) => 1
+(0, 58) ~ (5, 59) => 0.999999
+(0, 59) ~ (5, 60) => 0.999998
+(0, 60) ~ (5, 61) => 0.999997
+(0, 61) ~ (5, 62) => 0.999997
+(0, 62) ~ (5, 63) => 0.999999
+(0, 63) ~ (5, 64) => 1
+(0, 64) ~ (5, 65) => 1
+(0, 65) ~ (5, 66) => 1
+(0, 66) ~ (5, 67) => 1
+(0, 67) ~ (5, 68) => 1
+(0, 68) ~ (5, 69) => 1
+(0, 69) ~ (5, 70) => 1
+(0, 70) ~ (5, 71) => 1
+(0, 71) ~ (5, 72) => 1
+(0, 72) ~ (5, 73) => 1
+(0, 73) ~ (5, 74) => 1
+(0, 74) ~ (5, 75) => 1
+(0, 75) ~ (5, 76) => 1
+(0, 76) ~ (5, 77) => 0.999999
+(0, 77) ~ (5, 78) => 0.999997
+(0, 78) ~ (5, 79) => 0.999995
+(0, 79) ~ (5, 80) => 0.999994
+(0, 80) ~ (5, 81) => 0.999992
+(0, 81) ~ (5, 82) => 0.999995
+(0, 82) ~ (5, 83) => 0.999999
+(0, 83) ~ (5, 84) => 0.999999
+(0, 84) ~ (5, 85) => 0.999999
+(0, 85) ~ (5, 86) => 0.999998
+(0, 86) ~ (5, 87) => 0.999993
+(0, 87) ~ (5, 88) => 0.99999
+(0, 88) ~ (5, 89) => 0.999929
+(0, 89) ~ (5, 90) => 0.99991
+(0, 90) ~ (5, 91) => 0.999857
+(0, 91) ~ (5, 92) => 0.999844
+(0, 92) ~ (5, 93) => 0.999851
+(0, 93) ~ (5, 94) => 0.999971
+(0, 94) ~ (5, 95) => 0.999994
+(0, 95) ~ (5, 96) => 0.999999
+(0, 96) ~ (5, 97) => 1
+(0, 97) ~ (5, 98) => 0.999999
+(0, 98) ~ (5, 99) => 0.999991
+(0, 99) ~ (5, 100) => 0.999944
+(0, 100) ~ (5, 101) => 0.999938
+(0, 101) ~ (5, 102) => 0.999957
+(0, 102) ~ (5, 103) => 0.999976
+(0, 103) ~ (5, 104) => 0.999988
+(0, 104) ~ (5, 105) => 1
+(0, 105) ~ (5, 106) => 1
+(0, 106) ~ (5, 107) => 1
+(0, 107) ~ (5, 108) => 1
+(0, 108) ~ (5, 109) => 1
+(0, 109) ~ (5, 110) => 1
+(0, 110) ~ (5, 111) => 1
+(0, 111) ~ (5, 112) => 1
+(0, 112) ~ (5, 113) => 1
+(0, 113) ~ (5, 114) => 1
+(0, 114) ~ (5, 115) => 0.999999
+(0, 115) ~ (5, 116) => 0.999988
+(0, 116) ~ (5, 117) => 0.999983
+(0, 117) ~ (5, 118) => 0.999982
+(0, 118) ~ (5, 119) => 0.999984
+(0, 119) ~ (5, 120) => 0.99998
+(0, 120) ~ (5, 121) => 0.999979
+(0, 121) ~ (5, 122) => 0.999982
+(0, 122) ~ (5, 123) => 0.999999
+(0, 123) ~ (5, 124) => 1
+(0, 124) ~ (5, 125) => 1
+(0, 125) ~ (5, 126) => 1
+(0, 126) ~ (5, 127) => 1
+(0, 127) ~ (5, 128) => 1
+(0, 128) ~ (5, 129) => 1
+(0, 129) ~ (5, 130) => 0.999999
+(0, 130) ~ (5, 131) => 0.999999
+(0, 131) ~ (5, 132) => 0.999997
+(0, 132) ~ (5, 133) => 0.999998
+(0, 133) ~ (5, 134) => 0.999998
+(0, 134) ~ (5, 135) => 1
+(0, 135) ~ (5, 136) => 0.999999
+(0, 136) ~ (5, 137) => 0.999999
+(0, 137) ~ (5, 138) => 1
+(0, 138) ~ (5, 139) => 1
+(0, 139) ~ (5, 140) => 1
+(0, 140) ~ (5, 141) => 1
+(0, 141) ~ (5, 142) => 1
+(0, 142) ~ (5, 143) => 1
+(0, 143) ~ (5, 144) => 1
+(0, 144) ~ (5, 145) => 1
+(0, 145) ~ (5, 146) => 1
+(0, 146) ~ (5, 147) => 1
+(0, 147) ~ (5, 148) => 1
+(0, 148) ~ (5, 149) => 0.999999
+(0, 149) ~ (5, 150) => 0.999999
+(0, 150) ~ (5, 151) => 1
+(0, 151) ~ (5, 152) => 1
+(0, 152) ~ (5, 153) => 1
+(0, 153) ~ (5, 154) => 1
+(0, 154) ~ (5, 155) => 1
+(0, 155) ~ (5, 156) => 0.999997
+(0, 156) ~ (5, 157) => 0.999985
+(0, 157) ~ (5, 158) => 0.999981
+(0, 158) ~ (5, 159) => 0.999983
+(0, 159) ~ (5, 160) => 0.999982
+(0, 160) ~ (5, 161) => 0.999983
+(0, 161) ~ (5, 162) => 0.999985
+(0, 162) ~ (5, 163) => 0.999989
+(0, 163) ~ (5, 164) => 0.999989
+(0, 164) ~ (5, 165) => 0.999986
+(0, 165) ~ (5, 166) => 0.999986
+(0, 166) ~ (5, 167) => 0.999986
+(0, 167) ~ (5, 168) => 0.999965
+(0, 168) ~ (5, 169) => 0.999959
+(0, 169) ~ (5, 170) => 0.99996
+(0, 170) ~ (5, 171) => 0.999968
+(0, 171) ~ (5, 172) => 0.999976
+(0, 172) ~ (5, 173) => 0.999985
+(0, 173) ~ (5, 174) => 0.999988
+(0, 174) ~ (5, 175) => 0.99999
+(0, 175) ~ (5, 176) => 0.999996
+(0, 176) ~ (5, 177) => 1
+(0, 177) ~ (5, 178) => 1
+(0, 178) ~ (5, 179) => 1
+(0, 179) ~ (5, 180) => 1
+(0, 180) ~ (5, 181) => 1
+(0, 181) ~ (5, 182) => 0.999992
+(0, 182) ~ (5, 183) => 0.999986
+(0, 183) ~ (5, 184) => 0.999966
+(0, 184) ~ (5, 185) => 0.99989
+(0, 185) ~ (5, 186) => 0.999658
+(0, 186) ~ (5, 187) => 0.999182
+(0, 187) ~ (5, 188) => 0.998765
+(0, 188) ~ (5, 189) => 0.998509
+(0, 189) ~ (5, 190) => 0.998451
+(0, 190) ~ (5, 191) => 0.998407
+(0, 191) ~ (5, 192) => 0.998461
+(0, 192) ~ (5, 193) => 0.998468
+(0, 193) ~ (5, 194) => 0.998691
+(0, 194) ~ (5, 195) => 0.99909
+(0, 195) ~ (5, 196) => 0.999236
+(0, 196) ~ (5, 197) => 0.99956
+(0, 197) ~ (5, 198) => 0.999645
+(0, 198) ~ (5, 199) => 0.999706
+(0, 199) ~ (5, 200) => 0.999724
+(0, 200) ~ (5, 201) => 0.999772
+(0, 201) ~ (5, 202) => 0.999817
+(0, 202) ~ (5, 203) => 0.999875
+(0, 203) ~ (5, 204) => 0.999887
+(0, 204) ~ (5, 205) => 0.999913
+(0, 205) ~ (5, 206) => 0.999982
+(0, 206) ~ (5, 207) => 0.999997
+(0, 207) ~ (5, 208) => 0.999998
+(0, 208) ~ (5, 209) => 0.999999
+(0, 209) ~ (5, 210) => 0.999999
+(0, 210) ~ (5, 211) => 1
+(0, 211) ~ (5, 212) => 1
+(0, 212) ~ (5, 213) => 1
+(0, 213) ~ (5, 214) => 1
+(0, 214) ~ (5, 215) => 0.999999
+(0, 215) ~ (5, 216) => 0.999992
+(0, 216) ~ (5, 217) => 0.999918
+(0, 217) ~ (5, 218) => 0.999897
+(0, 218) ~ (5, 219) => 0.999875
+(0, 219) ~ (5, 220) => 0.999875
+(0, 220) ~ (5, 221) => 0.999937
+(0, 221) ~ (5, 222) => 0.99996
+(0, 222) ~ (5, 223) => 0.999996
+(0, 223) ~ (5, 224) => 1
+(0, 224) ~ (5, 225) => 1
+(0, 225) ~ (5, 226) => 1
+(0, 226) ~ (5, 227) => 0.999998
+(0, 227) ~ (5, 228) => 0.999994
+(0, 228) ~ (5, 229) => 0.999937
+(0, 229) ~ (5, 230) => 0.99993
+(0, 230) ~ (5, 231) => 0.999934
+(0, 231) ~ (5, 232) => 0.999949
+(0, 232) ~ (5, 233) => 0.999979
+
+; gap posteriors
+(0, 0) ~ (5, -1) => 0.0001
+(0, 1) ~ (5, -1) => 0.0001
+(0, 2) ~ (5, -1) => 0.0001
+(0, 3) ~ (5, -1) => 0.0001
+(0, 4) ~ (5, -1) => 0.0001
+(0, 5) ~ (5, -1) => 0.0001
+(0, 6) ~ (5, -1) => 0.0001
+(0, 7) ~ (5, -1) => 0.0001
+(0, 8) ~ (5, -1) => 0.0001
+(0, 9) ~ (5, -1) => 0.0001
+(0, 10) ~ (5, -1) => 0.000115097
+(0, 11) ~ (5, -1) => 0.00701809
+(0, 12) ~ (5, -1) => 0.000268403
+(0, 13) ~ (5, -1) => 0.00034149
+(0, 14) ~ (5, -1) => 0.000327647
+(0, 15) ~ (5, -1) => 0.0001
+(0, 16) ~ (5, -1) => 0.00453055
+(0, 17) ~ (5, -1) => 0.000145555
+(0, 18) ~ (5, -1) => 0.0001
+(0, 19) ~ (5, -1) => 0.0001
+(0, 20) ~ (5, -1) => 0.0001
+(0, 21) ~ (5, -1) => 0.0001
+(0, 22) ~ (5, -1) => 0.0001
+(0, 23) ~ (5, -1) => 0.0001
+(0, 24) ~ (5, -1) => 0.0001
+(0, 25) ~ (5, -1) => 0.0001
+(0, 26) ~ (5, -1) => 0.0001
+(0, 27) ~ (5, -1) => 0.0001
+(0, 28) ~ (5, -1) => 0.0001
+(0, 29) ~ (5, -1) => 0.0001
+(0, 30) ~ (5, -1) => 0.0001
+(0, 31) ~ (5, -1) => 0.0001
+(0, 32) ~ (5, -1) => 0.0001
+(0, 33) ~ (5, -1) => 0.0001
+(0, 34) ~ (5, -1) => 0.0001
+(0, 35) ~ (5, -1) => 0.0001
+(0, 36) ~ (5, -1) => 0.0001
+(0, 37) ~ (5, -1) => 0.0001
+(0, 38) ~ (5, -1) => 0.0001
+(0, 39) ~ (5, -1) => 0.0001
+(0, 40) ~ (5, -1) => 0.0001
+(0, 41) ~ (5, -1) => 0.0001
+(0, 42) ~ (5, -1) => 0.0001
+(0, 43) ~ (5, -1) => 0.0001
+(0, 44) ~ (5, -1) => 0.0001
+(0, 45) ~ (5, -1) => 0.0001
+(0, 46) ~ (5, -1) => 0.0001
+(0, 47) ~ (5, -1) => 0.0001
+(0, 48) ~ (5, -1) => 0.0001
+(0, 49) ~ (5, -1) => 0.0001
+(0, 50) ~ (5, -1) => 0.0001
+(0, 51) ~ (5, -1) => 0.0001
+(0, 52) ~ (5, -1) => 0.0001
+(0, 53) ~ (5, -1) => 0.0001
+(0, 54) ~ (5, -1) => 0.0001
+(0, 55) ~ (5, -1) => 0.0001
+(0, 56) ~ (5, -1) => 0.0001
+(0, 57) ~ (5, -1) => 0.0001
+(0, 58) ~ (5, -1) => 0.0001
+(0, 59) ~ (5, -1) => 0.0001
+(0, 60) ~ (5, -1) => 0.0001
+(0, 61) ~ (5, -1) => 0.0001
+(0, 62) ~ (5, -1) => 0.0001
+(0, 63) ~ (5, -1) => 0.0001
+(0, 64) ~ (5, -1) => 0.0001
+(0, 65) ~ (5, -1) => 0.0001
+(0, 66) ~ (5, -1) => 0.0001
+(0, 67) ~ (5, -1) => 0.0001
+(0, 68) ~ (5, -1) => 0.0001
+(0, 69) ~ (5, -1) => 0.0001
+(0, 70) ~ (5, -1) => 0.0001
+(0, 71) ~ (5, -1) => 0.0001
+(0, 72) ~ (5, -1) => 0.0001
+(0, 73) ~ (5, -1) => 0.0001
+(0, 74) ~ (5, -1) => 0.0001
+(0, 75) ~ (5, -1) => 0.0001
+(0, 76) ~ (5, -1) => 0.0001
+(0, 77) ~ (5, -1) => 0.0001
+(0, 78) ~ (5, -1) => 0.0001
+(0, 79) ~ (5, -1) => 0.0001
+(0, 80) ~ (5, -1) => 0.0001
+(0, 81) ~ (5, -1) => 0.0001
+(0, 82) ~ (5, -1) => 0.0001
+(0, 83) ~ (5, -1) => 0.0001
+(0, 84) ~ (5, -1) => 0.0001
+(0, 85) ~ (5, -1) => 0.0001
+(0, 86) ~ (5, -1) => 0.0001
+(0, 87) ~ (5, -1) => 0.0001
+(0, 88) ~ (5, -1) => 0.0001
+(0, 89) ~ (5, -1) => 0.0001
+(0, 90) ~ (5, -1) => 0.000143111
+(0, 91) ~ (5, -1) => 0.000156403
+(0, 92) ~ (5, -1) => 0.00014931
+(0, 93) ~ (5, -1) => 0.0001
+(0, 94) ~ (5, -1) => 0.0001
+(0, 95) ~ (5, -1) => 0.0001
+(0, 96) ~ (5, -1) => 0.0001
+(0, 97) ~ (5, -1) => 0.0001
+(0, 98) ~ (5, -1) => 0.0001
+(0, 99) ~ (5, -1) => 0.0001
+(0, 100) ~ (5, -1) => 0.0001
+(0, 101) ~ (5, -1) => 0.0001
+(0, 102) ~ (5, -1) => 0.0001
+(0, 103) ~ (5, -1) => 0.0001
+(0, 104) ~ (5, -1) => 0.0001
+(0, 105) ~ (5, -1) => 0.0001
+(0, 106) ~ (5, -1) => 0.0001
+(0, 107) ~ (5, -1) => 0.0001
+(0, 108) ~ (5, -1) => 0.0001
+(0, 109) ~ (5, -1) => 0.0001
+(0, 110) ~ (5, -1) => 0.0001
+(0, 111) ~ (5, -1) => 0.0001
+(0, 112) ~ (5, -1) => 0.0001
+(0, 113) ~ (5, -1) => 0.0001
+(0, 114) ~ (5, -1) => 0.0001
+(0, 115) ~ (5, -1) => 0.0001
+(0, 116) ~ (5, -1) => 0.0001
+(0, 117) ~ (5, -1) => 0.0001
+(0, 118) ~ (5, -1) => 0.0001
+(0, 119) ~ (5, -1) => 0.0001
+(0, 120) ~ (5, -1) => 0.0001
+(0, 121) ~ (5, -1) => 0.0001
+(0, 122) ~ (5, -1) => 0.0001
+(0, 123) ~ (5, -1) => 0.0001
+(0, 124) ~ (5, -1) => 0.0001
+(0, 125) ~ (5, -1) => 0.0001
+(0, 126) ~ (5, -1) => 0.0001
+(0, 127) ~ (5, -1) => 0.0001
+(0, 128) ~ (5, -1) => 0.0001
+(0, 129) ~ (5, -1) => 0.0001
+(0, 130) ~ (5, -1) => 0.0001
+(0, 131) ~ (5, -1) => 0.0001
+(0, 132) ~ (5, -1) => 0.0001
+(0, 133) ~ (5, -1) => 0.0001
+(0, 134) ~ (5, -1) => 0.0001
+(0, 135) ~ (5, -1) => 0.0001
+(0, 136) ~ (5, -1) => 0.0001
+(0, 137) ~ (5, -1) => 0.0001
+(0, 138) ~ (5, -1) => 0.0001
+(0, 139) ~ (5, -1) => 0.0001
+(0, 140) ~ (5, -1) => 0.0001
+(0, 141) ~ (5, -1) => 0.0001
+(0, 142) ~ (5, -1) => 0.0001
+(0, 143) ~ (5, -1) => 0.0001
+(0, 144) ~ (5, -1) => 0.0001
+(0, 145) ~ (5, -1) => 0.0001
+(0, 146) ~ (5, -1) => 0.0001
+(0, 147) ~ (5, -1) => 0.0001
+(0, 148) ~ (5, -1) => 0.0001
+(0, 149) ~ (5, -1) => 0.0001
+(0, 150) ~ (5, -1) => 0.0001
+(0, 151) ~ (5, -1) => 0.0001
+(0, 152) ~ (5, -1) => 0.0001
+(0, 153) ~ (5, -1) => 0.0001
+(0, 154) ~ (5, -1) => 0.0001
+(0, 155) ~ (5, -1) => 0.0001
+(0, 156) ~ (5, -1) => 0.0001
+(0, 157) ~ (5, -1) => 0.0001
+(0, 158) ~ (5, -1) => 0.0001
+(0, 159) ~ (5, -1) => 0.0001
+(0, 160) ~ (5, -1) => 0.0001
+(0, 161) ~ (5, -1) => 0.0001
+(0, 162) ~ (5, -1) => 0.0001
+(0, 163) ~ (5, -1) => 0.0001
+(0, 164) ~ (5, -1) => 0.0001
+(0, 165) ~ (5, -1) => 0.0001
+(0, 166) ~ (5, -1) => 0.0001
+(0, 167) ~ (5, -1) => 0.0001
+(0, 168) ~ (5, -1) => 0.0001
+(0, 169) ~ (5, -1) => 0.0001
+(0, 170) ~ (5, -1) => 0.0001
+(0, 171) ~ (5, -1) => 0.0001
+(0, 172) ~ (5, -1) => 0.0001
+(0, 173) ~ (5, -1) => 0.0001
+(0, 174) ~ (5, -1) => 0.0001
+(0, 175) ~ (5, -1) => 0.0001
+(0, 176) ~ (5, -1) => 0.0001
+(0, 177) ~ (5, -1) => 0.0001
+(0, 178) ~ (5, -1) => 0.0001
+(0, 179) ~ (5, -1) => 0.0001
+(0, 180) ~ (5, -1) => 0.0001
+(0, 181) ~ (5, -1) => 0.0001
+(0, 182) ~ (5, -1) => 0.0001
+(0, 183) ~ (5, -1) => 0.0001
+(0, 184) ~ (5, -1) => 0.00011009
+(0, 185) ~ (5, -1) => 0.000341892
+(0, 186) ~ (5, -1) => 0.000817537
+(0, 187) ~ (5, -1) => 0.00123513
+(0, 188) ~ (5, -1) => 0.00149065
+(0, 189) ~ (5, -1) => 0.00154889
+(0, 190) ~ (5, -1) => 0.00159281
+(0, 191) ~ (5, -1) => 0.00153947
+(0, 192) ~ (5, -1) => 0.00153232
+(0, 193) ~ (5, -1) => 0.00130916
+(0, 194) ~ (5, -1) => 0.000910282
+(0, 195) ~ (5, -1) => 0.00076437
+(0, 196) ~ (5, -1) => 0.0004403
+(0, 197) ~ (5, -1) => 0.000355244
+(0, 198) ~ (5, -1) => 0.000293911
+(0, 199) ~ (5, -1) => 0.000276268
+(0, 200) ~ (5, -1) => 0.000228465
+(0, 201) ~ (5, -1) => 0.000182867
+(0, 202) ~ (5, -1) => 0.000124633
+(0, 203) ~ (5, -1) => 0.000113487
+(0, 204) ~ (5, -1) => 0.0001
+(0, 205) ~ (5, -1) => 0.0001
+(0, 206) ~ (5, -1) => 0.0001
+(0, 207) ~ (5, -1) => 0.0001
+(0, 208) ~ (5, -1) => 0.0001
+(0, 209) ~ (5, -1) => 0.0001
+(0, 210) ~ (5, -1) => 0.0001
+(0, 211) ~ (5, -1) => 0.0001
+(0, 212) ~ (5, -1) => 0.0001
+(0, 213) ~ (5, -1) => 0.0001
+(0, 214) ~ (5, -1) => 0.0001
+(0, 215) ~ (5, -1) => 0.0001
+(0, 216) ~ (5, -1) => 0.0001
+(0, 217) ~ (5, -1) => 0.000102758
+(0, 218) ~ (5, -1) => 0.00012511
+(0, 219) ~ (5, -1) => 0.000124693
+(0, 220) ~ (5, -1) => 0.0001
+(0, 221) ~ (5, -1) => 0.0001
+(0, 222) ~ (5, -1) => 0.0001
+(0, 223) ~ (5, -1) => 0.0001
+(0, 224) ~ (5, -1) => 0.0001
+(0, 225) ~ (5, -1) => 0.0001
+(0, 226) ~ (5, -1) => 0.0001
+(0, 227) ~ (5, -1) => 0.0001
+(0, 228) ~ (5, -1) => 0.0001
+(0, 229) ~ (5, -1) => 0.0001
+(0, 230) ~ (5, -1) => 0.0001
+(0, 231) ~ (5, -1) => 0.0001
+(0, 232) ~ (5, -1) => 0.0001
+
+(0, -1) ~ (5, 0) => 0.0001
+(0, -1) ~ (5, 1) => 0.0001
+(0, -1) ~ (5, 2) => 0.0001
+(0, -1) ~ (5, 3) => 0.0001
+(0, -1) ~ (5, 4) => 0.0001
+(0, -1) ~ (5, 5) => 0.0001
+(0, -1) ~ (5, 6) => 0.0001
+(0, -1) ~ (5, 7) => 0.0001
+(0, -1) ~ (5, 8) => 0.0001
+(0, -1) ~ (5, 9) => 0.0001
+(0, -1) ~ (5, 10) => 0.000115097
+(0, -1) ~ (5, 11) => 0.00701809
+(0, -1) ~ (5, 12) => 0.0431774
+(0, -1) ~ (5, 13) => 0.0292513
+(0, -1) ~ (5, 14) => 0.391769
+(0, -1) ~ (5, 15) => 0.495122
+(0, -1) ~ (5, 16) => 0.0417121
+(0, -1) ~ (5, 17) => 0.00453055
+(0, -1) ~ (5, 18) => 0.000145555
+(0, -1) ~ (5, 19) => 0.0001
+(0, -1) ~ (5, 20) => 0.0001
+(0, -1) ~ (5, 21) => 0.0001
+(0, -1) ~ (5, 22) => 0.0001
+(0, -1) ~ (5, 23) => 0.0001
+(0, -1) ~ (5, 24) => 0.0001
+(0, -1) ~ (5, 25) => 0.0001
+(0, -1) ~ (5, 26) => 0.0001
+(0, -1) ~ (5, 27) => 0.0001
+(0, -1) ~ (5, 28) => 0.0001
+(0, -1) ~ (5, 29) => 0.0001
+(0, -1) ~ (5, 30) => 0.0001
+(0, -1) ~ (5, 31) => 0.0001
+(0, -1) ~ (5, 32) => 0.0001
+(0, -1) ~ (5, 33) => 0.0001
+(0, -1) ~ (5, 34) => 0.0001
+(0, -1) ~ (5, 35) => 0.0001
+(0, -1) ~ (5, 36) => 0.0001
+(0, -1) ~ (5, 37) => 0.0001
+(0, -1) ~ (5, 38) => 0.0001
+(0, -1) ~ (5, 39) => 0.0001
+(0, -1) ~ (5, 40) => 0.0001
+(0, -1) ~ (5, 41) => 0.0001
+(0, -1) ~ (5, 42) => 0.0001
+(0, -1) ~ (5, 43) => 0.0001
+(0, -1) ~ (5, 44) => 0.0001
+(0, -1) ~ (5, 45) => 0.0001
+(0, -1) ~ (5, 46) => 0.0001
+(0, -1) ~ (5, 47) => 0.0001
+(0, -1) ~ (5, 48) => 0.0001
+(0, -1) ~ (5, 49) => 0.0001
+(0, -1) ~ (5, 50) => 0.0001
+(0, -1) ~ (5, 51) => 0.0001
+(0, -1) ~ (5, 52) => 0.0001
+(0, -1) ~ (5, 53) => 0.0001
+(0, -1) ~ (5, 54) => 0.0001
+(0, -1) ~ (5, 55) => 0.0001
+(0, -1) ~ (5, 56) => 0.0001
+(0, -1) ~ (5, 57) => 0.0001
+(0, -1) ~ (5, 58) => 0.0001
+(0, -1) ~ (5, 59) => 0.0001
+(0, -1) ~ (5, 60) => 0.0001
+(0, -1) ~ (5, 61) => 0.0001
+(0, -1) ~ (5, 62) => 0.0001
+(0, -1) ~ (5, 63) => 0.0001
+(0, -1) ~ (5, 64) => 0.0001
+(0, -1) ~ (5, 65) => 0.0001
+(0, -1) ~ (5, 66) => 0.0001
+(0, -1) ~ (5, 67) => 0.0001
+(0, -1) ~ (5, 68) => 0.0001
+(0, -1) ~ (5, 69) => 0.0001
+(0, -1) ~ (5, 70) => 0.0001
+(0, -1) ~ (5, 71) => 0.0001
+(0, -1) ~ (5, 72) => 0.0001
+(0, -1) ~ (5, 73) => 0.0001
+(0, -1) ~ (5, 74) => 0.0001
+(0, -1) ~ (5, 75) => 0.0001
+(0, -1) ~ (5, 76) => 0.0001
+(0, -1) ~ (5, 77) => 0.0001
+(0, -1) ~ (5, 78) => 0.0001
+(0, -1) ~ (5, 79) => 0.0001
+(0, -1) ~ (5, 80) => 0.0001
+(0, -1) ~ (5, 81) => 0.0001
+(0, -1) ~ (5, 82) => 0.0001
+(0, -1) ~ (5, 83) => 0.0001
+(0, -1) ~ (5, 84) => 0.0001
+(0, -1) ~ (5, 85) => 0.0001
+(0, -1) ~ (5, 86) => 0.0001
+(0, -1) ~ (5, 87) => 0.0001
+(0, -1) ~ (5, 88) => 0.0001
+(0, -1) ~ (5, 89) => 0.0001
+(0, -1) ~ (5, 90) => 0.0001
+(0, -1) ~ (5, 91) => 0.000143111
+(0, -1) ~ (5, 92) => 0.000156403
+(0, -1) ~ (5, 93) => 0.00014931
+(0, -1) ~ (5, 94) => 0.0001
+(0, -1) ~ (5, 95) => 0.0001
+(0, -1) ~ (5, 96) => 0.0001
+(0, -1) ~ (5, 97) => 0.0001
+(0, -1) ~ (5, 98) => 0.0001
+(0, -1) ~ (5, 99) => 0.0001
+(0, -1) ~ (5, 100) => 0.0001
+(0, -1) ~ (5, 101) => 0.0001
+(0, -1) ~ (5, 102) => 0.0001
+(0, -1) ~ (5, 103) => 0.0001
+(0, -1) ~ (5, 104) => 0.0001
+(0, -1) ~ (5, 105) => 0.0001
+(0, -1) ~ (5, 106) => 0.0001
+(0, -1) ~ (5, 107) => 0.0001
+(0, -1) ~ (5, 108) => 0.0001
+(0, -1) ~ (5, 109) => 0.0001
+(0, -1) ~ (5, 110) => 0.0001
+(0, -1) ~ (5, 111) => 0.0001
+(0, -1) ~ (5, 112) => 0.0001
+(0, -1) ~ (5, 113) => 0.0001
+(0, -1) ~ (5, 114) => 0.0001
+(0, -1) ~ (5, 115) => 0.0001
+(0, -1) ~ (5, 116) => 0.0001
+(0, -1) ~ (5, 117) => 0.0001
+(0, -1) ~ (5, 118) => 0.0001
+(0, -1) ~ (5, 119) => 0.0001
+(0, -1) ~ (5, 120) => 0.0001
+(0, -1) ~ (5, 121) => 0.0001
+(0, -1) ~ (5, 122) => 0.0001
+(0, -1) ~ (5, 123) => 0.0001
+(0, -1) ~ (5, 124) => 0.0001
+(0, -1) ~ (5, 125) => 0.0001
+(0, -1) ~ (5, 126) => 0.0001
+(0, -1) ~ (5, 127) => 0.0001
+(0, -1) ~ (5, 128) => 0.0001
+(0, -1) ~ (5, 129) => 0.0001
+(0, -1) ~ (5, 130) => 0.0001
+(0, -1) ~ (5, 131) => 0.0001
+(0, -1) ~ (5, 132) => 0.0001
+(0, -1) ~ (5, 133) => 0.0001
+(0, -1) ~ (5, 134) => 0.0001
+(0, -1) ~ (5, 135) => 0.0001
+(0, -1) ~ (5, 136) => 0.0001
+(0, -1) ~ (5, 137) => 0.0001
+(0, -1) ~ (5, 138) => 0.0001
+(0, -1) ~ (5, 139) => 0.0001
+(0, -1) ~ (5, 140) => 0.0001
+(0, -1) ~ (5, 141) => 0.0001
+(0, -1) ~ (5, 142) => 0.0001
+(0, -1) ~ (5, 143) => 0.0001
+(0, -1) ~ (5, 144) => 0.0001
+(0, -1) ~ (5, 145) => 0.0001
+(0, -1) ~ (5, 146) => 0.0001
+(0, -1) ~ (5, 147) => 0.0001
+(0, -1) ~ (5, 148) => 0.0001
+(0, -1) ~ (5, 149) => 0.0001
+(0, -1) ~ (5, 150) => 0.0001
+(0, -1) ~ (5, 151) => 0.0001
+(0, -1) ~ (5, 152) => 0.0001
+(0, -1) ~ (5, 153) => 0.0001
+(0, -1) ~ (5, 154) => 0.0001
+(0, -1) ~ (5, 155) => 0.0001
+(0, -1) ~ (5, 156) => 0.0001
+(0, -1) ~ (5, 157) => 0.0001
+(0, -1) ~ (5, 158) => 0.0001
+(0, -1) ~ (5, 159) => 0.0001
+(0, -1) ~ (5, 160) => 0.0001
+(0, -1) ~ (5, 161) => 0.0001
+(0, -1) ~ (5, 162) => 0.0001
+(0, -1) ~ (5, 163) => 0.0001
+(0, -1) ~ (5, 164) => 0.0001
+(0, -1) ~ (5, 165) => 0.0001
+(0, -1) ~ (5, 166) => 0.0001
+(0, -1) ~ (5, 167) => 0.0001
+(0, -1) ~ (5, 168) => 0.0001
+(0, -1) ~ (5, 169) => 0.0001
+(0, -1) ~ (5, 170) => 0.0001
+(0, -1) ~ (5, 171) => 0.0001
+(0, -1) ~ (5, 172) => 0.0001
+(0, -1) ~ (5, 173) => 0.0001
+(0, -1) ~ (5, 174) => 0.0001
+(0, -1) ~ (5, 175) => 0.0001
+(0, -1) ~ (5, 176) => 0.0001
+(0, -1) ~ (5, 177) => 0.0001
+(0, -1) ~ (5, 178) => 0.0001
+(0, -1) ~ (5, 179) => 0.0001
+(0, -1) ~ (5, 180) => 0.0001
+(0, -1) ~ (5, 181) => 0.0001
+(0, -1) ~ (5, 182) => 0.0001
+(0, -1) ~ (5, 183) => 0.0001
+(0, -1) ~ (5, 184) => 0.0001
+(0, -1) ~ (5, 185) => 0.00011009
+(0, -1) ~ (5, 186) => 0.000341892
+(0, -1) ~ (5, 187) => 0.000817537
+(0, -1) ~ (5, 188) => 0.00123513
+(0, -1) ~ (5, 189) => 0.00149065
+(0, -1) ~ (5, 190) => 0.00154889
+(0, -1) ~ (5, 191) => 0.00159281
+(0, -1) ~ (5, 192) => 0.00153947
+(0, -1) ~ (5, 193) => 0.00153232
+(0, -1) ~ (5, 194) => 0.00130916
+(0, -1) ~ (5, 195) => 0.000910282
+(0, -1) ~ (5, 196) => 0.00076437
+(0, -1) ~ (5, 197) => 0.0004403
+(0, -1) ~ (5, 198) => 0.000355244
+(0, -1) ~ (5, 199) => 0.000293911
+(0, -1) ~ (5, 200) => 0.000276268
+(0, -1) ~ (5, 201) => 0.000228465
+(0, -1) ~ (5, 202) => 0.000182867
+(0, -1) ~ (5, 203) => 0.000124633
+(0, -1) ~ (5, 204) => 0.000113487
+(0, -1) ~ (5, 205) => 0.0001
+(0, -1) ~ (5, 206) => 0.0001
+(0, -1) ~ (5, 207) => 0.0001
+(0, -1) ~ (5, 208) => 0.0001
+(0, -1) ~ (5, 209) => 0.0001
+(0, -1) ~ (5, 210) => 0.0001
+(0, -1) ~ (5, 211) => 0.0001
+(0, -1) ~ (5, 212) => 0.0001
+(0, -1) ~ (5, 213) => 0.0001
+(0, -1) ~ (5, 214) => 0.0001
+(0, -1) ~ (5, 215) => 0.0001
+(0, -1) ~ (5, 216) => 0.0001
+(0, -1) ~ (5, 217) => 0.0001
+(0, -1) ~ (5, 218) => 0.000102758
+(0, -1) ~ (5, 219) => 0.00012511
+(0, -1) ~ (5, 220) => 0.000124693
+(0, -1) ~ (5, 221) => 0.0001
+(0, -1) ~ (5, 222) => 0.0001
+(0, -1) ~ (5, 223) => 0.0001
+(0, -1) ~ (5, 224) => 0.0001
+(0, -1) ~ (5, 225) => 0.0001
+(0, -1) ~ (5, 226) => 0.0001
+(0, -1) ~ (5, 227) => 0.0001
+(0, -1) ~ (5, 228) => 0.0001
+(0, -1) ~ (5, 229) => 0.0001
+(0, -1) ~ (5, 230) => 0.0001
+(0, -1) ~ (5, 231) => 0.0001
+(0, -1) ~ (5, 232) => 0.0001
+(0, -1) ~ (5, 233) => 0.0001
+
+; Sparse posterior probability matrix for sequences 1 and 2
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (2, 0) => 0.993019
+(1, 1) ~ (2, 1) => 0.989517
+(1, 2) ~ (2, 2) => 0.986456
+(1, 3) ~ (2, 3) => 0.964716
+(1, 3) ~ (2, 4) => 0.0164795
+(1, 3) ~ (2, 6) => 0.0165713
+(1, 4) ~ (2, 4) => 0.877497
+(1, 4) ~ (2, 5) => 0.0320993
+(1, 4) ~ (2, 7) => 0.0837111
+(1, 5) ~ (2, 5) => 0.857003
+(1, 5) ~ (2, 6) => 0.0329866
+(1, 5) ~ (2, 8) => 0.0974208
+(1, 6) ~ (2, 6) => 0.848276
+(1, 6) ~ (2, 7) => 0.0323247
+(1, 6) ~ (2, 9) => 0.106028
+(1, 7) ~ (2, 7) => 0.700335
+(1, 7) ~ (2, 8) => 0.0584836
+(1, 7) ~ (2, 10) => 0.21943
+(1, 8) ~ (2, 6) => 0.010108
+(1, 8) ~ (2, 8) => 0.418577
+(1, 8) ~ (2, 9) => 0.190819
+(1, 8) ~ (2, 11) => 0.341595
+(1, 9) ~ (2, 8) => 0.0316858
+(1, 9) ~ (2, 9) => 0.0806953
+(1, 9) ~ (2, 10) => 0.352615
+(1, 9) ~ (2, 12) => 0.495367
+(1, 10) ~ (2, 9) => 0.0579283
+(1, 10) ~ (2, 10) => 0.0226107
+(1, 10) ~ (2, 11) => 0.357558
+(1, 10) ~ (2, 13) => 0.549378
+(1, 11) ~ (2, 10) => 0.059208
+(1, 11) ~ (2, 11) => 0.016685
+(1, 11) ~ (2, 12) => 0.3456
+(1, 11) ~ (2, 14) => 0.56271
+(1, 12) ~ (2, 11) => 0.0493718
+(1, 12) ~ (2, 12) => 0.0129237
+(1, 12) ~ (2, 13) => 0.304786
+(1, 12) ~ (2, 14) => 0.0237175
+(1, 12) ~ (2, 15) => 0.602548
+(1, 13) ~ (2, 12) => 0.0173648
+(1, 13) ~ (2, 14) => 0.162943
+(1, 13) ~ (2, 15) => 0.0521418
+(1, 13) ~ (2, 16) => 0.752493
+(1, 14) ~ (2, 15) => 0.0748135
+(1, 14) ~ (2, 16) => 0.0295865
+(1, 14) ~ (2, 17) => 0.875726
+(1, 15) ~ (2, 18) => 0.9812
+(1, 16) ~ (2, 19) => 0.996636
+(1, 17) ~ (2, 20) => 0.998422
+(1, 18) ~ (2, 21) => 0.999791
+(1, 19) ~ (2, 22) => 0.999956
+(1, 20) ~ (2, 23) => 0.999992
+(1, 21) ~ (2, 24) => 0.999999
+(1, 22) ~ (2, 25) => 0.999999
+(1, 23) ~ (2, 26) => 0.999996
+(1, 24) ~ (2, 27) => 0.999979
+(1, 25) ~ (2, 28) => 0.999933
+(1, 26) ~ (2, 29) => 0.999937
+(1, 27) ~ (2, 30) => 0.999954
+(1, 28) ~ (2, 31) => 0.999923
+(1, 29) ~ (2, 32) => 0.999899
+(1, 30) ~ (2, 33) => 0.999922
+(1, 31) ~ (2, 34) => 0.99996
+(1, 32) ~ (2, 35) => 0.999958
+(1, 33) ~ (2, 36) => 0.999974
+(1, 34) ~ (2, 37) => 0.99987
+(1, 35) ~ (2, 38) => 0.999719
+(1, 36) ~ (2, 39) => 0.998912
+(1, 37) ~ (2, 40) => 0.998887
+(1, 38) ~ (2, 41) => 0.999479
+(1, 39) ~ (2, 42) => 0.999483
+(1, 40) ~ (2, 43) => 0.999599
+(1, 41) ~ (2, 44) => 0.999779
+(1, 42) ~ (2, 45) => 0.999968
+(1, 43) ~ (2, 46) => 0.99995
+(1, 44) ~ (2, 47) => 0.999757
+(1, 45) ~ (2, 48) => 0.998242
+(1, 46) ~ (2, 49) => 0.997388
+(1, 47) ~ (2, 50) => 0.995968
+(1, 48) ~ (2, 51) => 0.988918
+(1, 49) ~ (2, 52) => 0.980472
+(1, 49) ~ (2, 54) => 0.0153142
+(1, 50) ~ (2, 53) => 0.980386
+(1, 50) ~ (2, 55) => 0.0108652
+(1, 51) ~ (2, 54) => 0.980876
+(1, 52) ~ (2, 55) => 0.986462
+(1, 53) ~ (2, 56) => 0.993295
+(1, 54) ~ (2, 57) => 0.999768
+(1, 55) ~ (2, 58) => 0.999953
+(1, 56) ~ (2, 59) => 0.99999
+(1, 57) ~ (2, 60) => 0.999931
+(1, 58) ~ (2, 61) => 0.999724
+(1, 59) ~ (2, 62) => 0.995682
+(1, 60) ~ (2, 63) => 0.988752
+(1, 61) ~ (2, 63) => 0.0109703
+(1, 61) ~ (2, 64) => 0.931966
+(1, 62) ~ (2, 64) => 0.0670032
+(1, 62) ~ (2, 65) => 0.875257
+(1, 63) ~ (2, 65) => 0.122964
+(1, 63) ~ (2, 66) => 0.818801
+(1, 64) ~ (2, 66) => 0.178986
+(1, 64) ~ (2, 67) => 0.244021
+(1, 65) ~ (2, 67) => 0.753306
+(1, 65) ~ (2, 68) => 0.0259534
+(1, 66) ~ (2, 68) => 0.971919
+(1, 67) ~ (2, 69) => 0.992485
+(1, 68) ~ (2, 70) => 0.999919
+(1, 69) ~ (2, 71) => 0.999984
+(1, 70) ~ (2, 72) => 0.999991
+(1, 71) ~ (2, 73) => 0.999976
+(1, 72) ~ (2, 74) => 0.999978
+(1, 73) ~ (2, 75) => 0.999999
+(1, 74) ~ (2, 76) => 0.999999
+(1, 75) ~ (2, 77) => 0.999999
+(1, 76) ~ (2, 78) => 0.999998
+(1, 77) ~ (2, 79) => 0.999998
+(1, 78) ~ (2, 80) => 0.999994
+(1, 79) ~ (2, 81) => 0.999917
+(1, 80) ~ (2, 82) => 0.999562
+(1, 81) ~ (2, 83) => 0.999403
+(1, 82) ~ (2, 84) => 0.998313
+(1, 83) ~ (2, 85) => 0.997856
+(1, 84) ~ (2, 86) => 0.997466
+(1, 85) ~ (2, 87) => 0.997779
+(1, 86) ~ (2, 88) => 0.998361
+(1, 87) ~ (2, 89) => 0.998163
+(1, 88) ~ (2, 90) => 0.998516
+(1, 89) ~ (2, 91) => 0.999058
+(1, 90) ~ (2, 92) => 0.999901
+(1, 91) ~ (2, 93) => 0.999983
+(1, 92) ~ (2, 94) => 0.999993
+(1, 93) ~ (2, 95) => 0.999967
+(1, 94) ~ (2, 96) => 0.999852
+(1, 95) ~ (2, 97) => 0.999784
+(1, 96) ~ (2, 98) => 0.999846
+(1, 97) ~ (2, 99) => 0.99988
+(1, 98) ~ (2, 100) => 0.999436
+(1, 99) ~ (2, 101) => 0.999324
+(1, 100) ~ (2, 102) => 0.999353
+(1, 101) ~ (2, 103) => 0.999683
+(1, 102) ~ (2, 104) => 0.999953
+(1, 103) ~ (2, 105) => 0.999964
+(1, 104) ~ (2, 106) => 0.999958
+(1, 105) ~ (2, 107) => 0.999912
+(1, 106) ~ (2, 108) => 0.999928
+(1, 107) ~ (2, 109) => 0.999994
+(1, 108) ~ (2, 110) => 0.999989
+(1, 109) ~ (2, 111) => 0.999982
+(1, 110) ~ (2, 112) => 0.999991
+(1, 111) ~ (2, 113) => 0.999997
+(1, 112) ~ (2, 114) => 0.999997
+(1, 113) ~ (2, 115) => 0.999997
+(1, 114) ~ (2, 116) => 0.999998
+(1, 115) ~ (2, 117) => 0.999998
+(1, 116) ~ (2, 118) => 0.999999
+(1, 117) ~ (2, 119) => 0.99999
+(1, 118) ~ (2, 120) => 0.999973
+(1, 119) ~ (2, 121) => 0.999962
+(1, 120) ~ (2, 122) => 0.999961
+(1, 121) ~ (2, 123) => 0.999986
+(1, 122) ~ (2, 124) => 0.999988
+(1, 123) ~ (2, 125) => 0.999983
+(1, 124) ~ (2, 126) => 0.999988
+(1, 125) ~ (2, 127) => 0.999989
+(1, 126) ~ (2, 128) => 0.999988
+(1, 127) ~ (2, 129) => 0.999989
+(1, 128) ~ (2, 130) => 0.999927
+(1, 129) ~ (2, 131) => 0.999727
+(1, 130) ~ (2, 132) => 0.999564
+(1, 131) ~ (2, 133) => 0.999019
+(1, 132) ~ (2, 134) => 0.999027
+(1, 133) ~ (2, 135) => 0.999662
+(1, 134) ~ (2, 136) => 0.999625
+(1, 135) ~ (2, 137) => 0.999772
+(1, 136) ~ (2, 138) => 0.99997
+(1, 137) ~ (2, 139) => 0.999991
+(1, 138) ~ (2, 140) => 0.99998
+(1, 139) ~ (2, 141) => 0.999978
+(1, 140) ~ (2, 142) => 0.999985
+(1, 141) ~ (2, 143) => 0.999933
+(1, 142) ~ (2, 144) => 0.999919
+(1, 143) ~ (2, 145) => 0.99998
+(1, 144) ~ (2, 146) => 0.999986
+(1, 145) ~ (2, 147) => 0.999989
+(1, 146) ~ (2, 148) => 0.999994
+(1, 147) ~ (2, 149) => 1
+(1, 148) ~ (2, 150) => 1
+(1, 149) ~ (2, 151) => 1
+(1, 150) ~ (2, 152) => 0.999994
+(1, 151) ~ (2, 153) => 0.999707
+(1, 152) ~ (2, 154) => 0.999692
+(1, 153) ~ (2, 155) => 0.999924
+(1, 154) ~ (2, 156) => 0.99998
+(1, 155) ~ (2, 157) => 0.999973
+(1, 156) ~ (2, 158) => 0.999982
+(1, 157) ~ (2, 159) => 0.999996
+(1, 158) ~ (2, 160) => 0.999986
+(1, 159) ~ (2, 161) => 0.999879
+(1, 160) ~ (2, 162) => 0.999854
+(1, 161) ~ (2, 163) => 0.999879
+(1, 162) ~ (2, 164) => 0.999942
+(1, 163) ~ (2, 165) => 0.999944
+(1, 164) ~ (2, 166) => 0.999955
+(1, 165) ~ (2, 167) => 0.999948
+(1, 166) ~ (2, 168) => 0.999852
+(1, 167) ~ (2, 169) => 0.999395
+(1, 168) ~ (2, 170) => 0.998255
+(1, 169) ~ (2, 171) => 0.998097
+(1, 170) ~ (2, 172) => 0.998565
+(1, 171) ~ (2, 173) => 0.999131
+(1, 172) ~ (2, 174) => 0.999917
+(1, 173) ~ (2, 175) => 0.999981
+(1, 174) ~ (2, 176) => 0.999867
+(1, 175) ~ (2, 177) => 0.999505
+(1, 176) ~ (2, 178) => 0.998645
+(1, 177) ~ (2, 179) => 0.99776
+(1, 178) ~ (2, 180) => 0.997528
+(1, 179) ~ (2, 181) => 0.998172
+(1, 180) ~ (2, 182) => 0.999586
+(1, 181) ~ (2, 183) => 0.999974
+(1, 182) ~ (2, 184) => 0.999991
+(1, 183) ~ (2, 185) => 0.999986
+(1, 184) ~ (2, 186) => 0.999894
+(1, 185) ~ (2, 187) => 0.999849
+(1, 186) ~ (2, 188) => 0.999857
+(1, 187) ~ (2, 189) => 0.999261
+(1, 188) ~ (2, 190) => 0.990245
+(1, 189) ~ (2, 191) => 0.852272
+(1, 189) ~ (2, 193) => 0.13708
+(1, 190) ~ (2, 192) => 0.69463
+(1, 190) ~ (2, 194) => 0.28594
+(1, 191) ~ (2, 193) => 0.529572
+(1, 191) ~ (2, 195) => 0.450467
+(1, 192) ~ (2, 194) => 0.145408
+(1, 192) ~ (2, 196) => 0.837076
+(1, 193) ~ (2, 195) => 0.0520482
+(1, 193) ~ (2, 197) => 0.944347
+(1, 194) ~ (2, 196) => 0.0426213
+(1, 194) ~ (2, 198) => 0.95507
+(1, 195) ~ (2, 197) => 0.0219896
+(1, 195) ~ (2, 199) => 0.976453
+(1, 196) ~ (2, 200) => 0.995105
+(1, 197) ~ (2, 201) => 0.998556
+(1, 198) ~ (2, 202) => 0.99887
+(1, 199) ~ (2, 203) => 0.99898
+(1, 200) ~ (2, 204) => 0.999019
+(1, 201) ~ (2, 205) => 0.998817
+(1, 202) ~ (2, 206) => 0.998788
+(1, 203) ~ (2, 207) => 0.999054
+(1, 204) ~ (2, 208) => 0.999465
+(1, 205) ~ (2, 209) => 0.999668
+(1, 206) ~ (2, 210) => 0.999791
+(1, 207) ~ (2, 211) => 0.999927
+(1, 208) ~ (2, 212) => 0.999997
+(1, 209) ~ (2, 213) => 0.999988
+(1, 210) ~ (2, 214) => 0.999661
+(1, 211) ~ (2, 215) => 0.999566
+(1, 212) ~ (2, 216) => 0.999735
+(1, 213) ~ (2, 217) => 0.998825
+(1, 214) ~ (2, 218) => 0.997984
+(1, 215) ~ (2, 219) => 0.994981
+(1, 216) ~ (2, 220) => 0.987192
+(1, 216) ~ (2, 221) => 0.0100263
+(1, 217) ~ (2, 221) => 0.975322
+(1, 217) ~ (2, 222) => 0.0207732
+(1, 218) ~ (2, 222) => 0.916296
+(1, 218) ~ (2, 223) => 0.0741965
+(1, 219) ~ (2, 223) => 0.796245
+(1, 219) ~ (2, 224) => 0.188055
+(1, 220) ~ (2, 224) => 0.56354
+(1, 220) ~ (2, 225) => 0.420347
+(1, 221) ~ (2, 225) => 0.246711
+(1, 221) ~ (2, 226) => 0.742792
+(1, 222) ~ (2, 226) => 0.0362951
+(1, 222) ~ (2, 227) => 0.961443
+(1, 223) ~ (2, 228) => 0.999426
+(1, 224) ~ (2, 229) => 0.999884
+(1, 225) ~ (2, 230) => 0.999996
+(1, 226) ~ (2, 231) => 1
+(1, 227) ~ (2, 232) => 0.999998
+(1, 228) ~ (2, 233) => 0.999988
+(1, 229) ~ (2, 234) => 0.999976
+(1, 230) ~ (2, 235) => 0.999978
+(1, 231) ~ (2, 236) => 0.999938
+(1, 232) ~ (2, 237) => 0.999944
+(1, 233) ~ (2, 238) => 0.999999
+
+; gap posteriors
+(1, 0) ~ (2, -1) => 0.00698137
+(1, 1) ~ (2, -1) => 0.0104825
+(1, 2) ~ (2, -1) => 0.013544
+(1, 3) ~ (2, -1) => 0.00223297
+(1, 4) ~ (2, -1) => 0.00669251
+(1, 5) ~ (2, -1) => 0.0125901
+(1, 6) ~ (2, -1) => 0.0133718
+(1, 7) ~ (2, -1) => 0.0217519
+(1, 8) ~ (2, -1) => 0.0389011
+(1, 9) ~ (2, -1) => 0.039637
+(1, 10) ~ (2, -1) => 0.0125243
+(1, 11) ~ (2, -1) => 0.0157968
+(1, 12) ~ (2, -1) => 0.00665337
+(1, 13) ~ (2, -1) => 0.0150576
+(1, 14) ~ (2, -1) => 0.0198743
+(1, 15) ~ (2, -1) => 0.0187997
+(1, 16) ~ (2, -1) => 0.00336367
+(1, 17) ~ (2, -1) => 0.00157768
+(1, 18) ~ (2, -1) => 0.000208676
+(1, 19) ~ (2, -1) => 0.0001
+(1, 20) ~ (2, -1) => 0.0001
+(1, 21) ~ (2, -1) => 0.0001
+(1, 22) ~ (2, -1) => 0.0001
+(1, 23) ~ (2, -1) => 0.0001
+(1, 24) ~ (2, -1) => 0.0001
+(1, 25) ~ (2, -1) => 0.0001
+(1, 26) ~ (2, -1) => 0.0001
+(1, 27) ~ (2, -1) => 0.0001
+(1, 28) ~ (2, -1) => 0.0001
+(1, 29) ~ (2, -1) => 0.000100553
+(1, 30) ~ (2, -1) => 0.0001
+(1, 31) ~ (2, -1) => 0.0001
+(1, 32) ~ (2, -1) => 0.0001
+(1, 33) ~ (2, -1) => 0.0001
+(1, 34) ~ (2, -1) => 0.000129819
+(1, 35) ~ (2, -1) => 0.000280559
+(1, 36) ~ (2, -1) => 0.00108784
+(1, 37) ~ (2, -1) => 0.00111258
+(1, 38) ~ (2, -1) => 0.000520706
+(1, 39) ~ (2, -1) => 0.000517428
+(1, 40) ~ (2, -1) => 0.000401497
+(1, 41) ~ (2, -1) => 0.000220537
+(1, 42) ~ (2, -1) => 0.0001
+(1, 43) ~ (2, -1) => 0.0001
+(1, 44) ~ (2, -1) => 0.000243306
+(1, 45) ~ (2, -1) => 0.00175804
+(1, 46) ~ (2, -1) => 0.00261241
+(1, 47) ~ (2, -1) => 0.00403243
+(1, 48) ~ (2, -1) => 0.011082
+(1, 49) ~ (2, -1) => 0.00421365
+(1, 50) ~ (2, -1) => 0.008749
+(1, 51) ~ (2, -1) => 0.0191239
+(1, 52) ~ (2, -1) => 0.0135378
+(1, 53) ~ (2, -1) => 0.00670534
+(1, 54) ~ (2, -1) => 0.000231802
+(1, 55) ~ (2, -1) => 0.0001
+(1, 56) ~ (2, -1) => 0.0001
+(1, 57) ~ (2, -1) => 0.0001
+(1, 58) ~ (2, -1) => 0.00027585
+(1, 59) ~ (2, -1) => 0.00431806
+(1, 60) ~ (2, -1) => 0.0112481
+(1, 61) ~ (2, -1) => 0.0570636
+(1, 62) ~ (2, -1) => 0.0577396
+(1, 63) ~ (2, -1) => 0.0582351
+(1, 64) ~ (2, -1) => 0.576994
+(1, 65) ~ (2, -1) => 0.220741
+(1, 66) ~ (2, -1) => 0.0280811
+(1, 67) ~ (2, -1) => 0.00751543
+(1, 68) ~ (2, -1) => 0.0001
+(1, 69) ~ (2, -1) => 0.0001
+(1, 70) ~ (2, -1) => 0.0001
+(1, 71) ~ (2, -1) => 0.0001
+(1, 72) ~ (2, -1) => 0.0001
+(1, 73) ~ (2, -1) => 0.0001
+(1, 74) ~ (2, -1) => 0.0001
+(1, 75) ~ (2, -1) => 0.0001
+(1, 76) ~ (2, -1) => 0.0001
+(1, 77) ~ (2, -1) => 0.0001
+(1, 78) ~ (2, -1) => 0.0001
+(1, 79) ~ (2, -1) => 0.0001
+(1, 80) ~ (2, -1) => 0.000437737
+(1, 81) ~ (2, -1) => 0.000597179
+(1, 82) ~ (2, -1) => 0.00168735
+(1, 83) ~ (2, -1) => 0.00214356
+(1, 84) ~ (2, -1) => 0.00253403
+(1, 85) ~ (2, -1) => 0.00222147
+(1, 86) ~ (2, -1) => 0.00163895
+(1, 87) ~ (2, -1) => 0.00183743
+(1, 88) ~ (2, -1) => 0.00148404
+(1, 89) ~ (2, -1) => 0.000941992
+(1, 90) ~ (2, -1) => 0.0001
+(1, 91) ~ (2, -1) => 0.0001
+(1, 92) ~ (2, -1) => 0.0001
+(1, 93) ~ (2, -1) => 0.0001
+(1, 94) ~ (2, -1) => 0.0001477
+(1, 95) ~ (2, -1) => 0.000215888
+(1, 96) ~ (2, -1) => 0.000154197
+(1, 97) ~ (2, -1) => 0.000120282
+(1, 98) ~ (2, -1) => 0.000563562
+(1, 99) ~ (2, -1) => 0.000676334
+(1, 100) ~ (2, -1) => 0.000646591
+(1, 101) ~ (2, -1) => 0.000317156
+(1, 102) ~ (2, -1) => 0.0001
+(1, 103) ~ (2, -1) => 0.0001
+(1, 104) ~ (2, -1) => 0.0001
+(1, 105) ~ (2, -1) => 0.0001
+(1, 106) ~ (2, -1) => 0.0001
+(1, 107) ~ (2, -1) => 0.0001
+(1, 108) ~ (2, -1) => 0.0001
+(1, 109) ~ (2, -1) => 0.0001
+(1, 110) ~ (2, -1) => 0.0001
+(1, 111) ~ (2, -1) => 0.0001
+(1, 112) ~ (2, -1) => 0.0001
+(1, 113) ~ (2, -1) => 0.0001
+(1, 114) ~ (2, -1) => 0.0001
+(1, 115) ~ (2, -1) => 0.0001
+(1, 116) ~ (2, -1) => 0.0001
+(1, 117) ~ (2, -1) => 0.0001
+(1, 118) ~ (2, -1) => 0.0001
+(1, 119) ~ (2, -1) => 0.0001
+(1, 120) ~ (2, -1) => 0.0001
+(1, 121) ~ (2, -1) => 0.0001
+(1, 122) ~ (2, -1) => 0.0001
+(1, 123) ~ (2, -1) => 0.0001
+(1, 124) ~ (2, -1) => 0.0001
+(1, 125) ~ (2, -1) => 0.0001
+(1, 126) ~ (2, -1) => 0.0001
+(1, 127) ~ (2, -1) => 0.0001
+(1, 128) ~ (2, -1) => 0.0001
+(1, 129) ~ (2, -1) => 0.000272691
+(1, 130) ~ (2, -1) => 0.000435531
+(1, 131) ~ (2, -1) => 0.000981212
+(1, 132) ~ (2, -1) => 0.000972807
+(1, 133) ~ (2, -1) => 0.000337601
+(1, 134) ~ (2, -1) => 0.000375092
+(1, 135) ~ (2, -1) => 0.000227869
+(1, 136) ~ (2, -1) => 0.0001
+(1, 137) ~ (2, -1) => 0.0001
+(1, 138) ~ (2, -1) => 0.0001
+(1, 139) ~ (2, -1) => 0.0001
+(1, 140) ~ (2, -1) => 0.0001
+(1, 141) ~ (2, -1) => 0.0001
+(1, 142) ~ (2, -1) => 0.0001
+(1, 143) ~ (2, -1) => 0.0001
+(1, 144) ~ (2, -1) => 0.0001
+(1, 145) ~ (2, -1) => 0.0001
+(1, 146) ~ (2, -1) => 0.0001
+(1, 147) ~ (2, -1) => 0.0001
+(1, 148) ~ (2, -1) => 0.0001
+(1, 149) ~ (2, -1) => 0.0001
+(1, 150) ~ (2, -1) => 0.0001
+(1, 151) ~ (2, -1) => 0.000293076
+(1, 152) ~ (2, -1) => 0.000307739
+(1, 153) ~ (2, -1) => 0.0001
+(1, 154) ~ (2, -1) => 0.0001
+(1, 155) ~ (2, -1) => 0.0001
+(1, 156) ~ (2, -1) => 0.0001
+(1, 157) ~ (2, -1) => 0.0001
+(1, 158) ~ (2, -1) => 0.0001
+(1, 159) ~ (2, -1) => 0.000121117
+(1, 160) ~ (2, -1) => 0.000145912
+(1, 161) ~ (2, -1) => 0.000121474
+(1, 162) ~ (2, -1) => 0.0001
+(1, 163) ~ (2, -1) => 0.0001
+(1, 164) ~ (2, -1) => 0.0001
+(1, 165) ~ (2, -1) => 0.0001
+(1, 166) ~ (2, -1) => 0.000148177
+(1, 167) ~ (2, -1) => 0.000605285
+(1, 168) ~ (2, -1) => 0.00174481
+(1, 169) ~ (2, -1) => 0.00190264
+(1, 170) ~ (2, -1) => 0.00143516
+(1, 171) ~ (2, -1) => 0.000869155
+(1, 172) ~ (2, -1) => 0.0001
+(1, 173) ~ (2, -1) => 0.0001
+(1, 174) ~ (2, -1) => 0.000133157
+(1, 175) ~ (2, -1) => 0.000494659
+(1, 176) ~ (2, -1) => 0.00135493
+(1, 177) ~ (2, -1) => 0.00224036
+(1, 178) ~ (2, -1) => 0.00247151
+(1, 179) ~ (2, -1) => 0.00182831
+(1, 180) ~ (2, -1) => 0.000414133
+(1, 181) ~ (2, -1) => 0.0001
+(1, 182) ~ (2, -1) => 0.0001
+(1, 183) ~ (2, -1) => 0.0001
+(1, 184) ~ (2, -1) => 0.0001055
+(1, 185) ~ (2, -1) => 0.000151217
+(1, 186) ~ (2, -1) => 0.000142753
+(1, 187) ~ (2, -1) => 0.00073874
+(1, 188) ~ (2, -1) => 0.00975513
+(1, 189) ~ (2, -1) => 0.0106484
+(1, 190) ~ (2, -1) => 0.0194294
+(1, 191) ~ (2, -1) => 0.0199612
+(1, 192) ~ (2, -1) => 0.0175157
+(1, 193) ~ (2, -1) => 0.00360459
+(1, 194) ~ (2, -1) => 0.00230879
+(1, 195) ~ (2, -1) => 0.00155717
+(1, 196) ~ (2, -1) => 0.00489461
+(1, 197) ~ (2, -1) => 0.00144362
+(1, 198) ~ (2, -1) => 0.00112975
+(1, 199) ~ (2, -1) => 0.00102001
+(1, 200) ~ (2, -1) => 0.00098145
+(1, 201) ~ (2, -1) => 0.00118339
+(1, 202) ~ (2, -1) => 0.00121194
+(1, 203) ~ (2, -1) => 0.000945807
+(1, 204) ~ (2, -1) => 0.000535309
+(1, 205) ~ (2, -1) => 0.000332355
+(1, 206) ~ (2, -1) => 0.000208855
+(1, 207) ~ (2, -1) => 0.0001
+(1, 208) ~ (2, -1) => 0.0001
+(1, 209) ~ (2, -1) => 0.0001
+(1, 210) ~ (2, -1) => 0.000338793
+(1, 211) ~ (2, -1) => 0.000433743
+(1, 212) ~ (2, -1) => 0.000264943
+(1, 213) ~ (2, -1) => 0.00117528
+(1, 214) ~ (2, -1) => 0.00201565
+(1, 215) ~ (2, -1) => 0.00501925
+(1, 216) ~ (2, -1) => 0.00278168
+(1, 217) ~ (2, -1) => 0.00390463
+(1, 218) ~ (2, -1) => 0.00950745
+(1, 219) ~ (2, -1) => 0.0157005
+(1, 220) ~ (2, -1) => 0.0161128
+(1, 221) ~ (2, -1) => 0.0104968
+(1, 222) ~ (2, -1) => 0.0022617
+(1, 223) ~ (2, -1) => 0.00057447
+(1, 224) ~ (2, -1) => 0.000116169
+(1, 225) ~ (2, -1) => 0.0001
+(1, 226) ~ (2, -1) => 0.0001
+(1, 227) ~ (2, -1) => 0.0001
+(1, 228) ~ (2, -1) => 0.0001
+(1, 229) ~ (2, -1) => 0.0001
+(1, 230) ~ (2, -1) => 0.0001
+(1, 231) ~ (2, -1) => 0.0001
+(1, 232) ~ (2, -1) => 0.0001
+(1, 233) ~ (2, -1) => 0.0001
+
+(1, -1) ~ (2, 0) => 0.00698137
+(1, -1) ~ (2, 1) => 0.0104825
+(1, -1) ~ (2, 2) => 0.013544
+(1, -1) ~ (2, 3) => 0.0352837
+(1, -1) ~ (2, 4) => 0.106023
+(1, -1) ~ (2, 5) => 0.110898
+(1, -1) ~ (2, 6) => 0.0920584
+(1, -1) ~ (2, 7) => 0.183629
+(1, -1) ~ (2, 8) => 0.393832
+(1, -1) ~ (2, 9) => 0.56453
+(1, -1) ~ (2, 10) => 0.346137
+(1, -1) ~ (2, 11) => 0.23479
+(1, -1) ~ (2, 12) => 0.128745
+(1, -1) ~ (2, 13) => 0.145836
+(1, -1) ~ (2, 14) => 0.250629
+(1, -1) ~ (2, 15) => 0.270497
+(1, -1) ~ (2, 16) => 0.21792
+(1, -1) ~ (2, 17) => 0.124274
+(1, -1) ~ (2, 18) => 0.0187997
+(1, -1) ~ (2, 19) => 0.00336367
+(1, -1) ~ (2, 20) => 0.00157768
+(1, -1) ~ (2, 21) => 0.000208676
+(1, -1) ~ (2, 22) => 0.0001
+(1, -1) ~ (2, 23) => 0.0001
+(1, -1) ~ (2, 24) => 0.0001
+(1, -1) ~ (2, 25) => 0.0001
+(1, -1) ~ (2, 26) => 0.0001
+(1, -1) ~ (2, 27) => 0.0001
+(1, -1) ~ (2, 28) => 0.0001
+(1, -1) ~ (2, 29) => 0.0001
+(1, -1) ~ (2, 30) => 0.0001
+(1, -1) ~ (2, 31) => 0.0001
+(1, -1) ~ (2, 32) => 0.000100553
+(1, -1) ~ (2, 33) => 0.0001
+(1, -1) ~ (2, 34) => 0.0001
+(1, -1) ~ (2, 35) => 0.0001
+(1, -1) ~ (2, 36) => 0.0001
+(1, -1) ~ (2, 37) => 0.000129819
+(1, -1) ~ (2, 38) => 0.000280559
+(1, -1) ~ (2, 39) => 0.00108784
+(1, -1) ~ (2, 40) => 0.00111258
+(1, -1) ~ (2, 41) => 0.000520706
+(1, -1) ~ (2, 42) => 0.000517428
+(1, -1) ~ (2, 43) => 0.000401497
+(1, -1) ~ (2, 44) => 0.000220537
+(1, -1) ~ (2, 45) => 0.0001
+(1, -1) ~ (2, 46) => 0.0001
+(1, -1) ~ (2, 47) => 0.000243306
+(1, -1) ~ (2, 48) => 0.00175804
+(1, -1) ~ (2, 49) => 0.00261241
+(1, -1) ~ (2, 50) => 0.00403243
+(1, -1) ~ (2, 51) => 0.011082
+(1, -1) ~ (2, 52) => 0.0195279
+(1, -1) ~ (2, 53) => 0.0196142
+(1, -1) ~ (2, 54) => 0.00380969
+(1, -1) ~ (2, 55) => 0.00267261
+(1, -1) ~ (2, 56) => 0.00670534
+(1, -1) ~ (2, 57) => 0.000231802
+(1, -1) ~ (2, 58) => 0.0001
+(1, -1) ~ (2, 59) => 0.0001
+(1, -1) ~ (2, 60) => 0.0001
+(1, -1) ~ (2, 61) => 0.00027585
+(1, -1) ~ (2, 62) => 0.00431806
+(1, -1) ~ (2, 63) => 0.000277753
+(1, -1) ~ (2, 64) => 0.00103068
+(1, -1) ~ (2, 65) => 0.00177842
+(1, -1) ~ (2, 66) => 0.00221382
+(1, -1) ~ (2, 67) => 0.00267327
+(1, -1) ~ (2, 68) => 0.00212765
+(1, -1) ~ (2, 69) => 0.00751543
+(1, -1) ~ (2, 70) => 0.0001
+(1, -1) ~ (2, 71) => 0.0001
+(1, -1) ~ (2, 72) => 0.0001
+(1, -1) ~ (2, 73) => 0.0001
+(1, -1) ~ (2, 74) => 0.0001
+(1, -1) ~ (2, 75) => 0.0001
+(1, -1) ~ (2, 76) => 0.0001
+(1, -1) ~ (2, 77) => 0.0001
+(1, -1) ~ (2, 78) => 0.0001
+(1, -1) ~ (2, 79) => 0.0001
+(1, -1) ~ (2, 80) => 0.0001
+(1, -1) ~ (2, 81) => 0.0001
+(1, -1) ~ (2, 82) => 0.000437737
+(1, -1) ~ (2, 83) => 0.000597179
+(1, -1) ~ (2, 84) => 0.00168735
+(1, -1) ~ (2, 85) => 0.00214356
+(1, -1) ~ (2, 86) => 0.00253403
+(1, -1) ~ (2, 87) => 0.00222147
+(1, -1) ~ (2, 88) => 0.00163895
+(1, -1) ~ (2, 89) => 0.00183743
+(1, -1) ~ (2, 90) => 0.00148404
+(1, -1) ~ (2, 91) => 0.000941992
+(1, -1) ~ (2, 92) => 0.0001
+(1, -1) ~ (2, 93) => 0.0001
+(1, -1) ~ (2, 94) => 0.0001
+(1, -1) ~ (2, 95) => 0.0001
+(1, -1) ~ (2, 96) => 0.0001477
+(1, -1) ~ (2, 97) => 0.000215888
+(1, -1) ~ (2, 98) => 0.000154197
+(1, -1) ~ (2, 99) => 0.000120282
+(1, -1) ~ (2, 100) => 0.000563562
+(1, -1) ~ (2, 101) => 0.000676334
+(1, -1) ~ (2, 102) => 0.000646591
+(1, -1) ~ (2, 103) => 0.000317156
+(1, -1) ~ (2, 104) => 0.0001
+(1, -1) ~ (2, 105) => 0.0001
+(1, -1) ~ (2, 106) => 0.0001
+(1, -1) ~ (2, 107) => 0.0001
+(1, -1) ~ (2, 108) => 0.0001
+(1, -1) ~ (2, 109) => 0.0001
+(1, -1) ~ (2, 110) => 0.0001
+(1, -1) ~ (2, 111) => 0.0001
+(1, -1) ~ (2, 112) => 0.0001
+(1, -1) ~ (2, 113) => 0.0001
+(1, -1) ~ (2, 114) => 0.0001
+(1, -1) ~ (2, 115) => 0.0001
+(1, -1) ~ (2, 116) => 0.0001
+(1, -1) ~ (2, 117) => 0.0001
+(1, -1) ~ (2, 118) => 0.0001
+(1, -1) ~ (2, 119) => 0.0001
+(1, -1) ~ (2, 120) => 0.0001
+(1, -1) ~ (2, 121) => 0.0001
+(1, -1) ~ (2, 122) => 0.0001
+(1, -1) ~ (2, 123) => 0.0001
+(1, -1) ~ (2, 124) => 0.0001
+(1, -1) ~ (2, 125) => 0.0001
+(1, -1) ~ (2, 126) => 0.0001
+(1, -1) ~ (2, 127) => 0.0001
+(1, -1) ~ (2, 128) => 0.0001
+(1, -1) ~ (2, 129) => 0.0001
+(1, -1) ~ (2, 130) => 0.0001
+(1, -1) ~ (2, 131) => 0.000272691
+(1, -1) ~ (2, 132) => 0.000435531
+(1, -1) ~ (2, 133) => 0.000981212
+(1, -1) ~ (2, 134) => 0.000972807
+(1, -1) ~ (2, 135) => 0.000337601
+(1, -1) ~ (2, 136) => 0.000375092
+(1, -1) ~ (2, 137) => 0.000227869
+(1, -1) ~ (2, 138) => 0.0001
+(1, -1) ~ (2, 139) => 0.0001
+(1, -1) ~ (2, 140) => 0.0001
+(1, -1) ~ (2, 141) => 0.0001
+(1, -1) ~ (2, 142) => 0.0001
+(1, -1) ~ (2, 143) => 0.0001
+(1, -1) ~ (2, 144) => 0.0001
+(1, -1) ~ (2, 145) => 0.0001
+(1, -1) ~ (2, 146) => 0.0001
+(1, -1) ~ (2, 147) => 0.0001
+(1, -1) ~ (2, 148) => 0.0001
+(1, -1) ~ (2, 149) => 0.0001
+(1, -1) ~ (2, 150) => 0.0001
+(1, -1) ~ (2, 151) => 0.0001
+(1, -1) ~ (2, 152) => 0.0001
+(1, -1) ~ (2, 153) => 0.000293076
+(1, -1) ~ (2, 154) => 0.000307739
+(1, -1) ~ (2, 155) => 0.0001
+(1, -1) ~ (2, 156) => 0.0001
+(1, -1) ~ (2, 157) => 0.0001
+(1, -1) ~ (2, 158) => 0.0001
+(1, -1) ~ (2, 159) => 0.0001
+(1, -1) ~ (2, 160) => 0.0001
+(1, -1) ~ (2, 161) => 0.000121117
+(1, -1) ~ (2, 162) => 0.000145912
+(1, -1) ~ (2, 163) => 0.000121474
+(1, -1) ~ (2, 164) => 0.0001
+(1, -1) ~ (2, 165) => 0.0001
+(1, -1) ~ (2, 166) => 0.0001
+(1, -1) ~ (2, 167) => 0.0001
+(1, -1) ~ (2, 168) => 0.000148177
+(1, -1) ~ (2, 169) => 0.000605285
+(1, -1) ~ (2, 170) => 0.00174481
+(1, -1) ~ (2, 171) => 0.00190264
+(1, -1) ~ (2, 172) => 0.00143516
+(1, -1) ~ (2, 173) => 0.000869155
+(1, -1) ~ (2, 174) => 0.0001
+(1, -1) ~ (2, 175) => 0.0001
+(1, -1) ~ (2, 176) => 0.000133157
+(1, -1) ~ (2, 177) => 0.000494659
+(1, -1) ~ (2, 178) => 0.00135493
+(1, -1) ~ (2, 179) => 0.00224036
+(1, -1) ~ (2, 180) => 0.00247151
+(1, -1) ~ (2, 181) => 0.00182831
+(1, -1) ~ (2, 182) => 0.000414133
+(1, -1) ~ (2, 183) => 0.0001
+(1, -1) ~ (2, 184) => 0.0001
+(1, -1) ~ (2, 185) => 0.0001
+(1, -1) ~ (2, 186) => 0.0001055
+(1, -1) ~ (2, 187) => 0.000151217
+(1, -1) ~ (2, 188) => 0.000142753
+(1, -1) ~ (2, 189) => 0.00073874
+(1, -1) ~ (2, 190) => 0.00975513
+(1, -1) ~ (2, 191) => 0.147728
+(1, -1) ~ (2, 192) => 0.30537
+(1, -1) ~ (2, 193) => 0.333348
+(1, -1) ~ (2, 194) => 0.568652
+(1, -1) ~ (2, 195) => 0.497485
+(1, -1) ~ (2, 196) => 0.120302
+(1, -1) ~ (2, 197) => 0.0336632
+(1, -1) ~ (2, 198) => 0.0449301
+(1, -1) ~ (2, 199) => 0.0235468
+(1, -1) ~ (2, 200) => 0.00489461
+(1, -1) ~ (2, 201) => 0.00144362
+(1, -1) ~ (2, 202) => 0.00112975
+(1, -1) ~ (2, 203) => 0.00102001
+(1, -1) ~ (2, 204) => 0.00098145
+(1, -1) ~ (2, 205) => 0.00118339
+(1, -1) ~ (2, 206) => 0.00121194
+(1, -1) ~ (2, 207) => 0.000945807
+(1, -1) ~ (2, 208) => 0.000535309
+(1, -1) ~ (2, 209) => 0.000332355
+(1, -1) ~ (2, 210) => 0.000208855
+(1, -1) ~ (2, 211) => 0.0001
+(1, -1) ~ (2, 212) => 0.0001
+(1, -1) ~ (2, 213) => 0.0001
+(1, -1) ~ (2, 214) => 0.000338793
+(1, -1) ~ (2, 215) => 0.000433743
+(1, -1) ~ (2, 216) => 0.000264943
+(1, -1) ~ (2, 217) => 0.00117528
+(1, -1) ~ (2, 218) => 0.00201565
+(1, -1) ~ (2, 219) => 0.00501925
+(1, -1) ~ (2, 220) => 0.012808
+(1, -1) ~ (2, 221) => 0.0146515
+(1, -1) ~ (2, 222) => 0.0629308
+(1, -1) ~ (2, 223) => 0.129559
+(1, -1) ~ (2, 224) => 0.248405
+(1, -1) ~ (2, 225) => 0.332942
+(1, -1) ~ (2, 226) => 0.220913
+(1, -1) ~ (2, 227) => 0.0385568
+(1, -1) ~ (2, 228) => 0.00057447
+(1, -1) ~ (2, 229) => 0.000116169
+(1, -1) ~ (2, 230) => 0.0001
+(1, -1) ~ (2, 231) => 0.0001
+(1, -1) ~ (2, 232) => 0.0001
+(1, -1) ~ (2, 233) => 0.0001
+(1, -1) ~ (2, 234) => 0.0001
+(1, -1) ~ (2, 235) => 0.0001
+(1, -1) ~ (2, 236) => 0.0001
+(1, -1) ~ (2, 237) => 0.0001
+(1, -1) ~ (2, 238) => 0.0001
+
+; Sparse posterior probability matrix for sequences 1 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (3, 0) => 0.999726
+(1, 1) ~ (3, 1) => 0.99956
+(1, 2) ~ (3, 2) => 0.999525
+(1, 3) ~ (3, 3) => 0.999581
+(1, 4) ~ (3, 4) => 0.999677
+(1, 5) ~ (3, 5) => 0.999442
+(1, 6) ~ (3, 6) => 0.996046
+(1, 7) ~ (3, 7) => 0.995789
+(1, 8) ~ (3, 8) => 0.995553
+(1, 9) ~ (3, 9) => 0.991269
+(1, 10) ~ (3, 10) => 0.977453
+(1, 10) ~ (3, 12) => 0.0213676
+(1, 11) ~ (3, 11) => 0.955851
+(1, 11) ~ (3, 13) => 0.0341568
+(1, 12) ~ (3, 12) => 0.894457
+(1, 12) ~ (3, 13) => 0.0155478
+(1, 12) ~ (3, 14) => 0.0691138
+(1, 13) ~ (3, 12) => 0.0175064
+(1, 13) ~ (3, 13) => 0.683704
+(1, 13) ~ (3, 14) => 0.051098
+(1, 13) ~ (3, 15) => 0.205208
+(1, 14) ~ (3, 13) => 0.0535947
+(1, 14) ~ (3, 14) => 0.324391
+(1, 14) ~ (3, 15) => 0.0166838
+(1, 14) ~ (3, 16) => 0.598949
+(1, 15) ~ (3, 14) => 0.0284845
+(1, 15) ~ (3, 17) => 0.957961
+(1, 16) ~ (3, 18) => 0.996514
+(1, 17) ~ (3, 19) => 0.999199
+(1, 18) ~ (3, 20) => 0.999588
+(1, 19) ~ (3, 21) => 0.999624
+(1, 20) ~ (3, 22) => 0.999948
+(1, 21) ~ (3, 23) => 0.999999
+(1, 22) ~ (3, 24) => 1
+(1, 23) ~ (3, 25) => 0.999998
+(1, 24) ~ (3, 26) => 0.999992
+(1, 25) ~ (3, 27) => 0.999971
+(1, 26) ~ (3, 28) => 0.999971
+(1, 27) ~ (3, 29) => 0.999967
+(1, 28) ~ (3, 30) => 0.999943
+(1, 29) ~ (3, 31) => 0.999945
+(1, 30) ~ (3, 32) => 0.999968
+(1, 31) ~ (3, 33) => 0.999965
+(1, 32) ~ (3, 34) => 0.999956
+(1, 33) ~ (3, 35) => 0.999976
+(1, 34) ~ (3, 36) => 0.999975
+(1, 35) ~ (3, 37) => 0.999963
+(1, 36) ~ (3, 38) => 0.999938
+(1, 37) ~ (3, 39) => 0.999919
+(1, 38) ~ (3, 40) => 0.999855
+(1, 39) ~ (3, 41) => 0.999792
+(1, 40) ~ (3, 42) => 0.999836
+(1, 41) ~ (3, 43) => 0.999946
+(1, 42) ~ (3, 44) => 0.999994
+(1, 43) ~ (3, 45) => 0.999997
+(1, 44) ~ (3, 46) => 0.999997
+(1, 45) ~ (3, 47) => 0.99999
+(1, 46) ~ (3, 48) => 0.999947
+(1, 47) ~ (3, 49) => 0.999882
+(1, 48) ~ (3, 50) => 0.999857
+(1, 49) ~ (3, 51) => 0.999871
+(1, 50) ~ (3, 52) => 0.999944
+(1, 51) ~ (3, 53) => 0.999995
+(1, 52) ~ (3, 54) => 0.999999
+(1, 53) ~ (3, 55) => 0.999999
+(1, 54) ~ (3, 56) => 0.999999
+(1, 55) ~ (3, 57) => 0.999999
+(1, 56) ~ (3, 58) => 0.999999
+(1, 57) ~ (3, 59) => 0.999998
+(1, 58) ~ (3, 60) => 0.999997
+(1, 59) ~ (3, 61) => 0.999981
+(1, 60) ~ (3, 62) => 0.99998
+(1, 61) ~ (3, 63) => 0.999962
+(1, 62) ~ (3, 64) => 0.999939
+(1, 63) ~ (3, 65) => 0.999921
+(1, 64) ~ (3, 66) => 0.999852
+(1, 65) ~ (3, 67) => 0.999831
+(1, 66) ~ (3, 68) => 0.999842
+(1, 67) ~ (3, 69) => 0.99995
+(1, 68) ~ (3, 70) => 0.999999
+(1, 69) ~ (3, 71) => 0.999994
+(1, 70) ~ (3, 72) => 0.999976
+(1, 71) ~ (3, 73) => 0.999976
+(1, 72) ~ (3, 74) => 0.999987
+(1, 73) ~ (3, 75) => 0.999999
+(1, 74) ~ (3, 76) => 0.999999
+(1, 75) ~ (3, 77) => 0.999999
+(1, 76) ~ (3, 78) => 0.999998
+(1, 77) ~ (3, 79) => 0.999996
+(1, 78) ~ (3, 80) => 0.999993
+(1, 79) ~ (3, 81) => 0.999905
+(1, 80) ~ (3, 82) => 0.999037
+(1, 81) ~ (3, 83) => 0.998709
+(1, 82) ~ (3, 84) => 0.996773
+(1, 83) ~ (3, 85) => 0.99658
+(1, 84) ~ (3, 86) => 0.996474
+(1, 85) ~ (3, 87) => 0.996559
+(1, 86) ~ (3, 88) => 0.997084
+(1, 87) ~ (3, 89) => 0.997171
+(1, 88) ~ (3, 90) => 0.998425
+(1, 89) ~ (3, 91) => 0.99908
+(1, 90) ~ (3, 92) => 0.999952
+(1, 91) ~ (3, 93) => 0.999982
+(1, 92) ~ (3, 94) => 0.999995
+(1, 93) ~ (3, 95) => 0.999991
+(1, 94) ~ (3, 96) => 0.999969
+(1, 95) ~ (3, 97) => 0.999964
+(1, 96) ~ (3, 98) => 0.999987
+(1, 97) ~ (3, 99) => 0.999987
+(1, 98) ~ (3, 100) => 0.999923
+(1, 99) ~ (3, 101) => 0.999845
+(1, 100) ~ (3, 102) => 0.999782
+(1, 101) ~ (3, 103) => 0.999811
+(1, 102) ~ (3, 104) => 0.999856
+(1, 103) ~ (3, 105) => 0.999941
+(1, 104) ~ (3, 106) => 0.999972
+(1, 105) ~ (3, 107) => 0.999972
+(1, 106) ~ (3, 108) => 0.999983
+(1, 107) ~ (3, 109) => 0.999997
+(1, 108) ~ (3, 110) => 0.999994
+(1, 109) ~ (3, 111) => 0.999992
+(1, 110) ~ (3, 112) => 0.999996
+(1, 111) ~ (3, 113) => 0.999998
+(1, 112) ~ (3, 114) => 0.999998
+(1, 113) ~ (3, 115) => 0.999998
+(1, 114) ~ (3, 116) => 0.999996
+(1, 115) ~ (3, 117) => 0.999996
+(1, 116) ~ (3, 118) => 0.999998
+(1, 117) ~ (3, 119) => 0.999994
+(1, 118) ~ (3, 120) => 0.999986
+(1, 119) ~ (3, 121) => 0.999989
+(1, 120) ~ (3, 122) => 0.999996
+(1, 121) ~ (3, 123) => 0.999999
+(1, 122) ~ (3, 124) => 0.999995
+(1, 123) ~ (3, 125) => 0.999993
+(1, 124) ~ (3, 126) => 0.999996
+(1, 125) ~ (3, 127) => 0.999997
+(1, 126) ~ (3, 128) => 0.999997
+(1, 127) ~ (3, 129) => 0.999996
+(1, 128) ~ (3, 130) => 0.99992
+(1, 129) ~ (3, 131) => 0.999727
+(1, 130) ~ (3, 132) => 0.99955
+(1, 131) ~ (3, 133) => 0.999577
+(1, 132) ~ (3, 134) => 0.99993
+(1, 133) ~ (3, 135) => 0.999983
+(1, 134) ~ (3, 136) => 0.999977
+(1, 135) ~ (3, 137) => 0.999978
+(1, 136) ~ (3, 138) => 0.999937
+(1, 137) ~ (3, 139) => 0.999915
+(1, 138) ~ (3, 140) => 0.999504
+(1, 139) ~ (3, 141) => 0.999518
+(1, 140) ~ (3, 142) => 0.999947
+(1, 141) ~ (3, 143) => 0.999991
+(1, 142) ~ (3, 144) => 0.999998
+(1, 143) ~ (3, 145) => 0.999998
+(1, 144) ~ (3, 146) => 0.999999
+(1, 145) ~ (3, 147) => 0.999998
+(1, 146) ~ (3, 148) => 0.999997
+(1, 147) ~ (3, 149) => 0.999999
+(1, 148) ~ (3, 150) => 0.999999
+(1, 149) ~ (3, 151) => 0.999999
+(1, 150) ~ (3, 152) => 0.999997
+(1, 151) ~ (3, 153) => 0.99997
+(1, 152) ~ (3, 154) => 0.999967
+(1, 153) ~ (3, 155) => 0.999989
+(1, 154) ~ (3, 156) => 0.999997
+(1, 155) ~ (3, 157) => 0.999997
+(1, 156) ~ (3, 158) => 0.999997
+(1, 157) ~ (3, 159) => 0.999996
+(1, 158) ~ (3, 160) => 0.999987
+(1, 159) ~ (3, 161) => 0.999924
+(1, 160) ~ (3, 162) => 0.99987
+(1, 161) ~ (3, 163) => 0.999826
+(1, 162) ~ (3, 164) => 0.999844
+(1, 163) ~ (3, 165) => 0.999956
+(1, 164) ~ (3, 166) => 0.999982
+(1, 165) ~ (3, 167) => 0.999984
+(1, 166) ~ (3, 168) => 0.999984
+(1, 167) ~ (3, 169) => 0.999967
+(1, 168) ~ (3, 170) => 0.99997
+(1, 169) ~ (3, 171) => 0.999975
+(1, 170) ~ (3, 172) => 0.999974
+(1, 171) ~ (3, 173) => 0.999966
+(1, 172) ~ (3, 174) => 0.999975
+(1, 173) ~ (3, 175) => 0.999997
+(1, 174) ~ (3, 176) => 0.999998
+(1, 175) ~ (3, 177) => 0.999978
+(1, 176) ~ (3, 178) => 0.999971
+(1, 177) ~ (3, 179) => 0.99998
+(1, 178) ~ (3, 180) => 0.999996
+(1, 179) ~ (3, 181) => 0.999998
+(1, 180) ~ (3, 182) => 0.999998
+(1, 181) ~ (3, 183) => 0.999998
+(1, 182) ~ (3, 184) => 0.99999
+(1, 183) ~ (3, 185) => 0.999953
+(1, 184) ~ (3, 186) => 0.999887
+(1, 185) ~ (3, 187) => 0.999807
+(1, 186) ~ (3, 188) => 0.999693
+(1, 187) ~ (3, 189) => 0.999107
+(1, 188) ~ (3, 190) => 0.990967
+(1, 189) ~ (3, 191) => 0.863111
+(1, 189) ~ (3, 193) => 0.128317
+(1, 190) ~ (3, 192) => 0.719686
+(1, 190) ~ (3, 194) => 0.267641
+(1, 191) ~ (3, 193) => 0.565654
+(1, 191) ~ (3, 195) => 0.420557
+(1, 192) ~ (3, 194) => 0.118254
+(1, 192) ~ (3, 196) => 0.869737
+(1, 193) ~ (3, 195) => 0.0355752
+(1, 193) ~ (3, 197) => 0.959279
+(1, 194) ~ (3, 196) => 0.029588
+(1, 194) ~ (3, 198) => 0.965522
+(1, 195) ~ (3, 197) => 0.0260377
+(1, 195) ~ (3, 199) => 0.969083
+(1, 196) ~ (3, 198) => 0.0201736
+(1, 196) ~ (3, 200) => 0.975441
+(1, 197) ~ (3, 201) => 0.991701
+(1, 198) ~ (3, 202) => 0.99658
+(1, 199) ~ (3, 203) => 0.999517
+(1, 200) ~ (3, 204) => 0.999853
+(1, 201) ~ (3, 205) => 0.999938
+(1, 202) ~ (3, 206) => 0.999896
+(1, 203) ~ (3, 207) => 0.999869
+(1, 204) ~ (3, 208) => 0.999841
+(1, 205) ~ (3, 209) => 0.999795
+(1, 206) ~ (3, 210) => 0.999867
+(1, 207) ~ (3, 211) => 0.999958
+(1, 208) ~ (3, 212) => 0.999988
+(1, 209) ~ (3, 213) => 0.999981
+(1, 210) ~ (3, 214) => 0.999969
+(1, 211) ~ (3, 215) => 0.999975
+(1, 212) ~ (3, 216) => 0.999972
+(1, 213) ~ (3, 217) => 0.999713
+(1, 214) ~ (3, 218) => 0.9965
+(1, 215) ~ (3, 219) => 0.993385
+(1, 216) ~ (3, 220) => 0.977851
+(1, 216) ~ (3, 221) => 0.0211596
+(1, 217) ~ (3, 221) => 0.950753
+(1, 217) ~ (3, 222) => 0.0480003
+(1, 218) ~ (3, 222) => 0.816315
+(1, 218) ~ (3, 223) => 0.181398
+(1, 219) ~ (3, 223) => 0.778348
+(1, 219) ~ (3, 224) => 0.218191
+(1, 220) ~ (3, 224) => 0.540422
+(1, 220) ~ (3, 225) => 0.44963
+(1, 221) ~ (3, 225) => 0.305196
+(1, 221) ~ (3, 226) => 0.681579
+(1, 222) ~ (3, 226) => 0.100878
+(1, 222) ~ (3, 227) => 0.887649
+(1, 223) ~ (3, 228) => 0.995746
+(1, 224) ~ (3, 229) => 0.998132
+(1, 225) ~ (3, 230) => 0.999924
+(1, 226) ~ (3, 231) => 0.999984
+(1, 227) ~ (3, 232) => 0.999995
+(1, 228) ~ (3, 233) => 0.999993
+(1, 229) ~ (3, 234) => 0.99999
+(1, 230) ~ (3, 235) => 0.999992
+(1, 231) ~ (3, 236) => 0.999982
+(1, 232) ~ (3, 237) => 0.999985
+(1, 233) ~ (3, 238) => 0.999998
+
+; gap posteriors
+(1, 0) ~ (3, -1) => 0.000273585
+(1, 1) ~ (3, -1) => 0.000439703
+(1, 2) ~ (3, -1) => 0.000475466
+(1, 3) ~ (3, -1) => 0.000418901
+(1, 4) ~ (3, -1) => 0.000323057
+(1, 5) ~ (3, -1) => 0.000558197
+(1, 6) ~ (3, -1) => 0.00395393
+(1, 7) ~ (3, -1) => 0.00421083
+(1, 8) ~ (3, -1) => 0.00444686
+(1, 9) ~ (3, -1) => 0.00873119
+(1, 10) ~ (3, -1) => 0.00117948
+(1, 11) ~ (3, -1) => 0.00999258
+(1, 12) ~ (3, -1) => 0.020881
+(1, 13) ~ (3, -1) => 0.0424837
+(1, 14) ~ (3, -1) => 0.00638145
+(1, 15) ~ (3, -1) => 0.0135546
+(1, 16) ~ (3, -1) => 0.0034861
+(1, 17) ~ (3, -1) => 0.000800967
+(1, 18) ~ (3, -1) => 0.000411808
+(1, 19) ~ (3, -1) => 0.000376225
+(1, 20) ~ (3, -1) => 0.0001
+(1, 21) ~ (3, -1) => 0.0001
+(1, 22) ~ (3, -1) => 0.0001
+(1, 23) ~ (3, -1) => 0.0001
+(1, 24) ~ (3, -1) => 0.0001
+(1, 25) ~ (3, -1) => 0.0001
+(1, 26) ~ (3, -1) => 0.0001
+(1, 27) ~ (3, -1) => 0.0001
+(1, 28) ~ (3, -1) => 0.0001
+(1, 29) ~ (3, -1) => 0.0001
+(1, 30) ~ (3, -1) => 0.0001
+(1, 31) ~ (3, -1) => 0.0001
+(1, 32) ~ (3, -1) => 0.0001
+(1, 33) ~ (3, -1) => 0.0001
+(1, 34) ~ (3, -1) => 0.0001
+(1, 35) ~ (3, -1) => 0.0001
+(1, 36) ~ (3, -1) => 0.0001
+(1, 37) ~ (3, -1) => 0.0001
+(1, 38) ~ (3, -1) => 0.000145018
+(1, 39) ~ (3, -1) => 0.00020802
+(1, 40) ~ (3, -1) => 0.000163794
+(1, 41) ~ (3, -1) => 0.0001
+(1, 42) ~ (3, -1) => 0.0001
+(1, 43) ~ (3, -1) => 0.0001
+(1, 44) ~ (3, -1) => 0.0001
+(1, 45) ~ (3, -1) => 0.0001
+(1, 46) ~ (3, -1) => 0.0001
+(1, 47) ~ (3, -1) => 0.000118256
+(1, 48) ~ (3, -1) => 0.000143111
+(1, 49) ~ (3, -1) => 0.000129104
+(1, 50) ~ (3, -1) => 0.0001
+(1, 51) ~ (3, -1) => 0.0001
+(1, 52) ~ (3, -1) => 0.0001
+(1, 53) ~ (3, -1) => 0.0001
+(1, 54) ~ (3, -1) => 0.0001
+(1, 55) ~ (3, -1) => 0.0001
+(1, 56) ~ (3, -1) => 0.0001
+(1, 57) ~ (3, -1) => 0.0001
+(1, 58) ~ (3, -1) => 0.0001
+(1, 59) ~ (3, -1) => 0.0001
+(1, 60) ~ (3, -1) => 0.0001
+(1, 61) ~ (3, -1) => 0.0001
+(1, 62) ~ (3, -1) => 0.0001
+(1, 63) ~ (3, -1) => 0.0001
+(1, 64) ~ (3, -1) => 0.000147581
+(1, 65) ~ (3, -1) => 0.0001688
+(1, 66) ~ (3, -1) => 0.00015825
+(1, 67) ~ (3, -1) => 0.0001
+(1, 68) ~ (3, -1) => 0.0001
+(1, 69) ~ (3, -1) => 0.0001
+(1, 70) ~ (3, -1) => 0.0001
+(1, 71) ~ (3, -1) => 0.0001
+(1, 72) ~ (3, -1) => 0.0001
+(1, 73) ~ (3, -1) => 0.0001
+(1, 74) ~ (3, -1) => 0.0001
+(1, 75) ~ (3, -1) => 0.0001
+(1, 76) ~ (3, -1) => 0.0001
+(1, 77) ~ (3, -1) => 0.0001
+(1, 78) ~ (3, -1) => 0.0001
+(1, 79) ~ (3, -1) => 0.0001
+(1, 80) ~ (3, -1) => 0.000962973
+(1, 81) ~ (3, -1) => 0.00129086
+(1, 82) ~ (3, -1) => 0.00322717
+(1, 83) ~ (3, -1) => 0.00342023
+(1, 84) ~ (3, -1) => 0.00352556
+(1, 85) ~ (3, -1) => 0.00344127
+(1, 86) ~ (3, -1) => 0.00291592
+(1, 87) ~ (3, -1) => 0.00282913
+(1, 88) ~ (3, -1) => 0.00157523
+(1, 89) ~ (3, -1) => 0.000919878
+(1, 90) ~ (3, -1) => 0.0001
+(1, 91) ~ (3, -1) => 0.0001
+(1, 92) ~ (3, -1) => 0.0001
+(1, 93) ~ (3, -1) => 0.0001
+(1, 94) ~ (3, -1) => 0.0001
+(1, 95) ~ (3, -1) => 0.0001
+(1, 96) ~ (3, -1) => 0.0001
+(1, 97) ~ (3, -1) => 0.0001
+(1, 98) ~ (3, -1) => 0.0001
+(1, 99) ~ (3, -1) => 0.000154793
+(1, 100) ~ (3, -1) => 0.000217736
+(1, 101) ~ (3, -1) => 0.000189364
+(1, 102) ~ (3, -1) => 0.000143766
+(1, 103) ~ (3, -1) => 0.0001
+(1, 104) ~ (3, -1) => 0.0001
+(1, 105) ~ (3, -1) => 0.0001
+(1, 106) ~ (3, -1) => 0.0001
+(1, 107) ~ (3, -1) => 0.0001
+(1, 108) ~ (3, -1) => 0.0001
+(1, 109) ~ (3, -1) => 0.0001
+(1, 110) ~ (3, -1) => 0.0001
+(1, 111) ~ (3, -1) => 0.0001
+(1, 112) ~ (3, -1) => 0.0001
+(1, 113) ~ (3, -1) => 0.0001
+(1, 114) ~ (3, -1) => 0.0001
+(1, 115) ~ (3, -1) => 0.0001
+(1, 116) ~ (3, -1) => 0.0001
+(1, 117) ~ (3, -1) => 0.0001
+(1, 118) ~ (3, -1) => 0.0001
+(1, 119) ~ (3, -1) => 0.0001
+(1, 120) ~ (3, -1) => 0.0001
+(1, 121) ~ (3, -1) => 0.0001
+(1, 122) ~ (3, -1) => 0.0001
+(1, 123) ~ (3, -1) => 0.0001
+(1, 124) ~ (3, -1) => 0.0001
+(1, 125) ~ (3, -1) => 0.0001
+(1, 126) ~ (3, -1) => 0.0001
+(1, 127) ~ (3, -1) => 0.0001
+(1, 128) ~ (3, -1) => 0.0001
+(1, 129) ~ (3, -1) => 0.000272691
+(1, 130) ~ (3, -1) => 0.000450253
+(1, 131) ~ (3, -1) => 0.000423312
+(1, 132) ~ (3, -1) => 0.0001
+(1, 133) ~ (3, -1) => 0.0001
+(1, 134) ~ (3, -1) => 0.0001
+(1, 135) ~ (3, -1) => 0.0001
+(1, 136) ~ (3, -1) => 0.0001
+(1, 137) ~ (3, -1) => 0.0001
+(1, 138) ~ (3, -1) => 0.000496149
+(1, 139) ~ (3, -1) => 0.000481963
+(1, 140) ~ (3, -1) => 0.0001
+(1, 141) ~ (3, -1) => 0.0001
+(1, 142) ~ (3, -1) => 0.0001
+(1, 143) ~ (3, -1) => 0.0001
+(1, 144) ~ (3, -1) => 0.0001
+(1, 145) ~ (3, -1) => 0.0001
+(1, 146) ~ (3, -1) => 0.0001
+(1, 147) ~ (3, -1) => 0.0001
+(1, 148) ~ (3, -1) => 0.0001
+(1, 149) ~ (3, -1) => 0.0001
+(1, 150) ~ (3, -1) => 0.0001
+(1, 151) ~ (3, -1) => 0.0001
+(1, 152) ~ (3, -1) => 0.0001
+(1, 153) ~ (3, -1) => 0.0001
+(1, 154) ~ (3, -1) => 0.0001
+(1, 155) ~ (3, -1) => 0.0001
+(1, 156) ~ (3, -1) => 0.0001
+(1, 157) ~ (3, -1) => 0.0001
+(1, 158) ~ (3, -1) => 0.0001
+(1, 159) ~ (3, -1) => 0.0001
+(1, 160) ~ (3, -1) => 0.000130057
+(1, 161) ~ (3, -1) => 0.000174046
+(1, 162) ~ (3, -1) => 0.000155568
+(1, 163) ~ (3, -1) => 0.0001
+(1, 164) ~ (3, -1) => 0.0001
+(1, 165) ~ (3, -1) => 0.0001
+(1, 166) ~ (3, -1) => 0.0001
+(1, 167) ~ (3, -1) => 0.0001
+(1, 168) ~ (3, -1) => 0.0001
+(1, 169) ~ (3, -1) => 0.0001
+(1, 170) ~ (3, -1) => 0.0001
+(1, 171) ~ (3, -1) => 0.0001
+(1, 172) ~ (3, -1) => 0.0001
+(1, 173) ~ (3, -1) => 0.0001
+(1, 174) ~ (3, -1) => 0.0001
+(1, 175) ~ (3, -1) => 0.0001
+(1, 176) ~ (3, -1) => 0.0001
+(1, 177) ~ (3, -1) => 0.0001
+(1, 178) ~ (3, -1) => 0.0001
+(1, 179) ~ (3, -1) => 0.0001
+(1, 180) ~ (3, -1) => 0.0001
+(1, 181) ~ (3, -1) => 0.0001
+(1, 182) ~ (3, -1) => 0.0001
+(1, 183) ~ (3, -1) => 0.0001
+(1, 184) ~ (3, -1) => 0.000113487
+(1, 185) ~ (3, -1) => 0.000193119
+(1, 186) ~ (3, -1) => 0.000307083
+(1, 187) ~ (3, -1) => 0.000892937
+(1, 188) ~ (3, -1) => 0.00903308
+(1, 189) ~ (3, -1) => 0.00857249
+(1, 190) ~ (3, -1) => 0.0126731
+(1, 191) ~ (3, -1) => 0.0137887
+(1, 192) ~ (3, -1) => 0.0120088
+(1, 193) ~ (3, -1) => 0.00514621
+(1, 194) ~ (3, -1) => 0.00488979
+(1, 195) ~ (3, -1) => 0.00487965
+(1, 196) ~ (3, -1) => 0.00438541
+(1, 197) ~ (3, -1) => 0.00829947
+(1, 198) ~ (3, -1) => 0.00341988
+(1, 199) ~ (3, -1) => 0.000483453
+(1, 200) ~ (3, -1) => 0.000147283
+(1, 201) ~ (3, -1) => 0.0001
+(1, 202) ~ (3, -1) => 0.000104189
+(1, 203) ~ (3, -1) => 0.000131011
+(1, 204) ~ (3, -1) => 0.000158548
+(1, 205) ~ (3, -1) => 0.000204682
+(1, 206) ~ (3, -1) => 0.000133097
+(1, 207) ~ (3, -1) => 0.0001
+(1, 208) ~ (3, -1) => 0.0001
+(1, 209) ~ (3, -1) => 0.0001
+(1, 210) ~ (3, -1) => 0.0001
+(1, 211) ~ (3, -1) => 0.0001
+(1, 212) ~ (3, -1) => 0.0001
+(1, 213) ~ (3, -1) => 0.000287354
+(1, 214) ~ (3, -1) => 0.00350016
+(1, 215) ~ (3, -1) => 0.00661546
+(1, 216) ~ (3, -1) => 0.000989355
+(1, 217) ~ (3, -1) => 0.00124667
+(1, 218) ~ (3, -1) => 0.00228733
+(1, 219) ~ (3, -1) => 0.00346093
+(1, 220) ~ (3, -1) => 0.00994769
+(1, 221) ~ (3, -1) => 0.0132247
+(1, 222) ~ (3, -1) => 0.0114732
+(1, 223) ~ (3, -1) => 0.00425428
+(1, 224) ~ (3, -1) => 0.00186837
+(1, 225) ~ (3, -1) => 0.0001
+(1, 226) ~ (3, -1) => 0.0001
+(1, 227) ~ (3, -1) => 0.0001
+(1, 228) ~ (3, -1) => 0.0001
+(1, 229) ~ (3, -1) => 0.0001
+(1, 230) ~ (3, -1) => 0.0001
+(1, 231) ~ (3, -1) => 0.0001
+(1, 232) ~ (3, -1) => 0.0001
+(1, 233) ~ (3, -1) => 0.0001
+
+(1, -1) ~ (3, 0) => 0.000273585
+(1, -1) ~ (3, 1) => 0.000439703
+(1, -1) ~ (3, 2) => 0.000475466
+(1, -1) ~ (3, 3) => 0.000418901
+(1, -1) ~ (3, 4) => 0.000323057
+(1, -1) ~ (3, 5) => 0.000558197
+(1, -1) ~ (3, 6) => 0.00395393
+(1, -1) ~ (3, 7) => 0.00421083
+(1, -1) ~ (3, 8) => 0.00444686
+(1, -1) ~ (3, 9) => 0.00873119
+(1, -1) ~ (3, 10) => 0.0225471
+(1, -1) ~ (3, 11) => 0.0441494
+(1, -1) ~ (3, 12) => 0.0666685
+(1, -1) ~ (3, 13) => 0.212997
+(1, -1) ~ (3, 14) => 0.526913
+(1, -1) ~ (3, 15) => 0.778108
+(1, -1) ~ (3, 16) => 0.401051
+(1, -1) ~ (3, 17) => 0.0420391
+(1, -1) ~ (3, 18) => 0.0034861
+(1, -1) ~ (3, 19) => 0.000800967
+(1, -1) ~ (3, 20) => 0.000411808
+(1, -1) ~ (3, 21) => 0.000376225
+(1, -1) ~ (3, 22) => 0.0001
+(1, -1) ~ (3, 23) => 0.0001
+(1, -1) ~ (3, 24) => 0.0001
+(1, -1) ~ (3, 25) => 0.0001
+(1, -1) ~ (3, 26) => 0.0001
+(1, -1) ~ (3, 27) => 0.0001
+(1, -1) ~ (3, 28) => 0.0001
+(1, -1) ~ (3, 29) => 0.0001
+(1, -1) ~ (3, 30) => 0.0001
+(1, -1) ~ (3, 31) => 0.0001
+(1, -1) ~ (3, 32) => 0.0001
+(1, -1) ~ (3, 33) => 0.0001
+(1, -1) ~ (3, 34) => 0.0001
+(1, -1) ~ (3, 35) => 0.0001
+(1, -1) ~ (3, 36) => 0.0001
+(1, -1) ~ (3, 37) => 0.0001
+(1, -1) ~ (3, 38) => 0.0001
+(1, -1) ~ (3, 39) => 0.0001
+(1, -1) ~ (3, 40) => 0.000145018
+(1, -1) ~ (3, 41) => 0.00020802
+(1, -1) ~ (3, 42) => 0.000163794
+(1, -1) ~ (3, 43) => 0.0001
+(1, -1) ~ (3, 44) => 0.0001
+(1, -1) ~ (3, 45) => 0.0001
+(1, -1) ~ (3, 46) => 0.0001
+(1, -1) ~ (3, 47) => 0.0001
+(1, -1) ~ (3, 48) => 0.0001
+(1, -1) ~ (3, 49) => 0.000118256
+(1, -1) ~ (3, 50) => 0.000143111
+(1, -1) ~ (3, 51) => 0.000129104
+(1, -1) ~ (3, 52) => 0.0001
+(1, -1) ~ (3, 53) => 0.0001
+(1, -1) ~ (3, 54) => 0.0001
+(1, -1) ~ (3, 55) => 0.0001
+(1, -1) ~ (3, 56) => 0.0001
+(1, -1) ~ (3, 57) => 0.0001
+(1, -1) ~ (3, 58) => 0.0001
+(1, -1) ~ (3, 59) => 0.0001
+(1, -1) ~ (3, 60) => 0.0001
+(1, -1) ~ (3, 61) => 0.0001
+(1, -1) ~ (3, 62) => 0.0001
+(1, -1) ~ (3, 63) => 0.0001
+(1, -1) ~ (3, 64) => 0.0001
+(1, -1) ~ (3, 65) => 0.0001
+(1, -1) ~ (3, 66) => 0.000147581
+(1, -1) ~ (3, 67) => 0.0001688
+(1, -1) ~ (3, 68) => 0.00015825
+(1, -1) ~ (3, 69) => 0.0001
+(1, -1) ~ (3, 70) => 0.0001
+(1, -1) ~ (3, 71) => 0.0001
+(1, -1) ~ (3, 72) => 0.0001
+(1, -1) ~ (3, 73) => 0.0001
+(1, -1) ~ (3, 74) => 0.0001
+(1, -1) ~ (3, 75) => 0.0001
+(1, -1) ~ (3, 76) => 0.0001
+(1, -1) ~ (3, 77) => 0.0001
+(1, -1) ~ (3, 78) => 0.0001
+(1, -1) ~ (3, 79) => 0.0001
+(1, -1) ~ (3, 80) => 0.0001
+(1, -1) ~ (3, 81) => 0.0001
+(1, -1) ~ (3, 82) => 0.000962973
+(1, -1) ~ (3, 83) => 0.00129086
+(1, -1) ~ (3, 84) => 0.00322717
+(1, -1) ~ (3, 85) => 0.00342023
+(1, -1) ~ (3, 86) => 0.00352556
+(1, -1) ~ (3, 87) => 0.00344127
+(1, -1) ~ (3, 88) => 0.00291592
+(1, -1) ~ (3, 89) => 0.00282913
+(1, -1) ~ (3, 90) => 0.00157523
+(1, -1) ~ (3, 91) => 0.000919878
+(1, -1) ~ (3, 92) => 0.0001
+(1, -1) ~ (3, 93) => 0.0001
+(1, -1) ~ (3, 94) => 0.0001
+(1, -1) ~ (3, 95) => 0.0001
+(1, -1) ~ (3, 96) => 0.0001
+(1, -1) ~ (3, 97) => 0.0001
+(1, -1) ~ (3, 98) => 0.0001
+(1, -1) ~ (3, 99) => 0.0001
+(1, -1) ~ (3, 100) => 0.0001
+(1, -1) ~ (3, 101) => 0.000154793
+(1, -1) ~ (3, 102) => 0.000217736
+(1, -1) ~ (3, 103) => 0.000189364
+(1, -1) ~ (3, 104) => 0.000143766
+(1, -1) ~ (3, 105) => 0.0001
+(1, -1) ~ (3, 106) => 0.0001
+(1, -1) ~ (3, 107) => 0.0001
+(1, -1) ~ (3, 108) => 0.0001
+(1, -1) ~ (3, 109) => 0.0001
+(1, -1) ~ (3, 110) => 0.0001
+(1, -1) ~ (3, 111) => 0.0001
+(1, -1) ~ (3, 112) => 0.0001
+(1, -1) ~ (3, 113) => 0.0001
+(1, -1) ~ (3, 114) => 0.0001
+(1, -1) ~ (3, 115) => 0.0001
+(1, -1) ~ (3, 116) => 0.0001
+(1, -1) ~ (3, 117) => 0.0001
+(1, -1) ~ (3, 118) => 0.0001
+(1, -1) ~ (3, 119) => 0.0001
+(1, -1) ~ (3, 120) => 0.0001
+(1, -1) ~ (3, 121) => 0.0001
+(1, -1) ~ (3, 122) => 0.0001
+(1, -1) ~ (3, 123) => 0.0001
+(1, -1) ~ (3, 124) => 0.0001
+(1, -1) ~ (3, 125) => 0.0001
+(1, -1) ~ (3, 126) => 0.0001
+(1, -1) ~ (3, 127) => 0.0001
+(1, -1) ~ (3, 128) => 0.0001
+(1, -1) ~ (3, 129) => 0.0001
+(1, -1) ~ (3, 130) => 0.0001
+(1, -1) ~ (3, 131) => 0.000272691
+(1, -1) ~ (3, 132) => 0.000450253
+(1, -1) ~ (3, 133) => 0.000423312
+(1, -1) ~ (3, 134) => 0.0001
+(1, -1) ~ (3, 135) => 0.0001
+(1, -1) ~ (3, 136) => 0.0001
+(1, -1) ~ (3, 137) => 0.0001
+(1, -1) ~ (3, 138) => 0.0001
+(1, -1) ~ (3, 139) => 0.0001
+(1, -1) ~ (3, 140) => 0.000496149
+(1, -1) ~ (3, 141) => 0.000481963
+(1, -1) ~ (3, 142) => 0.0001
+(1, -1) ~ (3, 143) => 0.0001
+(1, -1) ~ (3, 144) => 0.0001
+(1, -1) ~ (3, 145) => 0.0001
+(1, -1) ~ (3, 146) => 0.0001
+(1, -1) ~ (3, 147) => 0.0001
+(1, -1) ~ (3, 148) => 0.0001
+(1, -1) ~ (3, 149) => 0.0001
+(1, -1) ~ (3, 150) => 0.0001
+(1, -1) ~ (3, 151) => 0.0001
+(1, -1) ~ (3, 152) => 0.0001
+(1, -1) ~ (3, 153) => 0.0001
+(1, -1) ~ (3, 154) => 0.0001
+(1, -1) ~ (3, 155) => 0.0001
+(1, -1) ~ (3, 156) => 0.0001
+(1, -1) ~ (3, 157) => 0.0001
+(1, -1) ~ (3, 158) => 0.0001
+(1, -1) ~ (3, 159) => 0.0001
+(1, -1) ~ (3, 160) => 0.0001
+(1, -1) ~ (3, 161) => 0.0001
+(1, -1) ~ (3, 162) => 0.000130057
+(1, -1) ~ (3, 163) => 0.000174046
+(1, -1) ~ (3, 164) => 0.000155568
+(1, -1) ~ (3, 165) => 0.0001
+(1, -1) ~ (3, 166) => 0.0001
+(1, -1) ~ (3, 167) => 0.0001
+(1, -1) ~ (3, 168) => 0.0001
+(1, -1) ~ (3, 169) => 0.0001
+(1, -1) ~ (3, 170) => 0.0001
+(1, -1) ~ (3, 171) => 0.0001
+(1, -1) ~ (3, 172) => 0.0001
+(1, -1) ~ (3, 173) => 0.0001
+(1, -1) ~ (3, 174) => 0.0001
+(1, -1) ~ (3, 175) => 0.0001
+(1, -1) ~ (3, 176) => 0.0001
+(1, -1) ~ (3, 177) => 0.0001
+(1, -1) ~ (3, 178) => 0.0001
+(1, -1) ~ (3, 179) => 0.0001
+(1, -1) ~ (3, 180) => 0.0001
+(1, -1) ~ (3, 181) => 0.0001
+(1, -1) ~ (3, 182) => 0.0001
+(1, -1) ~ (3, 183) => 0.0001
+(1, -1) ~ (3, 184) => 0.0001
+(1, -1) ~ (3, 185) => 0.0001
+(1, -1) ~ (3, 186) => 0.000113487
+(1, -1) ~ (3, 187) => 0.000193119
+(1, -1) ~ (3, 188) => 0.000307083
+(1, -1) ~ (3, 189) => 0.000892937
+(1, -1) ~ (3, 190) => 0.00903308
+(1, -1) ~ (3, 191) => 0.136889
+(1, -1) ~ (3, 192) => 0.280314
+(1, -1) ~ (3, 193) => 0.306029
+(1, -1) ~ (3, 194) => 0.614105
+(1, -1) ~ (3, 195) => 0.543868
+(1, -1) ~ (3, 196) => 0.100675
+(1, -1) ~ (3, 197) => 0.0146837
+(1, -1) ~ (3, 198) => 0.0143042
+(1, -1) ~ (3, 199) => 0.0309173
+(1, -1) ~ (3, 200) => 0.024559
+(1, -1) ~ (3, 201) => 0.00829947
+(1, -1) ~ (3, 202) => 0.00341988
+(1, -1) ~ (3, 203) => 0.000483453
+(1, -1) ~ (3, 204) => 0.000147283
+(1, -1) ~ (3, 205) => 0.0001
+(1, -1) ~ (3, 206) => 0.000104189
+(1, -1) ~ (3, 207) => 0.000131011
+(1, -1) ~ (3, 208) => 0.000158548
+(1, -1) ~ (3, 209) => 0.000204682
+(1, -1) ~ (3, 210) => 0.000133097
+(1, -1) ~ (3, 211) => 0.0001
+(1, -1) ~ (3, 212) => 0.0001
+(1, -1) ~ (3, 213) => 0.0001
+(1, -1) ~ (3, 214) => 0.0001
+(1, -1) ~ (3, 215) => 0.0001
+(1, -1) ~ (3, 216) => 0.0001
+(1, -1) ~ (3, 217) => 0.000287354
+(1, -1) ~ (3, 218) => 0.00350016
+(1, -1) ~ (3, 219) => 0.00661546
+(1, -1) ~ (3, 220) => 0.022149
+(1, -1) ~ (3, 221) => 0.0280874
+(1, -1) ~ (3, 222) => 0.135685
+(1, -1) ~ (3, 223) => 0.0402537
+(1, -1) ~ (3, 224) => 0.241387
+(1, -1) ~ (3, 225) => 0.245174
+(1, -1) ~ (3, 226) => 0.217543
+(1, -1) ~ (3, 227) => 0.112351
+(1, -1) ~ (3, 228) => 0.00425428
+(1, -1) ~ (3, 229) => 0.00186837
+(1, -1) ~ (3, 230) => 0.0001
+(1, -1) ~ (3, 231) => 0.0001
+(1, -1) ~ (3, 232) => 0.0001
+(1, -1) ~ (3, 233) => 0.0001
+(1, -1) ~ (3, 234) => 0.0001
+(1, -1) ~ (3, 235) => 0.0001
+(1, -1) ~ (3, 236) => 0.0001
+(1, -1) ~ (3, 237) => 0.0001
+(1, -1) ~ (3, 238) => 0.0001
+
+; Sparse posterior probability matrix for sequences 1 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (4, 0) => 0.994944
+(1, 1) ~ (4, 1) => 0.991771
+(1, 2) ~ (4, 2) => 0.98873
+(1, 3) ~ (4, 3) => 0.989058
+(1, 4) ~ (4, 4) => 0.987711
+(1, 5) ~ (4, 5) => 0.98873
+(1, 6) ~ (4, 6) => 0.986876
+(1, 7) ~ (4, 7) => 0.904069
+(1, 7) ~ (4, 9) => 0.0912081
+(1, 8) ~ (4, 8) => 0.694731
+(1, 8) ~ (4, 10) => 0.300541
+(1, 9) ~ (4, 9) => 0.685606
+(1, 9) ~ (4, 11) => 0.308914
+(1, 10) ~ (4, 10) => 0.66876
+(1, 10) ~ (4, 12) => 0.323109
+(1, 11) ~ (4, 11) => 0.663041
+(1, 11) ~ (4, 13) => 0.318723
+(1, 12) ~ (4, 12) => 0.647839
+(1, 12) ~ (4, 13) => 0.0156041
+(1, 12) ~ (4, 14) => 0.316004
+(1, 13) ~ (4, 13) => 0.610506
+(1, 13) ~ (4, 14) => 0.0372699
+(1, 13) ~ (4, 15) => 0.326203
+(1, 13) ~ (4, 16) => 0.0138145
+(1, 14) ~ (4, 14) => 0.535987
+(1, 14) ~ (4, 15) => 0.0720464
+(1, 14) ~ (4, 16) => 0.351931
+(1, 14) ~ (4, 17) => 0.0231614
+(1, 15) ~ (4, 15) => 0.483853
+(1, 15) ~ (4, 16) => 0.0924835
+(1, 15) ~ (4, 17) => 0.380851
+(1, 15) ~ (4, 18) => 0.0116282
+(1, 16) ~ (4, 16) => 0.420016
+(1, 16) ~ (4, 17) => 0.109448
+(1, 16) ~ (4, 18) => 0.439277
+(1, 17) ~ (4, 17) => 0.366106
+(1, 17) ~ (4, 18) => 0.0397265
+(1, 17) ~ (4, 19) => 0.565994
+(1, 18) ~ (4, 18) => 0.314945
+(1, 18) ~ (4, 20) => 0.662332
+(1, 19) ~ (4, 19) => 0.212978
+(1, 19) ~ (4, 21) => 0.770101
+(1, 20) ~ (4, 20) => 0.015187
+(1, 20) ~ (4, 22) => 0.981819
+(1, 21) ~ (4, 23) => 0.998723
+(1, 22) ~ (4, 24) => 0.99984
+(1, 23) ~ (4, 25) => 0.999651
+(1, 24) ~ (4, 26) => 0.999059
+(1, 25) ~ (4, 27) => 0.997627
+(1, 26) ~ (4, 28) => 0.996177
+(1, 27) ~ (4, 29) => 0.99038
+(1, 28) ~ (4, 30) => 0.987969
+(1, 29) ~ (4, 31) => 0.988904
+(1, 30) ~ (4, 32) => 0.993893
+(1, 31) ~ (4, 33) => 0.997115
+(1, 32) ~ (4, 34) => 0.998662
+(1, 33) ~ (4, 35) => 0.998147
+(1, 34) ~ (4, 36) => 0.997766
+(1, 35) ~ (4, 37) => 0.997975
+(1, 36) ~ (4, 38) => 0.997947
+(1, 37) ~ (4, 39) => 0.997963
+(1, 38) ~ (4, 40) => 0.998964
+(1, 39) ~ (4, 41) => 0.998773
+(1, 40) ~ (4, 42) => 0.997276
+(1, 41) ~ (4, 43) => 0.996895
+(1, 42) ~ (4, 44) => 0.995949
+(1, 43) ~ (4, 45) => 0.975381
+(1, 44) ~ (4, 45) => 0.0107168
+(1, 44) ~ (4, 46) => 0.955988
+(1, 45) ~ (4, 47) => 0.856988
+(1, 46) ~ (4, 46) => 0.0259819
+(1, 46) ~ (4, 47) => 0.011334
+(1, 46) ~ (4, 48) => 0.804507
+(1, 47) ~ (4, 47) => 0.113058
+(1, 47) ~ (4, 48) => 0.0170685
+(1, 47) ~ (4, 49) => 0.738338
+(1, 48) ~ (4, 48) => 0.15722
+(1, 48) ~ (4, 49) => 0.0236114
+(1, 48) ~ (4, 50) => 0.404766
+(1, 49) ~ (4, 49) => 0.21716
+(1, 49) ~ (4, 50) => 0.0104614
+(1, 49) ~ (4, 51) => 0.0997237
+(1, 50) ~ (4, 50) => 0.565035
+(1, 50) ~ (4, 51) => 0.0101291
+(1, 51) ~ (4, 51) => 0.876251
+(1, 52) ~ (4, 52) => 0.987023
+(1, 53) ~ (4, 53) => 0.996116
+(1, 54) ~ (4, 54) => 0.999647
+(1, 55) ~ (4, 55) => 0.999876
+(1, 56) ~ (4, 56) => 0.999851
+(1, 57) ~ (4, 57) => 0.999299
+(1, 58) ~ (4, 58) => 0.998963
+(1, 59) ~ (4, 59) => 0.998714
+(1, 60) ~ (4, 60) => 0.999196
+(1, 61) ~ (4, 61) => 0.999609
+(1, 62) ~ (4, 62) => 0.999533
+(1, 63) ~ (4, 63) => 0.99957
+(1, 64) ~ (4, 64) => 0.999883
+(1, 65) ~ (4, 65) => 0.999829
+(1, 66) ~ (4, 66) => 0.999434
+(1, 67) ~ (4, 67) => 0.999398
+(1, 68) ~ (4, 68) => 0.999831
+(1, 69) ~ (4, 69) => 0.999845
+(1, 70) ~ (4, 70) => 0.999077
+(1, 71) ~ (4, 71) => 0.998851
+(1, 72) ~ (4, 72) => 0.999237
+(1, 73) ~ (4, 73) => 0.999878
+(1, 74) ~ (4, 74) => 0.999906
+(1, 75) ~ (4, 75) => 0.99992
+(1, 76) ~ (4, 76) => 0.999714
+(1, 77) ~ (4, 77) => 0.998657
+(1, 78) ~ (4, 78) => 0.997165
+(1, 79) ~ (4, 79) => 0.967135
+(1, 80) ~ (4, 80) => 0.756688
+(1, 80) ~ (4, 81) => 0.0204138
+(1, 80) ~ (4, 84) => 0.0151265
+(1, 80) ~ (4, 86) => 0.0215564
+(1, 81) ~ (4, 80) => 0.0726278
+(1, 81) ~ (4, 81) => 0.571302
+(1, 81) ~ (4, 82) => 0.0104147
+(1, 81) ~ (4, 86) => 0.0105766
+(1, 81) ~ (4, 87) => 0.091539
+(1, 81) ~ (4, 88) => 0.0141562
+(1, 82) ~ (4, 81) => 0.144421
+(1, 82) ~ (4, 82) => 0.372116
+(1, 82) ~ (4, 84) => 0.023865
+(1, 82) ~ (4, 85) => 0.0137208
+(1, 82) ~ (4, 87) => 0.0166608
+(1, 82) ~ (4, 88) => 0.103474
+(1, 82) ~ (4, 89) => 0.0218947
+(1, 83) ~ (4, 80) => 0.0836311
+(1, 83) ~ (4, 82) => 0.136143
+(1, 83) ~ (4, 83) => 0.311751
+(1, 83) ~ (4, 85) => 0.0229525
+(1, 83) ~ (4, 86) => 0.0179798
+(1, 83) ~ (4, 88) => 0.0220569
+(1, 83) ~ (4, 89) => 0.090457
+(1, 83) ~ (4, 90) => 0.0370508
+(1, 84) ~ (4, 81) => 0.110818
+(1, 84) ~ (4, 83) => 0.12491
+(1, 84) ~ (4, 84) => 0.249541
+(1, 84) ~ (4, 85) => 0.0110579
+(1, 84) ~ (4, 86) => 0.0201665
+(1, 84) ~ (4, 87) => 0.0209943
+(1, 84) ~ (4, 89) => 0.0407234
+(1, 84) ~ (4, 90) => 0.0731161
+(1, 84) ~ (4, 91) => 0.0550254
+(1, 85) ~ (4, 82) => 0.265756
+(1, 85) ~ (4, 83) => 0.0111229
+(1, 85) ~ (4, 84) => 0.125586
+(1, 85) ~ (4, 85) => 0.233608
+(1, 85) ~ (4, 86) => 0.011643
+(1, 85) ~ (4, 87) => 0.0147802
+(1, 85) ~ (4, 88) => 0.0194274
+(1, 85) ~ (4, 90) => 0.0560704
+(1, 85) ~ (4, 91) => 0.0408148
+(1, 85) ~ (4, 92) => 0.0759568
+(1, 86) ~ (4, 83) => 0.312889
+(1, 86) ~ (4, 84) => 0.0100508
+(1, 86) ~ (4, 85) => 0.124365
+(1, 86) ~ (4, 86) => 0.19157
+(1, 86) ~ (4, 87) => 0.0157939
+(1, 86) ~ (4, 89) => 0.0202675
+(1, 86) ~ (4, 91) => 0.0815018
+(1, 86) ~ (4, 92) => 0.0220477
+(1, 86) ~ (4, 93) => 0.0987517
+(1, 87) ~ (4, 84) => 0.344397
+(1, 87) ~ (4, 86) => 0.125319
+(1, 87) ~ (4, 87) => 0.117103
+(1, 87) ~ (4, 88) => 0.0209876
+(1, 87) ~ (4, 90) => 0.0189649
+(1, 87) ~ (4, 92) => 0.0978522
+(1, 87) ~ (4, 93) => 0.013058
+(1, 87) ~ (4, 94) => 0.126188
+(1, 87) ~ (4, 95) => 0.0106016
+(1, 88) ~ (4, 85) => 0.353723
+(1, 88) ~ (4, 86) => 0.0131415
+(1, 88) ~ (4, 87) => 0.163172
+(1, 88) ~ (4, 88) => 0.0870018
+(1, 88) ~ (4, 89) => 0.0239416
+(1, 88) ~ (4, 91) => 0.0180844
+(1, 88) ~ (4, 93) => 0.0911661
+(1, 88) ~ (4, 95) => 0.144103
+(1, 88) ~ (4, 96) => 0.0102504
+(1, 89) ~ (4, 86) => 0.367954
+(1, 89) ~ (4, 87) => 0.0157616
+(1, 89) ~ (4, 88) => 0.171932
+(1, 89) ~ (4, 89) => 0.0651024
+(1, 89) ~ (4, 90) => 0.0255847
+(1, 89) ~ (4, 92) => 0.0159161
+(1, 89) ~ (4, 94) => 0.0662331
+(1, 89) ~ (4, 96) => 0.189146
+(1, 90) ~ (4, 87) => 0.384164
+(1, 90) ~ (4, 89) => 0.178715
+(1, 90) ~ (4, 90) => 0.0500917
+(1, 90) ~ (4, 91) => 0.0285306
+(1, 90) ~ (4, 93) => 0.0180759
+(1, 90) ~ (4, 95) => 0.0587357
+(1, 90) ~ (4, 97) => 0.207322
+(1, 91) ~ (4, 88) => 0.402651
+(1, 91) ~ (4, 90) => 0.188699
+(1, 91) ~ (4, 92) => 0.0351395
+(1, 91) ~ (4, 94) => 0.0188186
+(1, 91) ~ (4, 96) => 0.0605687
+(1, 91) ~ (4, 98) => 0.198561
+(1, 92) ~ (4, 89) => 0.39923
+(1, 92) ~ (4, 91) => 0.234962
+(1, 92) ~ (4, 93) => 0.0390534
+(1, 92) ~ (4, 95) => 0.0104074
+(1, 92) ~ (4, 97) => 0.0706072
+(1, 92) ~ (4, 99) => 0.158063
+(1, 93) ~ (4, 90) => 0.354564
+(1, 93) ~ (4, 92) => 0.231229
+(1, 93) ~ (4, 94) => 0.0787084
+(1, 93) ~ (4, 98) => 0.0995316
+(1, 93) ~ (4, 100) => 0.0509368
+(1, 94) ~ (4, 91) => 0.343578
+(1, 94) ~ (4, 93) => 0.100987
+(1, 94) ~ (4, 95) => 0.182099
+(1, 94) ~ (4, 99) => 0.169112
+(1, 94) ~ (4, 100) => 0.0302867
+(1, 94) ~ (4, 101) => 0.0344248
+(1, 95) ~ (4, 92) => 0.151725
+(1, 95) ~ (4, 94) => 0.0302835
+(1, 95) ~ (4, 96) => 0.439087
+(1, 95) ~ (4, 99) => 0.0103353
+(1, 95) ~ (4, 100) => 0.204526
+(1, 95) ~ (4, 101) => 0.0226278
+(1, 95) ~ (4, 102) => 0.0120776
+(1, 96) ~ (4, 93) => 0.118836
+(1, 96) ~ (4, 97) => 0.509981
+(1, 96) ~ (4, 101) => 0.163545
+(1, 96) ~ (4, 102) => 0.0110317
+(1, 97) ~ (4, 94) => 0.109462
+(1, 97) ~ (4, 98) => 0.510742
+(1, 97) ~ (4, 99) => 0.0197235
+(1, 97) ~ (4, 102) => 0.118364
+(1, 98) ~ (4, 95) => 0.0693256
+(1, 98) ~ (4, 99) => 0.451715
+(1, 98) ~ (4, 100) => 0.158207
+(1, 98) ~ (4, 103) => 0.0726801
+(1, 99) ~ (4, 96) => 0.049504
+(1, 99) ~ (4, 100) => 0.392911
+(1, 99) ~ (4, 101) => 0.297157
+(1, 99) ~ (4, 104) => 0.0331294
+(1, 100) ~ (4, 97) => 0.0314265
+(1, 100) ~ (4, 101) => 0.323625
+(1, 100) ~ (4, 102) => 0.460553
+(1, 100) ~ (4, 105) => 0.0228735
+(1, 101) ~ (4, 98) => 0.0117964
+(1, 101) ~ (4, 101) => 0.0163475
+(1, 101) ~ (4, 102) => 0.204806
+(1, 101) ~ (4, 103) => 0.659237
+(1, 102) ~ (4, 102) => 0.0265446
+(1, 102) ~ (4, 103) => 0.139869
+(1, 102) ~ (4, 104) => 0.779827
+(1, 103) ~ (4, 104) => 0.0686504
+(1, 103) ~ (4, 105) => 0.887088
+(1, 104) ~ (4, 106) => 0.980378
+(1, 105) ~ (4, 107) => 0.989012
+(1, 106) ~ (4, 108) => 0.994685
+(1, 107) ~ (4, 109) => 0.999768
+(1, 108) ~ (4, 110) => 0.999934
+(1, 109) ~ (4, 111) => 0.99998
+(1, 110) ~ (4, 112) => 0.999988
+(1, 111) ~ (4, 113) => 0.999962
+(1, 112) ~ (4, 114) => 0.999857
+(1, 113) ~ (4, 115) => 0.999829
+(1, 114) ~ (4, 116) => 0.999655
+(1, 115) ~ (4, 117) => 0.99962
+(1, 116) ~ (4, 118) => 0.999656
+(1, 117) ~ (4, 119) => 0.999818
+(1, 118) ~ (4, 120) => 0.999846
+(1, 119) ~ (4, 121) => 0.998998
+(1, 120) ~ (4, 122) => 0.998401
+(1, 121) ~ (4, 123) => 0.998428
+(1, 122) ~ (4, 124) => 0.999184
+(1, 123) ~ (4, 125) => 0.999443
+(1, 124) ~ (4, 126) => 0.996138
+(1, 125) ~ (4, 127) => 0.992652
+(1, 126) ~ (4, 128) => 0.993218
+(1, 127) ~ (4, 129) => 0.99101
+(1, 128) ~ (4, 130) => 0.906329
+(1, 128) ~ (4, 131) => 0.0147104
+(1, 129) ~ (4, 130) => 0.0135658
+(1, 129) ~ (4, 131) => 0.799308
+(1, 129) ~ (4, 132) => 0.0333574
+(1, 130) ~ (4, 130) => 0.0149936
+(1, 130) ~ (4, 131) => 0.0315317
+(1, 130) ~ (4, 132) => 0.6575
+(1, 130) ~ (4, 133) => 0.0439649
+(1, 130) ~ (4, 134) => 0.0233695
+(1, 130) ~ (4, 136) => 0.0106776
+(1, 131) ~ (4, 131) => 0.0282151
+(1, 131) ~ (4, 132) => 0.04486
+(1, 131) ~ (4, 133) => 0.515255
+(1, 131) ~ (4, 134) => 0.0977739
+(1, 131) ~ (4, 135) => 0.0421064
+(1, 131) ~ (4, 137) => 0.0116969
+(1, 132) ~ (4, 130) => 0.0267767
+(1, 132) ~ (4, 132) => 0.0742505
+(1, 132) ~ (4, 133) => 0.0609106
+(1, 132) ~ (4, 134) => 0.409821
+(1, 132) ~ (4, 135) => 0.0631348
+(1, 132) ~ (4, 136) => 0.0620993
+(1, 132) ~ (4, 138) => 0.0150662
+(1, 133) ~ (4, 131) => 0.0674515
+(1, 133) ~ (4, 133) => 0.120302
+(1, 133) ~ (4, 134) => 0.125145
+(1, 133) ~ (4, 135) => 0.314001
+(1, 133) ~ (4, 136) => 0.045285
+(1, 133) ~ (4, 137) => 0.0659222
+(1, 133) ~ (4, 139) => 0.0133682
+(1, 134) ~ (4, 132) => 0.117461
+(1, 134) ~ (4, 134) => 0.137658
+(1, 134) ~ (4, 135) => 0.214616
+(1, 134) ~ (4, 136) => 0.189129
+(1, 134) ~ (4, 137) => 0.0155879
+(1, 134) ~ (4, 138) => 0.0771059
+(1, 135) ~ (4, 133) => 0.106526
+(1, 135) ~ (4, 135) => 0.171764
+(1, 135) ~ (4, 136) => 0.354566
+(1, 135) ~ (4, 137) => 0.0695191
+(1, 135) ~ (4, 138) => 0.0123262
+(1, 135) ~ (4, 139) => 0.0879259
+(1, 136) ~ (4, 134) => 0.071584
+(1, 136) ~ (4, 136) => 0.104525
+(1, 136) ~ (4, 137) => 0.601234
+(1, 136) ~ (4, 138) => 0.0468989
+(1, 136) ~ (4, 139) => 0.0114798
+(1, 136) ~ (4, 140) => 0.0991672
+(1, 137) ~ (4, 135) => 0.0675154
+(1, 137) ~ (4, 137) => 0.110424
+(1, 137) ~ (4, 138) => 0.610069
+(1, 137) ~ (4, 139) => 0.04448
+(1, 137) ~ (4, 141) => 0.0650784
+(1, 138) ~ (4, 136) => 0.0619842
+(1, 138) ~ (4, 138) => 0.124434
+(1, 138) ~ (4, 139) => 0.627822
+(1, 138) ~ (4, 140) => 0.0253922
+(1, 138) ~ (4, 142) => 0.0511871
+(1, 139) ~ (4, 137) => 0.0375905
+(1, 139) ~ (4, 139) => 0.0739111
+(1, 139) ~ (4, 140) => 0.736601
+(1, 139) ~ (4, 141) => 0.0187119
+(1, 139) ~ (4, 143) => 0.0215202
+(1, 140) ~ (4, 138) => 0.01357
+(1, 140) ~ (4, 140) => 0.0185252
+(1, 140) ~ (4, 141) => 0.869013
+(1, 141) ~ (4, 142) => 0.925201
+(1, 142) ~ (4, 143) => 0.966595
+(1, 143) ~ (4, 144) => 0.998669
+(1, 144) ~ (4, 145) => 0.998798
+(1, 145) ~ (4, 146) => 0.999012
+(1, 146) ~ (4, 147) => 0.999761
+(1, 147) ~ (4, 148) => 0.999983
+(1, 148) ~ (4, 149) => 0.999992
+(1, 149) ~ (4, 150) => 0.999958
+(1, 150) ~ (4, 151) => 0.999549
+(1, 151) ~ (4, 152) => 0.999144
+(1, 152) ~ (4, 153) => 0.999207
+(1, 153) ~ (4, 154) => 0.999756
+(1, 154) ~ (4, 155) => 0.999914
+(1, 155) ~ (4, 156) => 0.999751
+(1, 156) ~ (4, 157) => 0.999685
+(1, 157) ~ (4, 158) => 0.999433
+(1, 158) ~ (4, 159) => 0.997397
+(1, 159) ~ (4, 160) => 0.995658
+(1, 160) ~ (4, 161) => 0.995048
+(1, 161) ~ (4, 162) => 0.994523
+(1, 162) ~ (4, 163) => 0.994902
+(1, 163) ~ (4, 164) => 0.994897
+(1, 164) ~ (4, 165) => 0.994414
+(1, 165) ~ (4, 166) => 0.995912
+(1, 166) ~ (4, 167) => 0.997012
+(1, 167) ~ (4, 168) => 0.997407
+(1, 168) ~ (4, 169) => 0.997563
+(1, 169) ~ (4, 170) => 0.997727
+(1, 170) ~ (4, 171) => 0.997693
+(1, 171) ~ (4, 172) => 0.998681
+(1, 172) ~ (4, 173) => 0.999854
+(1, 173) ~ (4, 174) => 0.999986
+(1, 174) ~ (4, 175) => 0.999981
+(1, 175) ~ (4, 176) => 0.999385
+(1, 176) ~ (4, 177) => 0.999157
+(1, 177) ~ (4, 178) => 0.999241
+(1, 178) ~ (4, 179) => 0.999388
+(1, 179) ~ (4, 180) => 0.999915
+(1, 180) ~ (4, 181) => 0.999972
+(1, 181) ~ (4, 182) => 0.999927
+(1, 182) ~ (4, 183) => 0.999227
+(1, 183) ~ (4, 184) => 0.99855
+(1, 184) ~ (4, 185) => 0.967167
+(1, 184) ~ (4, 186) => 0.0319884
+(1, 185) ~ (4, 186) => 0.9359
+(1, 185) ~ (4, 187) => 0.0625334
+(1, 186) ~ (4, 187) => 0.90218
+(1, 186) ~ (4, 188) => 0.0929544
+(1, 187) ~ (4, 188) => 0.782807
+(1, 187) ~ (4, 189) => 0.201041
+(1, 187) ~ (4, 190) => 0.0139164
+(1, 188) ~ (4, 189) => 0.653543
+(1, 188) ~ (4, 190) => 0.308075
+(1, 188) ~ (4, 191) => 0.0338042
+(1, 189) ~ (4, 190) => 0.559118
+(1, 189) ~ (4, 191) => 0.392585
+(1, 189) ~ (4, 192) => 0.0358691
+(1, 190) ~ (4, 191) => 0.496492
+(1, 190) ~ (4, 192) => 0.447633
+(1, 190) ~ (4, 193) => 0.0346356
+(1, 191) ~ (4, 192) => 0.443553
+(1, 191) ~ (4, 193) => 0.502776
+(1, 191) ~ (4, 194) => 0.0243296
+(1, 192) ~ (4, 193) => 0.0208528
+(1, 192) ~ (4, 194) => 0.945434
+(1, 193) ~ (4, 194) => 0.0114323
+(1, 193) ~ (4, 195) => 0.970704
+(1, 194) ~ (4, 196) => 0.979842
+(1, 195) ~ (4, 197) => 0.984163
+(1, 196) ~ (4, 198) => 0.984022
+(1, 197) ~ (4, 199) => 0.986753
+(1, 198) ~ (4, 200) => 0.989447
+(1, 199) ~ (4, 201) => 0.991588
+(1, 200) ~ (4, 202) => 0.992196
+(1, 201) ~ (4, 203) => 0.991872
+(1, 202) ~ (4, 204) => 0.99389
+(1, 203) ~ (4, 205) => 0.996707
+(1, 204) ~ (4, 206) => 0.998942
+(1, 205) ~ (4, 207) => 0.99975
+(1, 206) ~ (4, 208) => 0.999508
+(1, 207) ~ (4, 209) => 0.999192
+(1, 208) ~ (4, 210) => 0.999208
+(1, 209) ~ (4, 211) => 0.997871
+(1, 210) ~ (4, 212) => 0.984271
+(1, 210) ~ (4, 214) => 0.0113453
+(1, 211) ~ (4, 213) => 0.952313
+(1, 211) ~ (4, 215) => 0.0355963
+(1, 212) ~ (4, 214) => 0.920626
+(1, 212) ~ (4, 216) => 0.0605931
+(1, 213) ~ (4, 215) => 0.866341
+(1, 213) ~ (4, 217) => 0.10942
+(1, 214) ~ (4, 216) => 0.829978
+(1, 214) ~ (4, 218) => 0.146675
+(1, 215) ~ (4, 217) => 0.795447
+(1, 215) ~ (4, 219) => 0.184237
+(1, 216) ~ (4, 218) => 0.659993
+(1, 216) ~ (4, 220) => 0.313407
+(1, 216) ~ (4, 221) => 0.0186496
+(1, 217) ~ (4, 219) => 0.613031
+(1, 217) ~ (4, 221) => 0.353923
+(1, 217) ~ (4, 222) => 0.0241244
+(1, 218) ~ (4, 220) => 0.146149
+(1, 218) ~ (4, 222) => 0.816324
+(1, 218) ~ (4, 223) => 0.0208099
+(1, 219) ~ (4, 221) => 0.0285838
+(1, 219) ~ (4, 223) => 0.939567
+(1, 219) ~ (4, 224) => 0.0122971
+(1, 220) ~ (4, 222) => 0.0149912
+(1, 220) ~ (4, 224) => 0.966694
+(1, 221) ~ (4, 225) => 0.99623
+(1, 222) ~ (4, 226) => 0.999296
+(1, 223) ~ (4, 227) => 0.999893
+(1, 224) ~ (4, 228) => 0.999964
+(1, 225) ~ (4, 229) => 0.999972
+(1, 226) ~ (4, 230) => 0.999717
+(1, 227) ~ (4, 231) => 0.998467
+(1, 228) ~ (4, 232) => 0.998261
+(1, 229) ~ (4, 233) => 0.995957
+(1, 230) ~ (4, 234) => 0.994618
+(1, 231) ~ (4, 235) => 0.993542
+(1, 232) ~ (4, 236) => 0.994169
+(1, 233) ~ (4, 237) => 0.995455
+
+; gap posteriors
+(1, 0) ~ (4, -1) => 0.00505596
+(1, 1) ~ (4, -1) => 0.0082289
+(1, 2) ~ (4, -1) => 0.0112702
+(1, 3) ~ (4, -1) => 0.0109421
+(1, 4) ~ (4, -1) => 0.0122889
+(1, 5) ~ (4, -1) => 0.0112699
+(1, 6) ~ (4, -1) => 0.013124
+(1, 7) ~ (4, -1) => 0.0047228
+(1, 8) ~ (4, -1) => 0.00472772
+(1, 9) ~ (4, -1) => 0.00547948
+(1, 10) ~ (4, -1) => 0.00813046
+(1, 11) ~ (4, -1) => 0.0182358
+(1, 12) ~ (4, -1) => 0.0205531
+(1, 13) ~ (4, -1) => 0.0122073
+(1, 14) ~ (4, -1) => 0.0168737
+(1, 15) ~ (4, -1) => 0.0311842
+(1, 16) ~ (4, -1) => 0.0312586
+(1, 17) ~ (4, -1) => 0.0281737
+(1, 18) ~ (4, -1) => 0.0227236
+(1, 19) ~ (4, -1) => 0.016921
+(1, 20) ~ (4, -1) => 0.00299442
+(1, 21) ~ (4, -1) => 0.00127733
+(1, 22) ~ (4, -1) => 0.000160456
+(1, 23) ~ (4, -1) => 0.000348747
+(1, 24) ~ (4, -1) => 0.000940979
+(1, 25) ~ (4, -1) => 0.0023731
+(1, 26) ~ (4, -1) => 0.00382298
+(1, 27) ~ (4, -1) => 0.00962013
+(1, 28) ~ (4, -1) => 0.0120308
+(1, 29) ~ (4, -1) => 0.0110959
+(1, 30) ~ (4, -1) => 0.00610745
+(1, 31) ~ (4, -1) => 0.00288498
+(1, 32) ~ (4, -1) => 0.00133806
+(1, 33) ~ (4, -1) => 0.00185341
+(1, 34) ~ (4, -1) => 0.00223428
+(1, 35) ~ (4, -1) => 0.00202477
+(1, 36) ~ (4, -1) => 0.00205302
+(1, 37) ~ (4, -1) => 0.00203729
+(1, 38) ~ (4, -1) => 0.00103605
+(1, 39) ~ (4, -1) => 0.00122696
+(1, 40) ~ (4, -1) => 0.00272393
+(1, 41) ~ (4, -1) => 0.00310528
+(1, 42) ~ (4, -1) => 0.00405145
+(1, 43) ~ (4, -1) => 0.0246195
+(1, 44) ~ (4, -1) => 0.0332953
+(1, 45) ~ (4, -1) => 0.143012
+(1, 46) ~ (4, -1) => 0.158177
+(1, 47) ~ (4, -1) => 0.131536
+(1, 48) ~ (4, -1) => 0.414403
+(1, 49) ~ (4, -1) => 0.672655
+(1, 50) ~ (4, -1) => 0.424835
+(1, 51) ~ (4, -1) => 0.123749
+(1, 52) ~ (4, -1) => 0.0129771
+(1, 53) ~ (4, -1) => 0.00388378
+(1, 54) ~ (4, -1) => 0.000353277
+(1, 55) ~ (4, -1) => 0.000124097
+(1, 56) ~ (4, -1) => 0.000149369
+(1, 57) ~ (4, -1) => 0.000700772
+(1, 58) ~ (4, -1) => 0.00103742
+(1, 59) ~ (4, -1) => 0.00128621
+(1, 60) ~ (4, -1) => 0.000804067
+(1, 61) ~ (4, -1) => 0.000391304
+(1, 62) ~ (4, -1) => 0.000467181
+(1, 63) ~ (4, -1) => 0.000430107
+(1, 64) ~ (4, -1) => 0.000117242
+(1, 65) ~ (4, -1) => 0.000171423
+(1, 66) ~ (4, -1) => 0.000565886
+(1, 67) ~ (4, -1) => 0.000602186
+(1, 68) ~ (4, -1) => 0.000169039
+(1, 69) ~ (4, -1) => 0.000154674
+(1, 70) ~ (4, -1) => 0.000923455
+(1, 71) ~ (4, -1) => 0.00114882
+(1, 72) ~ (4, -1) => 0.000763237
+(1, 73) ~ (4, -1) => 0.00012207
+(1, 74) ~ (4, -1) => 0.0001
+(1, 75) ~ (4, -1) => 0.0001
+(1, 76) ~ (4, -1) => 0.000285804
+(1, 77) ~ (4, -1) => 0.00134259
+(1, 78) ~ (4, -1) => 0.00283498
+(1, 79) ~ (4, -1) => 0.0328649
+(1, 80) ~ (4, -1) => 0.186215
+(1, 81) ~ (4, -1) => 0.229384
+(1, 82) ~ (4, -1) => 0.303848
+(1, 83) ~ (4, -1) => 0.277978
+(1, 84) ~ (4, -1) => 0.293647
+(1, 85) ~ (4, -1) => 0.145235
+(1, 86) ~ (4, -1) => 0.122763
+(1, 87) ~ (4, -1) => 0.125528
+(1, 88) ~ (4, -1) => 0.0954174
+(1, 89) ~ (4, -1) => 0.0823698
+(1, 90) ~ (4, -1) => 0.0743653
+(1, 91) ~ (4, -1) => 0.0955611
+(1, 92) ~ (4, -1) => 0.0876763
+(1, 93) ~ (4, -1) => 0.18503
+(1, 94) ~ (4, -1) => 0.139513
+(1, 95) ~ (4, -1) => 0.129337
+(1, 96) ~ (4, -1) => 0.196606
+(1, 97) ~ (4, -1) => 0.241708
+(1, 98) ~ (4, -1) => 0.248072
+(1, 99) ~ (4, -1) => 0.227298
+(1, 100) ~ (4, -1) => 0.161523
+(1, 101) ~ (4, -1) => 0.107813
+(1, 102) ~ (4, -1) => 0.0537594
+(1, 103) ~ (4, -1) => 0.0442619
+(1, 104) ~ (4, -1) => 0.0196223
+(1, 105) ~ (4, -1) => 0.0109875
+(1, 106) ~ (4, -1) => 0.00531483
+(1, 107) ~ (4, -1) => 0.00023222
+(1, 108) ~ (4, -1) => 0.0001
+(1, 109) ~ (4, -1) => 0.0001
+(1, 110) ~ (4, -1) => 0.0001
+(1, 111) ~ (4, -1) => 0.0001
+(1, 112) ~ (4, -1) => 0.00014323
+(1, 113) ~ (4, -1) => 0.000171304
+(1, 114) ~ (4, -1) => 0.000344515
+(1, 115) ~ (4, -1) => 0.000379741
+(1, 116) ~ (4, -1) => 0.0003438
+(1, 117) ~ (4, -1) => 0.000181675
+(1, 118) ~ (4, -1) => 0.000153899
+(1, 119) ~ (4, -1) => 0.00100213
+(1, 120) ~ (4, -1) => 0.00159895
+(1, 121) ~ (4, -1) => 0.00157166
+(1, 122) ~ (4, -1) => 0.000816047
+(1, 123) ~ (4, -1) => 0.000556588
+(1, 124) ~ (4, -1) => 0.00386232
+(1, 125) ~ (4, -1) => 0.0073477
+(1, 126) ~ (4, -1) => 0.00678247
+(1, 127) ~ (4, -1) => 0.00898993
+(1, 128) ~ (4, -1) => 0.0789605
+(1, 129) ~ (4, -1) => 0.153769
+(1, 130) ~ (4, -1) => 0.217962
+(1, 131) ~ (4, -1) => 0.260093
+(1, 132) ~ (4, -1) => 0.287941
+(1, 133) ~ (4, -1) => 0.248525
+(1, 134) ~ (4, -1) => 0.248442
+(1, 135) ~ (4, -1) => 0.197373
+(1, 136) ~ (4, -1) => 0.0651105
+(1, 137) ~ (4, -1) => 0.102433
+(1, 138) ~ (4, -1) => 0.109181
+(1, 139) ~ (4, -1) => 0.111665
+(1, 140) ~ (4, -1) => 0.0988922
+(1, 141) ~ (4, -1) => 0.0747992
+(1, 142) ~ (4, -1) => 0.0334051
+(1, 143) ~ (4, -1) => 0.00133097
+(1, 144) ~ (4, -1) => 0.00120211
+(1, 145) ~ (4, -1) => 0.000988066
+(1, 146) ~ (4, -1) => 0.000238538
+(1, 147) ~ (4, -1) => 0.0001
+(1, 148) ~ (4, -1) => 0.0001
+(1, 149) ~ (4, -1) => 0.0001
+(1, 150) ~ (4, -1) => 0.000451267
+(1, 151) ~ (4, -1) => 0.000855923
+(1, 152) ~ (4, -1) => 0.000792801
+(1, 153) ~ (4, -1) => 0.000243545
+(1, 154) ~ (4, -1) => 0.0001
+(1, 155) ~ (4, -1) => 0.000248611
+(1, 156) ~ (4, -1) => 0.000314891
+(1, 157) ~ (4, -1) => 0.000566661
+(1, 158) ~ (4, -1) => 0.00260347
+(1, 159) ~ (4, -1) => 0.0043416
+(1, 160) ~ (4, -1) => 0.00495237
+(1, 161) ~ (4, -1) => 0.00547743
+(1, 162) ~ (4, -1) => 0.00509775
+(1, 163) ~ (4, -1) => 0.00510311
+(1, 164) ~ (4, -1) => 0.00558627
+(1, 165) ~ (4, -1) => 0.00408834
+(1, 166) ~ (4, -1) => 0.00298822
+(1, 167) ~ (4, -1) => 0.00259256
+(1, 168) ~ (4, -1) => 0.002437
+(1, 169) ~ (4, -1) => 0.0022735
+(1, 170) ~ (4, -1) => 0.0023067
+(1, 171) ~ (4, -1) => 0.00131947
+(1, 172) ~ (4, -1) => 0.000145912
+(1, 173) ~ (4, -1) => 0.0001
+(1, 174) ~ (4, -1) => 0.0001
+(1, 175) ~ (4, -1) => 0.000614524
+(1, 176) ~ (4, -1) => 0.00084269
+(1, 177) ~ (4, -1) => 0.000758886
+(1, 178) ~ (4, -1) => 0.000611544
+(1, 179) ~ (4, -1) => 0.0001
+(1, 180) ~ (4, -1) => 0.0001
+(1, 181) ~ (4, -1) => 0.0001
+(1, 182) ~ (4, -1) => 0.00077343
+(1, 183) ~ (4, -1) => 0.00145036
+(1, 184) ~ (4, -1) => 0.00084468
+(1, 185) ~ (4, -1) => 0.0015666
+(1, 186) ~ (4, -1) => 0.00486531
+(1, 187) ~ (4, -1) => 0.0022357
+(1, 188) ~ (4, -1) => 0.00457769
+(1, 189) ~ (4, -1) => 0.0124275
+(1, 190) ~ (4, -1) => 0.021239
+(1, 191) ~ (4, -1) => 0.0293408
+(1, 192) ~ (4, -1) => 0.0337133
+(1, 193) ~ (4, -1) => 0.017864
+(1, 194) ~ (4, -1) => 0.0201579
+(1, 195) ~ (4, -1) => 0.0158369
+(1, 196) ~ (4, -1) => 0.0159778
+(1, 197) ~ (4, -1) => 0.0132467
+(1, 198) ~ (4, -1) => 0.010553
+(1, 199) ~ (4, -1) => 0.00841218
+(1, 200) ~ (4, -1) => 0.00780421
+(1, 201) ~ (4, -1) => 0.0081284
+(1, 202) ~ (4, -1) => 0.0061096
+(1, 203) ~ (4, -1) => 0.00329334
+(1, 204) ~ (4, -1) => 0.00105816
+(1, 205) ~ (4, -1) => 0.000249743
+(1, 206) ~ (4, -1) => 0.000492454
+(1, 207) ~ (4, -1) => 0.000807583
+(1, 208) ~ (4, -1) => 0.000791788
+(1, 209) ~ (4, -1) => 0.00212926
+(1, 210) ~ (4, -1) => 0.00438351
+(1, 211) ~ (4, -1) => 0.0120902
+(1, 212) ~ (4, -1) => 0.0187811
+(1, 213) ~ (4, -1) => 0.0242385
+(1, 214) ~ (4, -1) => 0.0233469
+(1, 215) ~ (4, -1) => 0.0203169
+(1, 216) ~ (4, -1) => 0.00795005
+(1, 217) ~ (4, -1) => 0.00892122
+(1, 218) ~ (4, -1) => 0.0167171
+(1, 219) ~ (4, -1) => 0.0195522
+(1, 220) ~ (4, -1) => 0.0183151
+(1, 221) ~ (4, -1) => 0.00376999
+(1, 222) ~ (4, -1) => 0.000703633
+(1, 223) ~ (4, -1) => 0.000107408
+(1, 224) ~ (4, -1) => 0.0001
+(1, 225) ~ (4, -1) => 0.0001
+(1, 226) ~ (4, -1) => 0.000282764
+(1, 227) ~ (4, -1) => 0.00153261
+(1, 228) ~ (4, -1) => 0.00173867
+(1, 229) ~ (4, -1) => 0.00404304
+(1, 230) ~ (4, -1) => 0.00538242
+(1, 231) ~ (4, -1) => 0.00645834
+(1, 232) ~ (4, -1) => 0.00583088
+(1, 233) ~ (4, -1) => 0.00454479
+
+(1, -1) ~ (4, 0) => 0.00505596
+(1, -1) ~ (4, 1) => 0.0082289
+(1, -1) ~ (4, 2) => 0.0112702
+(1, -1) ~ (4, 3) => 0.0109421
+(1, -1) ~ (4, 4) => 0.0122889
+(1, -1) ~ (4, 5) => 0.0112699
+(1, -1) ~ (4, 6) => 0.013124
+(1, -1) ~ (4, 7) => 0.0959309
+(1, -1) ~ (4, 8) => 0.305269
+(1, -1) ~ (4, 9) => 0.223186
+(1, -1) ~ (4, 10) => 0.0306985
+(1, -1) ~ (4, 11) => 0.0280448
+(1, -1) ~ (4, 12) => 0.0290524
+(1, -1) ~ (4, 13) => 0.0551672
+(1, -1) ~ (4, 14) => 0.110738
+(1, -1) ~ (4, 15) => 0.117898
+(1, -1) ~ (4, 16) => 0.121754
+(1, -1) ~ (4, 17) => 0.120434
+(1, -1) ~ (4, 18) => 0.194424
+(1, -1) ~ (4, 19) => 0.221028
+(1, -1) ~ (4, 20) => 0.322481
+(1, -1) ~ (4, 21) => 0.229899
+(1, -1) ~ (4, 22) => 0.0181814
+(1, -1) ~ (4, 23) => 0.00127733
+(1, -1) ~ (4, 24) => 0.000160456
+(1, -1) ~ (4, 25) => 0.000348747
+(1, -1) ~ (4, 26) => 0.000940979
+(1, -1) ~ (4, 27) => 0.0023731
+(1, -1) ~ (4, 28) => 0.00382298
+(1, -1) ~ (4, 29) => 0.00962013
+(1, -1) ~ (4, 30) => 0.0120308
+(1, -1) ~ (4, 31) => 0.0110959
+(1, -1) ~ (4, 32) => 0.00610745
+(1, -1) ~ (4, 33) => 0.00288498
+(1, -1) ~ (4, 34) => 0.00133806
+(1, -1) ~ (4, 35) => 0.00185341
+(1, -1) ~ (4, 36) => 0.00223428
+(1, -1) ~ (4, 37) => 0.00202477
+(1, -1) ~ (4, 38) => 0.00205302
+(1, -1) ~ (4, 39) => 0.00203729
+(1, -1) ~ (4, 40) => 0.00103605
+(1, -1) ~ (4, 41) => 0.00122696
+(1, -1) ~ (4, 42) => 0.00272393
+(1, -1) ~ (4, 43) => 0.00310528
+(1, -1) ~ (4, 44) => 0.00405145
+(1, -1) ~ (4, 45) => 0.0139027
+(1, -1) ~ (4, 46) => 0.0180301
+(1, -1) ~ (4, 47) => 0.0186207
+(1, -1) ~ (4, 48) => 0.0212045
+(1, -1) ~ (4, 49) => 0.0208905
+(1, -1) ~ (4, 50) => 0.0197368
+(1, -1) ~ (4, 51) => 0.0138966
+(1, -1) ~ (4, 52) => 0.0129771
+(1, -1) ~ (4, 53) => 0.00388378
+(1, -1) ~ (4, 54) => 0.000353277
+(1, -1) ~ (4, 55) => 0.000124097
+(1, -1) ~ (4, 56) => 0.000149369
+(1, -1) ~ (4, 57) => 0.000700772
+(1, -1) ~ (4, 58) => 0.00103742
+(1, -1) ~ (4, 59) => 0.00128621
+(1, -1) ~ (4, 60) => 0.000804067
+(1, -1) ~ (4, 61) => 0.000391304
+(1, -1) ~ (4, 62) => 0.000467181
+(1, -1) ~ (4, 63) => 0.000430107
+(1, -1) ~ (4, 64) => 0.000117242
+(1, -1) ~ (4, 65) => 0.000171423
+(1, -1) ~ (4, 66) => 0.000565886
+(1, -1) ~ (4, 67) => 0.000602186
+(1, -1) ~ (4, 68) => 0.000169039
+(1, -1) ~ (4, 69) => 0.000154674
+(1, -1) ~ (4, 70) => 0.000923455
+(1, -1) ~ (4, 71) => 0.00114882
+(1, -1) ~ (4, 72) => 0.000763237
+(1, -1) ~ (4, 73) => 0.00012207
+(1, -1) ~ (4, 74) => 0.0001
+(1, -1) ~ (4, 75) => 0.0001
+(1, -1) ~ (4, 76) => 0.000285804
+(1, -1) ~ (4, 77) => 0.00134259
+(1, -1) ~ (4, 78) => 0.00283498
+(1, -1) ~ (4, 79) => 0.0328649
+(1, -1) ~ (4, 80) => 0.0870527
+(1, -1) ~ (4, 81) => 0.153046
+(1, -1) ~ (4, 82) => 0.21557
+(1, -1) ~ (4, 83) => 0.239327
+(1, -1) ~ (4, 84) => 0.231433
+(1, -1) ~ (4, 85) => 0.240573
+(1, -1) ~ (4, 86) => 0.220093
+(1, -1) ~ (4, 87) => 0.160031
+(1, -1) ~ (4, 88) => 0.158313
+(1, -1) ~ (4, 89) => 0.159668
+(1, -1) ~ (4, 90) => 0.195858
+(1, -1) ~ (4, 91) => 0.197503
+(1, -1) ~ (4, 92) => 0.370134
+(1, -1) ~ (4, 93) => 0.520072
+(1, -1) ~ (4, 94) => 0.570306
+(1, -1) ~ (4, 95) => 0.524728
+(1, -1) ~ (4, 96) => 0.251443
+(1, -1) ~ (4, 97) => 0.180663
+(1, -1) ~ (4, 98) => 0.179368
+(1, -1) ~ (4, 99) => 0.191051
+(1, -1) ~ (4, 100) => 0.163131
+(1, -1) ~ (4, 101) => 0.142273
+(1, -1) ~ (4, 102) => 0.166624
+(1, -1) ~ (4, 103) => 0.128214
+(1, -1) ~ (4, 104) => 0.118393
+(1, -1) ~ (4, 105) => 0.0900389
+(1, -1) ~ (4, 106) => 0.0196223
+(1, -1) ~ (4, 107) => 0.0109875
+(1, -1) ~ (4, 108) => 0.00531483
+(1, -1) ~ (4, 109) => 0.00023222
+(1, -1) ~ (4, 110) => 0.0001
+(1, -1) ~ (4, 111) => 0.0001
+(1, -1) ~ (4, 112) => 0.0001
+(1, -1) ~ (4, 113) => 0.0001
+(1, -1) ~ (4, 114) => 0.00014323
+(1, -1) ~ (4, 115) => 0.000171304
+(1, -1) ~ (4, 116) => 0.000344515
+(1, -1) ~ (4, 117) => 0.000379741
+(1, -1) ~ (4, 118) => 0.0003438
+(1, -1) ~ (4, 119) => 0.000181675
+(1, -1) ~ (4, 120) => 0.000153899
+(1, -1) ~ (4, 121) => 0.00100213
+(1, -1) ~ (4, 122) => 0.00159895
+(1, -1) ~ (4, 123) => 0.00157166
+(1, -1) ~ (4, 124) => 0.000816047
+(1, -1) ~ (4, 125) => 0.000556588
+(1, -1) ~ (4, 126) => 0.00386232
+(1, -1) ~ (4, 127) => 0.0073477
+(1, -1) ~ (4, 128) => 0.00678247
+(1, -1) ~ (4, 129) => 0.00898993
+(1, -1) ~ (4, 130) => 0.0383348
+(1, -1) ~ (4, 131) => 0.0587833
+(1, -1) ~ (4, 132) => 0.0725711
+(1, -1) ~ (4, 133) => 0.153042
+(1, -1) ~ (4, 134) => 0.134649
+(1, -1) ~ (4, 135) => 0.126863
+(1, -1) ~ (4, 136) => 0.171733
+(1, -1) ~ (4, 137) => 0.0880252
+(1, -1) ~ (4, 138) => 0.10053
+(1, -1) ~ (4, 139) => 0.141013
+(1, -1) ~ (4, 140) => 0.120314
+(1, -1) ~ (4, 141) => 0.047197
+(1, -1) ~ (4, 142) => 0.0236121
+(1, -1) ~ (4, 143) => 0.011885
+(1, -1) ~ (4, 144) => 0.00133097
+(1, -1) ~ (4, 145) => 0.00120211
+(1, -1) ~ (4, 146) => 0.000988066
+(1, -1) ~ (4, 147) => 0.000238538
+(1, -1) ~ (4, 148) => 0.0001
+(1, -1) ~ (4, 149) => 0.0001
+(1, -1) ~ (4, 150) => 0.0001
+(1, -1) ~ (4, 151) => 0.000451267
+(1, -1) ~ (4, 152) => 0.000855923
+(1, -1) ~ (4, 153) => 0.000792801
+(1, -1) ~ (4, 154) => 0.000243545
+(1, -1) ~ (4, 155) => 0.0001
+(1, -1) ~ (4, 156) => 0.000248611
+(1, -1) ~ (4, 157) => 0.000314891
+(1, -1) ~ (4, 158) => 0.000566661
+(1, -1) ~ (4, 159) => 0.00260347
+(1, -1) ~ (4, 160) => 0.0043416
+(1, -1) ~ (4, 161) => 0.00495237
+(1, -1) ~ (4, 162) => 0.00547743
+(1, -1) ~ (4, 163) => 0.00509775
+(1, -1) ~ (4, 164) => 0.00510311
+(1, -1) ~ (4, 165) => 0.00558627
+(1, -1) ~ (4, 166) => 0.00408834
+(1, -1) ~ (4, 167) => 0.00298822
+(1, -1) ~ (4, 168) => 0.00259256
+(1, -1) ~ (4, 169) => 0.002437
+(1, -1) ~ (4, 170) => 0.0022735
+(1, -1) ~ (4, 171) => 0.0023067
+(1, -1) ~ (4, 172) => 0.00131947
+(1, -1) ~ (4, 173) => 0.000145912
+(1, -1) ~ (4, 174) => 0.0001
+(1, -1) ~ (4, 175) => 0.0001
+(1, -1) ~ (4, 176) => 0.000614524
+(1, -1) ~ (4, 177) => 0.00084269
+(1, -1) ~ (4, 178) => 0.000758886
+(1, -1) ~ (4, 179) => 0.000611544
+(1, -1) ~ (4, 180) => 0.0001
+(1, -1) ~ (4, 181) => 0.0001
+(1, -1) ~ (4, 182) => 0.0001
+(1, -1) ~ (4, 183) => 0.00077343
+(1, -1) ~ (4, 184) => 0.00145036
+(1, -1) ~ (4, 185) => 0.032833
+(1, -1) ~ (4, 186) => 0.0321116
+(1, -1) ~ (4, 187) => 0.0352863
+(1, -1) ~ (4, 188) => 0.124239
+(1, -1) ~ (4, 189) => 0.145416
+(1, -1) ~ (4, 190) => 0.11889
+(1, -1) ~ (4, 191) => 0.0771186
+(1, -1) ~ (4, 192) => 0.0729445
+(1, -1) ~ (4, 193) => 0.441735
+(1, -1) ~ (4, 194) => 0.0188042
+(1, -1) ~ (4, 195) => 0.0292963
+(1, -1) ~ (4, 196) => 0.0201579
+(1, -1) ~ (4, 197) => 0.0158369
+(1, -1) ~ (4, 198) => 0.0159778
+(1, -1) ~ (4, 199) => 0.0132467
+(1, -1) ~ (4, 200) => 0.010553
+(1, -1) ~ (4, 201) => 0.00841218
+(1, -1) ~ (4, 202) => 0.00780421
+(1, -1) ~ (4, 203) => 0.0081284
+(1, -1) ~ (4, 204) => 0.0061096
+(1, -1) ~ (4, 205) => 0.00329334
+(1, -1) ~ (4, 206) => 0.00105816
+(1, -1) ~ (4, 207) => 0.000249743
+(1, -1) ~ (4, 208) => 0.000492454
+(1, -1) ~ (4, 209) => 0.000807583
+(1, -1) ~ (4, 210) => 0.000791788
+(1, -1) ~ (4, 211) => 0.00212926
+(1, -1) ~ (4, 212) => 0.0157288
+(1, -1) ~ (4, 213) => 0.0476865
+(1, -1) ~ (4, 214) => 0.0680289
+(1, -1) ~ (4, 215) => 0.0980626
+(1, -1) ~ (4, 216) => 0.109429
+(1, -1) ~ (4, 217) => 0.0951331
+(1, -1) ~ (4, 218) => 0.193332
+(1, -1) ~ (4, 219) => 0.202732
+(1, -1) ~ (4, 220) => 0.540444
+(1, -1) ~ (4, 221) => 0.598844
+(1, -1) ~ (4, 222) => 0.14456
+(1, -1) ~ (4, 223) => 0.0396232
+(1, -1) ~ (4, 224) => 0.0210092
+(1, -1) ~ (4, 225) => 0.00376999
+(1, -1) ~ (4, 226) => 0.000703633
+(1, -1) ~ (4, 227) => 0.000107408
+(1, -1) ~ (4, 228) => 0.0001
+(1, -1) ~ (4, 229) => 0.0001
+(1, -1) ~ (4, 230) => 0.000282764
+(1, -1) ~ (4, 231) => 0.00153261
+(1, -1) ~ (4, 232) => 0.00173867
+(1, -1) ~ (4, 233) => 0.00404304
+(1, -1) ~ (4, 234) => 0.00538242
+(1, -1) ~ (4, 235) => 0.00645834
+(1, -1) ~ (4, 236) => 0.00583088
+(1, -1) ~ (4, 237) => 0.00454479
+
+; Sparse posterior probability matrix for sequences 1 and 5
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (5, 0) => 0.958042
+(1, 0) ~ (5, 1) => 0.0173021
+(1, 1) ~ (5, 0) => 0.0203377
+(1, 1) ~ (5, 1) => 0.930597
+(1, 1) ~ (5, 2) => 0.0295409
+(1, 2) ~ (5, 1) => 0.0326152
+(1, 2) ~ (5, 2) => 0.892226
+(1, 2) ~ (5, 3) => 0.0548518
+(1, 3) ~ (5, 2) => 0.0412895
+(1, 3) ~ (5, 3) => 0.866271
+(1, 3) ~ (5, 4) => 0.0694495
+(1, 4) ~ (5, 3) => 0.0509149
+(1, 4) ~ (5, 4) => 0.82409
+(1, 4) ~ (5, 5) => 0.100239
+(1, 5) ~ (5, 4) => 0.0616242
+(1, 5) ~ (5, 5) => 0.658293
+(1, 5) ~ (5, 6) => 0.208087
+(1, 6) ~ (5, 5) => 0.12117
+(1, 6) ~ (5, 6) => 0.0636501
+(1, 6) ~ (5, 7) => 0.647546
+(1, 7) ~ (5, 6) => 0.285665
+(1, 7) ~ (5, 8) => 0.665554
+(1, 8) ~ (5, 7) => 0.325503
+(1, 8) ~ (5, 9) => 0.664932
+(1, 9) ~ (5, 8) => 0.325003
+(1, 9) ~ (5, 10) => 0.66719
+(1, 10) ~ (5, 9) => 0.320155
+(1, 10) ~ (5, 11) => 0.673119
+(1, 11) ~ (5, 10) => 0.308026
+(1, 11) ~ (5, 12) => 0.671974
+(1, 12) ~ (5, 11) => 0.291398
+(1, 12) ~ (5, 12) => 0.0128356
+(1, 12) ~ (5, 13) => 0.667022
+(1, 12) ~ (5, 14) => 0.0138242
+(1, 13) ~ (5, 12) => 0.245891
+(1, 13) ~ (5, 13) => 0.0276437
+(1, 13) ~ (5, 14) => 0.678459
+(1, 13) ~ (5, 15) => 0.0209167
+(1, 14) ~ (5, 12) => 0.0187756
+(1, 14) ~ (5, 13) => 0.211915
+(1, 14) ~ (5, 14) => 0.0420879
+(1, 14) ~ (5, 15) => 0.691725
+(1, 14) ~ (5, 16) => 0.0245672
+(1, 15) ~ (5, 13) => 0.0123515
+(1, 15) ~ (5, 14) => 0.174471
+(1, 15) ~ (5, 15) => 0.0710718
+(1, 15) ~ (5, 16) => 0.70819
+(1, 16) ~ (5, 15) => 0.147012
+(1, 16) ~ (5, 16) => 0.0875313
+(1, 16) ~ (5, 17) => 0.743498
+(1, 17) ~ (5, 16) => 0.128166
+(1, 17) ~ (5, 17) => 0.0487452
+(1, 17) ~ (5, 18) => 0.808772
+(1, 18) ~ (5, 17) => 0.0914237
+(1, 18) ~ (5, 18) => 0.013469
+(1, 18) ~ (5, 19) => 0.889166
+(1, 19) ~ (5, 18) => 0.0201669
+(1, 19) ~ (5, 20) => 0.968641
+(1, 20) ~ (5, 21) => 0.996883
+(1, 21) ~ (5, 22) => 0.999786
+(1, 22) ~ (5, 23) => 0.999967
+(1, 23) ~ (5, 24) => 0.999774
+(1, 24) ~ (5, 25) => 0.998439
+(1, 25) ~ (5, 26) => 0.997551
+(1, 26) ~ (5, 27) => 0.997625
+(1, 27) ~ (5, 28) => 0.999211
+(1, 28) ~ (5, 29) => 0.999313
+(1, 29) ~ (5, 30) => 0.999367
+(1, 30) ~ (5, 31) => 0.999746
+(1, 31) ~ (5, 32) => 0.999852
+(1, 32) ~ (5, 33) => 0.999407
+(1, 33) ~ (5, 34) => 0.999112
+(1, 34) ~ (5, 35) => 0.998312
+(1, 35) ~ (5, 36) => 0.997356
+(1, 36) ~ (5, 37) => 0.988463
+(1, 36) ~ (5, 38) => 0.0103803
+(1, 37) ~ (5, 38) => 0.985966
+(1, 37) ~ (5, 39) => 0.0113672
+(1, 38) ~ (5, 39) => 0.985408
+(1, 39) ~ (5, 40) => 0.988553
+(1, 40) ~ (5, 41) => 0.989917
+(1, 41) ~ (5, 42) => 0.990312
+(1, 42) ~ (5, 43) => 0.991787
+(1, 43) ~ (5, 44) => 0.97602
+(1, 44) ~ (5, 44) => 0.0125915
+(1, 44) ~ (5, 45) => 0.959794
+(1, 45) ~ (5, 45) => 0.0224818
+(1, 45) ~ (5, 46) => 0.715167
+(1, 45) ~ (5, 48) => 0.0363064
+(1, 46) ~ (5, 46) => 0.189516
+(1, 46) ~ (5, 47) => 0.658868
+(1, 46) ~ (5, 49) => 0.0393317
+(1, 47) ~ (5, 46) => 0.0489734
+(1, 47) ~ (5, 47) => 0.204782
+(1, 47) ~ (5, 48) => 0.585399
+(1, 47) ~ (5, 50) => 0.0444322
+(1, 48) ~ (5, 47) => 0.0804177
+(1, 48) ~ (5, 48) => 0.225806
+(1, 48) ~ (5, 49) => 0.449177
+(1, 48) ~ (5, 51) => 0.0492481
+(1, 49) ~ (5, 48) => 0.121019
+(1, 49) ~ (5, 49) => 0.231869
+(1, 49) ~ (5, 50) => 0.121791
+(1, 49) ~ (5, 52) => 0.046658
+(1, 50) ~ (5, 49) => 0.243087
+(1, 50) ~ (5, 50) => 0.191289
+(1, 50) ~ (5, 51) => 0.0247119
+(1, 51) ~ (5, 50) => 0.618028
+(1, 51) ~ (5, 51) => 0.132888
+(1, 52) ~ (5, 51) => 0.781381
+(1, 53) ~ (5, 52) => 0.940546
+(1, 54) ~ (5, 53) => 0.994694
+(1, 55) ~ (5, 54) => 0.998765
+(1, 56) ~ (5, 55) => 0.999428
+(1, 57) ~ (5, 56) => 0.999701
+(1, 58) ~ (5, 57) => 0.998816
+(1, 59) ~ (5, 58) => 0.979491
+(1, 60) ~ (5, 58) => 0.0201474
+(1, 60) ~ (5, 59) => 0.947816
+(1, 61) ~ (5, 59) => 0.0514377
+(1, 61) ~ (5, 60) => 0.690977
+(1, 62) ~ (5, 60) => 0.307028
+(1, 62) ~ (5, 61) => 0.435119
+(1, 63) ~ (5, 61) => 0.562645
+(1, 63) ~ (5, 62) => 0.177971
+(1, 64) ~ (5, 62) => 0.81879
+(1, 64) ~ (5, 63) => 0.0566139
+(1, 65) ~ (5, 63) => 0.939508
+(1, 65) ~ (5, 64) => 0.0107864
+(1, 66) ~ (5, 64) => 0.98594
+(1, 67) ~ (5, 65) => 0.990578
+(1, 68) ~ (5, 66) => 0.998754
+(1, 69) ~ (5, 67) => 0.999692
+(1, 70) ~ (5, 68) => 0.999752
+(1, 71) ~ (5, 69) => 0.999767
+(1, 72) ~ (5, 70) => 0.999833
+(1, 73) ~ (5, 71) => 0.999972
+(1, 74) ~ (5, 72) => 0.999976
+(1, 75) ~ (5, 73) => 0.99997
+(1, 76) ~ (5, 74) => 0.999897
+(1, 77) ~ (5, 75) => 0.999775
+(1, 78) ~ (5, 76) => 0.999196
+(1, 79) ~ (5, 77) => 0.97164
+(1, 79) ~ (5, 78) => 0.0264883
+(1, 80) ~ (5, 78) => 0.965948
+(1, 80) ~ (5, 79) => 0.0290874
+(1, 81) ~ (5, 79) => 0.967097
+(1, 81) ~ (5, 80) => 0.0210659
+(1, 82) ~ (5, 80) => 0.975915
+(1, 82) ~ (5, 81) => 0.0191911
+(1, 83) ~ (5, 81) => 0.975907
+(1, 83) ~ (5, 82) => 0.0194006
+(1, 84) ~ (5, 82) => 0.970947
+(1, 84) ~ (5, 83) => 0.024186
+(1, 85) ~ (5, 83) => 0.972037
+(1, 86) ~ (5, 84) => 0.986879
+(1, 87) ~ (5, 85) => 0.992556
+(1, 88) ~ (5, 86) => 0.995864
+(1, 89) ~ (5, 87) => 0.99739
+(1, 90) ~ (5, 88) => 0.999259
+(1, 91) ~ (5, 89) => 0.999094
+(1, 92) ~ (5, 90) => 0.999338
+(1, 93) ~ (5, 91) => 0.998167
+(1, 94) ~ (5, 92) => 0.997555
+(1, 95) ~ (5, 93) => 0.998064
+(1, 96) ~ (5, 94) => 0.998761
+(1, 97) ~ (5, 95) => 0.998846
+(1, 98) ~ (5, 96) => 0.996986
+(1, 99) ~ (5, 97) => 0.995943
+(1, 100) ~ (5, 98) => 0.99505
+(1, 101) ~ (5, 99) => 0.994027
+(1, 102) ~ (5, 100) => 0.995214
+(1, 103) ~ (5, 101) => 0.998756
+(1, 104) ~ (5, 102) => 0.999094
+(1, 105) ~ (5, 103) => 0.999437
+(1, 106) ~ (5, 104) => 0.999795
+(1, 107) ~ (5, 105) => 0.999987
+(1, 108) ~ (5, 106) => 0.99999
+(1, 109) ~ (5, 107) => 0.99999
+(1, 110) ~ (5, 108) => 0.99999
+(1, 111) ~ (5, 109) => 0.999943
+(1, 112) ~ (5, 110) => 0.999904
+(1, 113) ~ (5, 111) => 0.999923
+(1, 114) ~ (5, 112) => 0.999966
+(1, 115) ~ (5, 113) => 0.999986
+(1, 116) ~ (5, 114) => 0.999985
+(1, 117) ~ (5, 115) => 0.999771
+(1, 118) ~ (5, 116) => 0.998157
+(1, 119) ~ (5, 117) => 0.996866
+(1, 120) ~ (5, 118) => 0.992417
+(1, 121) ~ (5, 119) => 0.992282
+(1, 122) ~ (5, 120) => 0.996178
+(1, 123) ~ (5, 121) => 0.993222
+(1, 124) ~ (5, 122) => 0.98925
+(1, 125) ~ (5, 123) => 0.989601
+(1, 126) ~ (5, 124) => 0.997311
+(1, 127) ~ (5, 125) => 0.999575
+(1, 128) ~ (5, 126) => 0.9991
+(1, 129) ~ (5, 127) => 0.997582
+(1, 130) ~ (5, 128) => 0.996202
+(1, 131) ~ (5, 129) => 0.996515
+(1, 132) ~ (5, 130) => 0.999657
+(1, 133) ~ (5, 131) => 0.999754
+(1, 134) ~ (5, 132) => 0.999593
+(1, 135) ~ (5, 133) => 0.999617
+(1, 136) ~ (5, 134) => 0.999762
+(1, 137) ~ (5, 135) => 0.999921
+(1, 138) ~ (5, 136) => 0.999472
+(1, 139) ~ (5, 137) => 0.999391
+(1, 140) ~ (5, 138) => 0.99969
+(1, 141) ~ (5, 139) => 0.999991
+(1, 142) ~ (5, 140) => 0.999998
+(1, 143) ~ (5, 141) => 0.999996
+(1, 144) ~ (5, 142) => 0.999978
+(1, 145) ~ (5, 143) => 0.999968
+(1, 146) ~ (5, 144) => 0.999979
+(1, 147) ~ (5, 145) => 0.999996
+(1, 148) ~ (5, 146) => 0.999996
+(1, 149) ~ (5, 147) => 0.999986
+(1, 150) ~ (5, 148) => 0.999863
+(1, 151) ~ (5, 149) => 0.999842
+(1, 152) ~ (5, 150) => 0.999961
+(1, 153) ~ (5, 151) => 0.999981
+(1, 154) ~ (5, 152) => 0.999971
+(1, 155) ~ (5, 153) => 0.999893
+(1, 156) ~ (5, 154) => 0.999875
+(1, 157) ~ (5, 155) => 0.999816
+(1, 158) ~ (5, 156) => 0.999655
+(1, 159) ~ (5, 157) => 0.997794
+(1, 160) ~ (5, 158) => 0.996845
+(1, 161) ~ (5, 159) => 0.996285
+(1, 162) ~ (5, 160) => 0.995755
+(1, 163) ~ (5, 161) => 0.99637
+(1, 164) ~ (5, 162) => 0.99899
+(1, 165) ~ (5, 163) => 0.999417
+(1, 166) ~ (5, 164) => 0.999807
+(1, 167) ~ (5, 165) => 0.999503
+(1, 168) ~ (5, 166) => 0.999254
+(1, 169) ~ (5, 167) => 0.998386
+(1, 170) ~ (5, 168) => 0.996336
+(1, 171) ~ (5, 169) => 0.996611
+(1, 172) ~ (5, 170) => 0.999602
+(1, 173) ~ (5, 171) => 0.999838
+(1, 174) ~ (5, 172) => 0.999419
+(1, 175) ~ (5, 173) => 0.996827
+(1, 176) ~ (5, 174) => 0.994525
+(1, 177) ~ (5, 175) => 0.994355
+(1, 178) ~ (5, 176) => 0.994905
+(1, 179) ~ (5, 177) => 0.997391
+(1, 180) ~ (5, 178) => 0.999801
+(1, 181) ~ (5, 179) => 0.999954
+(1, 182) ~ (5, 180) => 0.999046
+(1, 183) ~ (5, 181) => 0.998157
+(1, 184) ~ (5, 182) => 0.956869
+(1, 184) ~ (5, 183) => 0.042778
+(1, 185) ~ (5, 183) => 0.915677
+(1, 185) ~ (5, 184) => 0.0837163
+(1, 186) ~ (5, 184) => 0.874434
+(1, 186) ~ (5, 185) => 0.124662
+(1, 187) ~ (5, 185) => 0.728442
+(1, 187) ~ (5, 186) => 0.269972
+(1, 188) ~ (5, 186) => 0.581247
+(1, 188) ~ (5, 187) => 0.415024
+(1, 189) ~ (5, 187) => 0.542439
+(1, 189) ~ (5, 188) => 0.4511
+(1, 190) ~ (5, 188) => 0.503933
+(1, 190) ~ (5, 189) => 0.487182
+(1, 191) ~ (5, 189) => 0.479292
+(1, 191) ~ (5, 190) => 0.511975
+(1, 192) ~ (5, 190) => 0.478804
+(1, 192) ~ (5, 191) => 0.512168
+(1, 193) ~ (5, 191) => 0.44809
+(1, 193) ~ (5, 192) => 0.540408
+(1, 194) ~ (5, 192) => 0.406227
+(1, 194) ~ (5, 193) => 0.580883
+(1, 195) ~ (5, 193) => 0.389324
+(1, 195) ~ (5, 194) => 0.598717
+(1, 196) ~ (5, 194) => 0.328026
+(1, 196) ~ (5, 195) => 0.660339
+(1, 197) ~ (5, 195) => 0.267357
+(1, 197) ~ (5, 196) => 0.723168
+(1, 198) ~ (5, 196) => 0.107525
+(1, 198) ~ (5, 197) => 0.888106
+(1, 199) ~ (5, 197) => 0.0579782
+(1, 199) ~ (5, 198) => 0.939756
+(1, 200) ~ (5, 199) => 0.98948
+(1, 201) ~ (5, 200) => 0.992391
+(1, 202) ~ (5, 201) => 0.996934
+(1, 203) ~ (5, 202) => 0.998128
+(1, 204) ~ (5, 203) => 0.999156
+(1, 205) ~ (5, 204) => 0.998643
+(1, 206) ~ (5, 205) => 0.998373
+(1, 207) ~ (5, 206) => 0.998729
+(1, 208) ~ (5, 207) => 0.999286
+(1, 209) ~ (5, 208) => 0.995858
+(1, 210) ~ (5, 209) => 0.922396
+(1, 210) ~ (5, 210) => 0.0747813
+(1, 211) ~ (5, 210) => 0.7681
+(1, 211) ~ (5, 211) => 0.228975
+(1, 212) ~ (5, 211) => 0.721845
+(1, 212) ~ (5, 212) => 0.276736
+(1, 213) ~ (5, 212) => 0.716736
+(1, 213) ~ (5, 213) => 0.278487
+(1, 214) ~ (5, 213) => 0.720551
+(1, 214) ~ (5, 214) => 0.253163
+(1, 215) ~ (5, 214) => 0.746043
+(1, 215) ~ (5, 215) => 0.245204
+(1, 216) ~ (5, 215) => 0.749537
+(1, 216) ~ (5, 216) => 0.248929
+(1, 217) ~ (5, 216) => 0.699117
+(1, 217) ~ (5, 217) => 0.29975
+(1, 218) ~ (5, 217) => 0.5008
+(1, 218) ~ (5, 218) => 0.496616
+(1, 219) ~ (5, 218) => 0.46909
+(1, 219) ~ (5, 219) => 0.527782
+(1, 220) ~ (5, 219) => 0.271941
+(1, 220) ~ (5, 220) => 0.724587
+(1, 221) ~ (5, 220) => 0.0223489
+(1, 221) ~ (5, 221) => 0.976191
+(1, 222) ~ (5, 222) => 0.993621
+(1, 223) ~ (5, 223) => 0.999558
+(1, 224) ~ (5, 224) => 0.999913
+(1, 225) ~ (5, 225) => 0.99999
+(1, 226) ~ (5, 226) => 0.999978
+(1, 227) ~ (5, 227) => 0.999898
+(1, 228) ~ (5, 228) => 0.999662
+(1, 229) ~ (5, 229) => 0.997598
+(1, 230) ~ (5, 230) => 0.996004
+(1, 231) ~ (5, 231) => 0.994446
+(1, 232) ~ (5, 232) => 0.993179
+(1, 233) ~ (5, 233) => 0.993937
+
+; gap posteriors
+(1, 0) ~ (5, -1) => 0.0246555
+(1, 1) ~ (5, -1) => 0.0195246
+(1, 2) ~ (5, -1) => 0.0203071
+(1, 3) ~ (5, -1) => 0.0229897
+(1, 4) ~ (5, -1) => 0.0247567
+(1, 5) ~ (5, -1) => 0.0719956
+(1, 6) ~ (5, -1) => 0.167634
+(1, 7) ~ (5, -1) => 0.0487813
+(1, 8) ~ (5, -1) => 0.00956553
+(1, 9) ~ (5, -1) => 0.00780714
+(1, 10) ~ (5, -1) => 0.00672591
+(1, 11) ~ (5, -1) => 0.0199999
+(1, 12) ~ (5, -1) => 0.0149195
+(1, 13) ~ (5, -1) => 0.0270896
+(1, 14) ~ (5, -1) => 0.0109289
+(1, 15) ~ (5, -1) => 0.0339161
+(1, 16) ~ (5, -1) => 0.0219582
+(1, 17) ~ (5, -1) => 0.0143168
+(1, 18) ~ (5, -1) => 0.00594157
+(1, 19) ~ (5, -1) => 0.0111925
+(1, 20) ~ (5, -1) => 0.00311673
+(1, 21) ~ (5, -1) => 0.0002141
+(1, 22) ~ (5, -1) => 0.0001
+(1, 23) ~ (5, -1) => 0.000226319
+(1, 24) ~ (5, -1) => 0.00156051
+(1, 25) ~ (5, -1) => 0.00244898
+(1, 26) ~ (5, -1) => 0.00237465
+(1, 27) ~ (5, -1) => 0.000788629
+(1, 28) ~ (5, -1) => 0.000686765
+(1, 29) ~ (5, -1) => 0.000632882
+(1, 30) ~ (5, -1) => 0.000254035
+(1, 31) ~ (5, -1) => 0.000148296
+(1, 32) ~ (5, -1) => 0.000592768
+(1, 33) ~ (5, -1) => 0.000888169
+(1, 34) ~ (5, -1) => 0.00168848
+(1, 35) ~ (5, -1) => 0.002644
+(1, 36) ~ (5, -1) => 0.00115705
+(1, 37) ~ (5, -1) => 0.00266637
+(1, 38) ~ (5, -1) => 0.0145921
+(1, 39) ~ (5, -1) => 0.0114473
+(1, 40) ~ (5, -1) => 0.0100831
+(1, 41) ~ (5, -1) => 0.00968802
+(1, 42) ~ (5, -1) => 0.00821328
+(1, 43) ~ (5, -1) => 0.0239797
+(1, 44) ~ (5, -1) => 0.0276148
+(1, 45) ~ (5, -1) => 0.226045
+(1, 46) ~ (5, -1) => 0.112284
+(1, 47) ~ (5, -1) => 0.116414
+(1, 48) ~ (5, -1) => 0.195351
+(1, 49) ~ (5, -1) => 0.478663
+(1, 50) ~ (5, -1) => 0.540912
+(1, 51) ~ (5, -1) => 0.249085
+(1, 52) ~ (5, -1) => 0.218619
+(1, 53) ~ (5, -1) => 0.0594541
+(1, 54) ~ (5, -1) => 0.00530553
+(1, 55) ~ (5, -1) => 0.00123483
+(1, 56) ~ (5, -1) => 0.000572443
+(1, 57) ~ (5, -1) => 0.000298858
+(1, 58) ~ (5, -1) => 0.00118405
+(1, 59) ~ (5, -1) => 0.0205086
+(1, 60) ~ (5, -1) => 0.0320362
+(1, 61) ~ (5, -1) => 0.257585
+(1, 62) ~ (5, -1) => 0.257853
+(1, 63) ~ (5, -1) => 0.259384
+(1, 64) ~ (5, -1) => 0.124596
+(1, 65) ~ (5, -1) => 0.0497058
+(1, 66) ~ (5, -1) => 0.0140601
+(1, 67) ~ (5, -1) => 0.009422
+(1, 68) ~ (5, -1) => 0.00124568
+(1, 69) ~ (5, -1) => 0.0003075
+(1, 70) ~ (5, -1) => 0.000247598
+(1, 71) ~ (5, -1) => 0.000232697
+(1, 72) ~ (5, -1) => 0.000167251
+(1, 73) ~ (5, -1) => 0.0001
+(1, 74) ~ (5, -1) => 0.0001
+(1, 75) ~ (5, -1) => 0.0001
+(1, 76) ~ (5, -1) => 0.000103354
+(1, 77) ~ (5, -1) => 0.000225186
+(1, 78) ~ (5, -1) => 0.000804067
+(1, 79) ~ (5, -1) => 0.00187185
+(1, 80) ~ (5, -1) => 0.00496418
+(1, 81) ~ (5, -1) => 0.0118373
+(1, 82) ~ (5, -1) => 0.00489422
+(1, 83) ~ (5, -1) => 0.00469263
+(1, 84) ~ (5, -1) => 0.00486686
+(1, 85) ~ (5, -1) => 0.0279629
+(1, 86) ~ (5, -1) => 0.0131206
+(1, 87) ~ (5, -1) => 0.00744396
+(1, 88) ~ (5, -1) => 0.00413597
+(1, 89) ~ (5, -1) => 0.00261033
+(1, 90) ~ (5, -1) => 0.000740767
+(1, 91) ~ (5, -1) => 0.000906169
+(1, 92) ~ (5, -1) => 0.00066185
+(1, 93) ~ (5, -1) => 0.0018335
+(1, 94) ~ (5, -1) => 0.00244474
+(1, 95) ~ (5, -1) => 0.00193578
+(1, 96) ~ (5, -1) => 0.00123858
+(1, 97) ~ (5, -1) => 0.00115353
+(1, 98) ~ (5, -1) => 0.00301391
+(1, 99) ~ (5, -1) => 0.00405729
+(1, 100) ~ (5, -1) => 0.00494969
+(1, 101) ~ (5, -1) => 0.00597274
+(1, 102) ~ (5, -1) => 0.00478584
+(1, 103) ~ (5, -1) => 0.00124425
+(1, 104) ~ (5, -1) => 0.000905514
+(1, 105) ~ (5, -1) => 0.000563085
+(1, 106) ~ (5, -1) => 0.000204861
+(1, 107) ~ (5, -1) => 0.0001
+(1, 108) ~ (5, -1) => 0.0001
+(1, 109) ~ (5, -1) => 0.0001
+(1, 110) ~ (5, -1) => 0.0001
+(1, 111) ~ (5, -1) => 0.0001
+(1, 112) ~ (5, -1) => 0.0001
+(1, 113) ~ (5, -1) => 0.0001
+(1, 114) ~ (5, -1) => 0.0001
+(1, 115) ~ (5, -1) => 0.0001
+(1, 116) ~ (5, -1) => 0.0001
+(1, 117) ~ (5, -1) => 0.000228763
+(1, 118) ~ (5, -1) => 0.00184309
+(1, 119) ~ (5, -1) => 0.00313443
+(1, 120) ~ (5, -1) => 0.00758314
+(1, 121) ~ (5, -1) => 0.00771832
+(1, 122) ~ (5, -1) => 0.00382239
+(1, 123) ~ (5, -1) => 0.00677836
+(1, 124) ~ (5, -1) => 0.0107498
+(1, 125) ~ (5, -1) => 0.0103994
+(1, 126) ~ (5, -1) => 0.00268865
+(1, 127) ~ (5, -1) => 0.000424504
+(1, 128) ~ (5, -1) => 0.000899613
+(1, 129) ~ (5, -1) => 0.00241792
+(1, 130) ~ (5, -1) => 0.00379843
+(1, 131) ~ (5, -1) => 0.00348544
+(1, 132) ~ (5, -1) => 0.000343263
+(1, 133) ~ (5, -1) => 0.00024575
+(1, 134) ~ (5, -1) => 0.000406921
+(1, 135) ~ (5, -1) => 0.000383019
+(1, 136) ~ (5, -1) => 0.00023824
+(1, 137) ~ (5, -1) => 0.0001
+(1, 138) ~ (5, -1) => 0.000527859
+(1, 139) ~ (5, -1) => 0.000608504
+(1, 140) ~ (5, -1) => 0.000310481
+(1, 141) ~ (5, -1) => 0.0001
+(1, 142) ~ (5, -1) => 0.0001
+(1, 143) ~ (5, -1) => 0.0001
+(1, 144) ~ (5, -1) => 0.0001
+(1, 145) ~ (5, -1) => 0.0001
+(1, 146) ~ (5, -1) => 0.0001
+(1, 147) ~ (5, -1) => 0.0001
+(1, 148) ~ (5, -1) => 0.0001
+(1, 149) ~ (5, -1) => 0.0001
+(1, 150) ~ (5, -1) => 0.00013715
+(1, 151) ~ (5, -1) => 0.000158429
+(1, 152) ~ (5, -1) => 0.0001
+(1, 153) ~ (5, -1) => 0.0001
+(1, 154) ~ (5, -1) => 0.0001
+(1, 155) ~ (5, -1) => 0.000106573
+(1, 156) ~ (5, -1) => 0.000124812
+(1, 157) ~ (5, -1) => 0.000183761
+(1, 158) ~ (5, -1) => 0.000344872
+(1, 159) ~ (5, -1) => 0.00220561
+(1, 160) ~ (5, -1) => 0.00315464
+(1, 161) ~ (5, -1) => 0.0037151
+(1, 162) ~ (5, -1) => 0.0042448
+(1, 163) ~ (5, -1) => 0.00362962
+(1, 164) ~ (5, -1) => 0.0010103
+(1, 165) ~ (5, -1) => 0.000583291
+(1, 166) ~ (5, -1) => 0.000193179
+(1, 167) ~ (5, -1) => 0.000496745
+(1, 168) ~ (5, -1) => 0.000746429
+(1, 169) ~ (5, -1) => 0.00161403
+(1, 170) ~ (5, -1) => 0.00366408
+(1, 171) ~ (5, -1) => 0.003389
+(1, 172) ~ (5, -1) => 0.00039798
+(1, 173) ~ (5, -1) => 0.000162423
+(1, 174) ~ (5, -1) => 0.000581324
+(1, 175) ~ (5, -1) => 0.00317287
+(1, 176) ~ (5, -1) => 0.00547522
+(1, 177) ~ (5, -1) => 0.00564486
+(1, 178) ~ (5, -1) => 0.00509483
+(1, 179) ~ (5, -1) => 0.00260878
+(1, 180) ~ (5, -1) => 0.000199139
+(1, 181) ~ (5, -1) => 0.0001
+(1, 182) ~ (5, -1) => 0.000954449
+(1, 183) ~ (5, -1) => 0.0018428
+(1, 184) ~ (5, -1) => 0.000352729
+(1, 185) ~ (5, -1) => 0.000606671
+(1, 186) ~ (5, -1) => 0.000904649
+(1, 187) ~ (5, -1) => 0.00158632
+(1, 188) ~ (5, -1) => 0.00372937
+(1, 189) ~ (5, -1) => 0.00646076
+(1, 190) ~ (5, -1) => 0.00888517
+(1, 191) ~ (5, -1) => 0.00873297
+(1, 192) ~ (5, -1) => 0.00902838
+(1, 193) ~ (5, -1) => 0.0115016
+(1, 194) ~ (5, -1) => 0.0128899
+(1, 195) ~ (5, -1) => 0.0119585
+(1, 196) ~ (5, -1) => 0.0116351
+(1, 197) ~ (5, -1) => 0.00947458
+(1, 198) ~ (5, -1) => 0.00436807
+(1, 199) ~ (5, -1) => 0.00226557
+(1, 200) ~ (5, -1) => 0.0105197
+(1, 201) ~ (5, -1) => 0.00760943
+(1, 202) ~ (5, -1) => 0.0030663
+(1, 203) ~ (5, -1) => 0.00187194
+(1, 204) ~ (5, -1) => 0.000843763
+(1, 205) ~ (5, -1) => 0.0013566
+(1, 206) ~ (5, -1) => 0.00162685
+(1, 207) ~ (5, -1) => 0.00127143
+(1, 208) ~ (5, -1) => 0.000714242
+(1, 209) ~ (5, -1) => 0.00414246
+(1, 210) ~ (5, -1) => 0.00282282
+(1, 211) ~ (5, -1) => 0.00292493
+(1, 212) ~ (5, -1) => 0.0014188
+(1, 213) ~ (5, -1) => 0.00477701
+(1, 214) ~ (5, -1) => 0.0262863
+(1, 215) ~ (5, -1) => 0.00875352
+(1, 216) ~ (5, -1) => 0.00153376
+(1, 217) ~ (5, -1) => 0.00113368
+(1, 218) ~ (5, -1) => 0.00258407
+(1, 219) ~ (5, -1) => 0.00312769
+(1, 220) ~ (5, -1) => 0.00347155
+(1, 221) ~ (5, -1) => 0.0014599
+(1, 222) ~ (5, -1) => 0.00637895
+(1, 223) ~ (5, -1) => 0.000442386
+(1, 224) ~ (5, -1) => 0.0001
+(1, 225) ~ (5, -1) => 0.0001
+(1, 226) ~ (5, -1) => 0.0001
+(1, 227) ~ (5, -1) => 0.000102162
+(1, 228) ~ (5, -1) => 0.000338435
+(1, 229) ~ (5, -1) => 0.00240248
+(1, 230) ~ (5, -1) => 0.0039956
+(1, 231) ~ (5, -1) => 0.00555378
+(1, 232) ~ (5, -1) => 0.00682056
+(1, 233) ~ (5, -1) => 0.00606287
+
+(1, -1) ~ (5, 0) => 0.0216199
+(1, -1) ~ (5, 1) => 0.0194858
+(1, -1) ~ (5, 2) => 0.0369438
+(1, -1) ~ (5, 3) => 0.027962
+(1, -1) ~ (5, 4) => 0.0448365
+(1, -1) ~ (5, 5) => 0.120298
+(1, -1) ~ (5, 6) => 0.442598
+(1, -1) ~ (5, 7) => 0.0269507
+(1, -1) ~ (5, 8) => 0.00944364
+(1, -1) ~ (5, 9) => 0.0149131
+(1, -1) ~ (5, 10) => 0.0247838
+(1, -1) ~ (5, 11) => 0.035483
+(1, -1) ~ (5, 12) => 0.0505233
+(1, -1) ~ (5, 13) => 0.081067
+(1, -1) ~ (5, 14) => 0.0911587
+(1, -1) ~ (5, 15) => 0.0692741
+(1, -1) ~ (5, 16) => 0.051545
+(1, -1) ~ (5, 17) => 0.116333
+(1, -1) ~ (5, 18) => 0.157592
+(1, -1) ~ (5, 19) => 0.110834
+(1, -1) ~ (5, 20) => 0.0313594
+(1, -1) ~ (5, 21) => 0.00311673
+(1, -1) ~ (5, 22) => 0.0002141
+(1, -1) ~ (5, 23) => 0.0001
+(1, -1) ~ (5, 24) => 0.000226319
+(1, -1) ~ (5, 25) => 0.00156051
+(1, -1) ~ (5, 26) => 0.00244898
+(1, -1) ~ (5, 27) => 0.00237465
+(1, -1) ~ (5, 28) => 0.000788629
+(1, -1) ~ (5, 29) => 0.000686765
+(1, -1) ~ (5, 30) => 0.000632882
+(1, -1) ~ (5, 31) => 0.000254035
+(1, -1) ~ (5, 32) => 0.000148296
+(1, -1) ~ (5, 33) => 0.000592768
+(1, -1) ~ (5, 34) => 0.000888169
+(1, -1) ~ (5, 35) => 0.00168848
+(1, -1) ~ (5, 36) => 0.002644
+(1, -1) ~ (5, 37) => 0.0115374
+(1, -1) ~ (5, 38) => 0.00365329
+(1, -1) ~ (5, 39) => 0.00322485
+(1, -1) ~ (5, 40) => 0.0114473
+(1, -1) ~ (5, 41) => 0.0100831
+(1, -1) ~ (5, 42) => 0.00968802
+(1, -1) ~ (5, 43) => 0.00821328
+(1, -1) ~ (5, 44) => 0.0113882
+(1, -1) ~ (5, 45) => 0.0177245
+(1, -1) ~ (5, 46) => 0.0463437
+(1, -1) ~ (5, 47) => 0.055932
+(1, -1) ~ (5, 48) => 0.0314697
+(1, -1) ~ (5, 49) => 0.036535
+(1, -1) ~ (5, 50) => 0.0244603
+(1, -1) ~ (5, 51) => 0.0117717
+(1, -1) ~ (5, 52) => 0.0127962
+(1, -1) ~ (5, 53) => 0.00530553
+(1, -1) ~ (5, 54) => 0.00123483
+(1, -1) ~ (5, 55) => 0.000572443
+(1, -1) ~ (5, 56) => 0.000298858
+(1, -1) ~ (5, 57) => 0.00118405
+(1, -1) ~ (5, 58) => 0.000361212
+(1, -1) ~ (5, 59) => 0.000745911
+(1, -1) ~ (5, 60) => 0.0019944
+(1, -1) ~ (5, 61) => 0.00223583
+(1, -1) ~ (5, 62) => 0.00323868
+(1, -1) ~ (5, 63) => 0.00387836
+(1, -1) ~ (5, 64) => 0.00327373
+(1, -1) ~ (5, 65) => 0.009422
+(1, -1) ~ (5, 66) => 0.00124568
+(1, -1) ~ (5, 67) => 0.0003075
+(1, -1) ~ (5, 68) => 0.000247598
+(1, -1) ~ (5, 69) => 0.000232697
+(1, -1) ~ (5, 70) => 0.000167251
+(1, -1) ~ (5, 71) => 0.0001
+(1, -1) ~ (5, 72) => 0.0001
+(1, -1) ~ (5, 73) => 0.0001
+(1, -1) ~ (5, 74) => 0.000103354
+(1, -1) ~ (5, 75) => 0.000225186
+(1, -1) ~ (5, 76) => 0.000804067
+(1, -1) ~ (5, 77) => 0.0283601
+(1, -1) ~ (5, 78) => 0.00756329
+(1, -1) ~ (5, 79) => 0.00381583
+(1, -1) ~ (5, 80) => 0.00301933
+(1, -1) ~ (5, 81) => 0.00490212
+(1, -1) ~ (5, 82) => 0.00965226
+(1, -1) ~ (5, 83) => 0.00377685
+(1, -1) ~ (5, 84) => 0.0131206
+(1, -1) ~ (5, 85) => 0.00744396
+(1, -1) ~ (5, 86) => 0.00413597
+(1, -1) ~ (5, 87) => 0.00261033
+(1, -1) ~ (5, 88) => 0.000740767
+(1, -1) ~ (5, 89) => 0.000906169
+(1, -1) ~ (5, 90) => 0.00066185
+(1, -1) ~ (5, 91) => 0.0018335
+(1, -1) ~ (5, 92) => 0.00244474
+(1, -1) ~ (5, 93) => 0.00193578
+(1, -1) ~ (5, 94) => 0.00123858
+(1, -1) ~ (5, 95) => 0.00115353
+(1, -1) ~ (5, 96) => 0.00301391
+(1, -1) ~ (5, 97) => 0.00405729
+(1, -1) ~ (5, 98) => 0.00494969
+(1, -1) ~ (5, 99) => 0.00597274
+(1, -1) ~ (5, 100) => 0.00478584
+(1, -1) ~ (5, 101) => 0.00124425
+(1, -1) ~ (5, 102) => 0.000905514
+(1, -1) ~ (5, 103) => 0.000563085
+(1, -1) ~ (5, 104) => 0.000204861
+(1, -1) ~ (5, 105) => 0.0001
+(1, -1) ~ (5, 106) => 0.0001
+(1, -1) ~ (5, 107) => 0.0001
+(1, -1) ~ (5, 108) => 0.0001
+(1, -1) ~ (5, 109) => 0.0001
+(1, -1) ~ (5, 110) => 0.0001
+(1, -1) ~ (5, 111) => 0.0001
+(1, -1) ~ (5, 112) => 0.0001
+(1, -1) ~ (5, 113) => 0.0001
+(1, -1) ~ (5, 114) => 0.0001
+(1, -1) ~ (5, 115) => 0.000228763
+(1, -1) ~ (5, 116) => 0.00184309
+(1, -1) ~ (5, 117) => 0.00313443
+(1, -1) ~ (5, 118) => 0.00758314
+(1, -1) ~ (5, 119) => 0.00771832
+(1, -1) ~ (5, 120) => 0.00382239
+(1, -1) ~ (5, 121) => 0.00677836
+(1, -1) ~ (5, 122) => 0.0107498
+(1, -1) ~ (5, 123) => 0.0103994
+(1, -1) ~ (5, 124) => 0.00268865
+(1, -1) ~ (5, 125) => 0.000424504
+(1, -1) ~ (5, 126) => 0.000899613
+(1, -1) ~ (5, 127) => 0.00241792
+(1, -1) ~ (5, 128) => 0.00379843
+(1, -1) ~ (5, 129) => 0.00348544
+(1, -1) ~ (5, 130) => 0.000343263
+(1, -1) ~ (5, 131) => 0.00024575
+(1, -1) ~ (5, 132) => 0.000406921
+(1, -1) ~ (5, 133) => 0.000383019
+(1, -1) ~ (5, 134) => 0.00023824
+(1, -1) ~ (5, 135) => 0.0001
+(1, -1) ~ (5, 136) => 0.000527859
+(1, -1) ~ (5, 137) => 0.000608504
+(1, -1) ~ (5, 138) => 0.000310481
+(1, -1) ~ (5, 139) => 0.0001
+(1, -1) ~ (5, 140) => 0.0001
+(1, -1) ~ (5, 141) => 0.0001
+(1, -1) ~ (5, 142) => 0.0001
+(1, -1) ~ (5, 143) => 0.0001
+(1, -1) ~ (5, 144) => 0.0001
+(1, -1) ~ (5, 145) => 0.0001
+(1, -1) ~ (5, 146) => 0.0001
+(1, -1) ~ (5, 147) => 0.0001
+(1, -1) ~ (5, 148) => 0.00013715
+(1, -1) ~ (5, 149) => 0.000158429
+(1, -1) ~ (5, 150) => 0.0001
+(1, -1) ~ (5, 151) => 0.0001
+(1, -1) ~ (5, 152) => 0.0001
+(1, -1) ~ (5, 153) => 0.000106573
+(1, -1) ~ (5, 154) => 0.000124812
+(1, -1) ~ (5, 155) => 0.000183761
+(1, -1) ~ (5, 156) => 0.000344872
+(1, -1) ~ (5, 157) => 0.00220561
+(1, -1) ~ (5, 158) => 0.00315464
+(1, -1) ~ (5, 159) => 0.0037151
+(1, -1) ~ (5, 160) => 0.0042448
+(1, -1) ~ (5, 161) => 0.00362962
+(1, -1) ~ (5, 162) => 0.0010103
+(1, -1) ~ (5, 163) => 0.000583291
+(1, -1) ~ (5, 164) => 0.000193179
+(1, -1) ~ (5, 165) => 0.000496745
+(1, -1) ~ (5, 166) => 0.000746429
+(1, -1) ~ (5, 167) => 0.00161403
+(1, -1) ~ (5, 168) => 0.00366408
+(1, -1) ~ (5, 169) => 0.003389
+(1, -1) ~ (5, 170) => 0.00039798
+(1, -1) ~ (5, 171) => 0.000162423
+(1, -1) ~ (5, 172) => 0.000581324
+(1, -1) ~ (5, 173) => 0.00317287
+(1, -1) ~ (5, 174) => 0.00547522
+(1, -1) ~ (5, 175) => 0.00564486
+(1, -1) ~ (5, 176) => 0.00509483
+(1, -1) ~ (5, 177) => 0.00260878
+(1, -1) ~ (5, 178) => 0.000199139
+(1, -1) ~ (5, 179) => 0.0001
+(1, -1) ~ (5, 180) => 0.000954449
+(1, -1) ~ (5, 181) => 0.0018428
+(1, -1) ~ (5, 182) => 0.0431308
+(1, -1) ~ (5, 183) => 0.041545
+(1, -1) ~ (5, 184) => 0.04185
+(1, -1) ~ (5, 185) => 0.146896
+(1, -1) ~ (5, 186) => 0.148782
+(1, -1) ~ (5, 187) => 0.0425369
+(1, -1) ~ (5, 188) => 0.044967
+(1, -1) ~ (5, 189) => 0.0335258
+(1, -1) ~ (5, 190) => 0.0092217
+(1, -1) ~ (5, 191) => 0.0397421
+(1, -1) ~ (5, 192) => 0.0533646
+(1, -1) ~ (5, 193) => 0.0297924
+(1, -1) ~ (5, 194) => 0.0732568
+(1, -1) ~ (5, 195) => 0.0723042
+(1, -1) ~ (5, 196) => 0.169306
+(1, -1) ~ (5, 197) => 0.0539154
+(1, -1) ~ (5, 198) => 0.0602437
+(1, -1) ~ (5, 199) => 0.0105197
+(1, -1) ~ (5, 200) => 0.00760943
+(1, -1) ~ (5, 201) => 0.0030663
+(1, -1) ~ (5, 202) => 0.00187194
+(1, -1) ~ (5, 203) => 0.000843763
+(1, -1) ~ (5, 204) => 0.0013566
+(1, -1) ~ (5, 205) => 0.00162685
+(1, -1) ~ (5, 206) => 0.00127143
+(1, -1) ~ (5, 207) => 0.000714242
+(1, -1) ~ (5, 208) => 0.00414246
+(1, -1) ~ (5, 209) => 0.0776041
+(1, -1) ~ (5, 210) => 0.157119
+(1, -1) ~ (5, 211) => 0.0491796
+(1, -1) ~ (5, 212) => 0.0065279
+(1, -1) ~ (5, 213) => 0.000961781
+(1, -1) ~ (5, 214) => 0.000794649
+(1, -1) ~ (5, 215) => 0.00525928
+(1, -1) ~ (5, 216) => 0.051954
+(1, -1) ~ (5, 217) => 0.199451
+(1, -1) ~ (5, 218) => 0.0342938
+(1, -1) ~ (5, 219) => 0.200277
+(1, -1) ~ (5, 220) => 0.253064
+(1, -1) ~ (5, 221) => 0.0238088
+(1, -1) ~ (5, 222) => 0.00637895
+(1, -1) ~ (5, 223) => 0.000442386
+(1, -1) ~ (5, 224) => 0.0001
+(1, -1) ~ (5, 225) => 0.0001
+(1, -1) ~ (5, 226) => 0.0001
+(1, -1) ~ (5, 227) => 0.000102162
+(1, -1) ~ (5, 228) => 0.000338435
+(1, -1) ~ (5, 229) => 0.00240248
+(1, -1) ~ (5, 230) => 0.0039956
+(1, -1) ~ (5, 231) => 0.00555378
+(1, -1) ~ (5, 232) => 0.00682056
+(1, -1) ~ (5, 233) => 0.00606287
+
+; Sparse posterior probability matrix for sequences 2 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (3, 0) => 0.641212
+(2, 1) ~ (3, 0) => 0.336422
+(2, 1) ~ (3, 1) => 0.511558
+(2, 2) ~ (3, 1) => 0.460287
+(2, 2) ~ (3, 2) => 0.384703
+(2, 3) ~ (3, 2) => 0.586674
+(2, 3) ~ (3, 3) => 0.273605
+(2, 4) ~ (3, 3) => 0.694718
+(2, 4) ~ (3, 4) => 0.0575482
+(2, 5) ~ (3, 4) => 0.915073
+(2, 5) ~ (3, 5) => 0.0338163
+(2, 6) ~ (3, 3) => 0.0147276
+(2, 6) ~ (3, 5) => 0.938848
+(2, 6) ~ (3, 6) => 0.0286899
+(2, 7) ~ (3, 4) => 0.0145278
+(2, 7) ~ (3, 6) => 0.946004
+(2, 7) ~ (3, 7) => 0.0239216
+(2, 8) ~ (3, 5) => 0.0105281
+(2, 8) ~ (3, 7) => 0.956457
+(2, 8) ~ (3, 8) => 0.0110752
+(2, 9) ~ (3, 8) => 0.974224
+(2, 10) ~ (3, 9) => 0.991668
+(2, 11) ~ (3, 10) => 0.998154
+(2, 12) ~ (3, 11) => 0.999307
+(2, 13) ~ (3, 12) => 0.999596
+(2, 14) ~ (3, 13) => 0.999836
+(2, 15) ~ (3, 14) => 0.999976
+(2, 16) ~ (3, 15) => 0.999972
+(2, 17) ~ (3, 16) => 0.999975
+(2, 18) ~ (3, 17) => 0.999996
+(2, 19) ~ (3, 18) => 0.999998
+(2, 20) ~ (3, 19) => 0.999997
+(2, 21) ~ (3, 20) => 0.999996
+(2, 22) ~ (3, 21) => 0.999995
+(2, 23) ~ (3, 22) => 0.999998
+(2, 24) ~ (3, 23) => 1
+(2, 25) ~ (3, 24) => 0.999999
+(2, 26) ~ (3, 25) => 0.999999
+(2, 27) ~ (3, 26) => 0.999999
+(2, 28) ~ (3, 27) => 0.999998
+(2, 29) ~ (3, 28) => 0.999997
+(2, 30) ~ (3, 29) => 0.999998
+(2, 31) ~ (3, 30) => 0.999998
+(2, 32) ~ (3, 31) => 0.999998
+(2, 33) ~ (3, 32) => 0.999997
+(2, 34) ~ (3, 33) => 0.999996
+(2, 35) ~ (3, 34) => 0.999995
+(2, 36) ~ (3, 35) => 0.999996
+(2, 37) ~ (3, 36) => 0.999987
+(2, 38) ~ (3, 37) => 0.999968
+(2, 39) ~ (3, 38) => 0.999948
+(2, 40) ~ (3, 39) => 0.999941
+(2, 41) ~ (3, 40) => 0.999937
+(2, 42) ~ (3, 41) => 0.999907
+(2, 43) ~ (3, 42) => 0.999918
+(2, 44) ~ (3, 43) => 0.999976
+(2, 45) ~ (3, 44) => 0.999996
+(2, 46) ~ (3, 45) => 0.999993
+(2, 47) ~ (3, 46) => 0.999988
+(2, 48) ~ (3, 47) => 0.999979
+(2, 49) ~ (3, 48) => 0.999974
+(2, 50) ~ (3, 49) => 0.999928
+(2, 51) ~ (3, 50) => 0.999902
+(2, 52) ~ (3, 51) => 0.999916
+(2, 53) ~ (3, 52) => 0.99991
+(2, 54) ~ (3, 53) => 0.999904
+(2, 55) ~ (3, 54) => 0.999936
+(2, 56) ~ (3, 55) => 0.999966
+(2, 57) ~ (3, 56) => 0.999997
+(2, 58) ~ (3, 57) => 0.999998
+(2, 59) ~ (3, 58) => 0.999997
+(2, 60) ~ (3, 59) => 0.999973
+(2, 61) ~ (3, 60) => 0.999882
+(2, 62) ~ (3, 61) => 0.997265
+(2, 63) ~ (3, 62) => 0.988991
+(2, 63) ~ (3, 63) => 0.010956
+(2, 64) ~ (3, 63) => 0.884033
+(2, 64) ~ (3, 64) => 0.115727
+(2, 65) ~ (3, 64) => 0.779124
+(2, 65) ~ (3, 65) => 0.220488
+(2, 66) ~ (3, 65) => 0.674288
+(2, 66) ~ (3, 66) => 0.325292
+(2, 67) ~ (3, 66) => 0.173069
+(2, 67) ~ (3, 67) => 0.826524
+(2, 68) ~ (3, 67) => 0.0935608
+(2, 68) ~ (3, 68) => 0.906057
+(2, 69) ~ (3, 68) => 0.0174093
+(2, 69) ~ (3, 69) => 0.982512
+(2, 70) ~ (3, 70) => 0.999794
+(2, 71) ~ (3, 71) => 0.999988
+(2, 72) ~ (3, 72) => 0.999988
+(2, 73) ~ (3, 73) => 0.999992
+(2, 74) ~ (3, 74) => 0.999995
+(2, 75) ~ (3, 75) => 0.999999
+(2, 76) ~ (3, 76) => 1
+(2, 77) ~ (3, 77) => 0.999999
+(2, 78) ~ (3, 78) => 0.999999
+(2, 79) ~ (3, 79) => 0.999999
+(2, 80) ~ (3, 80) => 0.999999
+(2, 81) ~ (3, 81) => 0.999997
+(2, 82) ~ (3, 82) => 0.999996
+(2, 83) ~ (3, 83) => 0.999997
+(2, 84) ~ (3, 84) => 0.999996
+(2, 85) ~ (3, 85) => 0.999997
+(2, 86) ~ (3, 86) => 0.999984
+(2, 87) ~ (3, 87) => 0.99998
+(2, 88) ~ (3, 88) => 0.999993
+(2, 89) ~ (3, 89) => 0.999995
+(2, 90) ~ (3, 90) => 0.999998
+(2, 91) ~ (3, 91) => 0.999999
+(2, 92) ~ (3, 92) => 0.999999
+(2, 93) ~ (3, 93) => 0.999999
+(2, 94) ~ (3, 94) => 0.999999
+(2, 95) ~ (3, 95) => 1
+(2, 96) ~ (3, 96) => 0.999999
+(2, 97) ~ (3, 97) => 0.999997
+(2, 98) ~ (3, 98) => 0.999997
+(2, 99) ~ (3, 99) => 0.999997
+(2, 100) ~ (3, 100) => 0.999984
+(2, 101) ~ (3, 101) => 0.99998
+(2, 102) ~ (3, 102) => 0.999981
+(2, 103) ~ (3, 103) => 0.999984
+(2, 104) ~ (3, 104) => 0.999989
+(2, 105) ~ (3, 105) => 0.999997
+(2, 106) ~ (3, 106) => 0.999998
+(2, 107) ~ (3, 107) => 0.999997
+(2, 108) ~ (3, 108) => 0.999998
+(2, 109) ~ (3, 109) => 0.999999
+(2, 110) ~ (3, 110) => 0.999999
+(2, 111) ~ (3, 111) => 0.999999
+(2, 112) ~ (3, 112) => 0.999999
+(2, 113) ~ (3, 113) => 0.999999
+(2, 114) ~ (3, 114) => 0.999999
+(2, 115) ~ (3, 115) => 0.999999
+(2, 116) ~ (3, 116) => 0.999998
+(2, 117) ~ (3, 117) => 0.999998
+(2, 118) ~ (3, 118) => 0.999999
+(2, 119) ~ (3, 119) => 0.999995
+(2, 120) ~ (3, 120) => 0.999987
+(2, 121) ~ (3, 121) => 0.999988
+(2, 122) ~ (3, 122) => 0.99999
+(2, 123) ~ (3, 123) => 0.999997
+(2, 124) ~ (3, 124) => 0.999999
+(2, 125) ~ (3, 125) => 0.999999
+(2, 126) ~ (3, 126) => 0.999999
+(2, 127) ~ (3, 127) => 0.999999
+(2, 128) ~ (3, 128) => 0.999999
+(2, 129) ~ (3, 129) => 0.999999
+(2, 130) ~ (3, 130) => 0.999997
+(2, 131) ~ (3, 131) => 0.999977
+(2, 132) ~ (3, 132) => 0.999956
+(2, 133) ~ (3, 133) => 0.999966
+(2, 134) ~ (3, 134) => 0.999969
+(2, 135) ~ (3, 135) => 0.999994
+(2, 136) ~ (3, 136) => 0.999995
+(2, 137) ~ (3, 137) => 0.999984
+(2, 138) ~ (3, 138) => 0.999983
+(2, 139) ~ (3, 139) => 0.999991
+(2, 140) ~ (3, 140) => 0.99998
+(2, 141) ~ (3, 141) => 0.99998
+(2, 142) ~ (3, 142) => 0.999994
+(2, 143) ~ (3, 143) => 0.99999
+(2, 144) ~ (3, 144) => 0.99997
+(2, 145) ~ (3, 145) => 0.999975
+(2, 146) ~ (3, 146) => 0.999986
+(2, 147) ~ (3, 147) => 0.999997
+(2, 148) ~ (3, 148) => 0.999998
+(2, 149) ~ (3, 149) => 0.999999
+(2, 150) ~ (3, 150) => 0.999999
+(2, 151) ~ (3, 151) => 0.999999
+(2, 152) ~ (3, 152) => 0.999999
+(2, 153) ~ (3, 153) => 0.999995
+(2, 154) ~ (3, 154) => 0.999992
+(2, 155) ~ (3, 155) => 0.999995
+(2, 156) ~ (3, 156) => 0.999998
+(2, 157) ~ (3, 157) => 0.999997
+(2, 158) ~ (3, 158) => 0.999997
+(2, 159) ~ (3, 159) => 0.999996
+(2, 160) ~ (3, 160) => 0.999995
+(2, 161) ~ (3, 161) => 0.999987
+(2, 162) ~ (3, 162) => 0.999988
+(2, 163) ~ (3, 163) => 0.999995
+(2, 164) ~ (3, 164) => 0.999991
+(2, 165) ~ (3, 165) => 0.999992
+(2, 166) ~ (3, 166) => 0.999996
+(2, 167) ~ (3, 167) => 0.999997
+(2, 168) ~ (3, 168) => 0.999993
+(2, 169) ~ (3, 169) => 0.999982
+(2, 170) ~ (3, 170) => 0.999971
+(2, 171) ~ (3, 171) => 0.999953
+(2, 172) ~ (3, 172) => 0.999961
+(2, 173) ~ (3, 173) => 0.999982
+(2, 174) ~ (3, 174) => 0.999991
+(2, 175) ~ (3, 175) => 0.999995
+(2, 176) ~ (3, 176) => 0.999964
+(2, 177) ~ (3, 177) => 0.999867
+(2, 178) ~ (3, 178) => 0.999636
+(2, 179) ~ (3, 179) => 0.999451
+(2, 180) ~ (3, 180) => 0.999448
+(2, 181) ~ (3, 181) => 0.999625
+(2, 182) ~ (3, 182) => 0.999892
+(2, 183) ~ (3, 183) => 0.999993
+(2, 184) ~ (3, 184) => 0.999999
+(2, 185) ~ (3, 185) => 0.999999
+(2, 186) ~ (3, 186) => 0.999999
+(2, 187) ~ (3, 187) => 0.999999
+(2, 188) ~ (3, 188) => 0.999999
+(2, 189) ~ (3, 189) => 0.999999
+(2, 190) ~ (3, 190) => 0.999999
+(2, 191) ~ (3, 191) => 1
+(2, 192) ~ (3, 192) => 0.999999
+(2, 193) ~ (3, 193) => 0.999999
+(2, 194) ~ (3, 194) => 0.999998
+(2, 195) ~ (3, 195) => 0.99999
+(2, 196) ~ (3, 196) => 0.999989
+(2, 197) ~ (3, 197) => 0.999996
+(2, 198) ~ (3, 198) => 0.999989
+(2, 199) ~ (3, 199) => 0.999875
+(2, 200) ~ (3, 200) => 0.999836
+(2, 201) ~ (3, 201) => 0.999867
+(2, 202) ~ (3, 202) => 0.999916
+(2, 203) ~ (3, 203) => 0.999955
+(2, 204) ~ (3, 204) => 0.999973
+(2, 205) ~ (3, 205) => 0.999936
+(2, 206) ~ (3, 206) => 0.999923
+(2, 207) ~ (3, 207) => 0.999931
+(2, 208) ~ (3, 208) => 0.999939
+(2, 209) ~ (3, 209) => 0.999943
+(2, 210) ~ (3, 210) => 0.999978
+(2, 211) ~ (3, 211) => 0.999995
+(2, 212) ~ (3, 212) => 0.999999
+(2, 213) ~ (3, 213) => 0.999992
+(2, 214) ~ (3, 214) => 0.999981
+(2, 215) ~ (3, 215) => 0.999978
+(2, 216) ~ (3, 216) => 0.999992
+(2, 217) ~ (3, 217) => 0.99998
+(2, 218) ~ (3, 218) => 0.999971
+(2, 219) ~ (3, 219) => 0.999974
+(2, 220) ~ (3, 220) => 0.999974
+(2, 221) ~ (3, 221) => 0.999983
+(2, 222) ~ (3, 222) => 0.999978
+(2, 223) ~ (3, 223) => 0.99993
+(2, 224) ~ (3, 224) => 0.999882
+(2, 225) ~ (3, 225) => 0.999901
+(2, 226) ~ (3, 226) => 0.999901
+(2, 227) ~ (3, 227) => 0.999947
+(2, 228) ~ (3, 228) => 0.999996
+(2, 229) ~ (3, 229) => 0.999997
+(2, 230) ~ (3, 230) => 0.999999
+(2, 231) ~ (3, 231) => 0.999999
+(2, 232) ~ (3, 232) => 0.999999
+(2, 233) ~ (3, 233) => 0.999999
+(2, 234) ~ (3, 234) => 0.999999
+(2, 235) ~ (3, 235) => 0.999999
+(2, 236) ~ (3, 236) => 0.999993
+(2, 237) ~ (3, 237) => 0.999994
+(2, 238) ~ (3, 238) => 0.999999
+
+; gap posteriors
+(2, 0) ~ (3, -1) => 0.358788
+(2, 1) ~ (3, -1) => 0.15202
+(2, 2) ~ (3, -1) => 0.15501
+(2, 3) ~ (3, -1) => 0.139721
+(2, 4) ~ (3, -1) => 0.247734
+(2, 5) ~ (3, -1) => 0.0511105
+(2, 6) ~ (3, -1) => 0.0177344
+(2, 7) ~ (3, -1) => 0.0155469
+(2, 8) ~ (3, -1) => 0.0219392
+(2, 9) ~ (3, -1) => 0.025776
+(2, 10) ~ (3, -1) => 0.00833166
+(2, 11) ~ (3, -1) => 0.0018459
+(2, 12) ~ (3, -1) => 0.000692904
+(2, 13) ~ (3, -1) => 0.000403762
+(2, 14) ~ (3, -1) => 0.00016439
+(2, 15) ~ (3, -1) => 0.0001
+(2, 16) ~ (3, -1) => 0.0001
+(2, 17) ~ (3, -1) => 0.0001
+(2, 18) ~ (3, -1) => 0.0001
+(2, 19) ~ (3, -1) => 0.0001
+(2, 20) ~ (3, -1) => 0.0001
+(2, 21) ~ (3, -1) => 0.0001
+(2, 22) ~ (3, -1) => 0.0001
+(2, 23) ~ (3, -1) => 0.0001
+(2, 24) ~ (3, -1) => 0.0001
+(2, 25) ~ (3, -1) => 0.0001
+(2, 26) ~ (3, -1) => 0.0001
+(2, 27) ~ (3, -1) => 0.0001
+(2, 28) ~ (3, -1) => 0.0001
+(2, 29) ~ (3, -1) => 0.0001
+(2, 30) ~ (3, -1) => 0.0001
+(2, 31) ~ (3, -1) => 0.0001
+(2, 32) ~ (3, -1) => 0.0001
+(2, 33) ~ (3, -1) => 0.0001
+(2, 34) ~ (3, -1) => 0.0001
+(2, 35) ~ (3, -1) => 0.0001
+(2, 36) ~ (3, -1) => 0.0001
+(2, 37) ~ (3, -1) => 0.0001
+(2, 38) ~ (3, -1) => 0.0001
+(2, 39) ~ (3, -1) => 0.0001
+(2, 40) ~ (3, -1) => 0.0001
+(2, 41) ~ (3, -1) => 0.0001
+(2, 42) ~ (3, -1) => 0.0001
+(2, 43) ~ (3, -1) => 0.0001
+(2, 44) ~ (3, -1) => 0.0001
+(2, 45) ~ (3, -1) => 0.0001
+(2, 46) ~ (3, -1) => 0.0001
+(2, 47) ~ (3, -1) => 0.0001
+(2, 48) ~ (3, -1) => 0.0001
+(2, 49) ~ (3, -1) => 0.0001
+(2, 50) ~ (3, -1) => 0.0001
+(2, 51) ~ (3, -1) => 0.0001
+(2, 52) ~ (3, -1) => 0.0001
+(2, 53) ~ (3, -1) => 0.0001
+(2, 54) ~ (3, -1) => 0.0001
+(2, 55) ~ (3, -1) => 0.0001
+(2, 56) ~ (3, -1) => 0.0001
+(2, 57) ~ (3, -1) => 0.0001
+(2, 58) ~ (3, -1) => 0.0001
+(2, 59) ~ (3, -1) => 0.0001
+(2, 60) ~ (3, -1) => 0.0001
+(2, 61) ~ (3, -1) => 0.000117719
+(2, 62) ~ (3, -1) => 0.0027349
+(2, 63) ~ (3, -1) => 0.0001
+(2, 64) ~ (3, -1) => 0.000240259
+(2, 65) ~ (3, -1) => 0.000388235
+(2, 66) ~ (3, -1) => 0.000420779
+(2, 67) ~ (3, -1) => 0.000407219
+(2, 68) ~ (3, -1) => 0.000381768
+(2, 69) ~ (3, -1) => 0.0001
+(2, 70) ~ (3, -1) => 0.000206292
+(2, 71) ~ (3, -1) => 0.0001
+(2, 72) ~ (3, -1) => 0.0001
+(2, 73) ~ (3, -1) => 0.0001
+(2, 74) ~ (3, -1) => 0.0001
+(2, 75) ~ (3, -1) => 0.0001
+(2, 76) ~ (3, -1) => 0.0001
+(2, 77) ~ (3, -1) => 0.0001
+(2, 78) ~ (3, -1) => 0.0001
+(2, 79) ~ (3, -1) => 0.0001
+(2, 80) ~ (3, -1) => 0.0001
+(2, 81) ~ (3, -1) => 0.0001
+(2, 82) ~ (3, -1) => 0.0001
+(2, 83) ~ (3, -1) => 0.0001
+(2, 84) ~ (3, -1) => 0.0001
+(2, 85) ~ (3, -1) => 0.0001
+(2, 86) ~ (3, -1) => 0.0001
+(2, 87) ~ (3, -1) => 0.0001
+(2, 88) ~ (3, -1) => 0.0001
+(2, 89) ~ (3, -1) => 0.0001
+(2, 90) ~ (3, -1) => 0.0001
+(2, 91) ~ (3, -1) => 0.0001
+(2, 92) ~ (3, -1) => 0.0001
+(2, 93) ~ (3, -1) => 0.0001
+(2, 94) ~ (3, -1) => 0.0001
+(2, 95) ~ (3, -1) => 0.0001
+(2, 96) ~ (3, -1) => 0.0001
+(2, 97) ~ (3, -1) => 0.0001
+(2, 98) ~ (3, -1) => 0.0001
+(2, 99) ~ (3, -1) => 0.0001
+(2, 100) ~ (3, -1) => 0.0001
+(2, 101) ~ (3, -1) => 0.0001
+(2, 102) ~ (3, -1) => 0.0001
+(2, 103) ~ (3, -1) => 0.0001
+(2, 104) ~ (3, -1) => 0.0001
+(2, 105) ~ (3, -1) => 0.0001
+(2, 106) ~ (3, -1) => 0.0001
+(2, 107) ~ (3, -1) => 0.0001
+(2, 108) ~ (3, -1) => 0.0001
+(2, 109) ~ (3, -1) => 0.0001
+(2, 110) ~ (3, -1) => 0.0001
+(2, 111) ~ (3, -1) => 0.0001
+(2, 112) ~ (3, -1) => 0.0001
+(2, 113) ~ (3, -1) => 0.0001
+(2, 114) ~ (3, -1) => 0.0001
+(2, 115) ~ (3, -1) => 0.0001
+(2, 116) ~ (3, -1) => 0.0001
+(2, 117) ~ (3, -1) => 0.0001
+(2, 118) ~ (3, -1) => 0.0001
+(2, 119) ~ (3, -1) => 0.0001
+(2, 120) ~ (3, -1) => 0.0001
+(2, 121) ~ (3, -1) => 0.0001
+(2, 122) ~ (3, -1) => 0.0001
+(2, 123) ~ (3, -1) => 0.0001
+(2, 124) ~ (3, -1) => 0.0001
+(2, 125) ~ (3, -1) => 0.0001
+(2, 126) ~ (3, -1) => 0.0001
+(2, 127) ~ (3, -1) => 0.0001
+(2, 128) ~ (3, -1) => 0.0001
+(2, 129) ~ (3, -1) => 0.0001
+(2, 130) ~ (3, -1) => 0.0001
+(2, 131) ~ (3, -1) => 0.0001
+(2, 132) ~ (3, -1) => 0.0001
+(2, 133) ~ (3, -1) => 0.0001
+(2, 134) ~ (3, -1) => 0.0001
+(2, 135) ~ (3, -1) => 0.0001
+(2, 136) ~ (3, -1) => 0.0001
+(2, 137) ~ (3, -1) => 0.0001
+(2, 138) ~ (3, -1) => 0.0001
+(2, 139) ~ (3, -1) => 0.0001
+(2, 140) ~ (3, -1) => 0.0001
+(2, 141) ~ (3, -1) => 0.0001
+(2, 142) ~ (3, -1) => 0.0001
+(2, 143) ~ (3, -1) => 0.0001
+(2, 144) ~ (3, -1) => 0.0001
+(2, 145) ~ (3, -1) => 0.0001
+(2, 146) ~ (3, -1) => 0.0001
+(2, 147) ~ (3, -1) => 0.0001
+(2, 148) ~ (3, -1) => 0.0001
+(2, 149) ~ (3, -1) => 0.0001
+(2, 150) ~ (3, -1) => 0.0001
+(2, 151) ~ (3, -1) => 0.0001
+(2, 152) ~ (3, -1) => 0.0001
+(2, 153) ~ (3, -1) => 0.0001
+(2, 154) ~ (3, -1) => 0.0001
+(2, 155) ~ (3, -1) => 0.0001
+(2, 156) ~ (3, -1) => 0.0001
+(2, 157) ~ (3, -1) => 0.0001
+(2, 158) ~ (3, -1) => 0.0001
+(2, 159) ~ (3, -1) => 0.0001
+(2, 160) ~ (3, -1) => 0.0001
+(2, 161) ~ (3, -1) => 0.0001
+(2, 162) ~ (3, -1) => 0.0001
+(2, 163) ~ (3, -1) => 0.0001
+(2, 164) ~ (3, -1) => 0.0001
+(2, 165) ~ (3, -1) => 0.0001
+(2, 166) ~ (3, -1) => 0.0001
+(2, 167) ~ (3, -1) => 0.0001
+(2, 168) ~ (3, -1) => 0.0001
+(2, 169) ~ (3, -1) => 0.0001
+(2, 170) ~ (3, -1) => 0.0001
+(2, 171) ~ (3, -1) => 0.0001
+(2, 172) ~ (3, -1) => 0.0001
+(2, 173) ~ (3, -1) => 0.0001
+(2, 174) ~ (3, -1) => 0.0001
+(2, 175) ~ (3, -1) => 0.0001
+(2, 176) ~ (3, -1) => 0.0001
+(2, 177) ~ (3, -1) => 0.00013268
+(2, 178) ~ (3, -1) => 0.000363886
+(2, 179) ~ (3, -1) => 0.00054872
+(2, 180) ~ (3, -1) => 0.000552475
+(2, 181) ~ (3, -1) => 0.00037545
+(2, 182) ~ (3, -1) => 0.000107765
+(2, 183) ~ (3, -1) => 0.0001
+(2, 184) ~ (3, -1) => 0.0001
+(2, 185) ~ (3, -1) => 0.0001
+(2, 186) ~ (3, -1) => 0.0001
+(2, 187) ~ (3, -1) => 0.0001
+(2, 188) ~ (3, -1) => 0.0001
+(2, 189) ~ (3, -1) => 0.0001
+(2, 190) ~ (3, -1) => 0.0001
+(2, 191) ~ (3, -1) => 0.0001
+(2, 192) ~ (3, -1) => 0.0001
+(2, 193) ~ (3, -1) => 0.0001
+(2, 194) ~ (3, -1) => 0.0001
+(2, 195) ~ (3, -1) => 0.0001
+(2, 196) ~ (3, -1) => 0.0001
+(2, 197) ~ (3, -1) => 0.0001
+(2, 198) ~ (3, -1) => 0.0001
+(2, 199) ~ (3, -1) => 0.00012517
+(2, 200) ~ (3, -1) => 0.000163734
+(2, 201) ~ (3, -1) => 0.000132918
+(2, 202) ~ (3, -1) => 0.0001
+(2, 203) ~ (3, -1) => 0.0001
+(2, 204) ~ (3, -1) => 0.0001
+(2, 205) ~ (3, -1) => 0.0001
+(2, 206) ~ (3, -1) => 0.0001
+(2, 207) ~ (3, -1) => 0.0001
+(2, 208) ~ (3, -1) => 0.0001
+(2, 209) ~ (3, -1) => 0.0001
+(2, 210) ~ (3, -1) => 0.0001
+(2, 211) ~ (3, -1) => 0.0001
+(2, 212) ~ (3, -1) => 0.0001
+(2, 213) ~ (3, -1) => 0.0001
+(2, 214) ~ (3, -1) => 0.0001
+(2, 215) ~ (3, -1) => 0.0001
+(2, 216) ~ (3, -1) => 0.0001
+(2, 217) ~ (3, -1) => 0.0001
+(2, 218) ~ (3, -1) => 0.0001
+(2, 219) ~ (3, -1) => 0.0001
+(2, 220) ~ (3, -1) => 0.0001
+(2, 221) ~ (3, -1) => 0.0001
+(2, 222) ~ (3, -1) => 0.0001
+(2, 223) ~ (3, -1) => 0.0001
+(2, 224) ~ (3, -1) => 0.000117719
+(2, 225) ~ (3, -1) => 0.0001
+(2, 226) ~ (3, -1) => 0.0001
+(2, 227) ~ (3, -1) => 0.0001
+(2, 228) ~ (3, -1) => 0.0001
+(2, 229) ~ (3, -1) => 0.0001
+(2, 230) ~ (3, -1) => 0.0001
+(2, 231) ~ (3, -1) => 0.0001
+(2, 232) ~ (3, -1) => 0.0001
+(2, 233) ~ (3, -1) => 0.0001
+(2, 234) ~ (3, -1) => 0.0001
+(2, 235) ~ (3, -1) => 0.0001
+(2, 236) ~ (3, -1) => 0.0001
+(2, 237) ~ (3, -1) => 0.0001
+(2, 238) ~ (3, -1) => 0.0001
+
+(2, -1) ~ (3, 0) => 0.0223667
+(2, -1) ~ (3, 1) => 0.0281544
+(2, -1) ~ (3, 2) => 0.0286234
+(2, -1) ~ (3, 3) => 0.0169492
+(2, -1) ~ (3, 4) => 0.0128508
+(2, -1) ~ (3, 5) => 0.0168075
+(2, -1) ~ (3, 6) => 0.0253065
+(2, -1) ~ (3, 7) => 0.0196209
+(2, -1) ~ (3, 8) => 0.0147008
+(2, -1) ~ (3, 9) => 0.00833166
+(2, -1) ~ (3, 10) => 0.0018459
+(2, -1) ~ (3, 11) => 0.000692904
+(2, -1) ~ (3, 12) => 0.000403762
+(2, -1) ~ (3, 13) => 0.00016439
+(2, -1) ~ (3, 14) => 0.0001
+(2, -1) ~ (3, 15) => 0.0001
+(2, -1) ~ (3, 16) => 0.0001
+(2, -1) ~ (3, 17) => 0.0001
+(2, -1) ~ (3, 18) => 0.0001
+(2, -1) ~ (3, 19) => 0.0001
+(2, -1) ~ (3, 20) => 0.0001
+(2, -1) ~ (3, 21) => 0.0001
+(2, -1) ~ (3, 22) => 0.0001
+(2, -1) ~ (3, 23) => 0.0001
+(2, -1) ~ (3, 24) => 0.0001
+(2, -1) ~ (3, 25) => 0.0001
+(2, -1) ~ (3, 26) => 0.0001
+(2, -1) ~ (3, 27) => 0.0001
+(2, -1) ~ (3, 28) => 0.0001
+(2, -1) ~ (3, 29) => 0.0001
+(2, -1) ~ (3, 30) => 0.0001
+(2, -1) ~ (3, 31) => 0.0001
+(2, -1) ~ (3, 32) => 0.0001
+(2, -1) ~ (3, 33) => 0.0001
+(2, -1) ~ (3, 34) => 0.0001
+(2, -1) ~ (3, 35) => 0.0001
+(2, -1) ~ (3, 36) => 0.0001
+(2, -1) ~ (3, 37) => 0.0001
+(2, -1) ~ (3, 38) => 0.0001
+(2, -1) ~ (3, 39) => 0.0001
+(2, -1) ~ (3, 40) => 0.0001
+(2, -1) ~ (3, 41) => 0.0001
+(2, -1) ~ (3, 42) => 0.0001
+(2, -1) ~ (3, 43) => 0.0001
+(2, -1) ~ (3, 44) => 0.0001
+(2, -1) ~ (3, 45) => 0.0001
+(2, -1) ~ (3, 46) => 0.0001
+(2, -1) ~ (3, 47) => 0.0001
+(2, -1) ~ (3, 48) => 0.0001
+(2, -1) ~ (3, 49) => 0.0001
+(2, -1) ~ (3, 50) => 0.0001
+(2, -1) ~ (3, 51) => 0.0001
+(2, -1) ~ (3, 52) => 0.0001
+(2, -1) ~ (3, 53) => 0.0001
+(2, -1) ~ (3, 54) => 0.0001
+(2, -1) ~ (3, 55) => 0.0001
+(2, -1) ~ (3, 56) => 0.0001
+(2, -1) ~ (3, 57) => 0.0001
+(2, -1) ~ (3, 58) => 0.0001
+(2, -1) ~ (3, 59) => 0.0001
+(2, -1) ~ (3, 60) => 0.000117719
+(2, -1) ~ (3, 61) => 0.0027349
+(2, -1) ~ (3, 62) => 0.0110089
+(2, -1) ~ (3, 63) => 0.105011
+(2, -1) ~ (3, 64) => 0.10515
+(2, -1) ~ (3, 65) => 0.105224
+(2, -1) ~ (3, 66) => 0.50164
+(2, -1) ~ (3, 67) => 0.0799153
+(2, -1) ~ (3, 68) => 0.0765333
+(2, -1) ~ (3, 69) => 0.0174879
+(2, -1) ~ (3, 70) => 0.000206292
+(2, -1) ~ (3, 71) => 0.0001
+(2, -1) ~ (3, 72) => 0.0001
+(2, -1) ~ (3, 73) => 0.0001
+(2, -1) ~ (3, 74) => 0.0001
+(2, -1) ~ (3, 75) => 0.0001
+(2, -1) ~ (3, 76) => 0.0001
+(2, -1) ~ (3, 77) => 0.0001
+(2, -1) ~ (3, 78) => 0.0001
+(2, -1) ~ (3, 79) => 0.0001
+(2, -1) ~ (3, 80) => 0.0001
+(2, -1) ~ (3, 81) => 0.0001
+(2, -1) ~ (3, 82) => 0.0001
+(2, -1) ~ (3, 83) => 0.0001
+(2, -1) ~ (3, 84) => 0.0001
+(2, -1) ~ (3, 85) => 0.0001
+(2, -1) ~ (3, 86) => 0.0001
+(2, -1) ~ (3, 87) => 0.0001
+(2, -1) ~ (3, 88) => 0.0001
+(2, -1) ~ (3, 89) => 0.0001
+(2, -1) ~ (3, 90) => 0.0001
+(2, -1) ~ (3, 91) => 0.0001
+(2, -1) ~ (3, 92) => 0.0001
+(2, -1) ~ (3, 93) => 0.0001
+(2, -1) ~ (3, 94) => 0.0001
+(2, -1) ~ (3, 95) => 0.0001
+(2, -1) ~ (3, 96) => 0.0001
+(2, -1) ~ (3, 97) => 0.0001
+(2, -1) ~ (3, 98) => 0.0001
+(2, -1) ~ (3, 99) => 0.0001
+(2, -1) ~ (3, 100) => 0.0001
+(2, -1) ~ (3, 101) => 0.0001
+(2, -1) ~ (3, 102) => 0.0001
+(2, -1) ~ (3, 103) => 0.0001
+(2, -1) ~ (3, 104) => 0.0001
+(2, -1) ~ (3, 105) => 0.0001
+(2, -1) ~ (3, 106) => 0.0001
+(2, -1) ~ (3, 107) => 0.0001
+(2, -1) ~ (3, 108) => 0.0001
+(2, -1) ~ (3, 109) => 0.0001
+(2, -1) ~ (3, 110) => 0.0001
+(2, -1) ~ (3, 111) => 0.0001
+(2, -1) ~ (3, 112) => 0.0001
+(2, -1) ~ (3, 113) => 0.0001
+(2, -1) ~ (3, 114) => 0.0001
+(2, -1) ~ (3, 115) => 0.0001
+(2, -1) ~ (3, 116) => 0.0001
+(2, -1) ~ (3, 117) => 0.0001
+(2, -1) ~ (3, 118) => 0.0001
+(2, -1) ~ (3, 119) => 0.0001
+(2, -1) ~ (3, 120) => 0.0001
+(2, -1) ~ (3, 121) => 0.0001
+(2, -1) ~ (3, 122) => 0.0001
+(2, -1) ~ (3, 123) => 0.0001
+(2, -1) ~ (3, 124) => 0.0001
+(2, -1) ~ (3, 125) => 0.0001
+(2, -1) ~ (3, 126) => 0.0001
+(2, -1) ~ (3, 127) => 0.0001
+(2, -1) ~ (3, 128) => 0.0001
+(2, -1) ~ (3, 129) => 0.0001
+(2, -1) ~ (3, 130) => 0.0001
+(2, -1) ~ (3, 131) => 0.0001
+(2, -1) ~ (3, 132) => 0.0001
+(2, -1) ~ (3, 133) => 0.0001
+(2, -1) ~ (3, 134) => 0.0001
+(2, -1) ~ (3, 135) => 0.0001
+(2, -1) ~ (3, 136) => 0.0001
+(2, -1) ~ (3, 137) => 0.0001
+(2, -1) ~ (3, 138) => 0.0001
+(2, -1) ~ (3, 139) => 0.0001
+(2, -1) ~ (3, 140) => 0.0001
+(2, -1) ~ (3, 141) => 0.0001
+(2, -1) ~ (3, 142) => 0.0001
+(2, -1) ~ (3, 143) => 0.0001
+(2, -1) ~ (3, 144) => 0.0001
+(2, -1) ~ (3, 145) => 0.0001
+(2, -1) ~ (3, 146) => 0.0001
+(2, -1) ~ (3, 147) => 0.0001
+(2, -1) ~ (3, 148) => 0.0001
+(2, -1) ~ (3, 149) => 0.0001
+(2, -1) ~ (3, 150) => 0.0001
+(2, -1) ~ (3, 151) => 0.0001
+(2, -1) ~ (3, 152) => 0.0001
+(2, -1) ~ (3, 153) => 0.0001
+(2, -1) ~ (3, 154) => 0.0001
+(2, -1) ~ (3, 155) => 0.0001
+(2, -1) ~ (3, 156) => 0.0001
+(2, -1) ~ (3, 157) => 0.0001
+(2, -1) ~ (3, 158) => 0.0001
+(2, -1) ~ (3, 159) => 0.0001
+(2, -1) ~ (3, 160) => 0.0001
+(2, -1) ~ (3, 161) => 0.0001
+(2, -1) ~ (3, 162) => 0.0001
+(2, -1) ~ (3, 163) => 0.0001
+(2, -1) ~ (3, 164) => 0.0001
+(2, -1) ~ (3, 165) => 0.0001
+(2, -1) ~ (3, 166) => 0.0001
+(2, -1) ~ (3, 167) => 0.0001
+(2, -1) ~ (3, 168) => 0.0001
+(2, -1) ~ (3, 169) => 0.0001
+(2, -1) ~ (3, 170) => 0.0001
+(2, -1) ~ (3, 171) => 0.0001
+(2, -1) ~ (3, 172) => 0.0001
+(2, -1) ~ (3, 173) => 0.0001
+(2, -1) ~ (3, 174) => 0.0001
+(2, -1) ~ (3, 175) => 0.0001
+(2, -1) ~ (3, 176) => 0.0001
+(2, -1) ~ (3, 177) => 0.00013268
+(2, -1) ~ (3, 178) => 0.000363886
+(2, -1) ~ (3, 179) => 0.00054872
+(2, -1) ~ (3, 180) => 0.000552475
+(2, -1) ~ (3, 181) => 0.00037545
+(2, -1) ~ (3, 182) => 0.000107765
+(2, -1) ~ (3, 183) => 0.0001
+(2, -1) ~ (3, 184) => 0.0001
+(2, -1) ~ (3, 185) => 0.0001
+(2, -1) ~ (3, 186) => 0.0001
+(2, -1) ~ (3, 187) => 0.0001
+(2, -1) ~ (3, 188) => 0.0001
+(2, -1) ~ (3, 189) => 0.0001
+(2, -1) ~ (3, 190) => 0.0001
+(2, -1) ~ (3, 191) => 0.0001
+(2, -1) ~ (3, 192) => 0.0001
+(2, -1) ~ (3, 193) => 0.0001
+(2, -1) ~ (3, 194) => 0.0001
+(2, -1) ~ (3, 195) => 0.0001
+(2, -1) ~ (3, 196) => 0.0001
+(2, -1) ~ (3, 197) => 0.0001
+(2, -1) ~ (3, 198) => 0.0001
+(2, -1) ~ (3, 199) => 0.00012517
+(2, -1) ~ (3, 200) => 0.000163734
+(2, -1) ~ (3, 201) => 0.000132918
+(2, -1) ~ (3, 202) => 0.0001
+(2, -1) ~ (3, 203) => 0.0001
+(2, -1) ~ (3, 204) => 0.0001
+(2, -1) ~ (3, 205) => 0.0001
+(2, -1) ~ (3, 206) => 0.0001
+(2, -1) ~ (3, 207) => 0.0001
+(2, -1) ~ (3, 208) => 0.0001
+(2, -1) ~ (3, 209) => 0.0001
+(2, -1) ~ (3, 210) => 0.0001
+(2, -1) ~ (3, 211) => 0.0001
+(2, -1) ~ (3, 212) => 0.0001
+(2, -1) ~ (3, 213) => 0.0001
+(2, -1) ~ (3, 214) => 0.0001
+(2, -1) ~ (3, 215) => 0.0001
+(2, -1) ~ (3, 216) => 0.0001
+(2, -1) ~ (3, 217) => 0.0001
+(2, -1) ~ (3, 218) => 0.0001
+(2, -1) ~ (3, 219) => 0.0001
+(2, -1) ~ (3, 220) => 0.0001
+(2, -1) ~ (3, 221) => 0.0001
+(2, -1) ~ (3, 222) => 0.0001
+(2, -1) ~ (3, 223) => 0.0001
+(2, -1) ~ (3, 224) => 0.000117719
+(2, -1) ~ (3, 225) => 0.0001
+(2, -1) ~ (3, 226) => 0.0001
+(2, -1) ~ (3, 227) => 0.0001
+(2, -1) ~ (3, 228) => 0.0001
+(2, -1) ~ (3, 229) => 0.0001
+(2, -1) ~ (3, 230) => 0.0001
+(2, -1) ~ (3, 231) => 0.0001
+(2, -1) ~ (3, 232) => 0.0001
+(2, -1) ~ (3, 233) => 0.0001
+(2, -1) ~ (3, 234) => 0.0001
+(2, -1) ~ (3, 235) => 0.0001
+(2, -1) ~ (3, 236) => 0.0001
+(2, -1) ~ (3, 237) => 0.0001
+(2, -1) ~ (3, 238) => 0.0001
+
+; Sparse posterior probability matrix for sequences 2 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (4, 0) => 0.999377
+(2, 1) ~ (4, 1) => 0.995467
+(2, 2) ~ (4, 2) => 0.99136
+(2, 3) ~ (4, 3) => 0.988979
+(2, 4) ~ (4, 4) => 0.988076
+(2, 5) ~ (4, 5) => 0.986908
+(2, 6) ~ (4, 6) => 0.985571
+(2, 7) ~ (4, 7) => 0.903828
+(2, 7) ~ (4, 8) => 0.0131013
+(2, 8) ~ (4, 7) => 0.0742643
+(2, 8) ~ (4, 8) => 0.575007
+(2, 9) ~ (4, 8) => 0.391165
+(2, 9) ~ (4, 9) => 0.145368
+(2, 10) ~ (4, 9) => 0.825541
+(2, 10) ~ (4, 10) => 0.0575333
+(2, 11) ~ (4, 10) => 0.922638
+(2, 12) ~ (4, 11) => 0.983404
+(2, 13) ~ (4, 12) => 0.991746
+(2, 14) ~ (4, 13) => 0.991947
+(2, 15) ~ (4, 14) => 0.991395
+(2, 16) ~ (4, 15) => 0.990648
+(2, 17) ~ (4, 16) => 0.990075
+(2, 18) ~ (4, 17) => 0.981819
+(2, 19) ~ (4, 17) => 0.014132
+(2, 19) ~ (4, 18) => 0.981233
+(2, 20) ~ (4, 19) => 0.988954
+(2, 21) ~ (4, 20) => 0.995239
+(2, 22) ~ (4, 21) => 0.996894
+(2, 23) ~ (4, 22) => 0.999589
+(2, 24) ~ (4, 23) => 0.999956
+(2, 25) ~ (4, 24) => 0.999953
+(2, 26) ~ (4, 25) => 0.999184
+(2, 27) ~ (4, 26) => 0.995703
+(2, 28) ~ (4, 27) => 0.986325
+(2, 28) ~ (4, 28) => 0.0128934
+(2, 29) ~ (4, 28) => 0.983552
+(2, 29) ~ (4, 29) => 0.0152537
+(2, 30) ~ (4, 29) => 0.973276
+(2, 30) ~ (4, 30) => 0.0237234
+(2, 31) ~ (4, 30) => 0.968983
+(2, 31) ~ (4, 31) => 0.0245086
+(2, 32) ~ (4, 31) => 0.971272
+(2, 33) ~ (4, 32) => 0.996187
+(2, 34) ~ (4, 33) => 0.997889
+(2, 35) ~ (4, 34) => 0.997284
+(2, 36) ~ (4, 35) => 0.997254
+(2, 37) ~ (4, 36) => 0.997789
+(2, 38) ~ (4, 37) => 0.998596
+(2, 39) ~ (4, 38) => 0.99907
+(2, 40) ~ (4, 39) => 0.999393
+(2, 41) ~ (4, 40) => 0.999426
+(2, 42) ~ (4, 41) => 0.999196
+(2, 43) ~ (4, 42) => 0.998651
+(2, 44) ~ (4, 43) => 0.997978
+(2, 45) ~ (4, 44) => 0.995911
+(2, 46) ~ (4, 45) => 0.979815
+(2, 47) ~ (4, 46) => 0.95256
+(2, 48) ~ (4, 47) => 0.726854
+(2, 49) ~ (4, 46) => 0.0339329
+(2, 49) ~ (4, 48) => 0.687985
+(2, 49) ~ (4, 50) => 0.0108284
+(2, 50) ~ (4, 47) => 0.241888
+(2, 50) ~ (4, 49) => 0.678871
+(2, 50) ~ (4, 50) => 0.0119812
+(2, 50) ~ (4, 51) => 0.0115149
+(2, 51) ~ (4, 48) => 0.278494
+(2, 51) ~ (4, 50) => 0.657617
+(2, 51) ~ (4, 51) => 0.0225763
+(2, 51) ~ (4, 52) => 0.0124146
+(2, 52) ~ (4, 48) => 0.0104511
+(2, 52) ~ (4, 49) => 0.278148
+(2, 52) ~ (4, 51) => 0.650281
+(2, 52) ~ (4, 52) => 0.0285677
+(2, 53) ~ (4, 50) => 0.2866
+(2, 53) ~ (4, 52) => 0.64166
+(2, 53) ~ (4, 53) => 0.0164001
+(2, 54) ~ (4, 51) => 0.28829
+(2, 54) ~ (4, 53) => 0.653138
+(2, 55) ~ (4, 52) => 0.301345
+(2, 55) ~ (4, 54) => 0.0274752
+(2, 56) ~ (4, 53) => 0.32171
+(2, 57) ~ (4, 54) => 0.969225
+(2, 58) ~ (4, 55) => 0.99623
+(2, 59) ~ (4, 56) => 0.999074
+(2, 60) ~ (4, 57) => 0.996927
+(2, 61) ~ (4, 58) => 0.993348
+(2, 62) ~ (4, 59) => 0.981947
+(2, 62) ~ (4, 60) => 0.0112494
+(2, 63) ~ (4, 60) => 0.9742
+(2, 63) ~ (4, 61) => 0.0165366
+(2, 64) ~ (4, 61) => 0.91059
+(2, 64) ~ (4, 62) => 0.0616296
+(2, 65) ~ (4, 61) => 0.0261191
+(2, 65) ~ (4, 62) => 0.846318
+(2, 65) ~ (4, 63) => 0.105919
+(2, 66) ~ (4, 62) => 0.044448
+(2, 66) ~ (4, 63) => 0.59303
+(2, 66) ~ (4, 64) => 0.338282
+(2, 67) ~ (4, 63) => 0.0556393
+(2, 67) ~ (4, 64) => 0.278658
+(2, 67) ~ (4, 65) => 0.637234
+(2, 68) ~ (4, 64) => 0.07158
+(2, 68) ~ (4, 65) => 0.171687
+(2, 68) ~ (4, 66) => 0.747612
+(2, 69) ~ (4, 65) => 0.040292
+(2, 69) ~ (4, 66) => 0.0781537
+(2, 69) ~ (4, 67) => 0.876963
+(2, 70) ~ (4, 68) => 0.99133
+(2, 71) ~ (4, 69) => 0.998491
+(2, 72) ~ (4, 70) => 0.997417
+(2, 73) ~ (4, 71) => 0.997108
+(2, 74) ~ (4, 72) => 0.997789
+(2, 75) ~ (4, 73) => 0.999677
+(2, 76) ~ (4, 74) => 0.999859
+(2, 77) ~ (4, 75) => 0.999964
+(2, 78) ~ (4, 76) => 0.99997
+(2, 79) ~ (4, 77) => 0.999968
+(2, 80) ~ (4, 78) => 0.999961
+(2, 81) ~ (4, 79) => 0.999508
+(2, 82) ~ (4, 80) => 0.998251
+(2, 83) ~ (4, 81) => 0.995278
+(2, 84) ~ (4, 82) => 0.993083
+(2, 85) ~ (4, 83) => 0.97802
+(2, 86) ~ (4, 84) => 0.866778
+(2, 87) ~ (4, 84) => 0.0107565
+(2, 87) ~ (4, 85) => 0.650642
+(2, 87) ~ (4, 87) => 0.012186
+(2, 88) ~ (4, 83) => 0.0198774
+(2, 88) ~ (4, 85) => 0.0300812
+(2, 88) ~ (4, 86) => 0.547291
+(2, 89) ~ (4, 84) => 0.111326
+(2, 89) ~ (4, 86) => 0.0429003
+(2, 89) ~ (4, 87) => 0.319238
+(2, 90) ~ (4, 85) => 0.281191
+(2, 90) ~ (4, 87) => 0.0511776
+(2, 90) ~ (4, 88) => 0.10468
+(2, 90) ~ (4, 95) => 0.0102433
+(2, 91) ~ (4, 86) => 0.358175
+(2, 91) ~ (4, 88) => 0.0486361
+(2, 91) ~ (4, 89) => 0.0277334
+(2, 91) ~ (4, 92) => 0.0105276
+(2, 91) ~ (4, 96) => 0.0155106
+(2, 92) ~ (4, 87) => 0.572855
+(2, 92) ~ (4, 89) => 0.0318876
+(2, 92) ~ (4, 90) => 0.0190857
+(2, 92) ~ (4, 93) => 0.0115667
+(2, 92) ~ (4, 97) => 0.0288382
+(2, 93) ~ (4, 88) => 0.792261
+(2, 93) ~ (4, 90) => 0.0313441
+(2, 93) ~ (4, 94) => 0.0122717
+(2, 93) ~ (4, 98) => 0.0298296
+(2, 94) ~ (4, 89) => 0.881622
+(2, 94) ~ (4, 91) => 0.0365619
+(2, 94) ~ (4, 99) => 0.028593
+(2, 95) ~ (4, 90) => 0.879989
+(2, 95) ~ (4, 92) => 0.0289476
+(2, 95) ~ (4, 94) => 0.0161728
+(2, 95) ~ (4, 100) => 0.0176833
+(2, 96) ~ (4, 91) => 0.867539
+(2, 96) ~ (4, 93) => 0.0120693
+(2, 96) ~ (4, 95) => 0.0378733
+(2, 96) ~ (4, 96) => 0.0230727
+(2, 96) ~ (4, 101) => 0.0121137
+(2, 97) ~ (4, 92) => 0.616811
+(2, 97) ~ (4, 93) => 0.0180544
+(2, 97) ~ (4, 96) => 0.241248
+(2, 97) ~ (4, 97) => 0.06405
+(2, 98) ~ (4, 93) => 0.53878
+(2, 98) ~ (4, 94) => 0.0166467
+(2, 98) ~ (4, 97) => 0.328101
+(2, 98) ~ (4, 98) => 0.0620916
+(2, 99) ~ (4, 94) => 0.509288
+(2, 99) ~ (4, 95) => 0.02923
+(2, 99) ~ (4, 98) => 0.33478
+(2, 99) ~ (4, 99) => 0.0707448
+(2, 100) ~ (4, 95) => 0.382786
+(2, 100) ~ (4, 96) => 0.0339894
+(2, 100) ~ (4, 98) => 0.0331953
+(2, 100) ~ (4, 99) => 0.274706
+(2, 100) ~ (4, 100) => 0.189478
+(2, 100) ~ (4, 101) => 0.0116248
+(2, 101) ~ (4, 96) => 0.260255
+(2, 101) ~ (4, 97) => 0.024511
+(2, 101) ~ (4, 98) => 0.010949
+(2, 101) ~ (4, 99) => 0.0710273
+(2, 101) ~ (4, 100) => 0.227393
+(2, 101) ~ (4, 101) => 0.338392
+(2, 101) ~ (4, 102) => 0.013659
+(2, 102) ~ (4, 97) => 0.143728
+(2, 102) ~ (4, 98) => 0.0147181
+(2, 102) ~ (4, 99) => 0.0159791
+(2, 102) ~ (4, 100) => 0.0961335
+(2, 102) ~ (4, 101) => 0.175616
+(2, 102) ~ (4, 102) => 0.495887
+(2, 102) ~ (4, 103) => 0.0130939
+(2, 103) ~ (4, 98) => 0.0589562
+(2, 103) ~ (4, 99) => 0.0103098
+(2, 103) ~ (4, 100) => 0.0145815
+(2, 103) ~ (4, 101) => 0.112961
+(2, 103) ~ (4, 102) => 0.123724
+(2, 103) ~ (4, 103) => 0.633627
+(2, 104) ~ (4, 99) => 0.027558
+(2, 104) ~ (4, 101) => 0.0106101
+(2, 104) ~ (4, 102) => 0.123473
+(2, 104) ~ (4, 103) => 0.0866922
+(2, 104) ~ (4, 104) => 0.720739
+(2, 105) ~ (4, 100) => 0.0163262
+(2, 105) ~ (4, 103) => 0.0540578
+(2, 105) ~ (4, 104) => 0.0458309
+(2, 105) ~ (4, 105) => 0.855941
+(2, 106) ~ (4, 106) => 0.979616
+(2, 107) ~ (4, 107) => 0.993891
+(2, 108) ~ (4, 108) => 0.99869
+(2, 109) ~ (4, 109) => 0.999881
+(2, 110) ~ (4, 110) => 0.999851
+(2, 111) ~ (4, 111) => 0.999825
+(2, 112) ~ (4, 112) => 0.999916
+(2, 113) ~ (4, 113) => 0.999912
+(2, 114) ~ (4, 114) => 0.999716
+(2, 115) ~ (4, 115) => 0.999642
+(2, 116) ~ (4, 116) => 0.998768
+(2, 117) ~ (4, 117) => 0.998126
+(2, 118) ~ (4, 118) => 0.996002
+(2, 119) ~ (4, 119) => 0.994507
+(2, 120) ~ (4, 120) => 0.987494
+(2, 121) ~ (4, 121) => 0.973605
+(2, 122) ~ (4, 121) => 0.0188086
+(2, 122) ~ (4, 122) => 0.970126
+(2, 123) ~ (4, 122) => 0.0154415
+(2, 123) ~ (4, 123) => 0.972656
+(2, 124) ~ (4, 123) => 0.0104184
+(2, 124) ~ (4, 124) => 0.978272
+(2, 125) ~ (4, 125) => 0.980455
+(2, 126) ~ (4, 126) => 0.985753
+(2, 127) ~ (4, 127) => 0.988099
+(2, 128) ~ (4, 128) => 0.991889
+(2, 129) ~ (4, 129) => 0.992822
+(2, 130) ~ (4, 130) => 0.979845
+(2, 131) ~ (4, 130) => 0.0124043
+(2, 131) ~ (4, 131) => 0.958938
+(2, 132) ~ (4, 131) => 0.0314649
+(2, 132) ~ (4, 132) => 0.939069
+(2, 133) ~ (4, 132) => 0.0499393
+(2, 133) ~ (4, 133) => 0.925327
+(2, 134) ~ (4, 133) => 0.064518
+(2, 134) ~ (4, 134) => 0.904356
+(2, 135) ~ (4, 134) => 0.0874957
+(2, 135) ~ (4, 135) => 0.512627
+(2, 136) ~ (4, 135) => 0.480568
+(2, 136) ~ (4, 136) => 0.121234
+(2, 137) ~ (4, 136) => 0.872754
+(2, 138) ~ (4, 137) => 0.984749
+(2, 139) ~ (4, 138) => 0.985533
+(2, 140) ~ (4, 139) => 0.987889
+(2, 141) ~ (4, 140) => 0.99008
+(2, 142) ~ (4, 141) => 0.993738
+(2, 143) ~ (4, 142) => 0.996114
+(2, 144) ~ (4, 143) => 0.997506
+(2, 145) ~ (4, 144) => 0.99962
+(2, 146) ~ (4, 145) => 0.999148
+(2, 147) ~ (4, 146) => 0.999114
+(2, 148) ~ (4, 147) => 0.99971
+(2, 149) ~ (4, 148) => 0.99998
+(2, 150) ~ (4, 149) => 0.999991
+(2, 151) ~ (4, 150) => 0.999981
+(2, 152) ~ (4, 151) => 0.999897
+(2, 153) ~ (4, 152) => 0.999746
+(2, 154) ~ (4, 153) => 0.999565
+(2, 155) ~ (4, 154) => 0.999748
+(2, 156) ~ (4, 155) => 0.999887
+(2, 157) ~ (4, 156) => 0.99957
+(2, 158) ~ (4, 157) => 0.998851
+(2, 159) ~ (4, 158) => 0.99727
+(2, 160) ~ (4, 159) => 0.99362
+(2, 161) ~ (4, 160) => 0.990669
+(2, 162) ~ (4, 161) => 0.992353
+(2, 163) ~ (4, 162) => 0.992952
+(2, 164) ~ (4, 163) => 0.991736
+(2, 165) ~ (4, 164) => 0.990478
+(2, 166) ~ (4, 165) => 0.990937
+(2, 167) ~ (4, 166) => 0.995662
+(2, 168) ~ (4, 167) => 0.998123
+(2, 169) ~ (4, 168) => 0.999097
+(2, 170) ~ (4, 169) => 0.997298
+(2, 171) ~ (4, 170) => 0.993123
+(2, 172) ~ (4, 171) => 0.992951
+(2, 173) ~ (4, 172) => 0.99647
+(2, 174) ~ (4, 173) => 0.999397
+(2, 175) ~ (4, 174) => 0.999737
+(2, 176) ~ (4, 175) => 0.997772
+(2, 177) ~ (4, 176) => 0.992775
+(2, 178) ~ (4, 177) => 0.987076
+(2, 179) ~ (4, 178) => 0.985322
+(2, 180) ~ (4, 179) => 0.982509
+(2, 181) ~ (4, 180) => 0.985344
+(2, 182) ~ (4, 181) => 0.997318
+(2, 183) ~ (4, 182) => 0.999442
+(2, 184) ~ (4, 183) => 0.999763
+(2, 185) ~ (4, 184) => 0.999256
+(2, 186) ~ (4, 185) => 0.975951
+(2, 186) ~ (4, 187) => 0.0199874
+(2, 187) ~ (4, 186) => 0.95252
+(2, 187) ~ (4, 188) => 0.0398334
+(2, 188) ~ (4, 187) => 0.928999
+(2, 188) ~ (4, 189) => 0.0618365
+(2, 189) ~ (4, 188) => 0.847431
+(2, 189) ~ (4, 189) => 0.011111
+(2, 189) ~ (4, 190) => 0.138835
+(2, 190) ~ (4, 189) => 0.69572
+(2, 190) ~ (4, 191) => 0.292114
+(2, 191) ~ (4, 190) => 0.652804
+(2, 191) ~ (4, 192) => 0.330463
+(2, 192) ~ (4, 191) => 0.632073
+(2, 192) ~ (4, 193) => 0.351775
+(2, 193) ~ (4, 192) => 0.631342
+(2, 193) ~ (4, 194) => 0.347036
+(2, 194) ~ (4, 193) => 0.590139
+(2, 194) ~ (4, 195) => 0.320567
+(2, 194) ~ (4, 196) => 0.0670835
+(2, 195) ~ (4, 194) => 0.362596
+(2, 195) ~ (4, 196) => 0.275061
+(2, 195) ~ (4, 197) => 0.305524
+(2, 196) ~ (4, 194) => 0.034709
+(2, 196) ~ (4, 195) => 0.176677
+(2, 196) ~ (4, 196) => 0.017532
+(2, 196) ~ (4, 197) => 0.220383
+(2, 196) ~ (4, 198) => 0.505078
+(2, 197) ~ (4, 195) => 0.0611033
+(2, 197) ~ (4, 196) => 0.122727
+(2, 197) ~ (4, 197) => 0.0121927
+(2, 197) ~ (4, 198) => 0.104907
+(2, 197) ~ (4, 199) => 0.677572
+(2, 198) ~ (4, 196) => 0.0656269
+(2, 198) ~ (4, 197) => 0.0619828
+(2, 198) ~ (4, 199) => 0.0137467
+(2, 198) ~ (4, 200) => 0.841791
+(2, 199) ~ (4, 197) => 0.0718305
+(2, 199) ~ (4, 198) => 0.0487367
+(2, 199) ~ (4, 201) => 0.854984
+(2, 200) ~ (4, 198) => 0.077077
+(2, 200) ~ (4, 199) => 0.034213
+(2, 200) ~ (4, 202) => 0.859631
+(2, 201) ~ (4, 199) => 0.0903718
+(2, 201) ~ (4, 200) => 0.0215372
+(2, 201) ~ (4, 203) => 0.85827
+(2, 202) ~ (4, 200) => 0.104338
+(2, 202) ~ (4, 201) => 0.0171283
+(2, 202) ~ (4, 204) => 0.854317
+(2, 203) ~ (4, 201) => 0.110089
+(2, 203) ~ (4, 202) => 0.0104044
+(2, 203) ~ (4, 205) => 0.846628
+(2, 204) ~ (4, 202) => 0.121167
+(2, 204) ~ (4, 203) => 0.0116148
+(2, 204) ~ (4, 206) => 0.837301
+(2, 205) ~ (4, 203) => 0.123615
+(2, 205) ~ (4, 207) => 0.821621
+(2, 206) ~ (4, 204) => 0.131417
+(2, 206) ~ (4, 208) => 0.805418
+(2, 207) ~ (4, 205) => 0.142724
+(2, 207) ~ (4, 209) => 0.415746
+(2, 207) ~ (4, 211) => 0.012047
+(2, 208) ~ (4, 206) => 0.157742
+(2, 208) ~ (4, 209) => 0.0284636
+(2, 208) ~ (4, 210) => 0.0623125
+(2, 208) ~ (4, 212) => 0.012678
+(2, 209) ~ (4, 207) => 0.174063
+(2, 209) ~ (4, 210) => 0.0138652
+(2, 209) ~ (4, 211) => 0.0430311
+(2, 209) ~ (4, 213) => 0.0124547
+(2, 210) ~ (4, 208) => 0.189384
+(2, 210) ~ (4, 210) => 0.012139
+(2, 210) ~ (4, 212) => 0.0402627
+(2, 211) ~ (4, 209) => 0.530548
+(2, 211) ~ (4, 211) => 0.0161999
+(2, 211) ~ (4, 213) => 0.0321077
+(2, 212) ~ (4, 210) => 0.895381
+(2, 212) ~ (4, 212) => 0.0123611
+(2, 212) ~ (4, 213) => 0.0121803
+(2, 212) ~ (4, 214) => 0.020117
+(2, 213) ~ (4, 211) => 0.913592
+(2, 213) ~ (4, 213) => 0.0117446
+(2, 213) ~ (4, 214) => 0.0116387
+(2, 213) ~ (4, 215) => 0.0104276
+(2, 214) ~ (4, 212) => 0.912789
+(2, 214) ~ (4, 214) => 0.0141391
+(2, 214) ~ (4, 215) => 0.0128698
+(2, 215) ~ (4, 213) => 0.914548
+(2, 215) ~ (4, 215) => 0.0114202
+(2, 215) ~ (4, 216) => 0.0126945
+(2, 216) ~ (4, 214) => 0.926153
+(2, 216) ~ (4, 216) => 0.0108052
+(2, 216) ~ (4, 217) => 0.0146284
+(2, 217) ~ (4, 215) => 0.934375
+(2, 217) ~ (4, 217) => 0.0112406
+(2, 217) ~ (4, 218) => 0.0164912
+(2, 218) ~ (4, 216) => 0.935083
+(2, 218) ~ (4, 218) => 0.0112321
+(2, 218) ~ (4, 219) => 0.0177604
+(2, 219) ~ (4, 216) => 0.0110034
+(2, 219) ~ (4, 217) => 0.934005
+(2, 219) ~ (4, 219) => 0.0105349
+(2, 219) ~ (4, 220) => 0.0187231
+(2, 220) ~ (4, 217) => 0.0102687
+(2, 220) ~ (4, 218) => 0.916327
+(2, 220) ~ (4, 219) => 0.0131654
+(2, 220) ~ (4, 220) => 0.0102873
+(2, 220) ~ (4, 221) => 0.0262625
+(2, 221) ~ (4, 219) => 0.891568
+(2, 221) ~ (4, 220) => 0.0128061
+(2, 221) ~ (4, 222) => 0.0534843
+(2, 222) ~ (4, 220) => 0.820421
+(2, 222) ~ (4, 221) => 0.0384082
+(2, 222) ~ (4, 222) => 0.0212307
+(2, 222) ~ (4, 223) => 0.071595
+(2, 223) ~ (4, 220) => 0.012806
+(2, 223) ~ (4, 221) => 0.746495
+(2, 223) ~ (4, 222) => 0.0925699
+(2, 223) ~ (4, 223) => 0.0199292
+(2, 223) ~ (4, 224) => 0.0353451
+(2, 224) ~ (4, 221) => 0.0248125
+(2, 224) ~ (4, 222) => 0.594999
+(2, 224) ~ (4, 223) => 0.242043
+(2, 224) ~ (4, 224) => 0.0177007
+(2, 224) ~ (4, 225) => 0.016086
+(2, 225) ~ (4, 222) => 0.0204229
+(2, 225) ~ (4, 223) => 0.375193
+(2, 225) ~ (4, 224) => 0.514634
+(2, 226) ~ (4, 223) => 0.0114303
+(2, 226) ~ (4, 224) => 0.15883
+(2, 226) ~ (4, 225) => 0.78772
+(2, 227) ~ (4, 225) => 0.0134843
+(2, 227) ~ (4, 226) => 0.972605
+(2, 228) ~ (4, 227) => 0.997118
+(2, 229) ~ (4, 228) => 0.99953
+(2, 230) ~ (4, 229) => 0.999896
+(2, 231) ~ (4, 230) => 0.999442
+(2, 232) ~ (4, 231) => 0.997135
+(2, 233) ~ (4, 232) => 0.996669
+(2, 234) ~ (4, 233) => 0.990841
+(2, 235) ~ (4, 234) => 0.984797
+(2, 236) ~ (4, 235) => 0.978651
+(2, 236) ~ (4, 236) => 0.0147076
+(2, 237) ~ (4, 236) => 0.980051
+(2, 237) ~ (4, 237) => 0.010605
+(2, 238) ~ (4, 237) => 0.98635
+
+; gap posteriors
+(2, 0) ~ (4, -1) => 0.00062269
+(2, 1) ~ (4, -1) => 0.00453311
+(2, 2) ~ (4, -1) => 0.00863999
+(2, 3) ~ (4, -1) => 0.0110213
+(2, 4) ~ (4, -1) => 0.0119237
+(2, 5) ~ (4, -1) => 0.013092
+(2, 6) ~ (4, -1) => 0.014429
+(2, 7) ~ (4, -1) => 0.0830709
+(2, 8) ~ (4, -1) => 0.350729
+(2, 9) ~ (4, -1) => 0.463467
+(2, 10) ~ (4, -1) => 0.116926
+(2, 11) ~ (4, -1) => 0.0773618
+(2, 12) ~ (4, -1) => 0.016596
+(2, 13) ~ (4, -1) => 0.00825429
+(2, 14) ~ (4, -1) => 0.008053
+(2, 15) ~ (4, -1) => 0.0086053
+(2, 16) ~ (4, -1) => 0.00935233
+(2, 17) ~ (4, -1) => 0.00992477
+(2, 18) ~ (4, -1) => 0.0181813
+(2, 19) ~ (4, -1) => 0.00463468
+(2, 20) ~ (4, -1) => 0.0110455
+(2, 21) ~ (4, -1) => 0.00476062
+(2, 22) ~ (4, -1) => 0.00310576
+(2, 23) ~ (4, -1) => 0.000410557
+(2, 24) ~ (4, -1) => 0.0001
+(2, 25) ~ (4, -1) => 0.0001
+(2, 26) ~ (4, -1) => 0.000816047
+(2, 27) ~ (4, -1) => 0.00429708
+(2, 28) ~ (4, -1) => 0.000781747
+(2, 29) ~ (4, -1) => 0.00119404
+(2, 30) ~ (4, -1) => 0.00300038
+(2, 31) ~ (4, -1) => 0.00650832
+(2, 32) ~ (4, -1) => 0.0287281
+(2, 33) ~ (4, -1) => 0.00381321
+(2, 34) ~ (4, -1) => 0.00211066
+(2, 35) ~ (4, -1) => 0.00271636
+(2, 36) ~ (4, -1) => 0.00274605
+(2, 37) ~ (4, -1) => 0.00221103
+(2, 38) ~ (4, -1) => 0.00140423
+(2, 39) ~ (4, -1) => 0.000929892
+(2, 40) ~ (4, -1) => 0.000607491
+(2, 41) ~ (4, -1) => 0.000573993
+(2, 42) ~ (4, -1) => 0.000804245
+(2, 43) ~ (4, -1) => 0.00134856
+(2, 44) ~ (4, -1) => 0.00202239
+(2, 45) ~ (4, -1) => 0.00408912
+(2, 46) ~ (4, -1) => 0.0201854
+(2, 47) ~ (4, -1) => 0.0474404
+(2, 48) ~ (4, -1) => 0.273146
+(2, 49) ~ (4, -1) => 0.267254
+(2, 50) ~ (4, -1) => 0.0557452
+(2, 51) ~ (4, -1) => 0.0288975
+(2, 52) ~ (4, -1) => 0.0325528
+(2, 53) ~ (4, -1) => 0.055339
+(2, 54) ~ (4, -1) => 0.058572
+(2, 55) ~ (4, -1) => 0.67118
+(2, 56) ~ (4, -1) => 0.67829
+(2, 57) ~ (4, -1) => 0.0307745
+(2, 58) ~ (4, -1) => 0.00377047
+(2, 59) ~ (4, -1) => 0.000926435
+(2, 60) ~ (4, -1) => 0.00307328
+(2, 61) ~ (4, -1) => 0.00665247
+(2, 62) ~ (4, -1) => 0.00680327
+(2, 63) ~ (4, -1) => 0.00926384
+(2, 64) ~ (4, -1) => 0.0277806
+(2, 65) ~ (4, -1) => 0.0216434
+(2, 66) ~ (4, -1) => 0.0242403
+(2, 67) ~ (4, -1) => 0.0284685
+(2, 68) ~ (4, -1) => 0.00912088
+(2, 69) ~ (4, -1) => 0.00459129
+(2, 70) ~ (4, -1) => 0.00866979
+(2, 71) ~ (4, -1) => 0.00150871
+(2, 72) ~ (4, -1) => 0.00258303
+(2, 73) ~ (4, -1) => 0.00289243
+(2, 74) ~ (4, -1) => 0.00221103
+(2, 75) ~ (4, -1) => 0.000323296
+(2, 76) ~ (4, -1) => 0.000140965
+(2, 77) ~ (4, -1) => 0.0001
+(2, 78) ~ (4, -1) => 0.0001
+(2, 79) ~ (4, -1) => 0.0001
+(2, 80) ~ (4, -1) => 0.0001
+(2, 81) ~ (4, -1) => 0.000492096
+(2, 82) ~ (4, -1) => 0.00174868
+(2, 83) ~ (4, -1) => 0.00472194
+(2, 84) ~ (4, -1) => 0.00691682
+(2, 85) ~ (4, -1) => 0.0219796
+(2, 86) ~ (4, -1) => 0.133222
+(2, 87) ~ (4, -1) => 0.326416
+(2, 88) ~ (4, -1) => 0.40275
+(2, 89) ~ (4, -1) => 0.526536
+(2, 90) ~ (4, -1) => 0.552709
+(2, 91) ~ (4, -1) => 0.539417
+(2, 92) ~ (4, -1) => 0.335767
+(2, 93) ~ (4, -1) => 0.134293
+(2, 94) ~ (4, -1) => 0.0532236
+(2, 95) ~ (4, -1) => 0.0572075
+(2, 96) ~ (4, -1) => 0.0473324
+(2, 97) ~ (4, -1) => 0.0598365
+(2, 98) ~ (4, -1) => 0.0543806
+(2, 99) ~ (4, -1) => 0.0559572
+(2, 100) ~ (4, -1) => 0.0742205
+(2, 101) ~ (4, -1) => 0.0538141
+(2, 102) ~ (4, -1) => 0.0448444
+(2, 103) ~ (4, -1) => 0.0458398
+(2, 104) ~ (4, -1) => 0.0309274
+(2, 105) ~ (4, -1) => 0.027844
+(2, 106) ~ (4, -1) => 0.0203845
+(2, 107) ~ (4, -1) => 0.00610912
+(2, 108) ~ (4, -1) => 0.00131005
+(2, 109) ~ (4, -1) => 0.000118613
+(2, 110) ~ (4, -1) => 0.00014931
+(2, 111) ~ (4, -1) => 0.000175178
+(2, 112) ~ (4, -1) => 0.0001
+(2, 113) ~ (4, -1) => 0.0001
+(2, 114) ~ (4, -1) => 0.000283778
+(2, 115) ~ (4, -1) => 0.000357509
+(2, 116) ~ (4, -1) => 0.00123197
+(2, 117) ~ (4, -1) => 0.00187367
+(2, 118) ~ (4, -1) => 0.00399792
+(2, 119) ~ (4, -1) => 0.00549346
+(2, 120) ~ (4, -1) => 0.0125063
+(2, 121) ~ (4, -1) => 0.0263948
+(2, 122) ~ (4, -1) => 0.0110652
+(2, 123) ~ (4, -1) => 0.011902
+(2, 124) ~ (4, -1) => 0.01131
+(2, 125) ~ (4, -1) => 0.0195451
+(2, 126) ~ (4, -1) => 0.0142466
+(2, 127) ~ (4, -1) => 0.0119007
+(2, 128) ~ (4, -1) => 0.00811148
+(2, 129) ~ (4, -1) => 0.00717759
+(2, 130) ~ (4, -1) => 0.0201553
+(2, 131) ~ (4, -1) => 0.0286579
+(2, 132) ~ (4, -1) => 0.0294662
+(2, 133) ~ (4, -1) => 0.024734
+(2, 134) ~ (4, -1) => 0.031126
+(2, 135) ~ (4, -1) => 0.399877
+(2, 136) ~ (4, -1) => 0.398198
+(2, 137) ~ (4, -1) => 0.127246
+(2, 138) ~ (4, -1) => 0.0152509
+(2, 139) ~ (4, -1) => 0.0144674
+(2, 140) ~ (4, -1) => 0.0121113
+(2, 141) ~ (4, -1) => 0.00992012
+(2, 142) ~ (4, -1) => 0.00626224
+(2, 143) ~ (4, -1) => 0.0038864
+(2, 144) ~ (4, -1) => 0.0024935
+(2, 145) ~ (4, -1) => 0.000380337
+(2, 146) ~ (4, -1) => 0.000851691
+(2, 147) ~ (4, -1) => 0.000886083
+(2, 148) ~ (4, -1) => 0.000290334
+(2, 149) ~ (4, -1) => 0.0001
+(2, 150) ~ (4, -1) => 0.0001
+(2, 151) ~ (4, -1) => 0.0001
+(2, 152) ~ (4, -1) => 0.000103354
+(2, 153) ~ (4, -1) => 0.000254452
+(2, 154) ~ (4, -1) => 0.000435233
+(2, 155) ~ (4, -1) => 0.000251949
+(2, 156) ~ (4, -1) => 0.000113487
+(2, 157) ~ (4, -1) => 0.000429749
+(2, 158) ~ (4, -1) => 0.00114912
+(2, 159) ~ (4, -1) => 0.00273001
+(2, 160) ~ (4, -1) => 0.00637978
+(2, 161) ~ (4, -1) => 0.00933099
+(2, 162) ~ (4, -1) => 0.00764734
+(2, 163) ~ (4, -1) => 0.00704801
+(2, 164) ~ (4, -1) => 0.00826371
+(2, 165) ~ (4, -1) => 0.00952238
+(2, 166) ~ (4, -1) => 0.00906336
+(2, 167) ~ (4, -1) => 0.0043382
+(2, 168) ~ (4, -1) => 0.00187695
+(2, 169) ~ (4, -1) => 0.000902832
+(2, 170) ~ (4, -1) => 0.00270224
+(2, 171) ~ (4, -1) => 0.00687683
+(2, 172) ~ (4, -1) => 0.00704914
+(2, 173) ~ (4, -1) => 0.00353038
+(2, 174) ~ (4, -1) => 0.000602961
+(2, 175) ~ (4, -1) => 0.000262678
+(2, 176) ~ (4, -1) => 0.00222796
+(2, 177) ~ (4, -1) => 0.00722468
+(2, 178) ~ (4, -1) => 0.0129237
+(2, 179) ~ (4, -1) => 0.0146778
+(2, 180) ~ (4, -1) => 0.017491
+(2, 181) ~ (4, -1) => 0.0146556
+(2, 182) ~ (4, -1) => 0.00268197
+(2, 183) ~ (4, -1) => 0.000558078
+(2, 184) ~ (4, -1) => 0.000236571
+(2, 185) ~ (4, -1) => 0.000744045
+(2, 186) ~ (4, -1) => 0.00406203
+(2, 187) ~ (4, -1) => 0.00764645
+(2, 188) ~ (4, -1) => 0.00916406
+(2, 189) ~ (4, -1) => 0.00262232
+(2, 190) ~ (4, -1) => 0.012166
+(2, 191) ~ (4, -1) => 0.0167331
+(2, 192) ~ (4, -1) => 0.016152
+(2, 193) ~ (4, -1) => 0.0216224
+(2, 194) ~ (4, -1) => 0.0222099
+(2, 195) ~ (4, -1) => 0.056819
+(2, 196) ~ (4, -1) => 0.0456216
+(2, 197) ~ (4, -1) => 0.0214978
+(2, 198) ~ (4, -1) => 0.0168523
+(2, 199) ~ (4, -1) => 0.0244486
+(2, 200) ~ (4, -1) => 0.0290787
+(2, 201) ~ (4, -1) => 0.0298215
+(2, 202) ~ (4, -1) => 0.0242169
+(2, 203) ~ (4, -1) => 0.0328787
+(2, 204) ~ (4, -1) => 0.0299174
+(2, 205) ~ (4, -1) => 0.0547638
+(2, 206) ~ (4, -1) => 0.0631655
+(2, 207) ~ (4, -1) => 0.429483
+(2, 208) ~ (4, -1) => 0.738804
+(2, 209) ~ (4, -1) => 0.756586
+(2, 210) ~ (4, -1) => 0.758214
+(2, 211) ~ (4, -1) => 0.421144
+(2, 212) ~ (4, -1) => 0.0599611
+(2, 213) ~ (4, -1) => 0.0525968
+(2, 214) ~ (4, -1) => 0.0602022
+(2, 215) ~ (4, -1) => 0.0613375
+(2, 216) ~ (4, -1) => 0.0484139
+(2, 217) ~ (4, -1) => 0.0378929
+(2, 218) ~ (4, -1) => 0.0359247
+(2, 219) ~ (4, -1) => 0.0257336
+(2, 220) ~ (4, -1) => 0.0236891
+(2, 221) ~ (4, -1) => 0.042142
+(2, 222) ~ (4, -1) => 0.0483451
+(2, 223) ~ (4, -1) => 0.0928549
+(2, 224) ~ (4, -1) => 0.104359
+(2, 225) ~ (4, -1) => 0.0897496
+(2, 226) ~ (4, -1) => 0.0420197
+(2, 227) ~ (4, -1) => 0.0139104
+(2, 228) ~ (4, -1) => 0.00288236
+(2, 229) ~ (4, -1) => 0.000469625
+(2, 230) ~ (4, -1) => 0.000104487
+(2, 231) ~ (4, -1) => 0.000557661
+(2, 232) ~ (4, -1) => 0.00286484
+(2, 233) ~ (4, -1) => 0.00333089
+(2, 234) ~ (4, -1) => 0.00915939
+(2, 235) ~ (4, -1) => 0.0152034
+(2, 236) ~ (4, -1) => 0.00664109
+(2, 237) ~ (4, -1) => 0.0093443
+(2, 238) ~ (4, -1) => 0.0136502
+
+(2, -1) ~ (4, 0) => 0.00062269
+(2, -1) ~ (4, 1) => 0.00453311
+(2, -1) ~ (4, 2) => 0.00863999
+(2, -1) ~ (4, 3) => 0.0110213
+(2, -1) ~ (4, 4) => 0.0119237
+(2, -1) ~ (4, 5) => 0.013092
+(2, -1) ~ (4, 6) => 0.014429
+(2, -1) ~ (4, 7) => 0.0219079
+(2, -1) ~ (4, 8) => 0.0207269
+(2, -1) ~ (4, 9) => 0.0290906
+(2, -1) ~ (4, 10) => 0.0198284
+(2, -1) ~ (4, 11) => 0.016596
+(2, -1) ~ (4, 12) => 0.00825429
+(2, -1) ~ (4, 13) => 0.008053
+(2, -1) ~ (4, 14) => 0.0086053
+(2, -1) ~ (4, 15) => 0.00935233
+(2, -1) ~ (4, 16) => 0.00992477
+(2, -1) ~ (4, 17) => 0.00404928
+(2, -1) ~ (4, 18) => 0.0187666
+(2, -1) ~ (4, 19) => 0.0110455
+(2, -1) ~ (4, 20) => 0.00476062
+(2, -1) ~ (4, 21) => 0.00310576
+(2, -1) ~ (4, 22) => 0.000410557
+(2, -1) ~ (4, 23) => 0.0001
+(2, -1) ~ (4, 24) => 0.0001
+(2, -1) ~ (4, 25) => 0.000816047
+(2, -1) ~ (4, 26) => 0.00429708
+(2, -1) ~ (4, 27) => 0.0136752
+(2, -1) ~ (4, 28) => 0.0035544
+(2, -1) ~ (4, 29) => 0.01147
+(2, -1) ~ (4, 30) => 0.00729352
+(2, -1) ~ (4, 31) => 0.00421947
+(2, -1) ~ (4, 32) => 0.00381321
+(2, -1) ~ (4, 33) => 0.00211066
+(2, -1) ~ (4, 34) => 0.00271636
+(2, -1) ~ (4, 35) => 0.00274605
+(2, -1) ~ (4, 36) => 0.00221103
+(2, -1) ~ (4, 37) => 0.00140423
+(2, -1) ~ (4, 38) => 0.000929892
+(2, -1) ~ (4, 39) => 0.000607491
+(2, -1) ~ (4, 40) => 0.000573993
+(2, -1) ~ (4, 41) => 0.000804245
+(2, -1) ~ (4, 42) => 0.00134856
+(2, -1) ~ (4, 43) => 0.00202239
+(2, -1) ~ (4, 44) => 0.00408912
+(2, -1) ~ (4, 45) => 0.0201854
+(2, -1) ~ (4, 46) => 0.0135075
+(2, -1) ~ (4, 47) => 0.0312583
+(2, -1) ~ (4, 48) => 0.0230699
+(2, -1) ~ (4, 49) => 0.0429817
+(2, -1) ~ (4, 50) => 0.0329728
+(2, -1) ~ (4, 51) => 0.0273381
+(2, -1) ~ (4, 52) => 0.016012
+(2, -1) ~ (4, 53) => 0.00875157
+(2, -1) ~ (4, 54) => 0.0032993
+(2, -1) ~ (4, 55) => 0.00377047
+(2, -1) ~ (4, 56) => 0.000926435
+(2, -1) ~ (4, 57) => 0.00307328
+(2, -1) ~ (4, 58) => 0.00665247
+(2, -1) ~ (4, 59) => 0.0180526
+(2, -1) ~ (4, 60) => 0.0145511
+(2, -1) ~ (4, 61) => 0.0467543
+(2, -1) ~ (4, 62) => 0.0476042
+(2, -1) ~ (4, 63) => 0.245412
+(2, -1) ~ (4, 64) => 0.31148
+(2, -1) ~ (4, 65) => 0.150787
+(2, -1) ~ (4, 66) => 0.174234
+(2, -1) ~ (4, 67) => 0.123037
+(2, -1) ~ (4, 68) => 0.00866979
+(2, -1) ~ (4, 69) => 0.00150871
+(2, -1) ~ (4, 70) => 0.00258303
+(2, -1) ~ (4, 71) => 0.00289243
+(2, -1) ~ (4, 72) => 0.00221103
+(2, -1) ~ (4, 73) => 0.000323296
+(2, -1) ~ (4, 74) => 0.000140965
+(2, -1) ~ (4, 75) => 0.0001
+(2, -1) ~ (4, 76) => 0.0001
+(2, -1) ~ (4, 77) => 0.0001
+(2, -1) ~ (4, 78) => 0.0001
+(2, -1) ~ (4, 79) => 0.000492096
+(2, -1) ~ (4, 80) => 0.00174868
+(2, -1) ~ (4, 81) => 0.00472194
+(2, -1) ~ (4, 82) => 0.00691682
+(2, -1) ~ (4, 83) => 0.00210216
+(2, -1) ~ (4, 84) => 0.0111396
+(2, -1) ~ (4, 85) => 0.0380861
+(2, -1) ~ (4, 86) => 0.0516339
+(2, -1) ~ (4, 87) => 0.0445442
+(2, -1) ~ (4, 88) => 0.0544231
+(2, -1) ~ (4, 89) => 0.0587574
+(2, -1) ~ (4, 90) => 0.0695813
+(2, -1) ~ (4, 91) => 0.0958995
+(2, -1) ~ (4, 92) => 0.343714
+(2, -1) ~ (4, 93) => 0.41953
+(2, -1) ~ (4, 94) => 0.445621
+(2, -1) ~ (4, 95) => 0.539867
+(2, -1) ~ (4, 96) => 0.425924
+(2, -1) ~ (4, 97) => 0.410771
+(2, -1) ~ (4, 98) => 0.45548
+(2, -1) ~ (4, 99) => 0.501082
+(2, -1) ~ (4, 100) => 0.438405
+(2, -1) ~ (4, 101) => 0.338683
+(2, -1) ~ (4, 102) => 0.243256
+(2, -1) ~ (4, 103) => 0.212529
+(2, -1) ~ (4, 104) => 0.23343
+(2, -1) ~ (4, 105) => 0.144059
+(2, -1) ~ (4, 106) => 0.0203845
+(2, -1) ~ (4, 107) => 0.00610912
+(2, -1) ~ (4, 108) => 0.00131005
+(2, -1) ~ (4, 109) => 0.000118613
+(2, -1) ~ (4, 110) => 0.00014931
+(2, -1) ~ (4, 111) => 0.000175178
+(2, -1) ~ (4, 112) => 0.0001
+(2, -1) ~ (4, 113) => 0.0001
+(2, -1) ~ (4, 114) => 0.000283778
+(2, -1) ~ (4, 115) => 0.000357509
+(2, -1) ~ (4, 116) => 0.00123197
+(2, -1) ~ (4, 117) => 0.00187367
+(2, -1) ~ (4, 118) => 0.00399792
+(2, -1) ~ (4, 119) => 0.00549346
+(2, -1) ~ (4, 120) => 0.0125063
+(2, -1) ~ (4, 121) => 0.00758627
+(2, -1) ~ (4, 122) => 0.0144323
+(2, -1) ~ (4, 123) => 0.0169252
+(2, -1) ~ (4, 124) => 0.0217284
+(2, -1) ~ (4, 125) => 0.0195451
+(2, -1) ~ (4, 126) => 0.0142466
+(2, -1) ~ (4, 127) => 0.0119007
+(2, -1) ~ (4, 128) => 0.00811148
+(2, -1) ~ (4, 129) => 0.00717759
+(2, -1) ~ (4, 130) => 0.00775095
+(2, -1) ~ (4, 131) => 0.00959737
+(2, -1) ~ (4, 132) => 0.0109917
+(2, -1) ~ (4, 133) => 0.0101552
+(2, -1) ~ (4, 134) => 0.00814831
+(2, -1) ~ (4, 135) => 0.0068053
+(2, -1) ~ (4, 136) => 0.00601137
+(2, -1) ~ (4, 137) => 0.0152509
+(2, -1) ~ (4, 138) => 0.0144674
+(2, -1) ~ (4, 139) => 0.0121113
+(2, -1) ~ (4, 140) => 0.00992012
+(2, -1) ~ (4, 141) => 0.00626224
+(2, -1) ~ (4, 142) => 0.0038864
+(2, -1) ~ (4, 143) => 0.0024935
+(2, -1) ~ (4, 144) => 0.000380337
+(2, -1) ~ (4, 145) => 0.000851691
+(2, -1) ~ (4, 146) => 0.000886083
+(2, -1) ~ (4, 147) => 0.000290334
+(2, -1) ~ (4, 148) => 0.0001
+(2, -1) ~ (4, 149) => 0.0001
+(2, -1) ~ (4, 150) => 0.0001
+(2, -1) ~ (4, 151) => 0.000103354
+(2, -1) ~ (4, 152) => 0.000254452
+(2, -1) ~ (4, 153) => 0.000435233
+(2, -1) ~ (4, 154) => 0.000251949
+(2, -1) ~ (4, 155) => 0.000113487
+(2, -1) ~ (4, 156) => 0.000429749
+(2, -1) ~ (4, 157) => 0.00114912
+(2, -1) ~ (4, 158) => 0.00273001
+(2, -1) ~ (4, 159) => 0.00637978
+(2, -1) ~ (4, 160) => 0.00933099
+(2, -1) ~ (4, 161) => 0.00764734
+(2, -1) ~ (4, 162) => 0.00704801
+(2, -1) ~ (4, 163) => 0.00826371
+(2, -1) ~ (4, 164) => 0.00952238
+(2, -1) ~ (4, 165) => 0.00906336
+(2, -1) ~ (4, 166) => 0.0043382
+(2, -1) ~ (4, 167) => 0.00187695
+(2, -1) ~ (4, 168) => 0.000902832
+(2, -1) ~ (4, 169) => 0.00270224
+(2, -1) ~ (4, 170) => 0.00687683
+(2, -1) ~ (4, 171) => 0.00704914
+(2, -1) ~ (4, 172) => 0.00353038
+(2, -1) ~ (4, 173) => 0.000602961
+(2, -1) ~ (4, 174) => 0.000262678
+(2, -1) ~ (4, 175) => 0.00222796
+(2, -1) ~ (4, 176) => 0.00722468
+(2, -1) ~ (4, 177) => 0.0129237
+(2, -1) ~ (4, 178) => 0.0146778
+(2, -1) ~ (4, 179) => 0.017491
+(2, -1) ~ (4, 180) => 0.0146556
+(2, -1) ~ (4, 181) => 0.00268197
+(2, -1) ~ (4, 182) => 0.000558078
+(2, -1) ~ (4, 183) => 0.000236571
+(2, -1) ~ (4, 184) => 0.000744045
+(2, -1) ~ (4, 185) => 0.0240494
+(2, -1) ~ (4, 186) => 0.0474799
+(2, -1) ~ (4, 187) => 0.0510132
+(2, -1) ~ (4, 188) => 0.112735
+(2, -1) ~ (4, 189) => 0.231332
+(2, -1) ~ (4, 190) => 0.20836
+(2, -1) ~ (4, 191) => 0.075813
+(2, -1) ~ (4, 192) => 0.0381954
+(2, -1) ~ (4, 193) => 0.058086
+(2, -1) ~ (4, 194) => 0.255659
+(2, -1) ~ (4, 195) => 0.441653
+(2, -1) ~ (4, 196) => 0.45197
+(2, -1) ~ (4, 197) => 0.328087
+(2, -1) ~ (4, 198) => 0.264202
+(2, -1) ~ (4, 199) => 0.184096
+(2, -1) ~ (4, 200) => 0.0323336
+(2, -1) ~ (4, 201) => 0.0177981
+(2, -1) ~ (4, 202) => 0.00879744
+(2, -1) ~ (4, 203) => 0.00650025
+(2, -1) ~ (4, 204) => 0.0142664
+(2, -1) ~ (4, 205) => 0.0106484
+(2, -1) ~ (4, 206) => 0.0049572
+(2, -1) ~ (4, 207) => 0.00431652
+(2, -1) ~ (4, 208) => 0.00519815
+(2, -1) ~ (4, 209) => 0.0252416
+(2, -1) ~ (4, 210) => 0.0163028
+(2, -1) ~ (4, 211) => 0.0151296
+(2, -1) ~ (4, 212) => 0.0219094
+(2, -1) ~ (4, 213) => 0.0169649
+(2, -1) ~ (4, 214) => 0.0279526
+(2, -1) ~ (4, 215) => 0.0309072
+(2, -1) ~ (4, 216) => 0.0304141
+(2, -1) ~ (4, 217) => 0.0298573
+(2, -1) ~ (4, 218) => 0.0559497
+(2, -1) ~ (4, 219) => 0.0669718
+(2, -1) ~ (4, 220) => 0.124957
+(2, -1) ~ (4, 221) => 0.164022
+(2, -1) ~ (4, 222) => 0.217293
+(2, -1) ~ (4, 223) => 0.27981
+(2, -1) ~ (4, 224) => 0.27349
+(2, -1) ~ (4, 225) => 0.18271
+(2, -1) ~ (4, 226) => 0.0273947
+(2, -1) ~ (4, 227) => 0.00288236
+(2, -1) ~ (4, 228) => 0.000469625
+(2, -1) ~ (4, 229) => 0.000104487
+(2, -1) ~ (4, 230) => 0.000557661
+(2, -1) ~ (4, 231) => 0.00286484
+(2, -1) ~ (4, 232) => 0.00333089
+(2, -1) ~ (4, 233) => 0.00915939
+(2, -1) ~ (4, 234) => 0.0152034
+(2, -1) ~ (4, 235) => 0.0213487
+(2, -1) ~ (4, 236) => 0.00524175
+(2, -1) ~ (4, 237) => 0.00304514
+
+; Sparse posterior probability matrix for sequences 2 and 5
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (5, 0) => 0.965705
+(2, 1) ~ (5, 1) => 0.866912
+(2, 1) ~ (5, 2) => 0.0312267
+(2, 2) ~ (5, 1) => 0.04144
+(2, 2) ~ (5, 2) => 0.681972
+(2, 2) ~ (5, 3) => 0.10241
+(2, 3) ~ (5, 1) => 0.0412685
+(2, 3) ~ (5, 2) => 0.0721227
+(2, 3) ~ (5, 3) => 0.539545
+(2, 3) ~ (5, 4) => 0.142845
+(2, 4) ~ (5, 2) => 0.101023
+(2, 4) ~ (5, 3) => 0.104643
+(2, 4) ~ (5, 4) => 0.343271
+(2, 4) ~ (5, 5) => 0.227508
+(2, 5) ~ (5, 2) => 0.0250082
+(2, 5) ~ (5, 3) => 0.16432
+(2, 5) ~ (5, 4) => 0.139211
+(2, 5) ~ (5, 5) => 0.189193
+(2, 5) ~ (5, 6) => 0.295575
+(2, 6) ~ (5, 3) => 0.0258215
+(2, 6) ~ (5, 4) => 0.234175
+(2, 6) ~ (5, 5) => 0.1307
+(2, 6) ~ (5, 6) => 0.0874166
+(2, 6) ~ (5, 7) => 0.301663
+(2, 7) ~ (5, 4) => 0.0314763
+(2, 7) ~ (5, 5) => 0.331163
+(2, 7) ~ (5, 6) => 0.128676
+(2, 7) ~ (5, 7) => 0.0407108
+(2, 7) ~ (5, 8) => 0.220162
+(2, 8) ~ (5, 5) => 0.0249036
+(2, 8) ~ (5, 6) => 0.432568
+(2, 8) ~ (5, 7) => 0.0671472
+(2, 8) ~ (5, 8) => 0.0305563
+(2, 8) ~ (5, 9) => 0.0588956
+(2, 9) ~ (5, 6) => 0.0111232
+(2, 9) ~ (5, 7) => 0.564082
+(2, 9) ~ (5, 8) => 0.0184652
+(2, 9) ~ (5, 9) => 0.0315808
+(2, 9) ~ (5, 10) => 0.0298202
+(2, 10) ~ (5, 8) => 0.714369
+(2, 10) ~ (5, 10) => 0.0260196
+(2, 11) ~ (5, 9) => 0.896072
+(2, 11) ~ (5, 11) => 0.0205885
+(2, 12) ~ (5, 10) => 0.931911
+(2, 12) ~ (5, 12) => 0.0141002
+(2, 13) ~ (5, 11) => 0.964756
+(2, 13) ~ (5, 13) => 0.0117975
+(2, 14) ~ (5, 12) => 0.975583
+(2, 15) ~ (5, 13) => 0.981036
+(2, 16) ~ (5, 14) => 0.988281
+(2, 17) ~ (5, 15) => 0.994784
+(2, 18) ~ (5, 16) => 0.994695
+(2, 19) ~ (5, 17) => 0.995438
+(2, 20) ~ (5, 18) => 0.997763
+(2, 21) ~ (5, 19) => 0.99898
+(2, 22) ~ (5, 20) => 0.999323
+(2, 23) ~ (5, 21) => 0.999899
+(2, 24) ~ (5, 22) => 0.99997
+(2, 25) ~ (5, 23) => 0.999995
+(2, 26) ~ (5, 24) => 0.999981
+(2, 27) ~ (5, 25) => 0.99992
+(2, 28) ~ (5, 26) => 0.999885
+(2, 29) ~ (5, 27) => 0.999843
+(2, 30) ~ (5, 28) => 0.99989
+(2, 31) ~ (5, 29) => 0.999696
+(2, 32) ~ (5, 30) => 0.999401
+(2, 33) ~ (5, 31) => 0.999288
+(2, 34) ~ (5, 32) => 0.999081
+(2, 35) ~ (5, 33) => 0.998717
+(2, 36) ~ (5, 34) => 0.996334
+(2, 37) ~ (5, 35) => 0.993133
+(2, 38) ~ (5, 36) => 0.984039
+(2, 39) ~ (5, 37) => 0.968068
+(2, 40) ~ (5, 38) => 0.916848
+(2, 41) ~ (5, 36) => 0.0105432
+(2, 41) ~ (5, 39) => 0.749724
+(2, 42) ~ (5, 37) => 0.0251114
+(2, 42) ~ (5, 40) => 0.737548
+(2, 43) ~ (5, 38) => 0.0761803
+(2, 43) ~ (5, 41) => 0.678643
+(2, 44) ~ (5, 39) => 0.239359
+(2, 44) ~ (5, 42) => 0.610671
+(2, 45) ~ (5, 40) => 0.252951
+(2, 45) ~ (5, 43) => 0.602419
+(2, 46) ~ (5, 41) => 0.317195
+(2, 46) ~ (5, 44) => 0.58781
+(2, 47) ~ (5, 42) => 0.387866
+(2, 47) ~ (5, 45) => 0.56844
+(2, 48) ~ (5, 43) => 0.396638
+(2, 48) ~ (5, 46) => 0.517664
+(2, 49) ~ (5, 44) => 0.403306
+(2, 49) ~ (5, 45) => 0.0191756
+(2, 49) ~ (5, 47) => 0.486331
+(2, 50) ~ (5, 45) => 0.408563
+(2, 50) ~ (5, 46) => 0.0571094
+(2, 50) ~ (5, 48) => 0.483039
+(2, 51) ~ (5, 46) => 0.421247
+(2, 51) ~ (5, 47) => 0.0787423
+(2, 51) ~ (5, 49) => 0.479044
+(2, 52) ~ (5, 47) => 0.433354
+(2, 52) ~ (5, 48) => 0.0802008
+(2, 52) ~ (5, 50) => 0.476712
+(2, 53) ~ (5, 48) => 0.432135
+(2, 53) ~ (5, 49) => 0.0833132
+(2, 53) ~ (5, 51) => 0.473256
+(2, 54) ~ (5, 49) => 0.430304
+(2, 54) ~ (5, 50) => 0.0873997
+(2, 54) ~ (5, 52) => 0.468644
+(2, 55) ~ (5, 50) => 0.427978
+(2, 55) ~ (5, 51) => 0.0956219
+(2, 55) ~ (5, 53) => 0.0195892
+(2, 56) ~ (5, 51) => 0.416475
+(2, 56) ~ (5, 52) => 0.113844
+(2, 57) ~ (5, 52) => 0.0134649
+(2, 57) ~ (5, 53) => 0.966558
+(2, 58) ~ (5, 54) => 0.996983
+(2, 59) ~ (5, 55) => 0.99977
+(2, 60) ~ (5, 56) => 0.99995
+(2, 61) ~ (5, 57) => 0.999979
+(2, 62) ~ (5, 58) => 0.999917
+(2, 63) ~ (5, 59) => 0.999916
+(2, 64) ~ (5, 60) => 0.999893
+(2, 65) ~ (5, 61) => 0.999869
+(2, 66) ~ (5, 62) => 0.999876
+(2, 67) ~ (5, 63) => 0.99996
+(2, 68) ~ (5, 64) => 0.999984
+(2, 69) ~ (5, 65) => 0.999983
+(2, 70) ~ (5, 66) => 0.999992
+(2, 71) ~ (5, 67) => 0.999994
+(2, 72) ~ (5, 68) => 0.999941
+(2, 73) ~ (5, 69) => 0.999924
+(2, 74) ~ (5, 70) => 0.999934
+(2, 75) ~ (5, 71) => 0.999988
+(2, 76) ~ (5, 72) => 0.999991
+(2, 77) ~ (5, 73) => 0.999992
+(2, 78) ~ (5, 74) => 0.99998
+(2, 79) ~ (5, 75) => 0.999972
+(2, 80) ~ (5, 76) => 0.999942
+(2, 81) ~ (5, 77) => 0.998714
+(2, 82) ~ (5, 78) => 0.998271
+(2, 83) ~ (5, 79) => 0.997722
+(2, 84) ~ (5, 80) => 0.997628
+(2, 85) ~ (5, 81) => 0.998095
+(2, 86) ~ (5, 82) => 0.998589
+(2, 87) ~ (5, 83) => 0.998864
+(2, 88) ~ (5, 84) => 0.999273
+(2, 89) ~ (5, 85) => 0.999504
+(2, 90) ~ (5, 86) => 0.999718
+(2, 91) ~ (5, 87) => 0.999721
+(2, 92) ~ (5, 88) => 0.999901
+(2, 93) ~ (5, 89) => 0.999755
+(2, 94) ~ (5, 90) => 0.999724
+(2, 95) ~ (5, 91) => 0.999337
+(2, 96) ~ (5, 92) => 0.999023
+(2, 97) ~ (5, 93) => 0.999149
+(2, 98) ~ (5, 94) => 0.999351
+(2, 99) ~ (5, 95) => 0.999452
+(2, 100) ~ (5, 96) => 0.99849
+(2, 101) ~ (5, 97) => 0.998197
+(2, 102) ~ (5, 98) => 0.997855
+(2, 103) ~ (5, 99) => 0.997752
+(2, 104) ~ (5, 100) => 0.998128
+(2, 105) ~ (5, 101) => 0.999121
+(2, 106) ~ (5, 102) => 0.999536
+(2, 107) ~ (5, 103) => 0.999763
+(2, 108) ~ (5, 104) => 0.999916
+(2, 109) ~ (5, 105) => 0.999991
+(2, 110) ~ (5, 106) => 0.999983
+(2, 111) ~ (5, 107) => 0.999976
+(2, 112) ~ (5, 108) => 0.999987
+(2, 113) ~ (5, 109) => 0.999982
+(2, 114) ~ (5, 110) => 0.999975
+(2, 115) ~ (5, 111) => 0.99998
+(2, 116) ~ (5, 112) => 0.999991
+(2, 117) ~ (5, 113) => 0.999996
+(2, 118) ~ (5, 114) => 0.999997
+(2, 119) ~ (5, 115) => 0.99998
+(2, 120) ~ (5, 116) => 0.999933
+(2, 121) ~ (5, 117) => 0.999889
+(2, 122) ~ (5, 118) => 0.999768
+(2, 123) ~ (5, 119) => 0.999788
+(2, 124) ~ (5, 120) => 0.999955
+(2, 125) ~ (5, 121) => 0.999931
+(2, 126) ~ (5, 122) => 0.999759
+(2, 127) ~ (5, 123) => 0.999744
+(2, 128) ~ (5, 124) => 0.999879
+(2, 129) ~ (5, 125) => 0.99997
+(2, 130) ~ (5, 126) => 0.999981
+(2, 131) ~ (5, 127) => 0.999887
+(2, 132) ~ (5, 128) => 0.999776
+(2, 133) ~ (5, 129) => 0.999838
+(2, 134) ~ (5, 130) => 0.999854
+(2, 135) ~ (5, 131) => 0.999976
+(2, 136) ~ (5, 132) => 0.99998
+(2, 137) ~ (5, 133) => 0.999956
+(2, 138) ~ (5, 134) => 0.999964
+(2, 139) ~ (5, 135) => 0.99999
+(2, 140) ~ (5, 136) => 0.999984
+(2, 141) ~ (5, 137) => 0.999968
+(2, 142) ~ (5, 138) => 0.999971
+(2, 143) ~ (5, 139) => 0.999947
+(2, 144) ~ (5, 140) => 0.999945
+(2, 145) ~ (5, 141) => 0.999993
+(2, 146) ~ (5, 142) => 0.999998
+(2, 147) ~ (5, 143) => 0.999995
+(2, 148) ~ (5, 144) => 0.999996
+(2, 149) ~ (5, 145) => 0.999999
+(2, 150) ~ (5, 146) => 0.999998
+(2, 151) ~ (5, 147) => 0.999991
+(2, 152) ~ (5, 148) => 0.999935
+(2, 153) ~ (5, 149) => 0.999897
+(2, 154) ~ (5, 150) => 0.99989
+(2, 155) ~ (5, 151) => 0.999952
+(2, 156) ~ (5, 152) => 0.999984
+(2, 157) ~ (5, 153) => 0.999979
+(2, 158) ~ (5, 154) => 0.999973
+(2, 159) ~ (5, 155) => 0.999969
+(2, 160) ~ (5, 156) => 0.999973
+(2, 161) ~ (5, 157) => 0.999887
+(2, 162) ~ (5, 158) => 0.99977
+(2, 163) ~ (5, 159) => 0.99972
+(2, 164) ~ (5, 160) => 0.999563
+(2, 165) ~ (5, 161) => 0.999618
+(2, 166) ~ (5, 162) => 0.999864
+(2, 167) ~ (5, 163) => 0.999891
+(2, 168) ~ (5, 164) => 0.999774
+(2, 169) ~ (5, 165) => 0.999231
+(2, 170) ~ (5, 166) => 0.998038
+(2, 171) ~ (5, 167) => 0.99762
+(2, 172) ~ (5, 168) => 0.997831
+(2, 173) ~ (5, 169) => 0.999037
+(2, 174) ~ (5, 170) => 0.999859
+(2, 175) ~ (5, 171) => 0.999954
+(2, 176) ~ (5, 172) => 0.999796
+(2, 177) ~ (5, 173) => 0.999592
+(2, 178) ~ (5, 174) => 0.999159
+(2, 179) ~ (5, 175) => 0.998981
+(2, 180) ~ (5, 176) => 0.998767
+(2, 181) ~ (5, 177) => 0.999141
+(2, 182) ~ (5, 178) => 0.999867
+(2, 183) ~ (5, 179) => 0.999984
+(2, 184) ~ (5, 180) => 0.999814
+(2, 185) ~ (5, 181) => 0.999526
+(2, 186) ~ (5, 182) => 0.990456
+(2, 187) ~ (5, 183) => 0.977243
+(2, 188) ~ (5, 184) => 0.958708
+(2, 188) ~ (5, 185) => 0.0144302
+(2, 189) ~ (5, 185) => 0.907112
+(2, 189) ~ (5, 186) => 0.0310306
+(2, 189) ~ (5, 187) => 0.0153566
+(2, 190) ~ (5, 185) => 0.0196453
+(2, 190) ~ (5, 186) => 0.833072
+(2, 190) ~ (5, 187) => 0.0466816
+(2, 190) ~ (5, 188) => 0.0324746
+(2, 190) ~ (5, 190) => 0.0134044
+(2, 191) ~ (5, 186) => 0.0349315
+(2, 191) ~ (5, 187) => 0.735645
+(2, 191) ~ (5, 188) => 0.0432368
+(2, 191) ~ (5, 189) => 0.0337234
+(2, 191) ~ (5, 190) => 0.016172
+(2, 191) ~ (5, 191) => 0.0308778
+(2, 192) ~ (5, 184) => 0.0114051
+(2, 192) ~ (5, 187) => 0.0807527
+(2, 192) ~ (5, 188) => 0.491378
+(2, 192) ~ (5, 189) => 0.0321929
+(2, 192) ~ (5, 190) => 0.0388919
+(2, 192) ~ (5, 191) => 0.0103536
+(2, 192) ~ (5, 192) => 0.0750708
+(2, 193) ~ (5, 185) => 0.0177142
+(2, 193) ~ (5, 188) => 0.250015
+(2, 193) ~ (5, 189) => 0.374006
+(2, 193) ~ (5, 190) => 0.0285442
+(2, 193) ~ (5, 191) => 0.0507393
+(2, 193) ~ (5, 192) => 0.01072
+(2, 193) ~ (5, 193) => 0.0774951
+(2, 194) ~ (5, 186) => 0.0248186
+(2, 194) ~ (5, 188) => 0.0185236
+(2, 194) ~ (5, 189) => 0.337723
+(2, 194) ~ (5, 190) => 0.269262
+(2, 194) ~ (5, 191) => 0.0206403
+(2, 194) ~ (5, 192) => 0.0652409
+(2, 194) ~ (5, 193) => 0.0126337
+(2, 194) ~ (5, 194) => 0.0647064
+(2, 195) ~ (5, 187) => 0.0382183
+(2, 195) ~ (5, 189) => 0.0328929
+(2, 195) ~ (5, 190) => 0.418498
+(2, 195) ~ (5, 191) => 0.231814
+(2, 195) ~ (5, 192) => 0.0177758
+(2, 195) ~ (5, 193) => 0.0620694
+(2, 195) ~ (5, 194) => 0.0233086
+(2, 195) ~ (5, 195) => 0.0554574
+(2, 196) ~ (5, 188) => 0.0580938
+(2, 196) ~ (5, 190) => 0.0450615
+(2, 196) ~ (5, 191) => 0.452326
+(2, 196) ~ (5, 192) => 0.195094
+(2, 196) ~ (5, 193) => 0.0159937
+(2, 196) ~ (5, 194) => 0.0561963
+(2, 196) ~ (5, 195) => 0.0336236
+(2, 196) ~ (5, 196) => 0.0463523
+(2, 197) ~ (5, 189) => 0.0668408
+(2, 197) ~ (5, 191) => 0.0494649
+(2, 197) ~ (5, 192) => 0.483548
+(2, 197) ~ (5, 193) => 0.164928
+(2, 197) ~ (5, 194) => 0.0117663
+(2, 197) ~ (5, 195) => 0.0523349
+(2, 197) ~ (5, 196) => 0.0425955
+(2, 197) ~ (5, 197) => 0.031346
+(2, 198) ~ (5, 190) => 0.0569692
+(2, 198) ~ (5, 192) => 0.0541603
+(2, 198) ~ (5, 193) => 0.524153
+(2, 198) ~ (5, 194) => 0.12069
+(2, 198) ~ (5, 196) => 0.0477326
+(2, 198) ~ (5, 197) => 0.0528417
+(2, 198) ~ (5, 198) => 0.0141958
+(2, 199) ~ (5, 191) => 0.0498255
+(2, 199) ~ (5, 193) => 0.0593905
+(2, 199) ~ (5, 194) => 0.589474
+(2, 199) ~ (5, 195) => 0.100915
+(2, 199) ~ (5, 197) => 0.0441529
+(2, 199) ~ (5, 198) => 0.0655189
+(2, 200) ~ (5, 192) => 0.0472487
+(2, 200) ~ (5, 194) => 0.0541348
+(2, 200) ~ (5, 195) => 0.624488
+(2, 200) ~ (5, 196) => 0.0683398
+(2, 200) ~ (5, 198) => 0.0208322
+(2, 200) ~ (5, 199) => 0.0665327
+(2, 201) ~ (5, 193) => 0.0361204
+(2, 201) ~ (5, 195) => 0.0490096
+(2, 201) ~ (5, 196) => 0.681663
+(2, 201) ~ (5, 197) => 0.0355623
+(2, 201) ~ (5, 199) => 0.0190646
+(2, 201) ~ (5, 200) => 0.0628654
+(2, 202) ~ (5, 194) => 0.0205305
+(2, 202) ~ (5, 196) => 0.0329888
+(2, 202) ~ (5, 197) => 0.767691
+(2, 202) ~ (5, 198) => 0.0214238
+(2, 202) ~ (5, 200) => 0.0113851
+(2, 202) ~ (5, 201) => 0.052037
+(2, 203) ~ (5, 197) => 0.0215287
+(2, 203) ~ (5, 198) => 0.840567
+(2, 203) ~ (5, 199) => 0.011726
+(2, 203) ~ (5, 202) => 0.0451028
+(2, 204) ~ (5, 199) => 0.875134
+(2, 204) ~ (5, 200) => 0.0110794
+(2, 204) ~ (5, 203) => 0.0364539
+(2, 205) ~ (5, 200) => 0.892823
+(2, 205) ~ (5, 204) => 0.0233417
+(2, 206) ~ (5, 201) => 0.921598
+(2, 206) ~ (5, 205) => 0.0102242
+(2, 207) ~ (5, 202) => 0.937914
+(2, 208) ~ (5, 203) => 0.956027
+(2, 209) ~ (5, 204) => 0.972089
+(2, 210) ~ (5, 205) => 0.986962
+(2, 211) ~ (5, 206) => 0.993115
+(2, 212) ~ (5, 207) => 0.999589
+(2, 213) ~ (5, 208) => 0.999948
+(2, 214) ~ (5, 209) => 0.999918
+(2, 215) ~ (5, 210) => 0.999675
+(2, 216) ~ (5, 211) => 0.998629
+(2, 217) ~ (5, 212) => 0.998099
+(2, 218) ~ (5, 213) => 0.998057
+(2, 219) ~ (5, 214) => 0.997472
+(2, 220) ~ (5, 215) => 0.994364
+(2, 221) ~ (5, 216) => 0.994276
+(2, 222) ~ (5, 217) => 0.993498
+(2, 223) ~ (5, 218) => 0.990812
+(2, 224) ~ (5, 219) => 0.988352
+(2, 225) ~ (5, 220) => 0.988671
+(2, 226) ~ (5, 221) => 0.994057
+(2, 227) ~ (5, 222) => 0.998133
+(2, 228) ~ (5, 223) => 0.999803
+(2, 229) ~ (5, 224) => 0.999973
+(2, 230) ~ (5, 225) => 0.999995
+(2, 231) ~ (5, 226) => 0.999983
+(2, 232) ~ (5, 227) => 0.999884
+(2, 233) ~ (5, 228) => 0.99952
+(2, 234) ~ (5, 229) => 0.996575
+(2, 235) ~ (5, 230) => 0.992865
+(2, 236) ~ (5, 231) => 0.988132
+(2, 237) ~ (5, 231) => 0.0111779
+(2, 237) ~ (5, 232) => 0.987253
+(2, 238) ~ (5, 232) => 0.0113051
+(2, 238) ~ (5, 233) => 0.988109
+
+; gap posteriors
+(2, 0) ~ (5, -1) => 0.0342945
+(2, 1) ~ (5, -1) => 0.101861
+(2, 2) ~ (5, -1) => 0.174178
+(2, 3) ~ (5, -1) => 0.204219
+(2, 4) ~ (5, -1) => 0.223554
+(2, 5) ~ (5, -1) => 0.186694
+(2, 6) ~ (5, -1) => 0.220224
+(2, 7) ~ (5, -1) => 0.247811
+(2, 8) ~ (5, -1) => 0.385929
+(2, 9) ~ (5, -1) => 0.344929
+(2, 10) ~ (5, -1) => 0.259611
+(2, 11) ~ (5, -1) => 0.0833392
+(2, 12) ~ (5, -1) => 0.0539891
+(2, 13) ~ (5, -1) => 0.0234464
+(2, 14) ~ (5, -1) => 0.0244175
+(2, 15) ~ (5, -1) => 0.0189638
+(2, 16) ~ (5, -1) => 0.0117192
+(2, 17) ~ (5, -1) => 0.00521618
+(2, 18) ~ (5, -1) => 0.00530517
+(2, 19) ~ (5, -1) => 0.0045622
+(2, 20) ~ (5, -1) => 0.00223655
+(2, 21) ~ (5, -1) => 0.00101978
+(2, 22) ~ (5, -1) => 0.000677168
+(2, 23) ~ (5, -1) => 0.000100553
+(2, 24) ~ (5, -1) => 0.0001
+(2, 25) ~ (5, -1) => 0.0001
+(2, 26) ~ (5, -1) => 0.0001
+(2, 27) ~ (5, -1) => 0.0001
+(2, 28) ~ (5, -1) => 0.000114799
+(2, 29) ~ (5, -1) => 0.000157416
+(2, 30) ~ (5, -1) => 0.00011003
+(2, 31) ~ (5, -1) => 0.000304163
+(2, 32) ~ (5, -1) => 0.000599027
+(2, 33) ~ (5, -1) => 0.000712216
+(2, 34) ~ (5, -1) => 0.000918686
+(2, 35) ~ (5, -1) => 0.00128347
+(2, 36) ~ (5, -1) => 0.00366557
+(2, 37) ~ (5, -1) => 0.00686747
+(2, 38) ~ (5, -1) => 0.0159606
+(2, 39) ~ (5, -1) => 0.0319321
+(2, 40) ~ (5, -1) => 0.0831518
+(2, 41) ~ (5, -1) => 0.239733
+(2, 42) ~ (5, -1) => 0.23734
+(2, 43) ~ (5, -1) => 0.245177
+(2, 44) ~ (5, -1) => 0.14997
+(2, 45) ~ (5, -1) => 0.14463
+(2, 46) ~ (5, -1) => 0.094995
+(2, 47) ~ (5, -1) => 0.0436937
+(2, 48) ~ (5, -1) => 0.085698
+(2, 49) ~ (5, -1) => 0.0911873
+(2, 50) ~ (5, -1) => 0.0512892
+(2, 51) ~ (5, -1) => 0.0209664
+(2, 52) ~ (5, -1) => 0.00973281
+(2, 53) ~ (5, -1) => 0.0112955
+(2, 54) ~ (5, -1) => 0.0136516
+(2, 55) ~ (5, -1) => 0.456811
+(2, 56) ~ (5, -1) => 0.469681
+(2, 57) ~ (5, -1) => 0.0199767
+(2, 58) ~ (5, -1) => 0.00301701
+(2, 59) ~ (5, -1) => 0.000229597
+(2, 60) ~ (5, -1) => 0.0001
+(2, 61) ~ (5, -1) => 0.0001
+(2, 62) ~ (5, -1) => 0.0001
+(2, 63) ~ (5, -1) => 0.0001
+(2, 64) ~ (5, -1) => 0.00010711
+(2, 65) ~ (5, -1) => 0.000131011
+(2, 66) ~ (5, -1) => 0.000123978
+(2, 67) ~ (5, -1) => 0.0001
+(2, 68) ~ (5, -1) => 0.0001
+(2, 69) ~ (5, -1) => 0.0001
+(2, 70) ~ (5, -1) => 0.0001
+(2, 71) ~ (5, -1) => 0.0001
+(2, 72) ~ (5, -1) => 0.0001
+(2, 73) ~ (5, -1) => 0.0001
+(2, 74) ~ (5, -1) => 0.0001
+(2, 75) ~ (5, -1) => 0.0001
+(2, 76) ~ (5, -1) => 0.0001
+(2, 77) ~ (5, -1) => 0.0001
+(2, 78) ~ (5, -1) => 0.0001
+(2, 79) ~ (5, -1) => 0.0001
+(2, 80) ~ (5, -1) => 0.0001
+(2, 81) ~ (5, -1) => 0.00128603
+(2, 82) ~ (5, -1) => 0.00172895
+(2, 83) ~ (5, -1) => 0.00227779
+(2, 84) ~ (5, -1) => 0.00237185
+(2, 85) ~ (5, -1) => 0.00190538
+(2, 86) ~ (5, -1) => 0.00141066
+(2, 87) ~ (5, -1) => 0.00113606
+(2, 88) ~ (5, -1) => 0.000727117
+(2, 89) ~ (5, -1) => 0.000495851
+(2, 90) ~ (5, -1) => 0.000281811
+(2, 91) ~ (5, -1) => 0.000279248
+(2, 92) ~ (5, -1) => 0.0001
+(2, 93) ~ (5, -1) => 0.000245214
+(2, 94) ~ (5, -1) => 0.00027591
+(2, 95) ~ (5, -1) => 0.000662625
+(2, 96) ~ (5, -1) => 0.00097698
+(2, 97) ~ (5, -1) => 0.000851095
+(2, 98) ~ (5, -1) => 0.000649273
+(2, 99) ~ (5, -1) => 0.000548482
+(2, 100) ~ (5, -1) => 0.00150973
+(2, 101) ~ (5, -1) => 0.0018034
+(2, 102) ~ (5, -1) => 0.00214529
+(2, 103) ~ (5, -1) => 0.00224793
+(2, 104) ~ (5, -1) => 0.001872
+(2, 105) ~ (5, -1) => 0.000878751
+(2, 106) ~ (5, -1) => 0.000464499
+(2, 107) ~ (5, -1) => 0.000236988
+(2, 108) ~ (5, -1) => 0.0001
+(2, 109) ~ (5, -1) => 0.0001
+(2, 110) ~ (5, -1) => 0.0001
+(2, 111) ~ (5, -1) => 0.0001
+(2, 112) ~ (5, -1) => 0.0001
+(2, 113) ~ (5, -1) => 0.0001
+(2, 114) ~ (5, -1) => 0.0001
+(2, 115) ~ (5, -1) => 0.0001
+(2, 116) ~ (5, -1) => 0.0001
+(2, 117) ~ (5, -1) => 0.0001
+(2, 118) ~ (5, -1) => 0.0001
+(2, 119) ~ (5, -1) => 0.0001
+(2, 120) ~ (5, -1) => 0.0001
+(2, 121) ~ (5, -1) => 0.000111341
+(2, 122) ~ (5, -1) => 0.0002321
+(2, 123) ~ (5, -1) => 0.000212431
+(2, 124) ~ (5, -1) => 0.0001
+(2, 125) ~ (5, -1) => 0.0001
+(2, 126) ~ (5, -1) => 0.000240862
+(2, 127) ~ (5, -1) => 0.000255644
+(2, 128) ~ (5, -1) => 0.00012064
+(2, 129) ~ (5, -1) => 0.0001
+(2, 130) ~ (5, -1) => 0.0001
+(2, 131) ~ (5, -1) => 0.00011301
+(2, 132) ~ (5, -1) => 0.000223577
+(2, 133) ~ (5, -1) => 0.000162005
+(2, 134) ~ (5, -1) => 0.000145614
+(2, 135) ~ (5, -1) => 0.0001
+(2, 136) ~ (5, -1) => 0.0001
+(2, 137) ~ (5, -1) => 0.0001
+(2, 138) ~ (5, -1) => 0.0001
+(2, 139) ~ (5, -1) => 0.0001
+(2, 140) ~ (5, -1) => 0.0001
+(2, 141) ~ (5, -1) => 0.0001
+(2, 142) ~ (5, -1) => 0.0001
+(2, 143) ~ (5, -1) => 0.0001
+(2, 144) ~ (5, -1) => 0.0001
+(2, 145) ~ (5, -1) => 0.0001
+(2, 146) ~ (5, -1) => 0.0001
+(2, 147) ~ (5, -1) => 0.0001
+(2, 148) ~ (5, -1) => 0.0001
+(2, 149) ~ (5, -1) => 0.0001
+(2, 150) ~ (5, -1) => 0.0001
+(2, 151) ~ (5, -1) => 0.0001
+(2, 152) ~ (5, -1) => 0.0001
+(2, 153) ~ (5, -1) => 0.000103235
+(2, 154) ~ (5, -1) => 0.00011003
+(2, 155) ~ (5, -1) => 0.0001
+(2, 156) ~ (5, -1) => 0.0001
+(2, 157) ~ (5, -1) => 0.0001
+(2, 158) ~ (5, -1) => 0.0001
+(2, 159) ~ (5, -1) => 0.0001
+(2, 160) ~ (5, -1) => 0.0001
+(2, 161) ~ (5, -1) => 0.000113249
+(2, 162) ~ (5, -1) => 0.000230491
+(2, 163) ~ (5, -1) => 0.000280261
+(2, 164) ~ (5, -1) => 0.000437021
+(2, 165) ~ (5, -1) => 0.000381947
+(2, 166) ~ (5, -1) => 0.000135541
+(2, 167) ~ (5, -1) => 0.000109136
+(2, 168) ~ (5, -1) => 0.00022608
+(2, 169) ~ (5, -1) => 0.000769079
+(2, 170) ~ (5, -1) => 0.00196171
+(2, 171) ~ (5, -1) => 0.00237989
+(2, 172) ~ (5, -1) => 0.00216937
+(2, 173) ~ (5, -1) => 0.00096333
+(2, 174) ~ (5, -1) => 0.000141382
+(2, 175) ~ (5, -1) => 0.0001
+(2, 176) ~ (5, -1) => 0.000203609
+(2, 177) ~ (5, -1) => 0.000407696
+(2, 178) ~ (5, -1) => 0.00084126
+(2, 179) ~ (5, -1) => 0.00101924
+(2, 180) ~ (5, -1) => 0.00123304
+(2, 181) ~ (5, -1) => 0.000858784
+(2, 182) ~ (5, -1) => 0.000133336
+(2, 183) ~ (5, -1) => 0.0001
+(2, 184) ~ (5, -1) => 0.000186026
+(2, 185) ~ (5, -1) => 0.000473619
+(2, 186) ~ (5, -1) => 0.00954372
+(2, 187) ~ (5, -1) => 0.0227571
+(2, 188) ~ (5, -1) => 0.026862
+(2, 189) ~ (5, -1) => 0.0465005
+(2, 190) ~ (5, -1) => 0.0547221
+(2, 191) ~ (5, -1) => 0.105413
+(2, 192) ~ (5, -1) => 0.259955
+(2, 193) ~ (5, -1) => 0.190767
+(2, 194) ~ (5, -1) => 0.186452
+(2, 195) ~ (5, -1) => 0.119966
+(2, 196) ~ (5, -1) => 0.0972595
+(2, 197) ~ (5, -1) => 0.0971753
+(2, 198) ~ (5, -1) => 0.129257
+(2, 199) ~ (5, -1) => 0.0907227
+(2, 200) ~ (5, -1) => 0.118424
+(2, 201) ~ (5, -1) => 0.115715
+(2, 202) ~ (5, -1) => 0.0939433
+(2, 203) ~ (5, -1) => 0.0810754
+(2, 204) ~ (5, -1) => 0.0773327
+(2, 205) ~ (5, -1) => 0.0838352
+(2, 206) ~ (5, -1) => 0.0681779
+(2, 207) ~ (5, -1) => 0.0620858
+(2, 208) ~ (5, -1) => 0.0439728
+(2, 209) ~ (5, -1) => 0.0279111
+(2, 210) ~ (5, -1) => 0.0130379
+(2, 211) ~ (5, -1) => 0.00688547
+(2, 212) ~ (5, -1) => 0.000411034
+(2, 213) ~ (5, -1) => 0.0001
+(2, 214) ~ (5, -1) => 0.0001
+(2, 215) ~ (5, -1) => 0.000324905
+(2, 216) ~ (5, -1) => 0.00137103
+(2, 217) ~ (5, -1) => 0.00190055
+(2, 218) ~ (5, -1) => 0.00194323
+(2, 219) ~ (5, -1) => 0.00252843
+(2, 220) ~ (5, -1) => 0.00563592
+(2, 221) ~ (5, -1) => 0.00572425
+(2, 222) ~ (5, -1) => 0.00650209
+(2, 223) ~ (5, -1) => 0.00918835
+(2, 224) ~ (5, -1) => 0.0116478
+(2, 225) ~ (5, -1) => 0.0113285
+(2, 226) ~ (5, -1) => 0.00594288
+(2, 227) ~ (5, -1) => 0.00186723
+(2, 228) ~ (5, -1) => 0.000196695
+(2, 229) ~ (5, -1) => 0.0001
+(2, 230) ~ (5, -1) => 0.0001
+(2, 231) ~ (5, -1) => 0.0001
+(2, 232) ~ (5, -1) => 0.000115693
+(2, 233) ~ (5, -1) => 0.000480354
+(2, 234) ~ (5, -1) => 0.0034247
+(2, 235) ~ (5, -1) => 0.00713491
+(2, 236) ~ (5, -1) => 0.0118684
+(2, 237) ~ (5, -1) => 0.00156945
+(2, 238) ~ (5, -1) => 0.000585794
+
+(2, -1) ~ (5, 0) => 0.0342945
+(2, -1) ~ (5, 1) => 0.0503796
+(2, -1) ~ (5, 2) => 0.0886474
+(2, -1) ~ (5, 3) => 0.0632602
+(2, -1) ~ (5, 4) => 0.109022
+(2, -1) ~ (5, 5) => 0.096533
+(2, -1) ~ (5, 6) => 0.0446408
+(2, -1) ~ (5, 7) => 0.026397
+(2, -1) ~ (5, 8) => 0.016447
+(2, -1) ~ (5, 9) => 0.0134513
+(2, -1) ~ (5, 10) => 0.0122495
+(2, -1) ~ (5, 11) => 0.0146555
+(2, -1) ~ (5, 12) => 0.0103173
+(2, -1) ~ (5, 13) => 0.00716621
+(2, -1) ~ (5, 14) => 0.0117192
+(2, -1) ~ (5, 15) => 0.00521618
+(2, -1) ~ (5, 16) => 0.00530517
+(2, -1) ~ (5, 17) => 0.0045622
+(2, -1) ~ (5, 18) => 0.00223655
+(2, -1) ~ (5, 19) => 0.00101978
+(2, -1) ~ (5, 20) => 0.000677168
+(2, -1) ~ (5, 21) => 0.000100553
+(2, -1) ~ (5, 22) => 0.0001
+(2, -1) ~ (5, 23) => 0.0001
+(2, -1) ~ (5, 24) => 0.0001
+(2, -1) ~ (5, 25) => 0.0001
+(2, -1) ~ (5, 26) => 0.000114799
+(2, -1) ~ (5, 27) => 0.000157416
+(2, -1) ~ (5, 28) => 0.00011003
+(2, -1) ~ (5, 29) => 0.000304163
+(2, -1) ~ (5, 30) => 0.000599027
+(2, -1) ~ (5, 31) => 0.000712216
+(2, -1) ~ (5, 32) => 0.000918686
+(2, -1) ~ (5, 33) => 0.00128347
+(2, -1) ~ (5, 34) => 0.00366557
+(2, -1) ~ (5, 35) => 0.00686747
+(2, -1) ~ (5, 36) => 0.0054174
+(2, -1) ~ (5, 37) => 0.00682068
+(2, -1) ~ (5, 38) => 0.0069715
+(2, -1) ~ (5, 39) => 0.010917
+(2, -1) ~ (5, 40) => 0.00950098
+(2, -1) ~ (5, 41) => 0.0041627
+(2, -1) ~ (5, 42) => 0.0014632
+(2, -1) ~ (5, 43) => 0.000943005
+(2, -1) ~ (5, 44) => 0.00888366
+(2, -1) ~ (5, 45) => 0.00382149
+(2, -1) ~ (5, 46) => 0.00397953
+(2, -1) ~ (5, 47) => 0.00157201
+(2, -1) ~ (5, 48) => 0.0046255
+(2, -1) ~ (5, 49) => 0.00733832
+(2, -1) ~ (5, 50) => 0.00790992
+(2, -1) ~ (5, 51) => 0.0146466
+(2, -1) ~ (5, 52) => 0.404047
+(2, -1) ~ (5, 53) => 0.0138524
+(2, -1) ~ (5, 54) => 0.00301701
+(2, -1) ~ (5, 55) => 0.000229597
+(2, -1) ~ (5, 56) => 0.0001
+(2, -1) ~ (5, 57) => 0.0001
+(2, -1) ~ (5, 58) => 0.0001
+(2, -1) ~ (5, 59) => 0.0001
+(2, -1) ~ (5, 60) => 0.00010711
+(2, -1) ~ (5, 61) => 0.000131011
+(2, -1) ~ (5, 62) => 0.000123978
+(2, -1) ~ (5, 63) => 0.0001
+(2, -1) ~ (5, 64) => 0.0001
+(2, -1) ~ (5, 65) => 0.0001
+(2, -1) ~ (5, 66) => 0.0001
+(2, -1) ~ (5, 67) => 0.0001
+(2, -1) ~ (5, 68) => 0.0001
+(2, -1) ~ (5, 69) => 0.0001
+(2, -1) ~ (5, 70) => 0.0001
+(2, -1) ~ (5, 71) => 0.0001
+(2, -1) ~ (5, 72) => 0.0001
+(2, -1) ~ (5, 73) => 0.0001
+(2, -1) ~ (5, 74) => 0.0001
+(2, -1) ~ (5, 75) => 0.0001
+(2, -1) ~ (5, 76) => 0.0001
+(2, -1) ~ (5, 77) => 0.00128603
+(2, -1) ~ (5, 78) => 0.00172895
+(2, -1) ~ (5, 79) => 0.00227779
+(2, -1) ~ (5, 80) => 0.00237185
+(2, -1) ~ (5, 81) => 0.00190538
+(2, -1) ~ (5, 82) => 0.00141066
+(2, -1) ~ (5, 83) => 0.00113606
+(2, -1) ~ (5, 84) => 0.000727117
+(2, -1) ~ (5, 85) => 0.000495851
+(2, -1) ~ (5, 86) => 0.000281811
+(2, -1) ~ (5, 87) => 0.000279248
+(2, -1) ~ (5, 88) => 0.0001
+(2, -1) ~ (5, 89) => 0.000245214
+(2, -1) ~ (5, 90) => 0.00027591
+(2, -1) ~ (5, 91) => 0.000662625
+(2, -1) ~ (5, 92) => 0.00097698
+(2, -1) ~ (5, 93) => 0.000851095
+(2, -1) ~ (5, 94) => 0.000649273
+(2, -1) ~ (5, 95) => 0.000548482
+(2, -1) ~ (5, 96) => 0.00150973
+(2, -1) ~ (5, 97) => 0.0018034
+(2, -1) ~ (5, 98) => 0.00214529
+(2, -1) ~ (5, 99) => 0.00224793
+(2, -1) ~ (5, 100) => 0.001872
+(2, -1) ~ (5, 101) => 0.000878751
+(2, -1) ~ (5, 102) => 0.000464499
+(2, -1) ~ (5, 103) => 0.000236988
+(2, -1) ~ (5, 104) => 0.0001
+(2, -1) ~ (5, 105) => 0.0001
+(2, -1) ~ (5, 106) => 0.0001
+(2, -1) ~ (5, 107) => 0.0001
+(2, -1) ~ (5, 108) => 0.0001
+(2, -1) ~ (5, 109) => 0.0001
+(2, -1) ~ (5, 110) => 0.0001
+(2, -1) ~ (5, 111) => 0.0001
+(2, -1) ~ (5, 112) => 0.0001
+(2, -1) ~ (5, 113) => 0.0001
+(2, -1) ~ (5, 114) => 0.0001
+(2, -1) ~ (5, 115) => 0.0001
+(2, -1) ~ (5, 116) => 0.0001
+(2, -1) ~ (5, 117) => 0.000111341
+(2, -1) ~ (5, 118) => 0.0002321
+(2, -1) ~ (5, 119) => 0.000212431
+(2, -1) ~ (5, 120) => 0.0001
+(2, -1) ~ (5, 121) => 0.0001
+(2, -1) ~ (5, 122) => 0.000240862
+(2, -1) ~ (5, 123) => 0.000255644
+(2, -1) ~ (5, 124) => 0.00012064
+(2, -1) ~ (5, 125) => 0.0001
+(2, -1) ~ (5, 126) => 0.0001
+(2, -1) ~ (5, 127) => 0.00011301
+(2, -1) ~ (5, 128) => 0.000223577
+(2, -1) ~ (5, 129) => 0.000162005
+(2, -1) ~ (5, 130) => 0.000145614
+(2, -1) ~ (5, 131) => 0.0001
+(2, -1) ~ (5, 132) => 0.0001
+(2, -1) ~ (5, 133) => 0.0001
+(2, -1) ~ (5, 134) => 0.0001
+(2, -1) ~ (5, 135) => 0.0001
+(2, -1) ~ (5, 136) => 0.0001
+(2, -1) ~ (5, 137) => 0.0001
+(2, -1) ~ (5, 138) => 0.0001
+(2, -1) ~ (5, 139) => 0.0001
+(2, -1) ~ (5, 140) => 0.0001
+(2, -1) ~ (5, 141) => 0.0001
+(2, -1) ~ (5, 142) => 0.0001
+(2, -1) ~ (5, 143) => 0.0001
+(2, -1) ~ (5, 144) => 0.0001
+(2, -1) ~ (5, 145) => 0.0001
+(2, -1) ~ (5, 146) => 0.0001
+(2, -1) ~ (5, 147) => 0.0001
+(2, -1) ~ (5, 148) => 0.0001
+(2, -1) ~ (5, 149) => 0.000103235
+(2, -1) ~ (5, 150) => 0.00011003
+(2, -1) ~ (5, 151) => 0.0001
+(2, -1) ~ (5, 152) => 0.0001
+(2, -1) ~ (5, 153) => 0.0001
+(2, -1) ~ (5, 154) => 0.0001
+(2, -1) ~ (5, 155) => 0.0001
+(2, -1) ~ (5, 156) => 0.0001
+(2, -1) ~ (5, 157) => 0.000113249
+(2, -1) ~ (5, 158) => 0.000230491
+(2, -1) ~ (5, 159) => 0.000280261
+(2, -1) ~ (5, 160) => 0.000437021
+(2, -1) ~ (5, 161) => 0.000381947
+(2, -1) ~ (5, 162) => 0.000135541
+(2, -1) ~ (5, 163) => 0.000109136
+(2, -1) ~ (5, 164) => 0.00022608
+(2, -1) ~ (5, 165) => 0.000769079
+(2, -1) ~ (5, 166) => 0.00196171
+(2, -1) ~ (5, 167) => 0.00237989
+(2, -1) ~ (5, 168) => 0.00216937
+(2, -1) ~ (5, 169) => 0.00096333
+(2, -1) ~ (5, 170) => 0.000141382
+(2, -1) ~ (5, 171) => 0.0001
+(2, -1) ~ (5, 172) => 0.000203609
+(2, -1) ~ (5, 173) => 0.000407696
+(2, -1) ~ (5, 174) => 0.00084126
+(2, -1) ~ (5, 175) => 0.00101924
+(2, -1) ~ (5, 176) => 0.00123304
+(2, -1) ~ (5, 177) => 0.000858784
+(2, -1) ~ (5, 178) => 0.000133336
+(2, -1) ~ (5, 179) => 0.0001
+(2, -1) ~ (5, 180) => 0.000186026
+(2, -1) ~ (5, 181) => 0.000473619
+(2, -1) ~ (5, 182) => 0.00954372
+(2, -1) ~ (5, 183) => 0.0227571
+(2, -1) ~ (5, 184) => 0.0298872
+(2, -1) ~ (5, 185) => 0.0410979
+(2, -1) ~ (5, 186) => 0.0761473
+(2, -1) ~ (5, 187) => 0.0833455
+(2, -1) ~ (5, 188) => 0.106279
+(2, -1) ~ (5, 189) => 0.122621
+(2, -1) ~ (5, 190) => 0.113197
+(2, -1) ~ (5, 191) => 0.103958
+(2, -1) ~ (5, 192) => 0.0511415
+(2, -1) ~ (5, 193) => 0.047216
+(2, -1) ~ (5, 194) => 0.0591925
+(2, -1) ~ (5, 195) => 0.0841714
+(2, -1) ~ (5, 196) => 0.0803282
+(2, -1) ~ (5, 197) => 0.046877
+(2, -1) ~ (5, 198) => 0.0374622
+(2, -1) ~ (5, 199) => 0.0275427
+(2, -1) ~ (5, 200) => 0.021847
+(2, -1) ~ (5, 201) => 0.0263651
+(2, -1) ~ (5, 202) => 0.016983
+(2, -1) ~ (5, 203) => 0.00751895
+(2, -1) ~ (5, 204) => 0.00456941
+(2, -1) ~ (5, 205) => 0.0028137
+(2, -1) ~ (5, 206) => 0.00688547
+(2, -1) ~ (5, 207) => 0.000411034
+(2, -1) ~ (5, 208) => 0.0001
+(2, -1) ~ (5, 209) => 0.0001
+(2, -1) ~ (5, 210) => 0.000324905
+(2, -1) ~ (5, 211) => 0.00137103
+(2, -1) ~ (5, 212) => 0.00190055
+(2, -1) ~ (5, 213) => 0.00194323
+(2, -1) ~ (5, 214) => 0.00252843
+(2, -1) ~ (5, 215) => 0.00563592
+(2, -1) ~ (5, 216) => 0.00572425
+(2, -1) ~ (5, 217) => 0.00650209
+(2, -1) ~ (5, 218) => 0.00918835
+(2, -1) ~ (5, 219) => 0.0116478
+(2, -1) ~ (5, 220) => 0.0113285
+(2, -1) ~ (5, 221) => 0.00594288
+(2, -1) ~ (5, 222) => 0.00186723
+(2, -1) ~ (5, 223) => 0.000196695
+(2, -1) ~ (5, 224) => 0.0001
+(2, -1) ~ (5, 225) => 0.0001
+(2, -1) ~ (5, 226) => 0.0001
+(2, -1) ~ (5, 227) => 0.000115693
+(2, -1) ~ (5, 228) => 0.000480354
+(2, -1) ~ (5, 229) => 0.0034247
+(2, -1) ~ (5, 230) => 0.00713491
+(2, -1) ~ (5, 231) => 0.000690488
+(2, -1) ~ (5, 232) => 0.00144227
+(2, -1) ~ (5, 233) => 0.0118909
+
+; Sparse posterior probability matrix for sequences 3 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(3, 0) ~ (4, 0) => 0.951893
+(3, 1) ~ (4, 0) => 0.0231938
+(3, 1) ~ (4, 1) => 0.932358
+(3, 1) ~ (4, 4) => 0.0127117
+(3, 2) ~ (4, 1) => 0.0244733
+(3, 2) ~ (4, 2) => 0.912862
+(3, 2) ~ (4, 5) => 0.0222288
+(3, 3) ~ (4, 1) => 0.0119398
+(3, 3) ~ (4, 2) => 0.0217802
+(3, 3) ~ (4, 3) => 0.90734
+(3, 3) ~ (4, 6) => 0.0265684
+(3, 4) ~ (4, 2) => 0.0223667
+(3, 4) ~ (4, 3) => 0.0212098
+(3, 4) ~ (4, 4) => 0.905986
+(3, 4) ~ (4, 7) => 0.0230667
+(3, 5) ~ (4, 3) => 0.0237293
+(3, 5) ~ (4, 4) => 0.0191216
+(3, 5) ~ (4, 5) => 0.909188
+(3, 5) ~ (4, 8) => 0.0110996
+(3, 6) ~ (4, 4) => 0.0249142
+(3, 6) ~ (4, 5) => 0.0151907
+(3, 6) ~ (4, 6) => 0.908706
+(3, 6) ~ (4, 8) => 0.0185315
+(3, 7) ~ (4, 5) => 0.0257061
+(3, 7) ~ (4, 7) => 0.913723
+(3, 7) ~ (4, 9) => 0.027937
+(3, 8) ~ (4, 6) => 0.0280147
+(3, 8) ~ (4, 8) => 0.918358
+(3, 8) ~ (4, 10) => 0.0315939
+(3, 9) ~ (4, 7) => 0.0163768
+(3, 9) ~ (4, 9) => 0.939925
+(3, 9) ~ (4, 11) => 0.0272587
+(3, 10) ~ (4, 10) => 0.950811
+(3, 10) ~ (4, 12) => 0.0254596
+(3, 11) ~ (4, 11) => 0.961134
+(3, 11) ~ (4, 13) => 0.0202756
+(3, 12) ~ (4, 12) => 0.961028
+(3, 12) ~ (4, 14) => 0.0176634
+(3, 13) ~ (4, 13) => 0.934923
+(3, 13) ~ (4, 15) => 0.01485
+(3, 14) ~ (4, 13) => 0.035531
+(3, 14) ~ (4, 14) => 0.927083
+(3, 14) ~ (4, 16) => 0.0103539
+(3, 15) ~ (4, 14) => 0.0439306
+(3, 15) ~ (4, 15) => 0.92019
+(3, 16) ~ (4, 15) => 0.0520454
+(3, 16) ~ (4, 16) => 0.921074
+(3, 17) ~ (4, 16) => 0.0549903
+(3, 17) ~ (4, 17) => 0.923366
+(3, 18) ~ (4, 17) => 0.0569456
+(3, 18) ~ (4, 18) => 0.930576
+(3, 19) ~ (4, 18) => 0.0197629
+(3, 19) ~ (4, 19) => 0.971317
+(3, 20) ~ (4, 20) => 0.993631
+(3, 21) ~ (4, 21) => 0.998848
+(3, 22) ~ (4, 22) => 0.999863
+(3, 23) ~ (4, 23) => 0.999982
+(3, 24) ~ (4, 24) => 0.999955
+(3, 25) ~ (4, 25) => 0.999064
+(3, 26) ~ (4, 26) => 0.99499
+(3, 27) ~ (4, 27) => 0.984126
+(3, 27) ~ (4, 28) => 0.0131033
+(3, 28) ~ (4, 28) => 0.978357
+(3, 28) ~ (4, 29) => 0.0154502
+(3, 29) ~ (4, 29) => 0.948532
+(3, 29) ~ (4, 30) => 0.0239112
+(3, 30) ~ (4, 30) => 0.931993
+(3, 30) ~ (4, 31) => 0.025203
+(3, 30) ~ (4, 33) => 0.0187476
+(3, 31) ~ (4, 31) => 0.925522
+(3, 31) ~ (4, 32) => 0.0202641
+(3, 31) ~ (4, 34) => 0.0208372
+(3, 32) ~ (4, 29) => 0.0126668
+(3, 32) ~ (4, 32) => 0.928993
+(3, 32) ~ (4, 33) => 0.0168849
+(3, 32) ~ (4, 35) => 0.0187887
+(3, 33) ~ (4, 30) => 0.0144211
+(3, 33) ~ (4, 33) => 0.928378
+(3, 33) ~ (4, 34) => 0.0153462
+(3, 33) ~ (4, 36) => 0.0171802
+(3, 34) ~ (4, 31) => 0.0181115
+(3, 34) ~ (4, 34) => 0.925728
+(3, 34) ~ (4, 35) => 0.0159388
+(3, 34) ~ (4, 37) => 0.0173675
+(3, 35) ~ (4, 32) => 0.0196781
+(3, 35) ~ (4, 35) => 0.928116
+(3, 35) ~ (4, 36) => 0.016575
+(3, 35) ~ (4, 38) => 0.0152515
+(3, 36) ~ (4, 33) => 0.0216784
+(3, 36) ~ (4, 36) => 0.93021
+(3, 36) ~ (4, 37) => 0.0169814
+(3, 36) ~ (4, 39) => 0.0108988
+(3, 37) ~ (4, 34) => 0.0211019
+(3, 37) ~ (4, 37) => 0.932412
+(3, 37) ~ (4, 38) => 0.011226
+(3, 38) ~ (4, 35) => 0.0208494
+(3, 38) ~ (4, 38) => 0.940229
+(3, 38) ~ (4, 39) => 0.0103459
+(3, 39) ~ (4, 36) => 0.0206608
+(3, 39) ~ (4, 39) => 0.946248
+(3, 40) ~ (4, 37) => 0.0204607
+(3, 40) ~ (4, 40) => 0.952388
+(3, 40) ~ (4, 41) => 0.0104458
+(3, 41) ~ (4, 38) => 0.0200957
+(3, 41) ~ (4, 41) => 0.952693
+(3, 42) ~ (4, 39) => 0.0180516
+(3, 42) ~ (4, 42) => 0.956988
+(3, 43) ~ (4, 40) => 0.0127755
+(3, 43) ~ (4, 43) => 0.964088
+(3, 44) ~ (4, 41) => 0.0105742
+(3, 44) ~ (4, 44) => 0.965804
+(3, 45) ~ (4, 42) => 0.0102718
+(3, 45) ~ (4, 45) => 0.911454
+(3, 46) ~ (4, 45) => 0.0190158
+(3, 46) ~ (4, 46) => 0.842845
+(3, 47) ~ (4, 44) => 0.0102297
+(3, 47) ~ (4, 45) => 0.0375291
+(3, 47) ~ (4, 47) => 0.464687
+(3, 48) ~ (4, 45) => 0.0149172
+(3, 48) ~ (4, 46) => 0.109271
+(3, 48) ~ (4, 48) => 0.365855
+(3, 49) ~ (4, 46) => 0.0188942
+(3, 49) ~ (4, 47) => 0.489579
+(3, 49) ~ (4, 49) => 0.223851
+(3, 50) ~ (4, 47) => 0.0204364
+(3, 50) ~ (4, 48) => 0.581009
+(3, 50) ~ (4, 50) => 0.0614976
+(3, 51) ~ (4, 48) => 0.0325967
+(3, 51) ~ (4, 49) => 0.726251
+(3, 51) ~ (4, 51) => 0.0284707
+(3, 52) ~ (4, 50) => 0.921263
+(3, 53) ~ (4, 51) => 0.962878
+(3, 54) ~ (4, 52) => 0.995387
+(3, 55) ~ (4, 53) => 0.999356
+(3, 56) ~ (4, 54) => 0.999882
+(3, 57) ~ (4, 55) => 0.999973
+(3, 58) ~ (4, 56) => 0.999948
+(3, 59) ~ (4, 57) => 0.999683
+(3, 60) ~ (4, 58) => 0.999527
+(3, 61) ~ (4, 59) => 0.999483
+(3, 62) ~ (4, 60) => 0.999485
+(3, 63) ~ (4, 61) => 0.998665
+(3, 64) ~ (4, 62) => 0.997677
+(3, 65) ~ (4, 63) => 0.996255
+(3, 66) ~ (4, 64) => 0.995124
+(3, 67) ~ (4, 65) => 0.994864
+(3, 68) ~ (4, 66) => 0.995056
+(3, 69) ~ (4, 67) => 0.997423
+(3, 70) ~ (4, 68) => 0.999777
+(3, 71) ~ (4, 69) => 0.999823
+(3, 72) ~ (4, 70) => 0.999459
+(3, 73) ~ (4, 71) => 0.998829
+(3, 74) ~ (4, 72) => 0.998844
+(3, 75) ~ (4, 73) => 0.999822
+(3, 76) ~ (4, 74) => 0.999931
+(3, 77) ~ (4, 75) => 0.999985
+(3, 78) ~ (4, 76) => 0.999986
+(3, 79) ~ (4, 77) => 0.999987
+(3, 80) ~ (4, 78) => 0.999991
+(3, 81) ~ (4, 79) => 0.999901
+(3, 82) ~ (4, 80) => 0.999578
+(3, 83) ~ (4, 81) => 0.994829
+(3, 84) ~ (4, 82) => 0.988861
+(3, 85) ~ (4, 83) => 0.94144
+(3, 86) ~ (4, 84) => 0.626877
+(3, 87) ~ (4, 85) => 0.530746
+(3, 88) ~ (4, 83) => 0.0557577
+(3, 88) ~ (4, 86) => 0.436543
+(3, 89) ~ (4, 84) => 0.36384
+(3, 89) ~ (4, 86) => 0.0114535
+(3, 89) ~ (4, 87) => 0.208152
+(3, 90) ~ (4, 85) => 0.449581
+(3, 90) ~ (4, 87) => 0.0157399
+(3, 90) ~ (4, 88) => 0.0407834
+(3, 91) ~ (4, 86) => 0.529679
+(3, 91) ~ (4, 88) => 0.0120309
+(3, 92) ~ (4, 87) => 0.750092
+(3, 93) ~ (4, 88) => 0.924302
+(3, 94) ~ (4, 89) => 0.963658
+(3, 95) ~ (4, 90) => 0.960472
+(3, 95) ~ (4, 94) => 0.0111816
+(3, 96) ~ (4, 91) => 0.948523
+(3, 96) ~ (4, 95) => 0.0272433
+(3, 97) ~ (4, 92) => 0.673074
+(3, 97) ~ (4, 96) => 0.291275
+(3, 98) ~ (4, 93) => 0.557529
+(3, 98) ~ (4, 97) => 0.407077
+(3, 98) ~ (4, 98) => 0.0111709
+(3, 99) ~ (4, 94) => 0.521469
+(3, 99) ~ (4, 95) => 0.0153112
+(3, 99) ~ (4, 98) => 0.417
+(3, 99) ~ (4, 99) => 0.0254847
+(3, 100) ~ (4, 95) => 0.344876
+(3, 100) ~ (4, 96) => 0.0187242
+(3, 100) ~ (4, 97) => 0.0219287
+(3, 100) ~ (4, 99) => 0.369988
+(3, 100) ~ (4, 100) => 0.208438
+(3, 101) ~ (4, 96) => 0.255283
+(3, 101) ~ (4, 97) => 0.0152727
+(3, 101) ~ (4, 98) => 0.0317343
+(3, 101) ~ (4, 99) => 0.0120994
+(3, 101) ~ (4, 100) => 0.315736
+(3, 101) ~ (4, 101) => 0.333712
+(3, 102) ~ (4, 97) => 0.161834
+(3, 102) ~ (4, 98) => 0.0109714
+(3, 102) ~ (4, 99) => 0.0544606
+(3, 102) ~ (4, 100) => 0.0143019
+(3, 102) ~ (4, 101) => 0.259131
+(3, 102) ~ (4, 102) => 0.464089
+(3, 103) ~ (4, 98) => 0.0921556
+(3, 103) ~ (4, 100) => 0.0710826
+(3, 103) ~ (4, 101) => 0.0133129
+(3, 103) ~ (4, 102) => 0.207263
+(3, 103) ~ (4, 103) => 0.577517
+(3, 104) ~ (4, 99) => 0.0657943
+(3, 104) ~ (4, 101) => 0.0805413
+(3, 104) ~ (4, 102) => 0.0117085
+(3, 104) ~ (4, 103) => 0.168314
+(3, 104) ~ (4, 104) => 0.646102
+(3, 105) ~ (4, 100) => 0.0383338
+(3, 105) ~ (4, 102) => 0.0494249
+(3, 105) ~ (4, 104) => 0.0859605
+(3, 105) ~ (4, 105) => 0.804322
+(3, 106) ~ (4, 101) => 0.0127803
+(3, 106) ~ (4, 106) => 0.968148
+(3, 107) ~ (4, 107) => 0.994289
+(3, 108) ~ (4, 108) => 0.998947
+(3, 109) ~ (4, 109) => 0.99982
+(3, 110) ~ (4, 110) => 0.999772
+(3, 111) ~ (4, 111) => 0.999803
+(3, 112) ~ (4, 112) => 0.999926
+(3, 113) ~ (4, 113) => 0.999964
+(3, 114) ~ (4, 114) => 0.999923
+(3, 115) ~ (4, 115) => 0.999902
+(3, 116) ~ (4, 116) => 0.999457
+(3, 117) ~ (4, 117) => 0.998831
+(3, 118) ~ (4, 118) => 0.998132
+(3, 119) ~ (4, 119) => 0.998068
+(3, 120) ~ (4, 120) => 0.996016
+(3, 121) ~ (4, 121) => 0.994735
+(3, 122) ~ (4, 122) => 0.993132
+(3, 123) ~ (4, 123) => 0.991387
+(3, 124) ~ (4, 124) => 0.991214
+(3, 125) ~ (4, 125) => 0.989351
+(3, 126) ~ (4, 126) => 0.986733
+(3, 127) ~ (4, 127) => 0.982122
+(3, 128) ~ (4, 128) => 0.982583
+(3, 129) ~ (4, 127) => 0.0144105
+(3, 129) ~ (4, 129) => 0.980294
+(3, 130) ~ (4, 128) => 0.0146398
+(3, 130) ~ (4, 130) => 0.920194
+(3, 130) ~ (4, 132) => 0.0123751
+(3, 131) ~ (4, 129) => 0.0156149
+(3, 131) ~ (4, 131) => 0.862632
+(3, 131) ~ (4, 133) => 0.0226769
+(3, 132) ~ (4, 130) => 0.0333613
+(3, 132) ~ (4, 132) => 0.78465
+(3, 132) ~ (4, 134) => 0.0434339
+(3, 133) ~ (4, 130) => 0.0246839
+(3, 133) ~ (4, 131) => 0.0490238
+(3, 133) ~ (4, 133) => 0.728827
+(3, 133) ~ (4, 135) => 0.0366124
+(3, 134) ~ (4, 131) => 0.0480119
+(3, 134) ~ (4, 132) => 0.0718318
+(3, 134) ~ (4, 134) => 0.676109
+(3, 134) ~ (4, 136) => 0.0322379
+(3, 134) ~ (4, 138) => 0.0114792
+(3, 135) ~ (4, 132) => 0.0708296
+(3, 135) ~ (4, 133) => 0.0903272
+(3, 135) ~ (4, 134) => 0.0173698
+(3, 135) ~ (4, 135) => 0.662772
+(3, 135) ~ (4, 137) => 0.0173804
+(3, 135) ~ (4, 139) => 0.010855
+(3, 136) ~ (4, 133) => 0.0963955
+(3, 136) ~ (4, 134) => 0.102288
+(3, 136) ~ (4, 135) => 0.0226344
+(3, 136) ~ (4, 136) => 0.651135
+(3, 137) ~ (4, 134) => 0.114992
+(3, 137) ~ (4, 135) => 0.110412
+(3, 137) ~ (4, 136) => 0.0266924
+(3, 137) ~ (4, 137) => 0.632063
+(3, 138) ~ (4, 133) => 0.0116559
+(3, 138) ~ (4, 135) => 0.122486
+(3, 138) ~ (4, 136) => 0.0943069
+(3, 138) ~ (4, 137) => 0.0398748
+(3, 138) ~ (4, 138) => 0.631033
+(3, 139) ~ (4, 134) => 0.0178402
+(3, 139) ~ (4, 136) => 0.140234
+(3, 139) ~ (4, 137) => 0.027895
+(3, 139) ~ (4, 138) => 0.0592639
+(3, 139) ~ (4, 139) => 0.629379
+(3, 140) ~ (4, 137) => 0.223417
+(3, 140) ~ (4, 139) => 0.0884437
+(3, 140) ~ (4, 140) => 0.620247
+(3, 141) ~ (4, 138) => 0.223558
+(3, 141) ~ (4, 140) => 0.116683
+(3, 141) ~ (4, 141) => 0.234542
+(3, 141) ~ (4, 142) => 0.0160345
+(3, 142) ~ (4, 139) => 0.14744
+(3, 142) ~ (4, 141) => 0.574023
+(3, 142) ~ (4, 142) => 0.105745
+(3, 142) ~ (4, 143) => 0.011599
+(3, 143) ~ (4, 140) => 0.113797
+(3, 143) ~ (4, 142) => 0.741928
+(3, 143) ~ (4, 143) => 0.0498886
+(3, 144) ~ (4, 141) => 0.11245
+(3, 144) ~ (4, 143) => 0.815263
+(3, 144) ~ (4, 144) => 0.0111685
+(3, 145) ~ (4, 142) => 0.0558653
+(3, 145) ~ (4, 144) => 0.917619
+(3, 146) ~ (4, 143) => 0.035392
+(3, 146) ~ (4, 145) => 0.946265
+(3, 147) ~ (4, 144) => 0.0149874
+(3, 147) ~ (4, 146) => 0.974435
+(3, 148) ~ (4, 147) => 0.996608
+(3, 149) ~ (4, 148) => 0.999804
+(3, 150) ~ (4, 149) => 0.999978
+(3, 151) ~ (4, 150) => 0.99999
+(3, 152) ~ (4, 151) => 0.99998
+(3, 153) ~ (4, 152) => 0.99996
+(3, 154) ~ (4, 153) => 0.999935
+(3, 155) ~ (4, 154) => 0.999956
+(3, 156) ~ (4, 155) => 0.999969
+(3, 157) ~ (4, 156) => 0.999923
+(3, 158) ~ (4, 157) => 0.99993
+(3, 159) ~ (4, 158) => 0.99995
+(3, 160) ~ (4, 159) => 0.999214
+(3, 161) ~ (4, 160) => 0.998841
+(3, 162) ~ (4, 161) => 0.998919
+(3, 163) ~ (4, 162) => 0.998972
+(3, 164) ~ (4, 163) => 0.998588
+(3, 165) ~ (4, 164) => 0.998529
+(3, 166) ~ (4, 165) => 0.998346
+(3, 167) ~ (4, 166) => 0.999018
+(3, 168) ~ (4, 167) => 0.999278
+(3, 169) ~ (4, 168) => 0.999459
+(3, 170) ~ (4, 169) => 0.999952
+(3, 171) ~ (4, 170) => 0.999748
+(3, 172) ~ (4, 171) => 0.999672
+(3, 173) ~ (4, 172) => 0.999845
+(3, 174) ~ (4, 173) => 0.999911
+(3, 175) ~ (4, 174) => 0.999989
+(3, 176) ~ (4, 175) => 0.99999
+(3, 177) ~ (4, 176) => 0.999787
+(3, 178) ~ (4, 177) => 0.999635
+(3, 179) ~ (4, 178) => 0.999593
+(3, 180) ~ (4, 179) => 0.999686
+(3, 181) ~ (4, 180) => 0.999951
+(3, 182) ~ (4, 181) => 0.999984
+(3, 183) ~ (4, 182) => 0.999984
+(3, 184) ~ (4, 183) => 0.999901
+(3, 185) ~ (4, 184) => 0.999637
+(3, 186) ~ (4, 185) => 0.988086
+(3, 187) ~ (4, 186) => 0.976341
+(3, 187) ~ (4, 188) => 0.0182114
+(3, 188) ~ (4, 187) => 0.964269
+(3, 188) ~ (4, 189) => 0.0281274
+(3, 189) ~ (4, 188) => 0.94284
+(3, 189) ~ (4, 190) => 0.0461856
+(3, 190) ~ (4, 189) => 0.904437
+(3, 190) ~ (4, 190) => 0.0108434
+(3, 190) ~ (4, 191) => 0.0820128
+(3, 191) ~ (4, 190) => 0.891233
+(3, 191) ~ (4, 191) => 0.0118939
+(3, 191) ~ (4, 192) => 0.0901022
+(3, 192) ~ (4, 191) => 0.884499
+(3, 192) ~ (4, 192) => 0.0109084
+(3, 192) ~ (4, 193) => 0.0941961
+(3, 193) ~ (4, 192) => 0.884804
+(3, 193) ~ (4, 193) => 0.0118684
+(3, 193) ~ (4, 194) => 0.0869012
+(3, 194) ~ (4, 193) => 0.85755
+(3, 194) ~ (4, 194) => 0.0246211
+(3, 194) ~ (4, 195) => 0.0719815
+(3, 195) ~ (4, 193) => 0.0173693
+(3, 195) ~ (4, 194) => 0.623688
+(3, 195) ~ (4, 195) => 0.116664
+(3, 195) ~ (4, 196) => 0.058098
+(3, 196) ~ (4, 194) => 0.165322
+(3, 196) ~ (4, 195) => 0.502309
+(3, 196) ~ (4, 196) => 0.176028
+(3, 196) ~ (4, 197) => 0.0605164
+(3, 197) ~ (4, 195) => 0.234941
+(3, 197) ~ (4, 196) => 0.460492
+(3, 197) ~ (4, 197) => 0.172701
+(3, 197) ~ (4, 198) => 0.0428083
+(3, 197) ~ (4, 199) => 0.0123687
+(3, 198) ~ (4, 196) => 0.276441
+(3, 198) ~ (4, 197) => 0.424376
+(3, 198) ~ (4, 198) => 0.169197
+(3, 198) ~ (4, 199) => 0.0235516
+(3, 198) ~ (4, 200) => 0.0194723
+(3, 199) ~ (4, 197) => 0.312881
+(3, 199) ~ (4, 198) => 0.361075
+(3, 199) ~ (4, 199) => 0.185524
+(3, 199) ~ (4, 200) => 0.0169067
+(3, 199) ~ (4, 201) => 0.0145921
+(3, 200) ~ (4, 198) => 0.380931
+(3, 200) ~ (4, 199) => 0.312733
+(3, 200) ~ (4, 200) => 0.151794
+(3, 200) ~ (4, 201) => 0.011973
+(3, 200) ~ (4, 202) => 0.0106083
+(3, 201) ~ (4, 199) => 0.444972
+(3, 201) ~ (4, 200) => 0.242607
+(3, 201) ~ (4, 201) => 0.0607832
+(3, 201) ~ (4, 203) => 0.0109726
+(3, 202) ~ (4, 200) => 0.558135
+(3, 202) ~ (4, 201) => 0.182627
+(3, 202) ~ (4, 202) => 0.0140618
+(3, 203) ~ (4, 201) => 0.721752
+(3, 203) ~ (4, 202) => 0.11856
+(3, 204) ~ (4, 202) => 0.841197
+(3, 204) ~ (4, 203) => 0.112229
+(3, 205) ~ (4, 203) => 0.857811
+(3, 205) ~ (4, 204) => 0.0414059
+(3, 206) ~ (4, 204) => 0.940791
+(3, 206) ~ (4, 205) => 0.0248701
+(3, 207) ~ (4, 205) => 0.956596
+(3, 208) ~ (4, 206) => 0.97186
+(3, 209) ~ (4, 207) => 0.968441
+(3, 210) ~ (4, 208) => 0.973031
+(3, 211) ~ (4, 209) => 0.974679
+(3, 212) ~ (4, 210) => 0.980944
+(3, 213) ~ (4, 211) => 0.97414
+(3, 214) ~ (4, 212) => 0.964015
+(3, 214) ~ (4, 213) => 0.0133724
+(3, 214) ~ (4, 215) => 0.010426
+(3, 215) ~ (4, 213) => 0.958603
+(3, 215) ~ (4, 214) => 0.0175099
+(3, 215) ~ (4, 216) => 0.0118418
+(3, 216) ~ (4, 214) => 0.953665
+(3, 216) ~ (4, 215) => 0.0190391
+(3, 216) ~ (4, 217) => 0.0140725
+(3, 217) ~ (4, 215) => 0.94587
+(3, 217) ~ (4, 216) => 0.0225375
+(3, 217) ~ (4, 218) => 0.0180829
+(3, 218) ~ (4, 216) => 0.941038
+(3, 218) ~ (4, 217) => 0.0252731
+(3, 218) ~ (4, 219) => 0.0226745
+(3, 219) ~ (4, 217) => 0.924221
+(3, 219) ~ (4, 218) => 0.0260596
+(3, 219) ~ (4, 220) => 0.0366655
+(3, 220) ~ (4, 218) => 0.790893
+(3, 220) ~ (4, 219) => 0.0365998
+(3, 220) ~ (4, 221) => 0.155418
+(3, 221) ~ (4, 219) => 0.672164
+(3, 221) ~ (4, 220) => 0.040614
+(3, 221) ~ (4, 222) => 0.266274
+(3, 222) ~ (4, 220) => 0.410384
+(3, 222) ~ (4, 221) => 0.16392
+(3, 222) ~ (4, 222) => 0.0271422
+(3, 222) ~ (4, 223) => 0.367659
+(3, 223) ~ (4, 221) => 0.133116
+(3, 223) ~ (4, 222) => 0.419202
+(3, 223) ~ (4, 223) => 0.0318261
+(3, 223) ~ (4, 224) => 0.356393
+(3, 224) ~ (4, 222) => 0.101355
+(3, 224) ~ (4, 223) => 0.454482
+(3, 224) ~ (4, 224) => 0.0228636
+(3, 224) ~ (4, 225) => 0.298612
+(3, 225) ~ (4, 223) => 0.0707337
+(3, 225) ~ (4, 224) => 0.51742
+(3, 225) ~ (4, 225) => 0.0132039
+(3, 225) ~ (4, 226) => 0.259939
+(3, 226) ~ (4, 224) => 0.040624
+(3, 226) ~ (4, 225) => 0.620801
+(3, 226) ~ (4, 227) => 0.191959
+(3, 227) ~ (4, 225) => 0.0361708
+(3, 227) ~ (4, 226) => 0.679926
+(3, 227) ~ (4, 228) => 0.131524
+(3, 228) ~ (4, 227) => 0.802162
+(3, 229) ~ (4, 228) => 0.866635
+(3, 230) ~ (4, 229) => 0.993957
+(3, 231) ~ (4, 230) => 0.998928
+(3, 232) ~ (4, 231) => 0.998306
+(3, 233) ~ (4, 232) => 0.998542
+(3, 234) ~ (4, 233) => 0.997272
+(3, 235) ~ (4, 234) => 0.99604
+(3, 236) ~ (4, 235) => 0.995386
+(3, 237) ~ (4, 236) => 0.995915
+(3, 238) ~ (4, 237) => 0.996862
+
+; gap posteriors
+(3, 0) ~ (4, -1) => 0.0481074
+(3, 1) ~ (4, -1) => 0.0317367
+(3, 2) ~ (4, -1) => 0.0404361
+(3, 3) ~ (4, -1) => 0.0323721
+(3, 4) ~ (4, -1) => 0.0273707
+(3, 5) ~ (4, -1) => 0.0368615
+(3, 6) ~ (4, -1) => 0.0326574
+(3, 7) ~ (4, -1) => 0.0326335
+(3, 8) ~ (4, -1) => 0.0220338
+(3, 9) ~ (4, -1) => 0.0164397
+(3, 10) ~ (4, -1) => 0.0237297
+(3, 11) ~ (4, -1) => 0.0185903
+(3, 12) ~ (4, -1) => 0.0213086
+(3, 13) ~ (4, -1) => 0.0502274
+(3, 14) ~ (4, -1) => 0.027032
+(3, 15) ~ (4, -1) => 0.0358791
+(3, 16) ~ (4, -1) => 0.026881
+(3, 17) ~ (4, -1) => 0.0216439
+(3, 18) ~ (4, -1) => 0.0124786
+(3, 19) ~ (4, -1) => 0.00892037
+(3, 20) ~ (4, -1) => 0.00636941
+(3, 21) ~ (4, -1) => 0.0011521
+(3, 22) ~ (4, -1) => 0.000136971
+(3, 23) ~ (4, -1) => 0.0001
+(3, 24) ~ (4, -1) => 0.0001
+(3, 25) ~ (4, -1) => 0.000936151
+(3, 26) ~ (4, -1) => 0.00500959
+(3, 27) ~ (4, -1) => 0.00277054
+(3, 28) ~ (4, -1) => 0.00619246
+(3, 29) ~ (4, -1) => 0.0275573
+(3, 30) ~ (4, -1) => 0.0240568
+(3, 31) ~ (4, -1) => 0.0333766
+(3, 32) ~ (4, -1) => 0.0226665
+(3, 33) ~ (4, -1) => 0.0246741
+(3, 34) ~ (4, -1) => 0.022854
+(3, 35) ~ (4, -1) => 0.0203792
+(3, 36) ~ (4, -1) => 0.0202309
+(3, 37) ~ (4, -1) => 0.0352598
+(3, 38) ~ (4, -1) => 0.0285752
+(3, 39) ~ (4, -1) => 0.0330911
+(3, 40) ~ (4, -1) => 0.0167055
+(3, 41) ~ (4, -1) => 0.0272115
+(3, 42) ~ (4, -1) => 0.0249609
+(3, 43) ~ (4, -1) => 0.0231368
+(3, 44) ~ (4, -1) => 0.0236217
+(3, 45) ~ (4, -1) => 0.0782737
+(3, 46) ~ (4, -1) => 0.13814
+(3, 47) ~ (4, -1) => 0.487554
+(3, 48) ~ (4, -1) => 0.509958
+(3, 49) ~ (4, -1) => 0.267676
+(3, 50) ~ (4, -1) => 0.337057
+(3, 51) ~ (4, -1) => 0.212681
+(3, 52) ~ (4, -1) => 0.0787374
+(3, 53) ~ (4, -1) => 0.0371221
+(3, 54) ~ (4, -1) => 0.00461268
+(3, 55) ~ (4, -1) => 0.000643671
+(3, 56) ~ (4, -1) => 0.000117838
+(3, 57) ~ (4, -1) => 0.0001
+(3, 58) ~ (4, -1) => 0.0001
+(3, 59) ~ (4, -1) => 0.000317037
+(3, 60) ~ (4, -1) => 0.000473022
+(3, 61) ~ (4, -1) => 0.000517309
+(3, 62) ~ (4, -1) => 0.000514805
+(3, 63) ~ (4, -1) => 0.00133467
+(3, 64) ~ (4, -1) => 0.00232345
+(3, 65) ~ (4, -1) => 0.00374454
+(3, 66) ~ (4, -1) => 0.00487602
+(3, 67) ~ (4, -1) => 0.00513637
+(3, 68) ~ (4, -1) => 0.00494426
+(3, 69) ~ (4, -1) => 0.00257689
+(3, 70) ~ (4, -1) => 0.000223041
+(3, 71) ~ (4, -1) => 0.000176787
+(3, 72) ~ (4, -1) => 0.000541389
+(3, 73) ~ (4, -1) => 0.00117064
+(3, 74) ~ (4, -1) => 0.00115567
+(3, 75) ~ (4, -1) => 0.000177622
+(3, 76) ~ (4, -1) => 0.0001
+(3, 77) ~ (4, -1) => 0.0001
+(3, 78) ~ (4, -1) => 0.0001
+(3, 79) ~ (4, -1) => 0.0001
+(3, 80) ~ (4, -1) => 0.0001
+(3, 81) ~ (4, -1) => 0.0001
+(3, 82) ~ (4, -1) => 0.000421643
+(3, 83) ~ (4, -1) => 0.00517052
+(3, 84) ~ (4, -1) => 0.0111391
+(3, 85) ~ (4, -1) => 0.05856
+(3, 86) ~ (4, -1) => 0.373123
+(3, 87) ~ (4, -1) => 0.469254
+(3, 88) ~ (4, -1) => 0.5077
+(3, 89) ~ (4, -1) => 0.416554
+(3, 90) ~ (4, -1) => 0.493896
+(3, 91) ~ (4, -1) => 0.45829
+(3, 92) ~ (4, -1) => 0.249908
+(3, 93) ~ (4, -1) => 0.0756977
+(3, 94) ~ (4, -1) => 0.0363416
+(3, 95) ~ (4, -1) => 0.0283462
+(3, 96) ~ (4, -1) => 0.0242341
+(3, 97) ~ (4, -1) => 0.0356512
+(3, 98) ~ (4, -1) => 0.0242235
+(3, 99) ~ (4, -1) => 0.0207348
+(3, 100) ~ (4, -1) => 0.0360454
+(3, 101) ~ (4, -1) => 0.0361618
+(3, 102) ~ (4, -1) => 0.0352124
+(3, 103) ~ (4, -1) => 0.0386688
+(3, 104) ~ (4, -1) => 0.0275401
+(3, 105) ~ (4, -1) => 0.0219589
+(3, 106) ~ (4, -1) => 0.0190713
+(3, 107) ~ (4, -1) => 0.0057106
+(3, 108) ~ (4, -1) => 0.00105268
+(3, 109) ~ (4, -1) => 0.000180185
+(3, 110) ~ (4, -1) => 0.000227749
+(3, 111) ~ (4, -1) => 0.000197291
+(3, 112) ~ (4, -1) => 0.0001
+(3, 113) ~ (4, -1) => 0.0001
+(3, 114) ~ (4, -1) => 0.0001
+(3, 115) ~ (4, -1) => 0.0001
+(3, 116) ~ (4, -1) => 0.000542939
+(3, 117) ~ (4, -1) => 0.00116867
+(3, 118) ~ (4, -1) => 0.00186825
+(3, 119) ~ (4, -1) => 0.00193202
+(3, 120) ~ (4, -1) => 0.00398368
+(3, 121) ~ (4, -1) => 0.00526488
+(3, 122) ~ (4, -1) => 0.00686759
+(3, 123) ~ (4, -1) => 0.00861305
+(3, 124) ~ (4, -1) => 0.00878602
+(3, 125) ~ (4, -1) => 0.0106489
+(3, 126) ~ (4, -1) => 0.0132666
+(3, 127) ~ (4, -1) => 0.0178778
+(3, 128) ~ (4, -1) => 0.017417
+(3, 129) ~ (4, -1) => 0.0052954
+(3, 130) ~ (4, -1) => 0.052791
+(3, 131) ~ (4, -1) => 0.099076
+(3, 132) ~ (4, -1) => 0.138555
+(3, 133) ~ (4, -1) => 0.160853
+(3, 134) ~ (4, -1) => 0.16033
+(3, 135) ~ (4, -1) => 0.130466
+(3, 136) ~ (4, -1) => 0.127547
+(3, 137) ~ (4, -1) => 0.115841
+(3, 138) ~ (4, -1) => 0.100643
+(3, 139) ~ (4, -1) => 0.125387
+(3, 140) ~ (4, -1) => 0.067892
+(3, 141) ~ (4, -1) => 0.409183
+(3, 142) ~ (4, -1) => 0.161192
+(3, 143) ~ (4, -1) => 0.094386
+(3, 144) ~ (4, -1) => 0.0611184
+(3, 145) ~ (4, -1) => 0.0265153
+(3, 146) ~ (4, -1) => 0.018343
+(3, 147) ~ (4, -1) => 0.0105776
+(3, 148) ~ (4, -1) => 0.00339246
+(3, 149) ~ (4, -1) => 0.000195682
+(3, 150) ~ (4, -1) => 0.0001
+(3, 151) ~ (4, -1) => 0.0001
+(3, 152) ~ (4, -1) => 0.0001
+(3, 153) ~ (4, -1) => 0.0001
+(3, 154) ~ (4, -1) => 0.0001
+(3, 155) ~ (4, -1) => 0.0001
+(3, 156) ~ (4, -1) => 0.0001
+(3, 157) ~ (4, -1) => 0.0001
+(3, 158) ~ (4, -1) => 0.0001
+(3, 159) ~ (4, -1) => 0.0001
+(3, 160) ~ (4, -1) => 0.000786066
+(3, 161) ~ (4, -1) => 0.00115883
+(3, 162) ~ (4, -1) => 0.00108081
+(3, 163) ~ (4, -1) => 0.00102836
+(3, 164) ~ (4, -1) => 0.00141203
+(3, 165) ~ (4, -1) => 0.00147116
+(3, 166) ~ (4, -1) => 0.00165385
+(3, 167) ~ (4, -1) => 0.000982285
+(3, 168) ~ (4, -1) => 0.00072217
+(3, 169) ~ (4, -1) => 0.000541031
+(3, 170) ~ (4, -1) => 0.0001
+(3, 171) ~ (4, -1) => 0.000252128
+(3, 172) ~ (4, -1) => 0.000328481
+(3, 173) ~ (4, -1) => 0.000154912
+(3, 174) ~ (4, -1) => 0.0001
+(3, 175) ~ (4, -1) => 0.0001
+(3, 176) ~ (4, -1) => 0.0001
+(3, 177) ~ (4, -1) => 0.000212669
+(3, 178) ~ (4, -1) => 0.000364661
+(3, 179) ~ (4, -1) => 0.00040704
+(3, 180) ~ (4, -1) => 0.000314355
+(3, 181) ~ (4, -1) => 0.0001
+(3, 182) ~ (4, -1) => 0.0001
+(3, 183) ~ (4, -1) => 0.0001
+(3, 184) ~ (4, -1) => 0.0001
+(3, 185) ~ (4, -1) => 0.000362515
+(3, 186) ~ (4, -1) => 0.011914
+(3, 187) ~ (4, -1) => 0.00544709
+(3, 188) ~ (4, -1) => 0.00760347
+(3, 189) ~ (4, -1) => 0.0109749
+(3, 190) ~ (4, -1) => 0.00270709
+(3, 191) ~ (4, -1) => 0.0067709
+(3, 192) ~ (4, -1) => 0.0103966
+(3, 193) ~ (4, -1) => 0.016426
+(3, 194) ~ (4, -1) => 0.0458477
+(3, 195) ~ (4, -1) => 0.18418
+(3, 196) ~ (4, -1) => 0.0958237
+(3, 197) ~ (4, -1) => 0.0766888
+(3, 198) ~ (4, -1) => 0.0869624
+(3, 199) ~ (4, -1) => 0.109022
+(3, 200) ~ (4, -1) => 0.131961
+(3, 201) ~ (4, -1) => 0.240666
+(3, 202) ~ (4, -1) => 0.245176
+(3, 203) ~ (4, -1) => 0.159688
+(3, 204) ~ (4, -1) => 0.0465739
+(3, 205) ~ (4, -1) => 0.100783
+(3, 206) ~ (4, -1) => 0.034339
+(3, 207) ~ (4, -1) => 0.043404
+(3, 208) ~ (4, -1) => 0.0281405
+(3, 209) ~ (4, -1) => 0.0315587
+(3, 210) ~ (4, -1) => 0.0269687
+(3, 211) ~ (4, -1) => 0.0253214
+(3, 212) ~ (4, -1) => 0.0190563
+(3, 213) ~ (4, -1) => 0.0258598
+(3, 214) ~ (4, -1) => 0.0121868
+(3, 215) ~ (4, -1) => 0.0120449
+(3, 216) ~ (4, -1) => 0.0132236
+(3, 217) ~ (4, -1) => 0.0135099
+(3, 218) ~ (4, -1) => 0.0110143
+(3, 219) ~ (4, -1) => 0.0130536
+(3, 220) ~ (4, -1) => 0.017089
+(3, 221) ~ (4, -1) => 0.0209478
+(3, 222) ~ (4, -1) => 0.0308945
+(3, 223) ~ (4, -1) => 0.0594629
+(3, 224) ~ (4, -1) => 0.122687
+(3, 225) ~ (4, -1) => 0.138704
+(3, 226) ~ (4, -1) => 0.146616
+(3, 227) ~ (4, -1) => 0.152379
+(3, 228) ~ (4, -1) => 0.197838
+(3, 229) ~ (4, -1) => 0.133365
+(3, 230) ~ (4, -1) => 0.00604314
+(3, 231) ~ (4, -1) => 0.00107229
+(3, 232) ~ (4, -1) => 0.00169373
+(3, 233) ~ (4, -1) => 0.00145829
+(3, 234) ~ (4, -1) => 0.00272769
+(3, 235) ~ (4, -1) => 0.00395983
+(3, 236) ~ (4, -1) => 0.00461376
+(3, 237) ~ (4, -1) => 0.00408548
+(3, 238) ~ (4, -1) => 0.00313812
+
+(3, -1) ~ (4, 0) => 0.0249136
+(3, -1) ~ (4, 1) => 0.0312291
+(3, -1) ~ (4, 2) => 0.0429913
+(3, -1) ~ (4, 3) => 0.0477214
+(3, -1) ~ (4, 4) => 0.0372665
+(3, -1) ~ (4, 5) => 0.0276864
+(3, -1) ~ (4, 6) => 0.0367105
+(3, -1) ~ (4, 7) => 0.0468331
+(3, -1) ~ (4, 8) => 0.0520113
+(3, -1) ~ (4, 9) => 0.0321381
+(3, -1) ~ (4, 10) => 0.0175955
+(3, -1) ~ (4, 11) => 0.0116073
+(3, -1) ~ (4, 12) => 0.0135124
+(3, -1) ~ (4, 13) => 0.00927085
+(3, -1) ~ (4, 14) => 0.0113229
+(3, -1) ~ (4, 15) => 0.0129143
+(3, -1) ~ (4, 16) => 0.0135822
+(3, -1) ~ (4, 17) => 0.0196886
+(3, -1) ~ (4, 18) => 0.0496613
+(3, -1) ~ (4, 19) => 0.0286832
+(3, -1) ~ (4, 20) => 0.00636941
+(3, -1) ~ (4, 21) => 0.0011521
+(3, -1) ~ (4, 22) => 0.000136971
+(3, -1) ~ (4, 23) => 0.0001
+(3, -1) ~ (4, 24) => 0.0001
+(3, -1) ~ (4, 25) => 0.000936151
+(3, -1) ~ (4, 26) => 0.00500959
+(3, -1) ~ (4, 27) => 0.0158738
+(3, -1) ~ (4, 28) => 0.00853938
+(3, -1) ~ (4, 29) => 0.0233514
+(3, -1) ~ (4, 30) => 0.0296751
+(3, -1) ~ (4, 31) => 0.0311634
+(3, -1) ~ (4, 32) => 0.0310646
+(3, -1) ~ (4, 33) => 0.0143107
+(3, -1) ~ (4, 34) => 0.0169863
+(3, -1) ~ (4, 35) => 0.0163069
+(3, -1) ~ (4, 36) => 0.0153735
+(3, -1) ~ (4, 37) => 0.0127783
+(3, -1) ~ (4, 38) => 0.0131973
+(3, -1) ~ (4, 39) => 0.0144555
+(3, -1) ~ (4, 40) => 0.0348365
+(3, -1) ~ (4, 41) => 0.0262871
+(3, -1) ~ (4, 42) => 0.0327407
+(3, -1) ~ (4, 43) => 0.0359123
+(3, -1) ~ (4, 44) => 0.0239662
+(3, -1) ~ (4, 45) => 0.0170835
+(3, -1) ~ (4, 46) => 0.0289908
+(3, -1) ~ (4, 47) => 0.0252979
+(3, -1) ~ (4, 48) => 0.0205394
+(3, -1) ~ (4, 49) => 0.0498978
+(3, -1) ~ (4, 50) => 0.0172397
+(3, -1) ~ (4, 51) => 0.00865144
+(3, -1) ~ (4, 52) => 0.00461268
+(3, -1) ~ (4, 53) => 0.000643671
+(3, -1) ~ (4, 54) => 0.000117838
+(3, -1) ~ (4, 55) => 0.0001
+(3, -1) ~ (4, 56) => 0.0001
+(3, -1) ~ (4, 57) => 0.000317037
+(3, -1) ~ (4, 58) => 0.000473022
+(3, -1) ~ (4, 59) => 0.000517309
+(3, -1) ~ (4, 60) => 0.000514805
+(3, -1) ~ (4, 61) => 0.00133467
+(3, -1) ~ (4, 62) => 0.00232345
+(3, -1) ~ (4, 63) => 0.00374454
+(3, -1) ~ (4, 64) => 0.00487602
+(3, -1) ~ (4, 65) => 0.00513637
+(3, -1) ~ (4, 66) => 0.00494426
+(3, -1) ~ (4, 67) => 0.00257689
+(3, -1) ~ (4, 68) => 0.000223041
+(3, -1) ~ (4, 69) => 0.000176787
+(3, -1) ~ (4, 70) => 0.000541389
+(3, -1) ~ (4, 71) => 0.00117064
+(3, -1) ~ (4, 72) => 0.00115567
+(3, -1) ~ (4, 73) => 0.000177622
+(3, -1) ~ (4, 74) => 0.0001
+(3, -1) ~ (4, 75) => 0.0001
+(3, -1) ~ (4, 76) => 0.0001
+(3, -1) ~ (4, 77) => 0.0001
+(3, -1) ~ (4, 78) => 0.0001
+(3, -1) ~ (4, 79) => 0.0001
+(3, -1) ~ (4, 80) => 0.000421643
+(3, -1) ~ (4, 81) => 0.00517052
+(3, -1) ~ (4, 82) => 0.0111391
+(3, -1) ~ (4, 83) => 0.0028022
+(3, -1) ~ (4, 84) => 0.00928301
+(3, -1) ~ (4, 85) => 0.0196739
+(3, -1) ~ (4, 86) => 0.0223252
+(3, -1) ~ (4, 87) => 0.0260161
+(3, -1) ~ (4, 88) => 0.0228834
+(3, -1) ~ (4, 89) => 0.0363416
+(3, -1) ~ (4, 90) => 0.0395278
+(3, -1) ~ (4, 91) => 0.0514774
+(3, -1) ~ (4, 92) => 0.326926
+(3, -1) ~ (4, 93) => 0.442471
+(3, -1) ~ (4, 94) => 0.467349
+(3, -1) ~ (4, 95) => 0.61257
+(3, -1) ~ (4, 96) => 0.434718
+(3, -1) ~ (4, 97) => 0.393888
+(3, -1) ~ (4, 98) => 0.436968
+(3, -1) ~ (4, 99) => 0.472173
+(3, -1) ~ (4, 100) => 0.352107
+(3, -1) ~ (4, 101) => 0.300522
+(3, -1) ~ (4, 102) => 0.267514
+(3, -1) ~ (4, 103) => 0.254169
+(3, -1) ~ (4, 104) => 0.267938
+(3, -1) ~ (4, 105) => 0.195678
+(3, -1) ~ (4, 106) => 0.0318516
+(3, -1) ~ (4, 107) => 0.0057106
+(3, -1) ~ (4, 108) => 0.00105268
+(3, -1) ~ (4, 109) => 0.000180185
+(3, -1) ~ (4, 110) => 0.000227749
+(3, -1) ~ (4, 111) => 0.000197291
+(3, -1) ~ (4, 112) => 0.0001
+(3, -1) ~ (4, 113) => 0.0001
+(3, -1) ~ (4, 114) => 0.0001
+(3, -1) ~ (4, 115) => 0.0001
+(3, -1) ~ (4, 116) => 0.000542939
+(3, -1) ~ (4, 117) => 0.00116867
+(3, -1) ~ (4, 118) => 0.00186825
+(3, -1) ~ (4, 119) => 0.00193202
+(3, -1) ~ (4, 120) => 0.00398368
+(3, -1) ~ (4, 121) => 0.00526488
+(3, -1) ~ (4, 122) => 0.00686759
+(3, -1) ~ (4, 123) => 0.00861305
+(3, -1) ~ (4, 124) => 0.00878602
+(3, -1) ~ (4, 125) => 0.0106489
+(3, -1) ~ (4, 126) => 0.0132666
+(3, -1) ~ (4, 127) => 0.00346729
+(3, -1) ~ (4, 128) => 0.00277723
+(3, -1) ~ (4, 129) => 0.00409102
+(3, -1) ~ (4, 130) => 0.0217607
+(3, -1) ~ (4, 131) => 0.0403322
+(3, -1) ~ (4, 132) => 0.0603136
+(3, -1) ~ (4, 133) => 0.0501179
+(3, -1) ~ (4, 134) => 0.0279671
+(3, -1) ~ (4, 135) => 0.0450833
+(3, -1) ~ (4, 136) => 0.0553932
+(3, -1) ~ (4, 137) => 0.0593698
+(3, -1) ~ (4, 138) => 0.0746651
+(3, -1) ~ (4, 139) => 0.123882
+(3, -1) ~ (4, 140) => 0.149273
+(3, -1) ~ (4, 141) => 0.0789851
+(3, -1) ~ (4, 142) => 0.0804265
+(3, -1) ~ (4, 143) => 0.0878573
+(3, -1) ~ (4, 144) => 0.0562247
+(3, -1) ~ (4, 145) => 0.053735
+(3, -1) ~ (4, 146) => 0.025565
+(3, -1) ~ (4, 147) => 0.00339246
+(3, -1) ~ (4, 148) => 0.000195682
+(3, -1) ~ (4, 149) => 0.0001
+(3, -1) ~ (4, 150) => 0.0001
+(3, -1) ~ (4, 151) => 0.0001
+(3, -1) ~ (4, 152) => 0.0001
+(3, -1) ~ (4, 153) => 0.0001
+(3, -1) ~ (4, 154) => 0.0001
+(3, -1) ~ (4, 155) => 0.0001
+(3, -1) ~ (4, 156) => 0.0001
+(3, -1) ~ (4, 157) => 0.0001
+(3, -1) ~ (4, 158) => 0.0001
+(3, -1) ~ (4, 159) => 0.000786066
+(3, -1) ~ (4, 160) => 0.00115883
+(3, -1) ~ (4, 161) => 0.00108081
+(3, -1) ~ (4, 162) => 0.00102836
+(3, -1) ~ (4, 163) => 0.00141203
+(3, -1) ~ (4, 164) => 0.00147116
+(3, -1) ~ (4, 165) => 0.00165385
+(3, -1) ~ (4, 166) => 0.000982285
+(3, -1) ~ (4, 167) => 0.00072217
+(3, -1) ~ (4, 168) => 0.000541031
+(3, -1) ~ (4, 169) => 0.0001
+(3, -1) ~ (4, 170) => 0.000252128
+(3, -1) ~ (4, 171) => 0.000328481
+(3, -1) ~ (4, 172) => 0.000154912
+(3, -1) ~ (4, 173) => 0.0001
+(3, -1) ~ (4, 174) => 0.0001
+(3, -1) ~ (4, 175) => 0.0001
+(3, -1) ~ (4, 176) => 0.000212669
+(3, -1) ~ (4, 177) => 0.000364661
+(3, -1) ~ (4, 178) => 0.00040704
+(3, -1) ~ (4, 179) => 0.000314355
+(3, -1) ~ (4, 180) => 0.0001
+(3, -1) ~ (4, 181) => 0.0001
+(3, -1) ~ (4, 182) => 0.0001
+(3, -1) ~ (4, 183) => 0.0001
+(3, -1) ~ (4, 184) => 0.000362515
+(3, -1) ~ (4, 185) => 0.011914
+(3, -1) ~ (4, 186) => 0.0236585
+(3, -1) ~ (4, 187) => 0.0357308
+(3, -1) ~ (4, 188) => 0.038949
+(3, -1) ~ (4, 189) => 0.0674359
+(3, -1) ~ (4, 190) => 0.0517381
+(3, -1) ~ (4, 191) => 0.0215944
+(3, -1) ~ (4, 192) => 0.0141849
+(3, -1) ~ (4, 193) => 0.0190164
+(3, -1) ~ (4, 194) => 0.099467
+(3, -1) ~ (4, 195) => 0.0741048
+(3, -1) ~ (4, 196) => 0.0289407
+(3, -1) ~ (4, 197) => 0.0295253
+(3, -1) ~ (4, 198) => 0.0459892
+(3, -1) ~ (4, 199) => 0.0208516
+(3, -1) ~ (4, 200) => 0.0110848
+(3, -1) ~ (4, 201) => 0.00827348
+(3, -1) ~ (4, 202) => 0.0155731
+(3, -1) ~ (4, 203) => 0.0189866
+(3, -1) ~ (4, 204) => 0.0178031
+(3, -1) ~ (4, 205) => 0.0185339
+(3, -1) ~ (4, 206) => 0.0281405
+(3, -1) ~ (4, 207) => 0.0315587
+(3, -1) ~ (4, 208) => 0.0269687
+(3, -1) ~ (4, 209) => 0.0253214
+(3, -1) ~ (4, 210) => 0.0190563
+(3, -1) ~ (4, 211) => 0.0258598
+(3, -1) ~ (4, 212) => 0.0359852
+(3, -1) ~ (4, 213) => 0.0280243
+(3, -1) ~ (4, 214) => 0.0288253
+(3, -1) ~ (4, 215) => 0.0246651
+(3, -1) ~ (4, 216) => 0.0245826
+(3, -1) ~ (4, 217) => 0.036433
+(3, -1) ~ (4, 218) => 0.164964
+(3, -1) ~ (4, 219) => 0.268562
+(3, -1) ~ (4, 220) => 0.512336
+(3, -1) ~ (4, 221) => 0.547546
+(3, -1) ~ (4, 222) => 0.186027
+(3, -1) ~ (4, 223) => 0.0752987
+(3, -1) ~ (4, 224) => 0.0626991
+(3, -1) ~ (4, 225) => 0.0312123
+(3, -1) ~ (4, 226) => 0.0601346
+(3, -1) ~ (4, 227) => 0.00587869
+(3, -1) ~ (4, 228) => 0.00184113
+(3, -1) ~ (4, 229) => 0.00604314
+(3, -1) ~ (4, 230) => 0.00107229
+(3, -1) ~ (4, 231) => 0.00169373
+(3, -1) ~ (4, 232) => 0.00145829
+(3, -1) ~ (4, 233) => 0.00272769
+(3, -1) ~ (4, 234) => 0.00395983
+(3, -1) ~ (4, 235) => 0.00461376
+(3, -1) ~ (4, 236) => 0.00408548
+(3, -1) ~ (4, 237) => 0.00313812
+
+; Sparse posterior probability matrix for sequences 3 and 5
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(3, 0) ~ (5, 0) => 0.501935
+(3, 1) ~ (5, 0) => 0.48644
+(3, 1) ~ (5, 1) => 0.390926
+(3, 1) ~ (5, 2) => 0.0101618
+(3, 2) ~ (5, 1) => 0.586952
+(3, 2) ~ (5, 2) => 0.331122
+(3, 3) ~ (5, 2) => 0.639813
+(3, 3) ~ (5, 3) => 0.284245
+(3, 4) ~ (5, 2) => 0.0129092
+(3, 4) ~ (5, 3) => 0.689515
+(3, 4) ~ (5, 4) => 0.267188
+(3, 5) ~ (5, 3) => 0.0100894
+(3, 5) ~ (5, 4) => 0.714287
+(3, 5) ~ (5, 5) => 0.16637
+(3, 6) ~ (5, 5) => 0.82519
+(3, 6) ~ (5, 6) => 0.0379714
+(3, 7) ~ (5, 6) => 0.959517
+(3, 8) ~ (5, 7) => 0.996875
+(3, 9) ~ (5, 8) => 0.99901
+(3, 10) ~ (5, 9) => 0.999668
+(3, 11) ~ (5, 10) => 0.999715
+(3, 12) ~ (5, 11) => 0.999811
+(3, 13) ~ (5, 12) => 0.999716
+(3, 14) ~ (5, 13) => 0.996745
+(3, 15) ~ (5, 14) => 0.994892
+(3, 16) ~ (5, 15) => 0.992157
+(3, 17) ~ (5, 16) => 0.989885
+(3, 18) ~ (5, 17) => 0.990172
+(3, 19) ~ (5, 18) => 0.993664
+(3, 20) ~ (5, 19) => 0.997258
+(3, 21) ~ (5, 20) => 0.999004
+(3, 22) ~ (5, 21) => 0.999879
+(3, 23) ~ (5, 22) => 0.999997
+(3, 24) ~ (5, 23) => 0.999978
+(3, 25) ~ (5, 24) => 0.99974
+(3, 26) ~ (5, 25) => 0.998063
+(3, 27) ~ (5, 26) => 0.99673
+(3, 28) ~ (5, 27) => 0.979527
+(3, 29) ~ (5, 28) => 0.962668
+(3, 30) ~ (5, 29) => 0.867626
+(3, 31) ~ (5, 27) => 0.0176343
+(3, 31) ~ (5, 30) => 0.801518
+(3, 32) ~ (5, 28) => 0.0338486
+(3, 32) ~ (5, 31) => 0.795244
+(3, 33) ~ (5, 29) => 0.130633
+(3, 33) ~ (5, 32) => 0.777133
+(3, 34) ~ (5, 30) => 0.195675
+(3, 34) ~ (5, 33) => 0.742507
+(3, 35) ~ (5, 31) => 0.202219
+(3, 35) ~ (5, 34) => 0.697786
+(3, 36) ~ (5, 32) => 0.218282
+(3, 36) ~ (5, 35) => 0.6134
+(3, 37) ~ (5, 33) => 0.240578
+(3, 37) ~ (5, 36) => 0.159804
+(3, 38) ~ (5, 33) => 0.0113623
+(3, 38) ~ (5, 34) => 0.284176
+(3, 38) ~ (5, 37) => 0.0491357
+(3, 39) ~ (5, 34) => 0.0106858
+(3, 39) ~ (5, 35) => 0.366396
+(3, 39) ~ (5, 38) => 0.0343438
+(3, 40) ~ (5, 36) => 0.821424
+(3, 40) ~ (5, 39) => 0.0293656
+(3, 41) ~ (5, 37) => 0.939382
+(3, 41) ~ (5, 40) => 0.0291821
+(3, 42) ~ (5, 38) => 0.958872
+(3, 42) ~ (5, 41) => 0.0294271
+(3, 43) ~ (5, 39) => 0.963925
+(3, 43) ~ (5, 42) => 0.0294518
+(3, 44) ~ (5, 40) => 0.963688
+(3, 44) ~ (5, 43) => 0.0307969
+(3, 45) ~ (5, 41) => 0.96524
+(3, 45) ~ (5, 44) => 0.0297339
+(3, 46) ~ (5, 42) => 0.966889
+(3, 46) ~ (5, 45) => 0.0286671
+(3, 47) ~ (5, 43) => 0.965998
+(3, 47) ~ (5, 46) => 0.0252859
+(3, 48) ~ (5, 44) => 0.966294
+(3, 48) ~ (5, 47) => 0.0172225
+(3, 49) ~ (5, 45) => 0.966107
+(3, 50) ~ (5, 46) => 0.936092
+(3, 50) ~ (5, 47) => 0.0406918
+(3, 51) ~ (5, 47) => 0.904978
+(3, 51) ~ (5, 48) => 0.0831536
+(3, 52) ~ (5, 48) => 0.635654
+(3, 52) ~ (5, 49) => 0.350092
+(3, 53) ~ (5, 49) => 0.231284
+(3, 53) ~ (5, 50) => 0.755451
+(3, 54) ~ (5, 50) => 0.159932
+(3, 54) ~ (5, 51) => 0.831653
+(3, 55) ~ (5, 51) => 0.0533727
+(3, 55) ~ (5, 52) => 0.94539
+(3, 56) ~ (5, 53) => 0.998071
+(3, 57) ~ (5, 54) => 0.999753
+(3, 58) ~ (5, 55) => 0.999934
+(3, 59) ~ (5, 56) => 0.999753
+(3, 60) ~ (5, 57) => 0.998701
+(3, 61) ~ (5, 58) => 0.959586
+(3, 62) ~ (5, 58) => 0.0400821
+(3, 62) ~ (5, 59) => 0.941392
+(3, 63) ~ (5, 59) => 0.0579732
+(3, 63) ~ (5, 60) => 0.793893
+(3, 64) ~ (5, 60) => 0.20421
+(3, 64) ~ (5, 61) => 0.64705
+(3, 65) ~ (5, 61) => 0.350423
+(3, 65) ~ (5, 62) => 0.498119
+(3, 66) ~ (5, 62) => 0.496786
+(3, 66) ~ (5, 63) => 0.256303
+(3, 67) ~ (5, 63) => 0.737786
+(3, 67) ~ (5, 64) => 0.200967
+(3, 68) ~ (5, 64) => 0.791596
+(3, 68) ~ (5, 65) => 0.148307
+(3, 69) ~ (5, 65) => 0.84602
+(3, 69) ~ (5, 66) => 0.0167467
+(3, 70) ~ (5, 66) => 0.982261
+(3, 71) ~ (5, 67) => 0.99688
+(3, 72) ~ (5, 68) => 0.997761
+(3, 73) ~ (5, 69) => 0.999069
+(3, 74) ~ (5, 70) => 0.999409
+(3, 75) ~ (5, 71) => 0.999944
+(3, 76) ~ (5, 72) => 0.999979
+(3, 77) ~ (5, 73) => 0.999987
+(3, 78) ~ (5, 74) => 0.999973
+(3, 79) ~ (5, 75) => 0.999972
+(3, 80) ~ (5, 76) => 0.999958
+(3, 81) ~ (5, 77) => 0.99907
+(3, 82) ~ (5, 78) => 0.998825
+(3, 83) ~ (5, 79) => 0.998669
+(3, 84) ~ (5, 80) => 0.99884
+(3, 85) ~ (5, 81) => 0.999501
+(3, 86) ~ (5, 82) => 0.999899
+(3, 87) ~ (5, 83) => 0.99981
+(3, 88) ~ (5, 84) => 0.999853
+(3, 89) ~ (5, 85) => 0.999945
+(3, 90) ~ (5, 86) => 0.999856
+(3, 91) ~ (5, 87) => 0.999832
+(3, 92) ~ (5, 88) => 0.999935
+(3, 93) ~ (5, 89) => 0.999809
+(3, 94) ~ (5, 90) => 0.99972
+(3, 95) ~ (5, 91) => 0.999144
+(3, 96) ~ (5, 92) => 0.998731
+(3, 97) ~ (5, 93) => 0.998883
+(3, 98) ~ (5, 94) => 0.999247
+(3, 99) ~ (5, 95) => 0.999717
+(3, 100) ~ (5, 96) => 0.999251
+(3, 101) ~ (5, 97) => 0.998927
+(3, 102) ~ (5, 98) => 0.998617
+(3, 103) ~ (5, 99) => 0.99857
+(3, 104) ~ (5, 100) => 0.998975
+(3, 105) ~ (5, 101) => 0.999537
+(3, 106) ~ (5, 102) => 0.999758
+(3, 107) ~ (5, 103) => 0.999908
+(3, 108) ~ (5, 104) => 0.999967
+(3, 109) ~ (5, 105) => 0.99999
+(3, 110) ~ (5, 106) => 0.999951
+(3, 111) ~ (5, 107) => 0.999938
+(3, 112) ~ (5, 108) => 0.999976
+(3, 113) ~ (5, 109) => 0.99997
+(3, 114) ~ (5, 110) => 0.999962
+(3, 115) ~ (5, 111) => 0.999973
+(3, 116) ~ (5, 112) => 0.999996
+(3, 117) ~ (5, 113) => 0.999993
+(3, 118) ~ (5, 114) => 0.999986
+(3, 119) ~ (5, 115) => 0.999819
+(3, 120) ~ (5, 116) => 0.998453
+(3, 121) ~ (5, 117) => 0.998068
+(3, 122) ~ (5, 118) => 0.996792
+(3, 123) ~ (5, 119) => 0.996844
+(3, 124) ~ (5, 120) => 0.999461
+(3, 125) ~ (5, 121) => 0.999346
+(3, 126) ~ (5, 122) => 0.999175
+(3, 127) ~ (5, 123) => 0.999255
+(3, 128) ~ (5, 124) => 0.999789
+(3, 129) ~ (5, 125) => 0.999962
+(3, 130) ~ (5, 126) => 0.999987
+(3, 131) ~ (5, 127) => 0.999993
+(3, 132) ~ (5, 128) => 0.999996
+(3, 133) ~ (5, 129) => 0.999995
+(3, 134) ~ (5, 130) => 0.999996
+(3, 135) ~ (5, 131) => 0.999988
+(3, 136) ~ (5, 132) => 0.999984
+(3, 137) ~ (5, 133) => 0.999936
+(3, 138) ~ (5, 134) => 0.999931
+(3, 139) ~ (5, 135) => 0.999975
+(3, 140) ~ (5, 136) => 0.999929
+(3, 141) ~ (5, 137) => 0.999877
+(3, 142) ~ (5, 138) => 0.99991
+(3, 143) ~ (5, 139) => 0.999983
+(3, 144) ~ (5, 140) => 0.99999
+(3, 145) ~ (5, 141) => 0.999978
+(3, 146) ~ (5, 142) => 0.999973
+(3, 147) ~ (5, 143) => 0.999982
+(3, 148) ~ (5, 144) => 0.999989
+(3, 149) ~ (5, 145) => 0.999997
+(3, 150) ~ (5, 146) => 0.999997
+(3, 151) ~ (5, 147) => 0.999991
+(3, 152) ~ (5, 148) => 0.99996
+(3, 153) ~ (5, 149) => 0.999901
+(3, 154) ~ (5, 150) => 0.999897
+(3, 155) ~ (5, 151) => 0.999957
+(3, 156) ~ (5, 152) => 0.999977
+(3, 157) ~ (5, 153) => 0.999922
+(3, 158) ~ (5, 154) => 0.999899
+(3, 159) ~ (5, 155) => 0.999809
+(3, 160) ~ (5, 156) => 0.999737
+(3, 161) ~ (5, 157) => 0.999158
+(3, 162) ~ (5, 158) => 0.998951
+(3, 163) ~ (5, 159) => 0.999108
+(3, 164) ~ (5, 160) => 0.999268
+(3, 165) ~ (5, 161) => 0.999635
+(3, 166) ~ (5, 162) => 0.999888
+(3, 167) ~ (5, 163) => 0.999955
+(3, 168) ~ (5, 164) => 0.999991
+(3, 169) ~ (5, 165) => 0.999985
+(3, 170) ~ (5, 166) => 0.999828
+(3, 171) ~ (5, 167) => 0.99948
+(3, 172) ~ (5, 168) => 0.99877
+(3, 173) ~ (5, 169) => 0.998858
+(3, 174) ~ (5, 170) => 0.999391
+(3, 175) ~ (5, 171) => 0.999924
+(3, 176) ~ (5, 172) => 0.999933
+(3, 177) ~ (5, 173) => 0.999872
+(3, 178) ~ (5, 174) => 0.99971
+(3, 179) ~ (5, 175) => 0.999559
+(3, 180) ~ (5, 176) => 0.99957
+(3, 181) ~ (5, 177) => 0.999761
+(3, 182) ~ (5, 178) => 0.999964
+(3, 183) ~ (5, 179) => 0.999995
+(3, 184) ~ (5, 180) => 0.999924
+(3, 185) ~ (5, 181) => 0.999848
+(3, 186) ~ (5, 182) => 0.996639
+(3, 187) ~ (5, 183) => 0.99281
+(3, 188) ~ (5, 184) => 0.988571
+(3, 189) ~ (5, 185) => 0.980677
+(3, 189) ~ (5, 186) => 0.0126861
+(3, 190) ~ (5, 186) => 0.971089
+(3, 190) ~ (5, 187) => 0.0171869
+(3, 191) ~ (5, 187) => 0.960689
+(3, 191) ~ (5, 188) => 0.0167335
+(3, 192) ~ (5, 187) => 0.011708
+(3, 192) ~ (5, 188) => 0.931883
+(3, 192) ~ (5, 189) => 0.0140752
+(3, 193) ~ (5, 188) => 0.0360679
+(3, 193) ~ (5, 189) => 0.919576
+(3, 193) ~ (5, 190) => 0.0132692
+(3, 194) ~ (5, 189) => 0.0488157
+(3, 194) ~ (5, 190) => 0.907796
+(3, 195) ~ (5, 190) => 0.0599797
+(3, 195) ~ (5, 191) => 0.903189
+(3, 196) ~ (5, 191) => 0.0696801
+(3, 196) ~ (5, 192) => 0.792728
+(3, 196) ~ (5, 193) => 0.0140078
+(3, 197) ~ (5, 192) => 0.171756
+(3, 197) ~ (5, 193) => 0.691711
+(3, 197) ~ (5, 194) => 0.0115629
+(3, 198) ~ (5, 193) => 0.272801
+(3, 198) ~ (5, 194) => 0.525836
+(3, 199) ~ (5, 194) => 0.442522
+(3, 199) ~ (5, 195) => 0.4417
+(3, 200) ~ (5, 195) => 0.530504
+(3, 200) ~ (5, 196) => 0.320527
+(3, 201) ~ (5, 196) => 0.657363
+(3, 201) ~ (5, 197) => 0.0426322
+(3, 202) ~ (5, 197) => 0.950248
+(3, 202) ~ (5, 198) => 0.0341275
+(3, 203) ~ (5, 198) => 0.9625
+(3, 203) ~ (5, 199) => 0.0253895
+(3, 204) ~ (5, 199) => 0.972016
+(3, 204) ~ (5, 200) => 0.0232212
+(3, 205) ~ (5, 200) => 0.974522
+(3, 205) ~ (5, 201) => 0.0144147
+(3, 206) ~ (5, 201) => 0.983757
+(3, 207) ~ (5, 202) => 0.990367
+(3, 208) ~ (5, 203) => 0.997165
+(3, 209) ~ (5, 204) => 0.998042
+(3, 210) ~ (5, 205) => 0.999549
+(3, 211) ~ (5, 206) => 0.999489
+(3, 212) ~ (5, 207) => 0.999656
+(3, 213) ~ (5, 208) => 0.998202
+(3, 214) ~ (5, 209) => 0.993613
+(3, 215) ~ (5, 210) => 0.959154
+(3, 215) ~ (5, 211) => 0.0402022
+(3, 216) ~ (5, 211) => 0.948764
+(3, 216) ~ (5, 212) => 0.0505854
+(3, 217) ~ (5, 212) => 0.94769
+(3, 217) ~ (5, 213) => 0.0499067
+(3, 218) ~ (5, 213) => 0.949655
+(3, 218) ~ (5, 214) => 0.0325627
+(3, 219) ~ (5, 214) => 0.967223
+(3, 219) ~ (5, 215) => 0.0151152
+(3, 220) ~ (5, 215) => 0.984661
+(3, 221) ~ (5, 216) => 0.996001
+(3, 222) ~ (5, 217) => 0.998056
+(3, 223) ~ (5, 218) => 0.999539
+(3, 224) ~ (5, 219) => 0.999652
+(3, 225) ~ (5, 220) => 0.999369
+(3, 226) ~ (5, 221) => 0.999186
+(3, 227) ~ (5, 222) => 0.99927
+(3, 228) ~ (5, 223) => 0.999739
+(3, 229) ~ (5, 224) => 0.999843
+(3, 230) ~ (5, 225) => 0.999989
+(3, 231) ~ (5, 226) => 0.999992
+(3, 232) ~ (5, 227) => 0.999943
+(3, 233) ~ (5, 228) => 0.999786
+(3, 234) ~ (5, 229) => 0.998515
+(3, 235) ~ (5, 230) => 0.997021
+(3, 236) ~ (5, 231) => 0.995883
+(3, 237) ~ (5, 232) => 0.995177
+(3, 238) ~ (5, 233) => 0.995589
+
+; gap posteriors
+(3, 0) ~ (5, -1) => 0.498065
+(3, 1) ~ (5, -1) => 0.112472
+(3, 2) ~ (5, -1) => 0.0819268
+(3, 3) ~ (5, -1) => 0.075942
+(3, 4) ~ (5, -1) => 0.0303884
+(3, 5) ~ (5, -1) => 0.109253
+(3, 6) ~ (5, -1) => 0.136839
+(3, 7) ~ (5, -1) => 0.0404828
+(3, 8) ~ (5, -1) => 0.00312519
+(3, 9) ~ (5, -1) => 0.000989854
+(3, 10) ~ (5, -1) => 0.000332177
+(3, 11) ~ (5, -1) => 0.000285387
+(3, 12) ~ (5, -1) => 0.000189066
+(3, 13) ~ (5, -1) => 0.000284195
+(3, 14) ~ (5, -1) => 0.00325525
+(3, 15) ~ (5, -1) => 0.00510758
+(3, 16) ~ (5, -1) => 0.00784349
+(3, 17) ~ (5, -1) => 0.0101147
+(3, 18) ~ (5, -1) => 0.00982839
+(3, 19) ~ (5, -1) => 0.00633556
+(3, 20) ~ (5, -1) => 0.00274241
+(3, 21) ~ (5, -1) => 0.000995636
+(3, 22) ~ (5, -1) => 0.000120997
+(3, 23) ~ (5, -1) => 0.0001
+(3, 24) ~ (5, -1) => 0.0001
+(3, 25) ~ (5, -1) => 0.000259697
+(3, 26) ~ (5, -1) => 0.00193715
+(3, 27) ~ (5, -1) => 0.00326985
+(3, 28) ~ (5, -1) => 0.0204731
+(3, 29) ~ (5, -1) => 0.0373315
+(3, 30) ~ (5, -1) => 0.132374
+(3, 31) ~ (5, -1) => 0.180848
+(3, 32) ~ (5, -1) => 0.170907
+(3, 33) ~ (5, -1) => 0.092234
+(3, 34) ~ (5, -1) => 0.0618187
+(3, 35) ~ (5, -1) => 0.0999948
+(3, 36) ~ (5, -1) => 0.168319
+(3, 37) ~ (5, -1) => 0.599618
+(3, 38) ~ (5, -1) => 0.655326
+(3, 39) ~ (5, -1) => 0.588574
+(3, 40) ~ (5, -1) => 0.149211
+(3, 41) ~ (5, -1) => 0.0314355
+(3, 42) ~ (5, -1) => 0.0117004
+(3, 43) ~ (5, -1) => 0.00662309
+(3, 44) ~ (5, -1) => 0.00551516
+(3, 45) ~ (5, -1) => 0.00502591
+(3, 46) ~ (5, -1) => 0.00444421
+(3, 47) ~ (5, -1) => 0.00871636
+(3, 48) ~ (5, -1) => 0.0164832
+(3, 49) ~ (5, -1) => 0.0338932
+(3, 50) ~ (5, -1) => 0.0232164
+(3, 51) ~ (5, -1) => 0.011868
+(3, 52) ~ (5, -1) => 0.0142536
+(3, 53) ~ (5, -1) => 0.0132649
+(3, 54) ~ (5, -1) => 0.00841528
+(3, 55) ~ (5, -1) => 0.00123703
+(3, 56) ~ (5, -1) => 0.00192946
+(3, 57) ~ (5, -1) => 0.000246763
+(3, 58) ~ (5, -1) => 0.0001
+(3, 59) ~ (5, -1) => 0.000246704
+(3, 60) ~ (5, -1) => 0.00129867
+(3, 61) ~ (5, -1) => 0.0404139
+(3, 62) ~ (5, -1) => 0.0185262
+(3, 63) ~ (5, -1) => 0.148134
+(3, 64) ~ (5, -1) => 0.14874
+(3, 65) ~ (5, -1) => 0.151459
+(3, 66) ~ (5, -1) => 0.246911
+(3, 67) ~ (5, -1) => 0.0612473
+(3, 68) ~ (5, -1) => 0.0600971
+(3, 69) ~ (5, -1) => 0.137233
+(3, 70) ~ (5, -1) => 0.0177386
+(3, 71) ~ (5, -1) => 0.0031203
+(3, 72) ~ (5, -1) => 0.00223863
+(3, 73) ~ (5, -1) => 0.000930965
+(3, 74) ~ (5, -1) => 0.000591457
+(3, 75) ~ (5, -1) => 0.0001
+(3, 76) ~ (5, -1) => 0.0001
+(3, 77) ~ (5, -1) => 0.0001
+(3, 78) ~ (5, -1) => 0.0001
+(3, 79) ~ (5, -1) => 0.0001
+(3, 80) ~ (5, -1) => 0.0001
+(3, 81) ~ (5, -1) => 0.000930071
+(3, 82) ~ (5, -1) => 0.00117522
+(3, 83) ~ (5, -1) => 0.00133109
+(3, 84) ~ (5, -1) => 0.00115985
+(3, 85) ~ (5, -1) => 0.000499249
+(3, 86) ~ (5, -1) => 0.000100672
+(3, 87) ~ (5, -1) => 0.000189841
+(3, 88) ~ (5, -1) => 0.000146866
+(3, 89) ~ (5, -1) => 0.0001
+(3, 90) ~ (5, -1) => 0.000143588
+(3, 91) ~ (5, -1) => 0.000168264
+(3, 92) ~ (5, -1) => 0.0001
+(3, 93) ~ (5, -1) => 0.000190675
+(3, 94) ~ (5, -1) => 0.000280082
+(3, 95) ~ (5, -1) => 0.000855565
+(3, 96) ~ (5, -1) => 0.00126904
+(3, 97) ~ (5, -1) => 0.00111663
+(3, 98) ~ (5, -1) => 0.000753284
+(3, 99) ~ (5, -1) => 0.00028336
+(3, 100) ~ (5, -1) => 0.00074929
+(3, 101) ~ (5, -1) => 0.0010727
+(3, 102) ~ (5, -1) => 0.00138301
+(3, 103) ~ (5, -1) => 0.00143009
+(3, 104) ~ (5, -1) => 0.00102538
+(3, 105) ~ (5, -1) => 0.000463188
+(3, 106) ~ (5, -1) => 0.000242174
+(3, 107) ~ (5, -1) => 0.0001
+(3, 108) ~ (5, -1) => 0.0001
+(3, 109) ~ (5, -1) => 0.0001
+(3, 110) ~ (5, -1) => 0.0001
+(3, 111) ~ (5, -1) => 0.0001
+(3, 112) ~ (5, -1) => 0.0001
+(3, 113) ~ (5, -1) => 0.0001
+(3, 114) ~ (5, -1) => 0.0001
+(3, 115) ~ (5, -1) => 0.0001
+(3, 116) ~ (5, -1) => 0.0001
+(3, 117) ~ (5, -1) => 0.0001
+(3, 118) ~ (5, -1) => 0.0001
+(3, 119) ~ (5, -1) => 0.000180602
+(3, 120) ~ (5, -1) => 0.00154704
+(3, 121) ~ (5, -1) => 0.00193202
+(3, 122) ~ (5, -1) => 0.00320792
+(3, 123) ~ (5, -1) => 0.00315636
+(3, 124) ~ (5, -1) => 0.000539362
+(3, 125) ~ (5, -1) => 0.000653565
+(3, 126) ~ (5, -1) => 0.000825405
+(3, 127) ~ (5, -1) => 0.000745118
+(3, 128) ~ (5, -1) => 0.000211477
+(3, 129) ~ (5, -1) => 0.0001
+(3, 130) ~ (5, -1) => 0.0001
+(3, 131) ~ (5, -1) => 0.0001
+(3, 132) ~ (5, -1) => 0.0001
+(3, 133) ~ (5, -1) => 0.0001
+(3, 134) ~ (5, -1) => 0.0001
+(3, 135) ~ (5, -1) => 0.0001
+(3, 136) ~ (5, -1) => 0.0001
+(3, 137) ~ (5, -1) => 0.0001
+(3, 138) ~ (5, -1) => 0.0001
+(3, 139) ~ (5, -1) => 0.0001
+(3, 140) ~ (5, -1) => 0.0001
+(3, 141) ~ (5, -1) => 0.000123143
+(3, 142) ~ (5, -1) => 0.0001
+(3, 143) ~ (5, -1) => 0.0001
+(3, 144) ~ (5, -1) => 0.0001
+(3, 145) ~ (5, -1) => 0.0001
+(3, 146) ~ (5, -1) => 0.0001
+(3, 147) ~ (5, -1) => 0.0001
+(3, 148) ~ (5, -1) => 0.0001
+(3, 149) ~ (5, -1) => 0.0001
+(3, 150) ~ (5, -1) => 0.0001
+(3, 151) ~ (5, -1) => 0.0001
+(3, 152) ~ (5, -1) => 0.0001
+(3, 153) ~ (5, -1) => 0.0001
+(3, 154) ~ (5, -1) => 0.00010252
+(3, 155) ~ (5, -1) => 0.0001
+(3, 156) ~ (5, -1) => 0.0001
+(3, 157) ~ (5, -1) => 0.0001
+(3, 158) ~ (5, -1) => 0.000101268
+(3, 159) ~ (5, -1) => 0.000190854
+(3, 160) ~ (5, -1) => 0.000262856
+(3, 161) ~ (5, -1) => 0.000842273
+(3, 162) ~ (5, -1) => 0.00104904
+(3, 163) ~ (5, -1) => 0.000891566
+(3, 164) ~ (5, -1) => 0.000731826
+(3, 165) ~ (5, -1) => 0.000365257
+(3, 166) ~ (5, -1) => 0.000111878
+(3, 167) ~ (5, -1) => 0.0001
+(3, 168) ~ (5, -1) => 0.0001
+(3, 169) ~ (5, -1) => 0.0001
+(3, 170) ~ (5, -1) => 0.000172198
+(3, 171) ~ (5, -1) => 0.000519991
+(3, 172) ~ (5, -1) => 0.00122958
+(3, 173) ~ (5, -1) => 0.00114179
+(3, 174) ~ (5, -1) => 0.0006091
+(3, 175) ~ (5, -1) => 0.0001
+(3, 176) ~ (5, -1) => 0.0001
+(3, 177) ~ (5, -1) => 0.00012821
+(3, 178) ~ (5, -1) => 0.000290275
+(3, 179) ~ (5, -1) => 0.000441074
+(3, 180) ~ (5, -1) => 0.000430465
+(3, 181) ~ (5, -1) => 0.000238717
+(3, 182) ~ (5, -1) => 0.0001
+(3, 183) ~ (5, -1) => 0.0001
+(3, 184) ~ (5, -1) => 0.0001
+(3, 185) ~ (5, -1) => 0.000151873
+(3, 186) ~ (5, -1) => 0.00336063
+(3, 187) ~ (5, -1) => 0.00719023
+(3, 188) ~ (5, -1) => 0.0114287
+(3, 189) ~ (5, -1) => 0.00663644
+(3, 190) ~ (5, -1) => 0.0117244
+(3, 191) ~ (5, -1) => 0.0225771
+(3, 192) ~ (5, -1) => 0.0423337
+(3, 193) ~ (5, -1) => 0.0310874
+(3, 194) ~ (5, -1) => 0.0433885
+(3, 195) ~ (5, -1) => 0.0368309
+(3, 196) ~ (5, -1) => 0.123584
+(3, 197) ~ (5, -1) => 0.12497
+(3, 198) ~ (5, -1) => 0.201363
+(3, 199) ~ (5, -1) => 0.115778
+(3, 200) ~ (5, -1) => 0.148969
+(3, 201) ~ (5, -1) => 0.300005
+(3, 202) ~ (5, -1) => 0.0156246
+(3, 203) ~ (5, -1) => 0.0121109
+(3, 204) ~ (5, -1) => 0.004763
+(3, 205) ~ (5, -1) => 0.0110629
+(3, 206) ~ (5, -1) => 0.0162433
+(3, 207) ~ (5, -1) => 0.00963253
+(3, 208) ~ (5, -1) => 0.00283521
+(3, 209) ~ (5, -1) => 0.00195801
+(3, 210) ~ (5, -1) => 0.000450909
+(3, 211) ~ (5, -1) => 0.000511169
+(3, 212) ~ (5, -1) => 0.000343621
+(3, 213) ~ (5, -1) => 0.00179845
+(3, 214) ~ (5, -1) => 0.00638652
+(3, 215) ~ (5, -1) => 0.000643779
+(3, 216) ~ (5, -1) => 0.000650886
+(3, 217) ~ (5, -1) => 0.00240277
+(3, 218) ~ (5, -1) => 0.0177826
+(3, 219) ~ (5, -1) => 0.0176623
+(3, 220) ~ (5, -1) => 0.015339
+(3, 221) ~ (5, -1) => 0.00399911
+(3, 222) ~ (5, -1) => 0.00194448
+(3, 223) ~ (5, -1) => 0.000460863
+(3, 224) ~ (5, -1) => 0.000347912
+(3, 225) ~ (5, -1) => 0.000630677
+(3, 226) ~ (5, -1) => 0.00081408
+(3, 227) ~ (5, -1) => 0.000730276
+(3, 228) ~ (5, -1) => 0.000261426
+(3, 229) ~ (5, -1) => 0.000156999
+(3, 230) ~ (5, -1) => 0.0001
+(3, 231) ~ (5, -1) => 0.0001
+(3, 232) ~ (5, -1) => 0.0001
+(3, 233) ~ (5, -1) => 0.000213742
+(3, 234) ~ (5, -1) => 0.00148493
+(3, 235) ~ (5, -1) => 0.00297862
+(3, 236) ~ (5, -1) => 0.00411654
+(3, 237) ~ (5, -1) => 0.00482345
+(3, 238) ~ (5, -1) => 0.00441128
+
+(3, -1) ~ (5, 0) => 0.0116247
+(3, -1) ~ (5, 1) => 0.022122
+(3, -1) ~ (5, 2) => 0.00599473
+(3, -1) ~ (5, 3) => 0.0161505
+(3, -1) ~ (5, 4) => 0.0185252
+(3, -1) ~ (5, 5) => 0.00844002
+(3, -1) ~ (5, 6) => 0.00251138
+(3, -1) ~ (5, 7) => 0.00312519
+(3, -1) ~ (5, 8) => 0.000989854
+(3, -1) ~ (5, 9) => 0.000332177
+(3, -1) ~ (5, 10) => 0.000285387
+(3, -1) ~ (5, 11) => 0.000189066
+(3, -1) ~ (5, 12) => 0.000284195
+(3, -1) ~ (5, 13) => 0.00325525
+(3, -1) ~ (5, 14) => 0.00510758
+(3, -1) ~ (5, 15) => 0.00784349
+(3, -1) ~ (5, 16) => 0.0101147
+(3, -1) ~ (5, 17) => 0.00982839
+(3, -1) ~ (5, 18) => 0.00633556
+(3, -1) ~ (5, 19) => 0.00274241
+(3, -1) ~ (5, 20) => 0.000995636
+(3, -1) ~ (5, 21) => 0.000120997
+(3, -1) ~ (5, 22) => 0.0001
+(3, -1) ~ (5, 23) => 0.0001
+(3, -1) ~ (5, 24) => 0.000259697
+(3, -1) ~ (5, 25) => 0.00193715
+(3, -1) ~ (5, 26) => 0.00326985
+(3, -1) ~ (5, 27) => 0.00283881
+(3, -1) ~ (5, 28) => 0.0034829
+(3, -1) ~ (5, 29) => 0.0017409
+(3, -1) ~ (5, 30) => 0.00280748
+(3, -1) ~ (5, 31) => 0.00253651
+(3, -1) ~ (5, 32) => 0.00458568
+(3, -1) ~ (5, 33) => 0.00555259
+(3, -1) ~ (5, 34) => 0.00735235
+(3, -1) ~ (5, 35) => 0.0202038
+(3, -1) ~ (5, 36) => 0.0187726
+(3, -1) ~ (5, 37) => 0.011482
+(3, -1) ~ (5, 38) => 0.00678372
+(3, -1) ~ (5, 39) => 0.00670922
+(3, -1) ~ (5, 40) => 0.00712991
+(3, -1) ~ (5, 41) => 0.00533271
+(3, -1) ~ (5, 42) => 0.00365949
+(3, -1) ~ (5, 43) => 0.00320542
+(3, -1) ~ (5, 44) => 0.00397182
+(3, -1) ~ (5, 45) => 0.00522614
+(3, -1) ~ (5, 46) => 0.0386223
+(3, -1) ~ (5, 47) => 0.0371073
+(3, -1) ~ (5, 48) => 0.281192
+(3, -1) ~ (5, 49) => 0.418624
+(3, -1) ~ (5, 50) => 0.0846169
+(3, -1) ~ (5, 51) => 0.114974
+(3, -1) ~ (5, 52) => 0.0546098
+(3, -1) ~ (5, 53) => 0.00192946
+(3, -1) ~ (5, 54) => 0.000246763
+(3, -1) ~ (5, 55) => 0.0001
+(3, -1) ~ (5, 56) => 0.000246704
+(3, -1) ~ (5, 57) => 0.00129867
+(3, -1) ~ (5, 58) => 0.000331815
+(3, -1) ~ (5, 59) => 0.00063514
+(3, -1) ~ (5, 60) => 0.00189771
+(3, -1) ~ (5, 61) => 0.00252706
+(3, -1) ~ (5, 62) => 0.00509557
+(3, -1) ~ (5, 63) => 0.00591069
+(3, -1) ~ (5, 64) => 0.00743711
+(3, -1) ~ (5, 65) => 0.00567269
+(3, -1) ~ (5, 66) => 0.00099194
+(3, -1) ~ (5, 67) => 0.0031203
+(3, -1) ~ (5, 68) => 0.00223863
+(3, -1) ~ (5, 69) => 0.000930965
+(3, -1) ~ (5, 70) => 0.000591457
+(3, -1) ~ (5, 71) => 0.0001
+(3, -1) ~ (5, 72) => 0.0001
+(3, -1) ~ (5, 73) => 0.0001
+(3, -1) ~ (5, 74) => 0.0001
+(3, -1) ~ (5, 75) => 0.0001
+(3, -1) ~ (5, 76) => 0.0001
+(3, -1) ~ (5, 77) => 0.000930071
+(3, -1) ~ (5, 78) => 0.00117522
+(3, -1) ~ (5, 79) => 0.00133109
+(3, -1) ~ (5, 80) => 0.00115985
+(3, -1) ~ (5, 81) => 0.000499249
+(3, -1) ~ (5, 82) => 0.000100672
+(3, -1) ~ (5, 83) => 0.000189841
+(3, -1) ~ (5, 84) => 0.000146866
+(3, -1) ~ (5, 85) => 0.0001
+(3, -1) ~ (5, 86) => 0.000143588
+(3, -1) ~ (5, 87) => 0.000168264
+(3, -1) ~ (5, 88) => 0.0001
+(3, -1) ~ (5, 89) => 0.000190675
+(3, -1) ~ (5, 90) => 0.000280082
+(3, -1) ~ (5, 91) => 0.000855565
+(3, -1) ~ (5, 92) => 0.00126904
+(3, -1) ~ (5, 93) => 0.00111663
+(3, -1) ~ (5, 94) => 0.000753284
+(3, -1) ~ (5, 95) => 0.00028336
+(3, -1) ~ (5, 96) => 0.00074929
+(3, -1) ~ (5, 97) => 0.0010727
+(3, -1) ~ (5, 98) => 0.00138301
+(3, -1) ~ (5, 99) => 0.00143009
+(3, -1) ~ (5, 100) => 0.00102538
+(3, -1) ~ (5, 101) => 0.000463188
+(3, -1) ~ (5, 102) => 0.000242174
+(3, -1) ~ (5, 103) => 0.0001
+(3, -1) ~ (5, 104) => 0.0001
+(3, -1) ~ (5, 105) => 0.0001
+(3, -1) ~ (5, 106) => 0.0001
+(3, -1) ~ (5, 107) => 0.0001
+(3, -1) ~ (5, 108) => 0.0001
+(3, -1) ~ (5, 109) => 0.0001
+(3, -1) ~ (5, 110) => 0.0001
+(3, -1) ~ (5, 111) => 0.0001
+(3, -1) ~ (5, 112) => 0.0001
+(3, -1) ~ (5, 113) => 0.0001
+(3, -1) ~ (5, 114) => 0.0001
+(3, -1) ~ (5, 115) => 0.000180602
+(3, -1) ~ (5, 116) => 0.00154704
+(3, -1) ~ (5, 117) => 0.00193202
+(3, -1) ~ (5, 118) => 0.00320792
+(3, -1) ~ (5, 119) => 0.00315636
+(3, -1) ~ (5, 120) => 0.000539362
+(3, -1) ~ (5, 121) => 0.000653565
+(3, -1) ~ (5, 122) => 0.000825405
+(3, -1) ~ (5, 123) => 0.000745118
+(3, -1) ~ (5, 124) => 0.000211477
+(3, -1) ~ (5, 125) => 0.0001
+(3, -1) ~ (5, 126) => 0.0001
+(3, -1) ~ (5, 127) => 0.0001
+(3, -1) ~ (5, 128) => 0.0001
+(3, -1) ~ (5, 129) => 0.0001
+(3, -1) ~ (5, 130) => 0.0001
+(3, -1) ~ (5, 131) => 0.0001
+(3, -1) ~ (5, 132) => 0.0001
+(3, -1) ~ (5, 133) => 0.0001
+(3, -1) ~ (5, 134) => 0.0001
+(3, -1) ~ (5, 135) => 0.0001
+(3, -1) ~ (5, 136) => 0.0001
+(3, -1) ~ (5, 137) => 0.000123143
+(3, -1) ~ (5, 138) => 0.0001
+(3, -1) ~ (5, 139) => 0.0001
+(3, -1) ~ (5, 140) => 0.0001
+(3, -1) ~ (5, 141) => 0.0001
+(3, -1) ~ (5, 142) => 0.0001
+(3, -1) ~ (5, 143) => 0.0001
+(3, -1) ~ (5, 144) => 0.0001
+(3, -1) ~ (5, 145) => 0.0001
+(3, -1) ~ (5, 146) => 0.0001
+(3, -1) ~ (5, 147) => 0.0001
+(3, -1) ~ (5, 148) => 0.0001
+(3, -1) ~ (5, 149) => 0.0001
+(3, -1) ~ (5, 150) => 0.00010252
+(3, -1) ~ (5, 151) => 0.0001
+(3, -1) ~ (5, 152) => 0.0001
+(3, -1) ~ (5, 153) => 0.0001
+(3, -1) ~ (5, 154) => 0.000101268
+(3, -1) ~ (5, 155) => 0.000190854
+(3, -1) ~ (5, 156) => 0.000262856
+(3, -1) ~ (5, 157) => 0.000842273
+(3, -1) ~ (5, 158) => 0.00104904
+(3, -1) ~ (5, 159) => 0.000891566
+(3, -1) ~ (5, 160) => 0.000731826
+(3, -1) ~ (5, 161) => 0.000365257
+(3, -1) ~ (5, 162) => 0.000111878
+(3, -1) ~ (5, 163) => 0.0001
+(3, -1) ~ (5, 164) => 0.0001
+(3, -1) ~ (5, 165) => 0.0001
+(3, -1) ~ (5, 166) => 0.000172198
+(3, -1) ~ (5, 167) => 0.000519991
+(3, -1) ~ (5, 168) => 0.00122958
+(3, -1) ~ (5, 169) => 0.00114179
+(3, -1) ~ (5, 170) => 0.0006091
+(3, -1) ~ (5, 171) => 0.0001
+(3, -1) ~ (5, 172) => 0.0001
+(3, -1) ~ (5, 173) => 0.00012821
+(3, -1) ~ (5, 174) => 0.000290275
+(3, -1) ~ (5, 175) => 0.000441074
+(3, -1) ~ (5, 176) => 0.000430465
+(3, -1) ~ (5, 177) => 0.000238717
+(3, -1) ~ (5, 178) => 0.0001
+(3, -1) ~ (5, 179) => 0.0001
+(3, -1) ~ (5, 180) => 0.0001
+(3, -1) ~ (5, 181) => 0.000151873
+(3, -1) ~ (5, 182) => 0.00336063
+(3, -1) ~ (5, 183) => 0.00719023
+(3, -1) ~ (5, 184) => 0.0114287
+(3, -1) ~ (5, 185) => 0.0193225
+(3, -1) ~ (5, 186) => 0.0162252
+(3, -1) ~ (5, 187) => 0.0104157
+(3, -1) ~ (5, 188) => 0.0153155
+(3, -1) ~ (5, 189) => 0.0175335
+(3, -1) ~ (5, 190) => 0.0189553
+(3, -1) ~ (5, 191) => 0.0271305
+(3, -1) ~ (5, 192) => 0.0355152
+(3, -1) ~ (5, 193) => 0.0214802
+(3, -1) ~ (5, 194) => 0.020079
+(3, -1) ~ (5, 195) => 0.0277961
+(3, -1) ~ (5, 196) => 0.0221101
+(3, -1) ~ (5, 197) => 0.00711989
+(3, -1) ~ (5, 198) => 0.00337291
+(3, -1) ~ (5, 199) => 0.00259471
+(3, -1) ~ (5, 200) => 0.00225639
+(3, -1) ~ (5, 201) => 0.00182855
+(3, -1) ~ (5, 202) => 0.00963253
+(3, -1) ~ (5, 203) => 0.00283521
+(3, -1) ~ (5, 204) => 0.00195801
+(3, -1) ~ (5, 205) => 0.000450909
+(3, -1) ~ (5, 206) => 0.000511169
+(3, -1) ~ (5, 207) => 0.000343621
+(3, -1) ~ (5, 208) => 0.00179845
+(3, -1) ~ (5, 209) => 0.00638652
+(3, -1) ~ (5, 210) => 0.0408459
+(3, -1) ~ (5, 211) => 0.0110342
+(3, -1) ~ (5, 212) => 0.00172406
+(3, -1) ~ (5, 213) => 0.000438571
+(3, -1) ~ (5, 214) => 0.000214815
+(3, -1) ~ (5, 215) => 0.000223815
+(3, -1) ~ (5, 216) => 0.00399911
+(3, -1) ~ (5, 217) => 0.00194448
+(3, -1) ~ (5, 218) => 0.000460863
+(3, -1) ~ (5, 219) => 0.000347912
+(3, -1) ~ (5, 220) => 0.000630677
+(3, -1) ~ (5, 221) => 0.00081408
+(3, -1) ~ (5, 222) => 0.000730276
+(3, -1) ~ (5, 223) => 0.000261426
+(3, -1) ~ (5, 224) => 0.000156999
+(3, -1) ~ (5, 225) => 0.0001
+(3, -1) ~ (5, 226) => 0.0001
+(3, -1) ~ (5, 227) => 0.0001
+(3, -1) ~ (5, 228) => 0.000213742
+(3, -1) ~ (5, 229) => 0.00148493
+(3, -1) ~ (5, 230) => 0.00297862
+(3, -1) ~ (5, 231) => 0.00411654
+(3, -1) ~ (5, 232) => 0.00482345
+(3, -1) ~ (5, 233) => 0.00441128
+
+; Sparse posterior probability matrix for sequences 4 and 5
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(4, 0) ~ (5, 0) => 0.991697
+(4, 1) ~ (5, 1) => 0.979934
+(4, 2) ~ (5, 2) => 0.912263
+(4, 3) ~ (5, 2) => 0.0175144
+(4, 3) ~ (5, 3) => 0.749855
+(4, 4) ~ (5, 3) => 0.0524001
+(4, 4) ~ (5, 4) => 0.439019
+(4, 4) ~ (5, 5) => 0.019692
+(4, 5) ~ (5, 2) => 0.0554116
+(4, 5) ~ (5, 4) => 0.044772
+(4, 5) ~ (5, 5) => 0.384828
+(4, 5) ~ (5, 6) => 0.0285336
+(4, 6) ~ (5, 3) => 0.172431
+(4, 6) ~ (5, 5) => 0.0501567
+(4, 6) ~ (5, 6) => 0.0907301
+(4, 6) ~ (5, 7) => 0.0708937
+(4, 7) ~ (5, 4) => 0.484598
+(4, 7) ~ (5, 6) => 0.11106
+(4, 7) ~ (5, 7) => 0.057601
+(4, 7) ~ (5, 8) => 0.0573761
+(4, 8) ~ (5, 5) => 0.524962
+(4, 8) ~ (5, 6) => 0.0119001
+(4, 8) ~ (5, 7) => 0.123273
+(4, 8) ~ (5, 8) => 0.0377591
+(4, 8) ~ (5, 9) => 0.0349957
+(4, 9) ~ (5, 6) => 0.711895
+(4, 9) ~ (5, 8) => 0.162611
+(4, 9) ~ (5, 9) => 0.0168709
+(4, 9) ~ (5, 10) => 0.0231115
+(4, 10) ~ (5, 7) => 0.737377
+(4, 10) ~ (5, 9) => 0.205062
+(4, 11) ~ (5, 8) => 0.718004
+(4, 11) ~ (5, 10) => 0.24907
+(4, 12) ~ (5, 9) => 0.568692
+(4, 12) ~ (5, 11) => 0.414661
+(4, 13) ~ (5, 10) => 0.397542
+(4, 13) ~ (5, 11) => 0.0223839
+(4, 13) ~ (5, 12) => 0.562633
+(4, 14) ~ (5, 11) => 0.309075
+(4, 14) ~ (5, 12) => 0.0249949
+(4, 14) ~ (5, 13) => 0.648832
+(4, 15) ~ (5, 12) => 0.147399
+(4, 15) ~ (5, 13) => 0.0186717
+(4, 15) ~ (5, 14) => 0.822563
+(4, 16) ~ (5, 13) => 0.0117158
+(4, 16) ~ (5, 15) => 0.980655
+(4, 17) ~ (5, 16) => 0.998331
+(4, 18) ~ (5, 17) => 0.999354
+(4, 19) ~ (5, 18) => 0.9994
+(4, 20) ~ (5, 19) => 0.999656
+(4, 21) ~ (5, 20) => 0.999772
+(4, 22) ~ (5, 21) => 0.999904
+(4, 23) ~ (5, 22) => 0.999942
+(4, 24) ~ (5, 23) => 0.99982
+(4, 25) ~ (5, 24) => 0.998441
+(4, 26) ~ (5, 25) => 0.991443
+(4, 27) ~ (5, 26) => 0.979296
+(4, 28) ~ (5, 26) => 0.0189358
+(4, 28) ~ (5, 27) => 0.974228
+(4, 29) ~ (5, 27) => 0.0219114
+(4, 29) ~ (5, 28) => 0.972476
+(4, 30) ~ (5, 28) => 0.0225773
+(4, 30) ~ (5, 29) => 0.973472
+(4, 31) ~ (5, 29) => 0.0186767
+(4, 31) ~ (5, 30) => 0.979326
+(4, 32) ~ (5, 31) => 0.993977
+(4, 33) ~ (5, 32) => 0.995496
+(4, 34) ~ (5, 33) => 0.994387
+(4, 35) ~ (5, 34) => 0.993063
+(4, 36) ~ (5, 35) => 0.993502
+(4, 37) ~ (5, 36) => 0.995787
+(4, 38) ~ (5, 37) => 0.997318
+(4, 39) ~ (5, 38) => 0.997312
+(4, 40) ~ (5, 39) => 0.996773
+(4, 41) ~ (5, 40) => 0.997472
+(4, 42) ~ (5, 41) => 0.996228
+(4, 43) ~ (5, 42) => 0.996508
+(4, 44) ~ (5, 43) => 0.999298
+(4, 45) ~ (5, 44) => 0.998442
+(4, 46) ~ (5, 45) => 0.998075
+(4, 47) ~ (5, 46) => 0.998492
+(4, 48) ~ (5, 47) => 0.999628
+(4, 49) ~ (5, 48) => 0.999315
+(4, 50) ~ (5, 49) => 0.999244
+(4, 51) ~ (5, 50) => 0.999557
+(4, 52) ~ (5, 51) => 0.9997
+(4, 53) ~ (5, 52) => 0.999992
+(4, 54) ~ (5, 53) => 0.999992
+(4, 55) ~ (5, 54) => 0.99989
+(4, 56) ~ (5, 55) => 0.999077
+(4, 57) ~ (5, 56) => 0.983224
+(4, 58) ~ (5, 56) => 0.0129493
+(4, 58) ~ (5, 57) => 0.967451
+(4, 59) ~ (5, 57) => 0.0251793
+(4, 59) ~ (5, 58) => 0.883315
+(4, 60) ~ (5, 58) => 0.107699
+(4, 60) ~ (5, 59) => 0.870657
+(4, 61) ~ (5, 59) => 0.117726
+(4, 61) ~ (5, 60) => 0.811434
+(4, 61) ~ (5, 61) => 0.0189447
+(4, 62) ~ (5, 60) => 0.16843
+(4, 62) ~ (5, 61) => 0.757065
+(4, 62) ~ (5, 62) => 0.0205162
+(4, 63) ~ (5, 61) => 0.21879
+(4, 63) ~ (5, 62) => 0.304644
+(4, 63) ~ (5, 63) => 0.0400312
+(4, 64) ~ (5, 62) => 0.649813
+(4, 64) ~ (5, 63) => 0.157468
+(4, 64) ~ (5, 64) => 0.0487662
+(4, 65) ~ (5, 63) => 0.787217
+(4, 65) ~ (5, 64) => 0.105002
+(4, 65) ~ (5, 65) => 0.031472
+(4, 66) ~ (5, 64) => 0.840949
+(4, 66) ~ (5, 65) => 0.0560462
+(4, 67) ~ (5, 65) => 0.91065
+(4, 68) ~ (5, 66) => 0.996247
+(4, 69) ~ (5, 67) => 0.999286
+(4, 70) ~ (5, 68) => 0.99885
+(4, 71) ~ (5, 69) => 0.999118
+(4, 72) ~ (5, 70) => 0.99967
+(4, 73) ~ (5, 71) => 0.999952
+(4, 74) ~ (5, 72) => 0.999986
+(4, 75) ~ (5, 73) => 0.999966
+(4, 76) ~ (5, 74) => 0.999873
+(4, 77) ~ (5, 75) => 0.999712
+(4, 78) ~ (5, 76) => 0.997778
+(4, 79) ~ (5, 77) => 0.911924
+(4, 79) ~ (5, 78) => 0.0399049
+(4, 80) ~ (5, 78) => 0.877491
+(4, 80) ~ (5, 79) => 0.0444782
+(4, 81) ~ (5, 79) => 0.807386
+(4, 81) ~ (5, 80) => 0.0618952
+(4, 82) ~ (5, 77) => 0.0403393
+(4, 82) ~ (5, 80) => 0.745158
+(4, 82) ~ (5, 81) => 0.0576096
+(4, 83) ~ (5, 78) => 0.0624854
+(4, 83) ~ (5, 80) => 0.0218748
+(4, 83) ~ (5, 81) => 0.703513
+(4, 83) ~ (5, 82) => 0.0403615
+(4, 84) ~ (5, 79) => 0.108016
+(4, 84) ~ (5, 80) => 0.0237587
+(4, 84) ~ (5, 81) => 0.0502033
+(4, 84) ~ (5, 82) => 0.620344
+(4, 84) ~ (5, 83) => 0.0261696
+(4, 84) ~ (5, 85) => 0.0129049
+(4, 85) ~ (5, 80) => 0.128073
+(4, 85) ~ (5, 81) => 0.0164063
+(4, 85) ~ (5, 82) => 0.150609
+(4, 85) ~ (5, 83) => 0.4421
+(4, 85) ~ (5, 84) => 0.0197721
+(4, 85) ~ (5, 86) => 0.0133109
+(4, 86) ~ (5, 81) => 0.142603
+(4, 86) ~ (5, 83) => 0.35213
+(4, 86) ~ (5, 84) => 0.206134
+(4, 86) ~ (5, 85) => 0.0126332
+(4, 86) ~ (5, 87) => 0.0129993
+(4, 87) ~ (5, 82) => 0.0660617
+(4, 87) ~ (5, 84) => 0.674652
+(4, 87) ~ (5, 85) => 0.0964684
+(4, 87) ~ (5, 86) => 0.0127315
+(4, 87) ~ (5, 88) => 0.0129553
+(4, 88) ~ (5, 83) => 0.0118055
+(4, 88) ~ (5, 85) => 0.849604
+(4, 88) ~ (5, 86) => 0.069336
+(4, 88) ~ (5, 87) => 0.0121369
+(4, 88) ~ (5, 89) => 0.0129575
+(4, 89) ~ (5, 86) => 0.878824
+(4, 89) ~ (5, 87) => 0.0508736
+(4, 89) ~ (5, 88) => 0.0129093
+(4, 89) ~ (5, 90) => 0.0125386
+(4, 90) ~ (5, 87) => 0.903725
+(4, 90) ~ (5, 88) => 0.0375328
+(4, 90) ~ (5, 89) => 0.0135442
+(4, 91) ~ (5, 88) => 0.919873
+(4, 91) ~ (5, 89) => 0.0174058
+(4, 91) ~ (5, 90) => 0.0181008
+(4, 92) ~ (5, 89) => 0.943577
+(4, 93) ~ (5, 90) => 0.956481
+(4, 94) ~ (5, 91) => 0.986929
+(4, 95) ~ (5, 92) => 0.997046
+(4, 96) ~ (5, 93) => 0.998901
+(4, 97) ~ (5, 94) => 0.997225
+(4, 98) ~ (5, 95) => 0.991247
+(4, 99) ~ (5, 96) => 0.927545
+(4, 100) ~ (5, 96) => 0.0635944
+(4, 100) ~ (5, 97) => 0.780445
+(4, 101) ~ (5, 97) => 0.115161
+(4, 101) ~ (5, 98) => 0.636892
+(4, 102) ~ (5, 97) => 0.0892044
+(4, 102) ~ (5, 98) => 0.169473
+(4, 102) ~ (5, 99) => 0.485616
+(4, 103) ~ (5, 98) => 0.172993
+(4, 103) ~ (5, 99) => 0.216358
+(4, 103) ~ (5, 100) => 0.323292
+(4, 104) ~ (5, 99) => 0.273576
+(4, 104) ~ (5, 100) => 0.378203
+(4, 104) ~ (5, 101) => 0.14312
+(4, 105) ~ (5, 100) => 0.0826387
+(4, 105) ~ (5, 101) => 0.755185
+(4, 105) ~ (5, 102) => 0.0536536
+(4, 106) ~ (5, 101) => 0.0292408
+(4, 106) ~ (5, 102) => 0.90726
+(4, 106) ~ (5, 103) => 0.0128189
+(4, 107) ~ (5, 103) => 0.977187
+(4, 108) ~ (5, 104) => 0.993763
+(4, 109) ~ (5, 105) => 0.999806
+(4, 110) ~ (5, 106) => 0.999956
+(4, 111) ~ (5, 107) => 0.999982
+(4, 112) ~ (5, 108) => 0.999987
+(4, 113) ~ (5, 109) => 0.99997
+(4, 114) ~ (5, 110) => 0.99993
+(4, 115) ~ (5, 111) => 0.999877
+(4, 116) ~ (5, 112) => 0.999272
+(4, 117) ~ (5, 113) => 0.997905
+(4, 118) ~ (5, 114) => 0.996055
+(4, 119) ~ (5, 115) => 0.995388
+(4, 120) ~ (5, 116) => 0.987455
+(4, 121) ~ (5, 117) => 0.981562
+(4, 122) ~ (5, 118) => 0.976131
+(4, 123) ~ (5, 117) => 0.0136727
+(4, 123) ~ (5, 119) => 0.975452
+(4, 124) ~ (5, 118) => 0.0189666
+(4, 124) ~ (5, 120) => 0.974688
+(4, 125) ~ (5, 119) => 0.0190977
+(4, 125) ~ (5, 121) => 0.972238
+(4, 126) ~ (5, 120) => 0.0197414
+(4, 126) ~ (5, 122) => 0.963008
+(4, 127) ~ (5, 121) => 0.0227725
+(4, 127) ~ (5, 123) => 0.963567
+(4, 128) ~ (5, 122) => 0.0342402
+(4, 128) ~ (5, 124) => 0.962104
+(4, 129) ~ (5, 123) => 0.0356696
+(4, 129) ~ (5, 125) => 0.956914
+(4, 130) ~ (5, 124) => 0.0368804
+(4, 130) ~ (5, 126) => 0.890247
+(4, 130) ~ (5, 129) => 0.0165156
+(4, 131) ~ (5, 125) => 0.0401186
+(4, 131) ~ (5, 127) => 0.808262
+(4, 131) ~ (5, 128) => 0.0134412
+(4, 131) ~ (5, 130) => 0.0313812
+(4, 132) ~ (5, 126) => 0.0646188
+(4, 132) ~ (5, 127) => 0.0128781
+(4, 132) ~ (5, 128) => 0.661035
+(4, 132) ~ (5, 129) => 0.0237735
+(4, 132) ~ (5, 130) => 0.0124272
+(4, 132) ~ (5, 131) => 0.0418569
+(4, 132) ~ (5, 133) => 0.0101764
+(4, 133) ~ (5, 127) => 0.101633
+(4, 133) ~ (5, 128) => 0.0181393
+(4, 133) ~ (5, 129) => 0.63167
+(4, 133) ~ (5, 130) => 0.0313643
+(4, 133) ~ (5, 131) => 0.0156989
+(4, 133) ~ (5, 132) => 0.0444972
+(4, 133) ~ (5, 134) => 0.0113635
+(4, 134) ~ (5, 128) => 0.211818
+(4, 134) ~ (5, 129) => 0.0210982
+(4, 134) ~ (5, 130) => 0.555826
+(4, 134) ~ (5, 131) => 0.0799173
+(4, 134) ~ (5, 132) => 0.0172378
+(4, 134) ~ (5, 133) => 0.0462234
+(4, 134) ~ (5, 135) => 0.0148785
+(4, 135) ~ (5, 129) => 0.205536
+(4, 135) ~ (5, 130) => 0.0204298
+(4, 135) ~ (5, 131) => 0.445106
+(4, 135) ~ (5, 132) => 0.185733
+(4, 135) ~ (5, 133) => 0.0240459
+(4, 135) ~ (5, 134) => 0.0493429
+(4, 135) ~ (5, 136) => 0.0103193
+(4, 136) ~ (5, 130) => 0.199756
+(4, 136) ~ (5, 131) => 0.0218772
+(4, 136) ~ (5, 132) => 0.344879
+(4, 136) ~ (5, 133) => 0.296604
+(4, 136) ~ (5, 134) => 0.0190493
+(4, 136) ~ (5, 135) => 0.0481526
+(4, 137) ~ (5, 129) => 0.0162622
+(4, 137) ~ (5, 131) => 0.15587
+(4, 137) ~ (5, 132) => 0.029561
+(4, 137) ~ (5, 133) => 0.296495
+(4, 137) ~ (5, 134) => 0.387931
+(4, 137) ~ (5, 135) => 0.0182651
+(4, 137) ~ (5, 136) => 0.0460607
+(4, 138) ~ (5, 130) => 0.0244895
+(4, 138) ~ (5, 132) => 0.115498
+(4, 138) ~ (5, 133) => 0.0316436
+(4, 138) ~ (5, 134) => 0.303482
+(4, 138) ~ (5, 135) => 0.419629
+(4, 138) ~ (5, 136) => 0.0136077
+(4, 138) ~ (5, 137) => 0.0404103
+(4, 139) ~ (5, 131) => 0.0263556
+(4, 139) ~ (5, 133) => 0.0984052
+(4, 139) ~ (5, 134) => 0.027568
+(4, 139) ~ (5, 135) => 0.279063
+(4, 139) ~ (5, 136) => 0.486093
+(4, 139) ~ (5, 137) => 0.0106673
+(4, 139) ~ (5, 138) => 0.0234269
+(4, 140) ~ (5, 132) => 0.0273216
+(4, 140) ~ (5, 134) => 0.0851947
+(4, 140) ~ (5, 135) => 0.0203716
+(4, 140) ~ (5, 136) => 0.270775
+(4, 140) ~ (5, 137) => 0.533033
+(4, 140) ~ (5, 139) => 0.0173544
+(4, 141) ~ (5, 133) => 0.0246714
+(4, 141) ~ (5, 135) => 0.0267439
+(4, 141) ~ (5, 137) => 0.178367
+(4, 141) ~ (5, 138) => 0.729351
+(4, 141) ~ (5, 140) => 0.0167251
+(4, 142) ~ (5, 134) => 0.0117175
+(4, 142) ~ (5, 136) => 0.0125979
+(4, 142) ~ (5, 138) => 0.0808088
+(4, 142) ~ (5, 139) => 0.867198
+(4, 143) ~ (5, 139) => 0.0420874
+(4, 143) ~ (5, 140) => 0.923009
+(4, 144) ~ (5, 141) => 0.994481
+(4, 145) ~ (5, 142) => 0.994528
+(4, 146) ~ (5, 143) => 0.995285
+(4, 147) ~ (5, 144) => 0.998924
+(4, 148) ~ (5, 145) => 0.999937
+(4, 149) ~ (5, 146) => 0.999988
+(4, 150) ~ (5, 147) => 0.999978
+(4, 151) ~ (5, 148) => 0.999834
+(4, 152) ~ (5, 149) => 0.999715
+(4, 153) ~ (5, 150) => 0.999763
+(4, 154) ~ (5, 151) => 0.999905
+(4, 155) ~ (5, 152) => 0.999973
+(4, 156) ~ (5, 153) => 0.999903
+(4, 157) ~ (5, 154) => 0.999381
+(4, 158) ~ (5, 155) => 0.998601
+(4, 159) ~ (5, 156) => 0.996588
+(4, 160) ~ (5, 157) => 0.995186
+(4, 161) ~ (5, 158) => 0.99525
+(4, 162) ~ (5, 159) => 0.995388
+(4, 163) ~ (5, 160) => 0.9952
+(4, 164) ~ (5, 161) => 0.995061
+(4, 165) ~ (5, 162) => 0.994839
+(4, 166) ~ (5, 163) => 0.997274
+(4, 167) ~ (5, 164) => 0.997699
+(4, 168) ~ (5, 165) => 0.9983
+(4, 169) ~ (5, 166) => 0.999597
+(4, 170) ~ (5, 167) => 0.999931
+(4, 171) ~ (5, 168) => 0.999927
+(4, 172) ~ (5, 169) => 0.999917
+(4, 173) ~ (5, 170) => 0.999962
+(4, 174) ~ (5, 171) => 0.999969
+(4, 175) ~ (5, 172) => 0.999904
+(4, 176) ~ (5, 173) => 0.999713
+(4, 177) ~ (5, 174) => 0.999444
+(4, 178) ~ (5, 175) => 0.999473
+(4, 179) ~ (5, 176) => 0.999644
+(4, 180) ~ (5, 177) => 0.999869
+(4, 181) ~ (5, 178) => 0.999939
+(4, 182) ~ (5, 179) => 0.99995
+(4, 183) ~ (5, 180) => 0.999933
+(4, 184) ~ (5, 181) => 0.999918
+(4, 185) ~ (5, 182) => 0.999207
+(4, 186) ~ (5, 183) => 0.998534
+(4, 187) ~ (5, 184) => 0.997983
+(4, 188) ~ (5, 185) => 0.993793
+(4, 189) ~ (5, 186) => 0.989392
+(4, 190) ~ (5, 187) => 0.974521
+(4, 191) ~ (5, 187) => 0.0229916
+(4, 191) ~ (5, 188) => 0.96636
+(4, 192) ~ (5, 188) => 0.0277932
+(4, 192) ~ (5, 189) => 0.909195
+(4, 192) ~ (5, 191) => 0.0178671
+(4, 193) ~ (5, 189) => 0.0662925
+(4, 193) ~ (5, 190) => 0.804318
+(4, 193) ~ (5, 192) => 0.0360613
+(4, 194) ~ (5, 190) => 0.152294
+(4, 194) ~ (5, 191) => 0.80189
+(4, 194) ~ (5, 193) => 0.0342183
+(4, 195) ~ (5, 191) => 0.141637
+(4, 195) ~ (5, 192) => 0.81276
+(4, 195) ~ (5, 194) => 0.0311249
+(4, 196) ~ (5, 192) => 0.122447
+(4, 196) ~ (5, 193) => 0.832518
+(4, 196) ~ (5, 195) => 0.0163448
+(4, 197) ~ (5, 193) => 0.117926
+(4, 197) ~ (5, 194) => 0.835697
+(4, 197) ~ (5, 195) => 0.0111676
+(4, 198) ~ (5, 194) => 0.0984847
+(4, 198) ~ (5, 195) => 0.860901
+(4, 198) ~ (5, 196) => 0.0205571
+(4, 199) ~ (5, 195) => 0.08009
+(4, 199) ~ (5, 196) => 0.881803
+(4, 199) ~ (5, 197) => 0.0168026
+(4, 200) ~ (5, 196) => 0.0485721
+(4, 200) ~ (5, 197) => 0.920448
+(4, 200) ~ (5, 198) => 0.0117355
+(4, 201) ~ (5, 197) => 0.0310406
+(4, 201) ~ (5, 198) => 0.948131
+(4, 202) ~ (5, 198) => 0.0129935
+(4, 202) ~ (5, 199) => 0.974535
+(4, 203) ~ (5, 200) => 0.984237
+(4, 204) ~ (5, 201) => 0.992832
+(4, 205) ~ (5, 202) => 0.99747
+(4, 206) ~ (5, 203) => 0.998777
+(4, 207) ~ (5, 204) => 0.997484
+(4, 208) ~ (5, 205) => 0.997208
+(4, 209) ~ (5, 206) => 0.997798
+(4, 210) ~ (5, 207) => 0.999329
+(4, 211) ~ (5, 208) => 0.999432
+(4, 212) ~ (5, 209) => 0.998118
+(4, 213) ~ (5, 210) => 0.997809
+(4, 214) ~ (5, 211) => 0.997594
+(4, 215) ~ (5, 212) => 0.993974
+(4, 216) ~ (5, 213) => 0.991368
+(4, 217) ~ (5, 214) => 0.989309
+(4, 218) ~ (5, 215) => 0.974487
+(4, 219) ~ (5, 215) => 0.0159262
+(4, 219) ~ (5, 216) => 0.943091
+(4, 220) ~ (5, 216) => 0.0402485
+(4, 220) ~ (5, 217) => 0.597892
+(4, 221) ~ (5, 217) => 0.371447
+(4, 221) ~ (5, 218) => 0.100179
+(4, 222) ~ (5, 217) => 0.0108068
+(4, 222) ~ (5, 218) => 0.865488
+(4, 222) ~ (5, 219) => 0.0514171
+(4, 223) ~ (5, 217) => 0.013435
+(4, 223) ~ (5, 218) => 0.0101998
+(4, 223) ~ (5, 219) => 0.918256
+(4, 223) ~ (5, 220) => 0.0304178
+(4, 224) ~ (5, 218) => 0.0120889
+(4, 224) ~ (5, 220) => 0.948775
+(4, 225) ~ (5, 221) => 0.992003
+(4, 226) ~ (5, 222) => 0.996834
+(4, 227) ~ (5, 223) => 0.999751
+(4, 228) ~ (5, 224) => 0.999946
+(4, 229) ~ (5, 225) => 0.999971
+(4, 230) ~ (5, 226) => 0.999489
+(4, 231) ~ (5, 227) => 0.993171
+(4, 232) ~ (5, 228) => 0.992642
+(4, 233) ~ (5, 229) => 0.988214
+(4, 234) ~ (5, 230) => 0.986684
+(4, 235) ~ (5, 231) => 0.986058
+(4, 236) ~ (5, 232) => 0.987291
+(4, 237) ~ (5, 233) => 0.991024
+
+; gap posteriors
+(4, 0) ~ (5, -1) => 0.00830293
+(4, 1) ~ (5, -1) => 0.0200657
+(4, 2) ~ (5, -1) => 0.0877373
+(4, 3) ~ (5, -1) => 0.232631
+(4, 4) ~ (5, -1) => 0.488889
+(4, 5) ~ (5, -1) => 0.486454
+(4, 6) ~ (5, -1) => 0.615789
+(4, 7) ~ (5, -1) => 0.289365
+(4, 8) ~ (5, -1) => 0.267109
+(4, 9) ~ (5, -1) => 0.0855115
+(4, 10) ~ (5, -1) => 0.0575607
+(4, 11) ~ (5, -1) => 0.0329259
+(4, 12) ~ (5, -1) => 0.0166478
+(4, 13) ~ (5, -1) => 0.0174409
+(4, 14) ~ (5, -1) => 0.0170979
+(4, 15) ~ (5, -1) => 0.0113667
+(4, 16) ~ (5, -1) => 0.0076288
+(4, 17) ~ (5, -1) => 0.00166917
+(4, 18) ~ (5, -1) => 0.000645757
+(4, 19) ~ (5, -1) => 0.00060004
+(4, 20) ~ (5, -1) => 0.000344455
+(4, 21) ~ (5, -1) => 0.000227749
+(4, 22) ~ (5, -1) => 0.0001
+(4, 23) ~ (5, -1) => 0.0001
+(4, 24) ~ (5, -1) => 0.000180185
+(4, 25) ~ (5, -1) => 0.00155902
+(4, 26) ~ (5, -1) => 0.0085572
+(4, 27) ~ (5, -1) => 0.0207042
+(4, 28) ~ (5, -1) => 0.00683653
+(4, 29) ~ (5, -1) => 0.00561303
+(4, 30) ~ (5, -1) => 0.0039506
+(4, 31) ~ (5, -1) => 0.00199711
+(4, 32) ~ (5, -1) => 0.00602311
+(4, 33) ~ (5, -1) => 0.00450391
+(4, 34) ~ (5, -1) => 0.00561333
+(4, 35) ~ (5, -1) => 0.00693655
+(4, 36) ~ (5, -1) => 0.00649816
+(4, 37) ~ (5, -1) => 0.00421274
+(4, 38) ~ (5, -1) => 0.00268179
+(4, 39) ~ (5, -1) => 0.00268757
+(4, 40) ~ (5, -1) => 0.00322717
+(4, 41) ~ (5, -1) => 0.00252825
+(4, 42) ~ (5, -1) => 0.00377244
+(4, 43) ~ (5, -1) => 0.00349224
+(4, 44) ~ (5, -1) => 0.000701845
+(4, 45) ~ (5, -1) => 0.00155759
+(4, 46) ~ (5, -1) => 0.00192535
+(4, 47) ~ (5, -1) => 0.00150841
+(4, 48) ~ (5, -1) => 0.000372052
+(4, 49) ~ (5, -1) => 0.000685096
+(4, 50) ~ (5, -1) => 0.000755787
+(4, 51) ~ (5, -1) => 0.000443041
+(4, 52) ~ (5, -1) => 0.00030005
+(4, 53) ~ (5, -1) => 0.0001
+(4, 54) ~ (5, -1) => 0.0001
+(4, 55) ~ (5, -1) => 0.000110149
+(4, 56) ~ (5, -1) => 0.000923097
+(4, 57) ~ (5, -1) => 0.016776
+(4, 58) ~ (5, -1) => 0.0195995
+(4, 59) ~ (5, -1) => 0.0915062
+(4, 60) ~ (5, -1) => 0.0216439
+(4, 61) ~ (5, -1) => 0.0518963
+(4, 62) ~ (5, -1) => 0.0539894
+(4, 63) ~ (5, -1) => 0.436534
+(4, 64) ~ (5, -1) => 0.143953
+(4, 65) ~ (5, -1) => 0.0763088
+(4, 66) ~ (5, -1) => 0.103005
+(4, 67) ~ (5, -1) => 0.0893503
+(4, 68) ~ (5, -1) => 0.00375253
+(4, 69) ~ (5, -1) => 0.000714064
+(4, 70) ~ (5, -1) => 0.00115037
+(4, 71) ~ (5, -1) => 0.00088191
+(4, 72) ~ (5, -1) => 0.000329554
+(4, 73) ~ (5, -1) => 0.0001
+(4, 74) ~ (5, -1) => 0.0001
+(4, 75) ~ (5, -1) => 0.0001
+(4, 76) ~ (5, -1) => 0.000126898
+(4, 77) ~ (5, -1) => 0.00028795
+(4, 78) ~ (5, -1) => 0.00222164
+(4, 79) ~ (5, -1) => 0.0481706
+(4, 80) ~ (5, -1) => 0.0780304
+(4, 81) ~ (5, -1) => 0.130719
+(4, 82) ~ (5, -1) => 0.156893
+(4, 83) ~ (5, -1) => 0.171765
+(4, 84) ~ (5, -1) => 0.158603
+(4, 85) ~ (5, -1) => 0.229728
+(4, 86) ~ (5, -1) => 0.2735
+(4, 87) ~ (5, -1) => 0.137132
+(4, 88) ~ (5, -1) => 0.0441598
+(4, 89) ~ (5, -1) => 0.0448542
+(4, 90) ~ (5, -1) => 0.0451982
+(4, 91) ~ (5, -1) => 0.0446208
+(4, 92) ~ (5, -1) => 0.0564228
+(4, 93) ~ (5, -1) => 0.0435186
+(4, 94) ~ (5, -1) => 0.0130714
+(4, 95) ~ (5, -1) => 0.00295448
+(4, 96) ~ (5, -1) => 0.00109863
+(4, 97) ~ (5, -1) => 0.00277549
+(4, 98) ~ (5, -1) => 0.00875264
+(4, 99) ~ (5, -1) => 0.0724546
+(4, 100) ~ (5, -1) => 0.155961
+(4, 101) ~ (5, -1) => 0.247946
+(4, 102) ~ (5, -1) => 0.255707
+(4, 103) ~ (5, -1) => 0.287356
+(4, 104) ~ (5, -1) => 0.205101
+(4, 105) ~ (5, -1) => 0.108523
+(4, 106) ~ (5, -1) => 0.0506801
+(4, 107) ~ (5, -1) => 0.0228128
+(4, 108) ~ (5, -1) => 0.00623691
+(4, 109) ~ (5, -1) => 0.000193536
+(4, 110) ~ (5, -1) => 0.0001
+(4, 111) ~ (5, -1) => 0.0001
+(4, 112) ~ (5, -1) => 0.0001
+(4, 113) ~ (5, -1) => 0.0001
+(4, 114) ~ (5, -1) => 0.0001
+(4, 115) ~ (5, -1) => 0.000123084
+(4, 116) ~ (5, -1) => 0.000728011
+(4, 117) ~ (5, -1) => 0.00209528
+(4, 118) ~ (5, -1) => 0.00394499
+(4, 119) ~ (5, -1) => 0.00461245
+(4, 120) ~ (5, -1) => 0.012545
+(4, 121) ~ (5, -1) => 0.0184383
+(4, 122) ~ (5, -1) => 0.0238687
+(4, 123) ~ (5, -1) => 0.010875
+(4, 124) ~ (5, -1) => 0.00634587
+(4, 125) ~ (5, -1) => 0.00866425
+(4, 126) ~ (5, -1) => 0.0172509
+(4, 127) ~ (5, -1) => 0.01366
+(4, 128) ~ (5, -1) => 0.00365621
+(4, 129) ~ (5, -1) => 0.00741619
+(4, 130) ~ (5, -1) => 0.0563572
+(4, 131) ~ (5, -1) => 0.106797
+(4, 132) ~ (5, -1) => 0.173235
+(4, 133) ~ (5, -1) => 0.145634
+(4, 134) ~ (5, -1) => 0.0530007
+(4, 135) ~ (5, -1) => 0.0594869
+(4, 136) ~ (5, -1) => 0.0696822
+(4, 137) ~ (5, -1) => 0.0495547
+(4, 138) ~ (5, -1) => 0.0512398
+(4, 139) ~ (5, -1) => 0.0484207
+(4, 140) ~ (5, -1) => 0.0459497
+(4, 141) ~ (5, -1) => 0.0241418
+(4, 142) ~ (5, -1) => 0.0276774
+(4, 143) ~ (5, -1) => 0.0349033
+(4, 144) ~ (5, -1) => 0.00551897
+(4, 145) ~ (5, -1) => 0.00547171
+(4, 146) ~ (5, -1) => 0.00471509
+(4, 147) ~ (5, -1) => 0.00107574
+(4, 148) ~ (5, -1) => 0.0001
+(4, 149) ~ (5, -1) => 0.0001
+(4, 150) ~ (5, -1) => 0.0001
+(4, 151) ~ (5, -1) => 0.000165939
+(4, 152) ~ (5, -1) => 0.000285149
+(4, 153) ~ (5, -1) => 0.000236571
+(4, 154) ~ (5, -1) => 0.0001
+(4, 155) ~ (5, -1) => 0.0001
+(4, 156) ~ (5, -1) => 0.0001
+(4, 157) ~ (5, -1) => 0.000618815
+(4, 158) ~ (5, -1) => 0.00139904
+(4, 159) ~ (5, -1) => 0.00341249
+(4, 160) ~ (5, -1) => 0.00481391
+(4, 161) ~ (5, -1) => 0.00474977
+(4, 162) ~ (5, -1) => 0.00461185
+(4, 163) ~ (5, -1) => 0.00480044
+(4, 164) ~ (5, -1) => 0.00493944
+(4, 165) ~ (5, -1) => 0.00516111
+(4, 166) ~ (5, -1) => 0.00272596
+(4, 167) ~ (5, -1) => 0.0023011
+(4, 168) ~ (5, -1) => 0.00169957
+(4, 169) ~ (5, -1) => 0.000403464
+(4, 170) ~ (5, -1) => 0.0001
+(4, 171) ~ (5, -1) => 0.0001
+(4, 172) ~ (5, -1) => 0.0001
+(4, 173) ~ (5, -1) => 0.0001
+(4, 174) ~ (5, -1) => 0.0001
+(4, 175) ~ (5, -1) => 0.0001
+(4, 176) ~ (5, -1) => 0.000287175
+(4, 177) ~ (5, -1) => 0.000555873
+(4, 178) ~ (5, -1) => 0.000527382
+(4, 179) ~ (5, -1) => 0.000355721
+(4, 180) ~ (5, -1) => 0.000130832
+(4, 181) ~ (5, -1) => 0.0001
+(4, 182) ~ (5, -1) => 0.0001
+(4, 183) ~ (5, -1) => 0.0001
+(4, 184) ~ (5, -1) => 0.0001
+(4, 185) ~ (5, -1) => 0.000792623
+(4, 186) ~ (5, -1) => 0.00146574
+(4, 187) ~ (5, -1) => 0.00201696
+(4, 188) ~ (5, -1) => 0.00620741
+(4, 189) ~ (5, -1) => 0.0106084
+(4, 190) ~ (5, -1) => 0.0254791
+(4, 191) ~ (5, -1) => 0.0106484
+(4, 192) ~ (5, -1) => 0.0451448
+(4, 193) ~ (5, -1) => 0.0933278
+(4, 194) ~ (5, -1) => 0.0115977
+(4, 195) ~ (5, -1) => 0.0144784
+(4, 196) ~ (5, -1) => 0.0286904
+(4, 197) ~ (5, -1) => 0.0352095
+(4, 198) ~ (5, -1) => 0.0200569
+(4, 199) ~ (5, -1) => 0.0213048
+(4, 200) ~ (5, -1) => 0.0192446
+(4, 201) ~ (5, -1) => 0.0208282
+(4, 202) ~ (5, -1) => 0.0124717
+(4, 203) ~ (5, -1) => 0.0157629
+(4, 204) ~ (5, -1) => 0.00716817
+(4, 205) ~ (5, -1) => 0.00253022
+(4, 206) ~ (5, -1) => 0.00122267
+(4, 207) ~ (5, -1) => 0.00251597
+(4, 208) ~ (5, -1) => 0.002792
+(4, 209) ~ (5, -1) => 0.00220209
+(4, 210) ~ (5, -1) => 0.000670612
+(4, 211) ~ (5, -1) => 0.000568151
+(4, 212) ~ (5, -1) => 0.00188202
+(4, 213) ~ (5, -1) => 0.00219101
+(4, 214) ~ (5, -1) => 0.00240576
+(4, 215) ~ (5, -1) => 0.00602597
+(4, 216) ~ (5, -1) => 0.00863236
+(4, 217) ~ (5, -1) => 0.0106911
+(4, 218) ~ (5, -1) => 0.0255126
+(4, 219) ~ (5, -1) => 0.0409829
+(4, 220) ~ (5, -1) => 0.36186
+(4, 221) ~ (5, -1) => 0.528374
+(4, 222) ~ (5, -1) => 0.0722878
+(4, 223) ~ (5, -1) => 0.0276918
+(4, 224) ~ (5, -1) => 0.0391362
+(4, 225) ~ (5, -1) => 0.00799662
+(4, 226) ~ (5, -1) => 0.0031665
+(4, 227) ~ (5, -1) => 0.000249028
+(4, 228) ~ (5, -1) => 0.0001
+(4, 229) ~ (5, -1) => 0.0001
+(4, 230) ~ (5, -1) => 0.000510991
+(4, 231) ~ (5, -1) => 0.00682896
+(4, 232) ~ (5, -1) => 0.00735795
+(4, 233) ~ (5, -1) => 0.0117856
+(4, 234) ~ (5, -1) => 0.0133163
+(4, 235) ~ (5, -1) => 0.0139425
+(4, 236) ~ (5, -1) => 0.0127094
+(4, 237) ~ (5, -1) => 0.00897563
+
+(4, -1) ~ (5, 0) => 0.00830293
+(4, -1) ~ (5, 1) => 0.0200657
+(4, -1) ~ (5, 2) => 0.0148113
+(4, -1) ~ (5, 3) => 0.0253138
+(4, -1) ~ (5, 4) => 0.0316113
+(4, -1) ~ (5, 5) => 0.0203605
+(4, -1) ~ (5, 6) => 0.0458813
+(4, -1) ~ (5, 7) => 0.0108548
+(4, -1) ~ (5, 8) => 0.02425
+(4, -1) ~ (5, 9) => 0.17438
+(4, -1) ~ (5, 10) => 0.330276
+(4, -1) ~ (5, 11) => 0.25388
+(4, -1) ~ (5, 12) => 0.264973
+(4, -1) ~ (5, 13) => 0.32078
+(4, -1) ~ (5, 14) => 0.177437
+(4, -1) ~ (5, 15) => 0.0193446
+(4, -1) ~ (5, 16) => 0.00166917
+(4, -1) ~ (5, 17) => 0.000645757
+(4, -1) ~ (5, 18) => 0.00060004
+(4, -1) ~ (5, 19) => 0.000344455
+(4, -1) ~ (5, 20) => 0.000227749
+(4, -1) ~ (5, 21) => 0.0001
+(4, -1) ~ (5, 22) => 0.0001
+(4, -1) ~ (5, 23) => 0.000180185
+(4, -1) ~ (5, 24) => 0.00155902
+(4, -1) ~ (5, 25) => 0.0085572
+(4, -1) ~ (5, 26) => 0.00176845
+(4, -1) ~ (5, 27) => 0.00386084
+(4, -1) ~ (5, 28) => 0.00494721
+(4, -1) ~ (5, 29) => 0.00785119
+(4, -1) ~ (5, 30) => 0.0206738
+(4, -1) ~ (5, 31) => 0.00602311
+(4, -1) ~ (5, 32) => 0.00450391
+(4, -1) ~ (5, 33) => 0.00561333
+(4, -1) ~ (5, 34) => 0.00693655
+(4, -1) ~ (5, 35) => 0.00649816
+(4, -1) ~ (5, 36) => 0.00421274
+(4, -1) ~ (5, 37) => 0.00268179
+(4, -1) ~ (5, 38) => 0.00268757
+(4, -1) ~ (5, 39) => 0.00322717
+(4, -1) ~ (5, 40) => 0.00252825
+(4, -1) ~ (5, 41) => 0.00377244
+(4, -1) ~ (5, 42) => 0.00349224
+(4, -1) ~ (5, 43) => 0.000701845
+(4, -1) ~ (5, 44) => 0.00155759
+(4, -1) ~ (5, 45) => 0.00192535
+(4, -1) ~ (5, 46) => 0.00150841
+(4, -1) ~ (5, 47) => 0.000372052
+(4, -1) ~ (5, 48) => 0.000685096
+(4, -1) ~ (5, 49) => 0.000755787
+(4, -1) ~ (5, 50) => 0.000443041
+(4, -1) ~ (5, 51) => 0.00030005
+(4, -1) ~ (5, 52) => 0.0001
+(4, -1) ~ (5, 53) => 0.0001
+(4, -1) ~ (5, 54) => 0.000110149
+(4, -1) ~ (5, 55) => 0.000923097
+(4, -1) ~ (5, 56) => 0.00382677
+(4, -1) ~ (5, 57) => 0.00736943
+(4, -1) ~ (5, 58) => 0.00898623
+(4, -1) ~ (5, 59) => 0.0116176
+(4, -1) ~ (5, 60) => 0.0201368
+(4, -1) ~ (5, 61) => 0.00520004
+(4, -1) ~ (5, 62) => 0.0250269
+(4, -1) ~ (5, 63) => 0.0152845
+(4, -1) ~ (5, 64) => 0.0052827
+(4, -1) ~ (5, 65) => 0.00183207
+(4, -1) ~ (5, 66) => 0.00375253
+(4, -1) ~ (5, 67) => 0.000714064
+(4, -1) ~ (5, 68) => 0.00115037
+(4, -1) ~ (5, 69) => 0.00088191
+(4, -1) ~ (5, 70) => 0.000329554
+(4, -1) ~ (5, 71) => 0.0001
+(4, -1) ~ (5, 72) => 0.0001
+(4, -1) ~ (5, 73) => 0.0001
+(4, -1) ~ (5, 74) => 0.000126898
+(4, -1) ~ (5, 75) => 0.00028795
+(4, -1) ~ (5, 76) => 0.00222164
+(4, -1) ~ (5, 77) => 0.0477362
+(4, -1) ~ (5, 78) => 0.0201183
+(4, -1) ~ (5, 79) => 0.0401195
+(4, -1) ~ (5, 80) => 0.0192403
+(4, -1) ~ (5, 81) => 0.0296648
+(4, -1) ~ (5, 82) => 0.122623
+(4, -1) ~ (5, 83) => 0.167794
+(4, -1) ~ (5, 84) => 0.0994424
+(4, -1) ~ (5, 85) => 0.0283891
+(4, -1) ~ (5, 86) => 0.0257975
+(4, -1) ~ (5, 87) => 0.0202653
+(4, -1) ~ (5, 88) => 0.0167301
+(4, -1) ~ (5, 89) => 0.0125154
+(4, -1) ~ (5, 90) => 0.0128792
+(4, -1) ~ (5, 91) => 0.0130714
+(4, -1) ~ (5, 92) => 0.00295448
+(4, -1) ~ (5, 93) => 0.00109863
+(4, -1) ~ (5, 94) => 0.00277549
+(4, -1) ~ (5, 95) => 0.00875264
+(4, -1) ~ (5, 96) => 0.00886019
+(4, -1) ~ (5, 97) => 0.0151895
+(4, -1) ~ (5, 98) => 0.0206416
+(4, -1) ~ (5, 99) => 0.0244502
+(4, -1) ~ (5, 100) => 0.215866
+(4, -1) ~ (5, 101) => 0.0724543
+(4, -1) ~ (5, 102) => 0.0390862
+(4, -1) ~ (5, 103) => 0.00999391
+(4, -1) ~ (5, 104) => 0.00623691
+(4, -1) ~ (5, 105) => 0.000193536
+(4, -1) ~ (5, 106) => 0.0001
+(4, -1) ~ (5, 107) => 0.0001
+(4, -1) ~ (5, 108) => 0.0001
+(4, -1) ~ (5, 109) => 0.0001
+(4, -1) ~ (5, 110) => 0.0001
+(4, -1) ~ (5, 111) => 0.000123084
+(4, -1) ~ (5, 112) => 0.000728011
+(4, -1) ~ (5, 113) => 0.00209528
+(4, -1) ~ (5, 114) => 0.00394499
+(4, -1) ~ (5, 115) => 0.00461245
+(4, -1) ~ (5, 116) => 0.012545
+(4, -1) ~ (5, 117) => 0.0047656
+(4, -1) ~ (5, 118) => 0.0049021
+(4, -1) ~ (5, 119) => 0.00545003
+(4, -1) ~ (5, 120) => 0.00557105
+(4, -1) ~ (5, 121) => 0.0049895
+(4, -1) ~ (5, 122) => 0.00275214
+(4, -1) ~ (5, 123) => 0.00076291
+(4, -1) ~ (5, 124) => 0.00101596
+(4, -1) ~ (5, 125) => 0.00296714
+(4, -1) ~ (5, 126) => 0.0451344
+(4, -1) ~ (5, 127) => 0.0772271
+(4, -1) ~ (5, 128) => 0.0955666
+(4, -1) ~ (5, 129) => 0.0851445
+(4, -1) ~ (5, 130) => 0.124327
+(4, -1) ~ (5, 131) => 0.213319
+(4, -1) ~ (5, 132) => 0.235272
+(4, -1) ~ (5, 133) => 0.171735
+(4, -1) ~ (5, 134) => 0.10435
+(4, -1) ~ (5, 135) => 0.172896
+(4, -1) ~ (5, 136) => 0.160547
+(4, -1) ~ (5, 137) => 0.237522
+(4, -1) ~ (5, 138) => 0.166414
+(4, -1) ~ (5, 139) => 0.0733598
+(4, -1) ~ (5, 140) => 0.0602657
+(4, -1) ~ (5, 141) => 0.00551897
+(4, -1) ~ (5, 142) => 0.00547171
+(4, -1) ~ (5, 143) => 0.00471509
+(4, -1) ~ (5, 144) => 0.00107574
+(4, -1) ~ (5, 145) => 0.0001
+(4, -1) ~ (5, 146) => 0.0001
+(4, -1) ~ (5, 147) => 0.0001
+(4, -1) ~ (5, 148) => 0.000165939
+(4, -1) ~ (5, 149) => 0.000285149
+(4, -1) ~ (5, 150) => 0.000236571
+(4, -1) ~ (5, 151) => 0.0001
+(4, -1) ~ (5, 152) => 0.0001
+(4, -1) ~ (5, 153) => 0.0001
+(4, -1) ~ (5, 154) => 0.000618815
+(4, -1) ~ (5, 155) => 0.00139904
+(4, -1) ~ (5, 156) => 0.00341249
+(4, -1) ~ (5, 157) => 0.00481391
+(4, -1) ~ (5, 158) => 0.00474977
+(4, -1) ~ (5, 159) => 0.00461185
+(4, -1) ~ (5, 160) => 0.00480044
+(4, -1) ~ (5, 161) => 0.00493944
+(4, -1) ~ (5, 162) => 0.00516111
+(4, -1) ~ (5, 163) => 0.00272596
+(4, -1) ~ (5, 164) => 0.0023011
+(4, -1) ~ (5, 165) => 0.00169957
+(4, -1) ~ (5, 166) => 0.000403464
+(4, -1) ~ (5, 167) => 0.0001
+(4, -1) ~ (5, 168) => 0.0001
+(4, -1) ~ (5, 169) => 0.0001
+(4, -1) ~ (5, 170) => 0.0001
+(4, -1) ~ (5, 171) => 0.0001
+(4, -1) ~ (5, 172) => 0.0001
+(4, -1) ~ (5, 173) => 0.000287175
+(4, -1) ~ (5, 174) => 0.000555873
+(4, -1) ~ (5, 175) => 0.000527382
+(4, -1) ~ (5, 176) => 0.000355721
+(4, -1) ~ (5, 177) => 0.000130832
+(4, -1) ~ (5, 178) => 0.0001
+(4, -1) ~ (5, 179) => 0.0001
+(4, -1) ~ (5, 180) => 0.0001
+(4, -1) ~ (5, 181) => 0.0001
+(4, -1) ~ (5, 182) => 0.000792623
+(4, -1) ~ (5, 183) => 0.00146574
+(4, -1) ~ (5, 184) => 0.00201696
+(4, -1) ~ (5, 185) => 0.00620741
+(4, -1) ~ (5, 186) => 0.0106084
+(4, -1) ~ (5, 187) => 0.00248756
+(4, -1) ~ (5, 188) => 0.00584678
+(4, -1) ~ (5, 189) => 0.0245125
+(4, -1) ~ (5, 190) => 0.0433872
+(4, -1) ~ (5, 191) => 0.0386063
+(4, -1) ~ (5, 192) => 0.0287319
+(4, -1) ~ (5, 193) => 0.0153383
+(4, -1) ~ (5, 194) => 0.0346931
+(4, -1) ~ (5, 195) => 0.0314964
+(4, -1) ~ (5, 196) => 0.0490682
+(4, -1) ~ (5, 197) => 0.0317091
+(4, -1) ~ (5, 198) => 0.0271398
+(4, -1) ~ (5, 199) => 0.0254651
+(4, -1) ~ (5, 200) => 0.0157629
+(4, -1) ~ (5, 201) => 0.00716817
+(4, -1) ~ (5, 202) => 0.00253022
+(4, -1) ~ (5, 203) => 0.00122267
+(4, -1) ~ (5, 204) => 0.00251597
+(4, -1) ~ (5, 205) => 0.002792
+(4, -1) ~ (5, 206) => 0.00220209
+(4, -1) ~ (5, 207) => 0.000670612
+(4, -1) ~ (5, 208) => 0.000568151
+(4, -1) ~ (5, 209) => 0.00188202
+(4, -1) ~ (5, 210) => 0.00219101
+(4, -1) ~ (5, 211) => 0.00240576
+(4, -1) ~ (5, 212) => 0.00602597
+(4, -1) ~ (5, 213) => 0.00863236
+(4, -1) ~ (5, 214) => 0.0106911
+(4, -1) ~ (5, 215) => 0.0095864
+(4, -1) ~ (5, 216) => 0.0166607
+(4, -1) ~ (5, 217) => 0.00641899
+(4, -1) ~ (5, 218) => 0.0120443
+(4, -1) ~ (5, 219) => 0.0303273
+(4, -1) ~ (5, 220) => 0.0208074
+(4, -1) ~ (5, 221) => 0.00799662
+(4, -1) ~ (5, 222) => 0.0031665
+(4, -1) ~ (5, 223) => 0.000249028
+(4, -1) ~ (5, 224) => 0.0001
+(4, -1) ~ (5, 225) => 0.0001
+(4, -1) ~ (5, 226) => 0.000510991
+(4, -1) ~ (5, 227) => 0.00682896
+(4, -1) ~ (5, 228) => 0.00735795
+(4, -1) ~ (5, 229) => 0.0117856
+(4, -1) ~ (5, 230) => 0.0133163
+(4, -1) ~ (5, 231) => 0.0139425
+(4, -1) ~ (5, 232) => 0.0127094
+(4, -1) ~ (5, 233) => 0.00897563
+
diff --git a/examples/RV12.BBS12030.mfa b/examples/RV12.BBS12030.mfa
new file mode 100644
index 0000000..1c4a080
--- /dev/null
+++ b/examples/RV12.BBS12030.mfa
@@ -0,0 +1,13 @@
+>POL_MPMV
+APQQCA-EPITWKSDE--P-VWVDQWPLTNDKLAAAQQLVQEQLEAGHITESS--SPWNTPIFVIKKK-SGKWRLLQDLRAVNATMVLMGALQPGLPSPV----AIPQ-GYLKIIIDLKDCFFSIPLHPSDQKRFAFSLPSTNFKEPMQRFQWKVLPQGMANSPTLCQKYVATAIHKVRHAWKQMYIIHYMDDILIAGKDGQ-QVLQCFDQLKQELTAAGLHIAPEKVQL-QDPYTYLGFELNGPKI
+>POL_BIV06
+HTEKIEPL--PVKVRG--PGPKVPQWPLTKEKYQALKEIVKDLLAEGKISEAAWDNPYNTPVFVIKKKGTGRWRMLMDFRELNKITVKGQEFSTGLPYPP----GIKE-CEHLTAIDIKDAYFTIPLHEDFRPFTAFSVVPVNREGPIERFQWNVLPQGWVCSPAIYQTTTQKIIENIKKSHPDVMLYQYMDDLLIGSNRD--DHKQIVQEIRDKLGSYGFKTPDEKVQ--EERVKWIGFELTPKKW
+>POL_CAEVC
+LEEKRIPI-TKVKLKEGCTGPHVPQWPLTEEKLKGLTEIIDKLVEEGKLGKAPPHWTCNTPIFCIKKK-SGKWRMLIDFRELNKQTEDLTEAQLGLPHPG----GLQK-KKHVTILDIGDAYFTIPLYEPYREYTCFTLLSPNNLGPCKRYYWKVLPQGWKLSPSVYQFTMQEILEDWIQQHPEIQFGIYMDDIYIGSDLEIKKHREIVKDLANYIAQYGFTLPEEKRQK-GYPAKWLGFELHPQTW
+>1bqm_A
+PISPIETV--PVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPA----GLKK-KKSVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFKKQNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELRQHLLRWGLTTPDKKHQK-EPPFLWMGYELHPDKW
+>1d0e_A
+LAVRQAPLI--IPLKATSTPVSIKQYPMSQEARLGIKPHIQRLLDQGILVPCQ--SPWNTPLLPVKKPGTNDYRPVQDLREVNKRVEDI---HPTVPNPYNLLSGLPPSHQWYTVLDLKDAFFCLRLHPTSQPLFAFEWRDPEM-GISGQLTWTRLPQGFKNSPTLFDEALHRDLADFRIQHPDLILLQYVDDLLLAATSEL-DCQQGTRALLQTLGNLGYRASAKKAQICQKQVKYLGYLLKEGQR
+>POL_RSVP
+VALHLA-IPLKW--KPDHTPVWIDQWPLPEGKLVALTQLVEKELQLGHIEPSL--SCWNTPVFVIRKA-SGSYRLLHDLRAVNAKLVPFGAVQQGAPVLS----ALPR-GWPLMVLDLKDCFFSIPLAEQDREAFAFTLPSVNNQAPARRFQWKVLPQGMTCSPTICQLVVGQVLEPLRLKHPSLCMLHYMDDLLLAASSHD-GLEAAGEEVISTLERAGFTISPDKVQR-EPGVQYLGYKLGSTYV
+
diff --git a/examples/RV12.BBS12030.reference.mfa b/examples/RV12.BBS12030.reference.mfa
new file mode 100644
index 0000000..24877df
--- /dev/null
+++ b/examples/RV12.BBS12030.reference.mfa
@@ -0,0 +1,36 @@
+>POL_MPMV
+APQQCAEPITWKSDE---PVWVDQWPLTNDKLAAAQQLVQEQLEAGHITE
+SS--SPWNTPIFVIKKKS-GKWRLLQDLRAVNATMVLMGALQPGLP-SPV
+AIPQGY-LKIIIDLKDCFFSIPLHPSDQKRFAFSLPSTNFKEPMQRFQWK
+VLPQGMANSPTLCQKYVATAIHKVRHAWKQMYIIHYMDDILIAGKD-GQQ
+VLQCFDQLKQELTAAGLHIAPEKVQL-QDPYTYLGFELNGPKI
+>POL_BIV06
+HTEK-IEPLPVKVRG--PGPKVPQWPLTKEKYQALKEIVKDLLAEGKISE
+AAWDNPYNTPVFVIKKKGTGRWRMLMDFRELNKITVKGQEFSTGLP-YPP
+GIKECE-HLTAIDIKDAYFTIPLHEDFRPFTAFSVVPVNREGPIERFQWN
+VLPQGWVCSPAIYQTTTQKIIENIKKSHPDVMLYQYMDDLLIGSNR--DD
+HKQIVQEIRDKLGSYGFKTPDEKVQE--ERVKWIGFELTPKKW
+>POL_CAEVC
+LEEKRIPITKVKLKEGCTGPHVPQWPLTEEKLKGLTEIIDKLVEEGKLGK
+APPHWTCNTPIFCIKKKS-GKWRMLIDFRELNKQTEDLTEAQLGLP-HPG
+GLQKKK-HVTILDIGDAYFTIPLYEPYREYTCFTLLSPNNLGPCKRYYWK
+VLPQGWKLSPSVYQFTMQEILEDWIQQHPEIQFGIYMDDIYIGSDLEIKK
+HREIVKDLANYIAQYGFTLPEEKRQK-GYPAKWLGFELHPQTW
+>1bqm_A
+PISP-IETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISK
+IGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIP-HPA
+GLKKKK-SVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYN
+VLPQGWKGSPAIFQSSMTKILEPFKKQNPDIVIYQYMDDLYVGSDLEIGQ
+HRTKIEELRQHLLRWGLTTPDKKHQK-EPPFLWMGYELHPDKW
+>1d0e_A
+LAVR-QAPLIIPLKATSTPVSIKQYPMSQEARLGIKPHIQRLLDQGILVP
+CQ--SPWNTPLLPVKKPGTNDYRPVQDLREVNKRVEDIHPTVPNPYNLLS
+GLPPSHQWYTVLDLKDAFFCLRLHPTSQPLFAFEWRDPEMGISG-QLTWT
+RLPQGFKNSPTLFDEALHRDLADFRIQHPDLILLQYVDDLLLAATS-ELD
+CQQGTRALLQTLGNLGYRASAKKAQICQKQVKYLGYLLKEGQR
+>POL_RSVP
+VALHLAIPLKWKPDH--TPVWIDQWPLPEGKLVALTQLVEKELQLGHIEP
+SL--SCWNTPVFVIRKAS-GSYRLLHDLRAVNAKLVPFGAVQQGAP-VLS
+ALPRGW-PLMVLDLKDCFFSIPLAEQDREAFAFTLPSVNNQAPARRFQWK
+VLPQGMTCSPTICQLVVGQVLEPLRLKHPSLCMLHYMDDLLLAASS-HDG
+LEAAGEEVISTLERAGFTISPDKVQR-EPGVQYLGYKLGSTYV
diff --git a/examples/RV12.BBS12030.reference.stock b/examples/RV12.BBS12030.reference.stock
new file mode 100644
index 0000000..4e096fc
--- /dev/null
+++ b/examples/RV12.BBS12030.reference.stock
@@ -0,0 +1,8 @@
+# STOCKHOLM 1.0
+POL_MPMV  APQQCAEPITWKSDE...PVWVDQWPLTNDKLAAAQQLVQEQLEAGHITESS..SPWNTPIFVIKKKS.GKWRLLQDLRAVNATMVLMGALQPGLP.SPVAIPQGY.LKIIIDLKDCFFSIPLHPSDQKRFAFSLPSTNFKEPMQRFQWKVLPQGMANSPTLCQKYVATAIHKVRHAWKQMYIIHYMDDILIAGKD.GQQVLQCFDQLKQELTAAGLHIAPEKVQL.QDPYTYLGFELNGPKI
+POL_BIV06 HTEK.IEPLPVKVRG..PGPKVPQWPLTKEKYQALKEIVKDLLAEGKISEAAWDNPYNTPVFVIKKKGTGRWRMLMDFRELNKITVKGQEFSTGLP.YPPGIKECE.HLTAIDIKDAYFTIPLHEDFRPFTAFSVVPVNREGPIERFQWNVLPQGWVCSPAIYQTTTQKIIENIKKSHPDVMLYQYMDDLLIGSNR..DDHKQIVQEIRDKLGSYGFKTPDEKVQE..ERVKWIGFELTPKKW
+POL_CAEVC LEEKRIPITKVKLKEGCTGPHVPQWPLTEEKLKGLTEIIDKLVEEGKLGKAPPHWTCNTPIFCIKKKS.GKWRMLIDFRELNKQTEDLTEAQLGLP.HPGGLQKKK.HVTILDIGDAYFTIPLYEPYREYTCFTLLSPNNLGPCKRYYWKVLPQGWKLSPSVYQFTMQEILEDWIQQHPEIQFGIYMDDIYIGSDLEIKKHREIVKDLANYIAQYGFTLPEEKRQK.GYPAKWLGFELHPQTW
+1bqm_A    PISP.IETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIP.HPAGLKKKK.SVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFKKQNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELRQHLLRWGLTTPDKKHQK.EPPFLWMGYELHPDKW
+POL_RSVP  VALHLAIPLKWKPDH..TPVWIDQWPLPEGKLVALTQLVEKELQLGHIEPSL..SCWNTPVFVIRKAS.GSYRLLHDLRAVNAKLVPFGAVQQGAP.VLSALPRGW.PLMVLDLKDCFFSIPLAEQDREAFAFTLPSVNNQAPARRFQWKVLPQGMTCSPTICQLVVGQVLEPLRLKHPSLCMLHYMDDLLLAASS.HDGLEAAGEEVISTLERAGFTISPDKVQR.EPGVQYLGYKLGSTYV
+1d0e_A    LAVR.QAPLIIPLKATSTPVSIKQYPMSQEARLGIKPHIQRLLDQGILVPCQ..SPWNTPLLPVKKPGTNDYRPVQDLREVNKRVEDIHPTVPNPYNLLSGLPPSHQWYTVLDLKDAFFCLRLHPTSQPLFAFEWRDPEMGISG.QLTWTRLPQGFKNSPTLFDEALHRDLADFRIQHPDLILLQYVDDLLLAATS.ELDCQQGTRALLQTLGNLGYRASAKKAQICQKQVKYLGYLLKEGQR
+//
diff --git a/examples/RV12.BBS12030.stock b/examples/RV12.BBS12030.stock
new file mode 100644
index 0000000..046f133
--- /dev/null
+++ b/examples/RV12.BBS12030.stock
@@ -0,0 +1,10 @@
+# STOCKHOLM 1.0
+#=GF Accuracy 0.900656
+POL_MPMV      APQQCA-EPITWKSDE--P-VWVDQWPLTNDKLAAAQQLVQEQLEAGHITESS--SPWNTPIFVIKKK-SGKWRLLQDLRAVNATMVLMGALQPGLPSPV----AIPQ-GYLKIIIDLKDCFFSIPLHPSDQKRFAFSLPSTNFKEPMQRFQWKVLPQGMANSPTLCQKYVATAIHKVRHAWKQMYIIHYMDDILIAGKDGQ-QVLQCFDQLKQELTAAGLHIAPEKVQL-QDPYTYLGFELNGPKI
+POL_BIV06     HTEKIEPL--PVKVRG--PGPKVPQWPLTKEKYQALKEIVKDLLAEGKISEAAWDNPYNTPVFVIKKKGTGRWRMLMDFRELNKITVKGQEFSTGLPYPP----GIKE-CEHLTAIDIKDAYFTIPLHEDFRPFTAFSVVPVNREGPIERFQWNVLPQGWVCSPAIYQTTTQKIIENIKKSHPDVMLYQYMDDLLIGSNRD--DHKQIVQEIRDKLGSYGFKTPDEKVQ--EERVKWIGFELTPKKW
+POL_CAEVC     LEEKRIPI-TKVKLKEGCTGPHVPQWPLTEEKLKGLTEIIDKLVEEGKLGKAPPHWTCNTPIFCIKKK-SGKWRMLIDFRELNKQTEDLTEAQLGLPHPG----GLQK-KKHVTILDIGDAYFTIPLYEPYREYTCFTLLSPNNLGPCKRYYWKVLPQGWKLSPSVYQFTMQEILEDWIQQHPEIQFGIYMDDIYIGSDLEIKKHREIVKDLANYIAQYGFTLPEEKRQK-GYPAKWLGFELHPQTW
+1bqm_A        PISPIETV--PVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPA----GLKK-KKSVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFKKQNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELRQHLLRWGLTTPDKKHQK-EPPFLWMGYELHPDKW
+1d0e_A        LAVRQAPLI--IPLKATSTPVSIKQYPMSQEARLGIKPHIQRLLDQGILVPCQ--SPWNTPLLPVKKPGTNDYRPVQDLREVNKRVEDI---HPTVPNPYNLLSGLPPSHQWYTVLDLKDAFFCLRLHPTSQPLFAFEWRDPEM-GISGQLTWTRLPQGFKNSPTLFDEALHRDLADFRIQHPDLILLQYVDDLLLAATSEL-DCQQGTRALLQTLGNLGYRASAKKAQICQKQVKYLGYLLKEGQR
+POL_RSVP      VALHLA-IPLKW--KPDHTPVWIDQWPLPEGKLVALTQLVEKELQLGHIEPSL--SCWNTPVFVIRKA-SGSYRLLHDLRAVNAKLVPFGAVQQGAPVLS----ALPR-GWPLMVLDLKDCFFSIPLAEQDREAFAFTLPSVNNQAPARRFQWKVLPQGMTCSPTICQLVVGQVLEPLRLKHPSLCMLHYMDDLLLAASSHD-GLEAAGEEVISTLERAGFTISPDKVQR-EPGVQYLGYKLGSTYV
+#=GC Accuracy 8777655523455565676788999999999999999999999999988877655788999999998768999999999999999988888888888888334288873788999999999999999999999999999998888888899999999999999999999999999999999999999999999999887665366677788999999999999999999746789999999999999
+//
diff --git a/examples/U5.aln1.fasta b/examples/U5.aln1.fasta
new file mode 100644
index 0000000..8af7851
--- /dev/null
+++ b/examples/U5.aln1.fasta
@@ -0,0 +1,20 @@
+>AC005719.2-130462_130570
+UACUCUGGUUUCUCUUCAAUUGUCGAAUAAAUCUUUCGCCUUUUACUAAA
+GAUUUCCGUGGAGAGGAACACUCUAAUGAGUCUAAACUCAAUUUUUGUAU
+GACCUGGCU
+>AC000104.1-17376_17496
+AGCCAUGUGGUGAGCACAUAGCGAACUAUUCUUUCGCCUUUUACUAAAGA
+AUACCGUGUGCUCUCCACGCUAAGUGGCAUACGCCUAUUUUUGGAGGGUU
+CCCACUUUACUGUGGGUCCCA
+>AC009948.3-27597_27481
+AUACUCUGGAUUCUCUUCAGAUCAUAUAUCUUUUGCCUUUUAUUAGAAUU
+UCUAGAGAGAGGAUAAAUUAUGAGUUUGUAGCCAGUUUUUUCUUUGCUUU
+UUAUUUUUGGCAGGGUU
+>AL606646.3-46909_46786
+AGCUGCGCAGUGGGCACAAAGCGAACUAUUCUUUCGCCUUUUACUAAAGA
+AUACCGUGUGCACGCUGCAAAUAGCAGCAUACUCUAAUUUUUUGAGGGGA
+UUUCCUAUCUAAGGACAAACCCCA
+>M23811.1-5_119
+AUACUCUGGUUUCUCUUCAGAUCGUAUAAAUCUUUCCCCUUUCANCAAAG
+AUUUCCGUGGAGAGGAACAACUCUGAGUCUUAAACCAAUUUUUUGAGCCU
+UGUUCCGGCAAGGCU
diff --git a/examples/U5.aln1.fasta.gui b/examples/U5.aln1.fasta.gui
new file mode 100644
index 0000000..0c08714
--- /dev/null
+++ b/examples/U5.aln1.fasta.gui
@@ -0,0 +1,1048 @@
+; Initial DAG
+; Format is:
+;   column: (sequence, position)
+; sequence is 0-based and position is 0-based
+
+0: (0, 0)
+1: (1, 0)
+2: (2, 0)
+3: (3, 0)
+4: (4, 0)
+5: (0, 1)
+6: (1, 1)
+7: (2, 1)
+8: (3, 1)
+9: (4, 1)
+10: (0, 2)
+11: (1, 2)
+12: (2, 2)
+13: (3, 2)
+14: (4, 2)
+15: (0, 3)
+16: (1, 3)
+17: (2, 3)
+18: (3, 3)
+19: (4, 3)
+20: (0, 4)
+21: (1, 4)
+22: (2, 4)
+23: (3, 4)
+24: (4, 4)
+25: (0, 5)
+26: (1, 5)
+27: (2, 5)
+28: (3, 5)
+29: (4, 5)
+30: (0, 6)
+31: (1, 6)
+32: (2, 6)
+33: (3, 6)
+34: (4, 6)
+35: (0, 7)
+36: (1, 7)
+37: (2, 7)
+38: (3, 7)
+39: (4, 7)
+40: (0, 8)
+41: (1, 8)
+42: (2, 8)
+43: (3, 8)
+44: (4, 8)
+45: (0, 9)
+46: (1, 9)
+47: (2, 9)
+48: (3, 9)
+49: (4, 9)
+50: (0, 10)
+51: (1, 10)
+52: (2, 10)
+53: (3, 10)
+54: (4, 10)
+55: (0, 11)
+56: (1, 11)
+57: (2, 11)
+58: (3, 11)
+59: (4, 11)
+60: (0, 12)
+61: (1, 12)
+62: (2, 12)
+63: (3, 12)
+64: (4, 12)
+65: (0, 13)
+66: (1, 13)
+67: (2, 13)
+68: (3, 13)
+69: (4, 13)
+70: (0, 14)
+71: (1, 14)
+72: (2, 14)
+73: (3, 14)
+74: (4, 14)
+75: (0, 15)
+76: (1, 15)
+77: (2, 15)
+78: (3, 15)
+79: (4, 15)
+80: (0, 16)
+81: (1, 16)
+82: (2, 16)
+83: (3, 16)
+84: (4, 16)
+85: (0, 17)
+86: (1, 17)
+87: (2, 17)
+88: (3, 17)
+89: (4, 17)
+90: (0, 18)
+91: (1, 18)
+92: (2, 18)
+93: (3, 18)
+94: (4, 18)
+95: (0, 19)
+96: (1, 19)
+97: (2, 19)
+98: (3, 19)
+99: (4, 19)
+100: (0, 20)
+101: (1, 20)
+102: (2, 20)
+103: (3, 20)
+104: (4, 20)
+105: (0, 21)
+106: (1, 21)
+107: (2, 21)
+108: (3, 21)
+109: (4, 21)
+110: (0, 22)
+111: (1, 22)
+112: (2, 22)
+113: (3, 22)
+114: (4, 22)
+115: (0, 23)
+116: (1, 23)
+117: (2, 23)
+118: (3, 23)
+119: (4, 23)
+120: (0, 24)
+121: (1, 24)
+122: (2, 24)
+123: (3, 24)
+124: (4, 24)
+125: (0, 25)
+126: (1, 25)
+127: (2, 25)
+128: (3, 25)
+129: (4, 25)
+130: (0, 26)
+131: (1, 26)
+132: (2, 26)
+133: (3, 26)
+134: (4, 26)
+135: (0, 27)
+136: (1, 27)
+137: (2, 27)
+138: (3, 27)
+139: (4, 27)
+140: (0, 28)
+141: (1, 28)
+142: (2, 28)
+143: (3, 28)
+144: (4, 28)
+145: (0, 29)
+146: (1, 29)
+147: (2, 29)
+148: (3, 29)
+149: (4, 29)
+150: (0, 30)
+151: (1, 30)
+152: (2, 30)
+153: (3, 30)
+154: (4, 30)
+155: (0, 31)
+156: (1, 31)
+157: (2, 31)
+158: (3, 31)
+159: (4, 31)
+160: (0, 32)
+161: (1, 32)
+162: (2, 32)
+163: (3, 32)
+164: (4, 32)
+165: (0, 33)
+166: (1, 33)
+167: (2, 33)
+168: (3, 33)
+169: (4, 33)
+170: (0, 34)
+171: (1, 34)
+172: (2, 34)
+173: (3, 34)
+174: (4, 34)
+175: (0, 35)
+176: (1, 35)
+177: (2, 35)
+178: (3, 35)
+179: (4, 35)
+180: (0, 36)
+181: (1, 36)
+182: (2, 36)
+183: (3, 36)
+184: (4, 36)
+185: (0, 37)
+186: (1, 37)
+187: (2, 37)
+188: (3, 37)
+189: (4, 37)
+190: (0, 38)
+191: (1, 38)
+192: (2, 38)
+193: (3, 38)
+194: (4, 38)
+195: (0, 39)
+196: (1, 39)
+197: (2, 39)
+198: (3, 39)
+199: (4, 39)
+200: (0, 40)
+201: (1, 40)
+202: (2, 40)
+203: (3, 40)
+204: (4, 40)
+205: (0, 41)
+206: (1, 41)
+207: (2, 41)
+208: (3, 41)
+209: (4, 41)
+210: (0, 42)
+211: (1, 42)
+212: (2, 42)
+213: (3, 42)
+214: (4, 42)
+215: (0, 43)
+216: (1, 43)
+217: (2, 43)
+218: (3, 43)
+219: (4, 43)
+220: (0, 44)
+221: (1, 44)
+222: (2, 44)
+223: (3, 44)
+224: (4, 44)
+225: (0, 45)
+226: (1, 45)
+227: (2, 45)
+228: (3, 45)
+229: (4, 45)
+230: (0, 46)
+231: (1, 46)
+232: (2, 46)
+233: (3, 46)
+234: (4, 46)
+235: (0, 47)
+236: (1, 47)
+237: (2, 47)
+238: (3, 47)
+239: (4, 47)
+240: (0, 48)
+241: (1, 48)
+242: (2, 48)
+243: (3, 48)
+244: (4, 48)
+245: (0, 49)
+246: (1, 49)
+247: (2, 49)
+248: (3, 49)
+249: (4, 49)
+250: (0, 50)
+251: (1, 50)
+252: (2, 50)
+253: (3, 50)
+254: (4, 50)
+255: (0, 51)
+256: (1, 51)
+257: (2, 51)
+258: (3, 51)
+259: (4, 51)
+260: (0, 52)
+261: (1, 52)
+262: (2, 52)
+263: (3, 52)
+264: (4, 52)
+265: (0, 53)
+266: (1, 53)
+267: (2, 53)
+268: (3, 53)
+269: (4, 53)
+270: (0, 54)
+271: (1, 54)
+272: (2, 54)
+273: (3, 54)
+274: (4, 54)
+275: (0, 55)
+276: (1, 55)
+277: (2, 55)
+278: (3, 55)
+279: (4, 55)
+280: (0, 56)
+281: (1, 56)
+282: (2, 56)
+283: (3, 56)
+284: (4, 56)
+285: (0, 57)
+286: (1, 57)
+287: (2, 57)
+288: (3, 57)
+289: (4, 57)
+290: (0, 58)
+291: (1, 58)
+292: (2, 58)
+293: (3, 58)
+294: (4, 58)
+295: (0, 59)
+296: (1, 59)
+297: (2, 59)
+298: (3, 59)
+299: (4, 59)
+300: (0, 60)
+301: (1, 60)
+302: (2, 60)
+303: (3, 60)
+304: (4, 60)
+305: (0, 61)
+306: (1, 61)
+307: (2, 61)
+308: (3, 61)
+309: (4, 61)
+310: (0, 62)
+311: (1, 62)
+312: (2, 62)
+313: (3, 62)
+314: (4, 62)
+315: (0, 63)
+316: (1, 63)
+317: (2, 63)
+318: (3, 63)
+319: (4, 63)
+320: (0, 64)
+321: (1, 64)
+322: (2, 64)
+323: (3, 64)
+324: (4, 64)
+325: (0, 65)
+326: (1, 65)
+327: (2, 65)
+328: (3, 65)
+329: (4, 65)
+330: (0, 66)
+331: (1, 66)
+332: (2, 66)
+333: (3, 66)
+334: (4, 66)
+335: (0, 67)
+336: (1, 67)
+337: (2, 67)
+338: (3, 67)
+339: (4, 67)
+340: (0, 68)
+341: (1, 68)
+342: (2, 68)
+343: (3, 68)
+344: (4, 68)
+345: (0, 69)
+346: (1, 69)
+347: (2, 69)
+348: (3, 69)
+349: (4, 69)
+350: (0, 70)
+351: (1, 70)
+352: (2, 70)
+353: (3, 70)
+354: (4, 70)
+355: (0, 71)
+356: (1, 71)
+357: (2, 71)
+358: (3, 71)
+359: (4, 71)
+360: (0, 72)
+361: (1, 72)
+362: (2, 72)
+363: (3, 72)
+364: (4, 72)
+365: (0, 73)
+366: (1, 73)
+367: (2, 73)
+368: (3, 73)
+369: (4, 73)
+370: (0, 74)
+371: (1, 74)
+372: (2, 74)
+373: (3, 74)
+374: (4, 74)
+375: (0, 75)
+376: (1, 75)
+377: (2, 75)
+378: (3, 75)
+379: (4, 75)
+380: (0, 76)
+381: (1, 76)
+382: (2, 76)
+383: (3, 76)
+384: (4, 76)
+385: (0, 77)
+386: (1, 77)
+387: (2, 77)
+388: (3, 77)
+389: (4, 77)
+390: (0, 78)
+391: (1, 78)
+392: (2, 78)
+393: (3, 78)
+394: (4, 78)
+395: (0, 79)
+396: (1, 79)
+397: (2, 79)
+398: (3, 79)
+399: (4, 79)
+400: (0, 80)
+401: (1, 80)
+402: (2, 80)
+403: (3, 80)
+404: (4, 80)
+405: (0, 81)
+406: (1, 81)
+407: (2, 81)
+408: (3, 81)
+409: (4, 81)
+410: (0, 82)
+411: (1, 82)
+412: (2, 82)
+413: (3, 82)
+414: (4, 82)
+415: (0, 83)
+416: (1, 83)
+417: (2, 83)
+418: (3, 83)
+419: (4, 83)
+420: (0, 84)
+421: (1, 84)
+422: (2, 84)
+423: (3, 84)
+424: (4, 84)
+425: (0, 85)
+426: (1, 85)
+427: (2, 85)
+428: (3, 85)
+429: (4, 85)
+430: (0, 86)
+431: (1, 86)
+432: (2, 86)
+433: (3, 86)
+434: (4, 86)
+435: (0, 87)
+436: (1, 87)
+437: (2, 87)
+438: (3, 87)
+439: (4, 87)
+440: (0, 88)
+441: (1, 88)
+442: (2, 88)
+443: (3, 88)
+444: (4, 88)
+445: (0, 89)
+446: (1, 89)
+447: (2, 89)
+448: (3, 89)
+449: (4, 89)
+450: (0, 90)
+451: (1, 90)
+452: (2, 90)
+453: (3, 90)
+454: (4, 90)
+455: (0, 91)
+456: (1, 91)
+457: (2, 91)
+458: (3, 91)
+459: (4, 91)
+460: (0, 92)
+461: (1, 92)
+462: (2, 92)
+463: (3, 92)
+464: (4, 92)
+465: (0, 93)
+466: (1, 93)
+467: (2, 93)
+468: (3, 93)
+469: (4, 93)
+470: (0, 94)
+471: (1, 94)
+472: (2, 94)
+473: (3, 94)
+474: (4, 94)
+475: (0, 95)
+476: (1, 95)
+477: (2, 95)
+478: (3, 95)
+479: (4, 95)
+480: (0, 96)
+481: (1, 96)
+482: (2, 96)
+483: (3, 96)
+484: (4, 96)
+485: (0, 97)
+486: (1, 97)
+487: (2, 97)
+488: (3, 97)
+489: (4, 97)
+490: (0, 98)
+491: (1, 98)
+492: (2, 98)
+493: (3, 98)
+494: (4, 98)
+495: (0, 99)
+496: (1, 99)
+497: (2, 99)
+498: (3, 99)
+499: (4, 99)
+500: (0, 100)
+501: (1, 100)
+502: (2, 100)
+503: (3, 100)
+504: (4, 100)
+505: (0, 101)
+506: (1, 101)
+507: (2, 101)
+508: (3, 101)
+509: (4, 101)
+510: (0, 102)
+511: (1, 102)
+512: (2, 102)
+513: (3, 102)
+514: (4, 102)
+515: (0, 103)
+516: (1, 103)
+517: (2, 103)
+518: (3, 103)
+519: (4, 103)
+520: (0, 104)
+521: (1, 104)
+522: (2, 104)
+523: (3, 104)
+524: (4, 104)
+525: (0, 105)
+526: (1, 105)
+527: (2, 105)
+528: (3, 105)
+529: (4, 105)
+530: (0, 106)
+531: (1, 106)
+532: (2, 106)
+533: (3, 106)
+534: (4, 106)
+535: (0, 107)
+536: (1, 107)
+537: (2, 107)
+538: (3, 107)
+539: (4, 107)
+540: (0, 108)
+541: (1, 108)
+542: (2, 108)
+543: (3, 108)
+544: (4, 108)
+545: (1, 109)
+546: (2, 109)
+547: (3, 109)
+548: (4, 109)
+549: (1, 110)
+550: (2, 110)
+551: (3, 110)
+552: (4, 110)
+553: (1, 111)
+554: (2, 111)
+555: (3, 111)
+556: (4, 111)
+557: (1, 112)
+558: (2, 112)
+559: (3, 112)
+560: (4, 112)
+561: (1, 113)
+562: (2, 113)
+563: (3, 113)
+564: (4, 113)
+565: (1, 114)
+566: (2, 114)
+567: (3, 114)
+568: (4, 114)
+569: (1, 115)
+570: (2, 115)
+571: (3, 115)
+572: (1, 116)
+573: (2, 116)
+574: (3, 116)
+575: (1, 117)
+576: (3, 117)
+577: (1, 118)
+578: (3, 118)
+579: (1, 119)
+580: (3, 119)
+581: (1, 120)
+582: (3, 120)
+583: (3, 121)
+584: (3, 122)
+585: (3, 123)
+
+; Merges (added edges)
+; Format is:
+;   source_column -> dest_column
+; (new accuracy is source_column_accuracy + dest_column_accuracy + accuracy_change)
+; (note that all accuracies are unnormalized)
+
+108 -> 106
+178 -> 176
+3 -> 1
+128 -> 126
+113 -> 111
+218 -> 216
+268 -> 266
+73 -> 71
+263 -> 261
+78 -> 76
+585 -> 581
+223 -> 221
+133 -> 131
+173 -> 171
+83 -> 81
+258 -> 256
+273 -> 271
+213 -> 211
+138 -> 136
+123 -> 121
+118 -> 116
+183 -> 181
+243 -> 241
+103 -> 101
+253 -> 251
+248 -> 246
+188 -> 186
+8 -> 6
+153 -> 151
+228 -> 226
+143 -> 141
+238 -> 236
+148 -> 146
+233 -> 231
+278 -> 276
+168 -> 166
+68 -> 66
+158 -> 156
+403 -> 401
+88 -> 86
+53 -> 51
+163 -> 161
+98 -> 96
+208 -> 206
+193 -> 191
+13 -> 11
+48 -> 46
+58 -> 56
+290 -> 289
+93 -> 91
+283 -> 281
+584 -> 579
+203 -> 201
+63 -> 61
+285 -> 284
+198 -> 196
+4 -> 2
+288 -> 286
+408 -> 406
+583 -> 577
+9 -> 7
+14 -> 12
+398 -> 396
+94 -> 92
+255 -> 254
+19 -> 17
+89 -> 87
+25 -> 34
+43 -> 41
+225 -> 218
+99 -> 97
+305 -> 304
+30 -> 39
+35 -> 44
+250 -> 249
+24 -> 22
+38 -> 36
+160 -> 159
+310 -> 309
+155 -> 154
+295 -> 294
+315 -> 314
+280 -> 279
+293 -> 291
+33 -> 31
+27 -> 29
+18 -> 16
+300 -> 299
+275 -> 274
+185 -> 178
+23 -> 21
+55 -> 64
+28 -> 26
+223 -> 230
+582 -> 575
+220 -> 213
+180 -> 173
+60 -> 69
+298 -> 296
+74 -> 72
+357 -> 374
+183 -> 190
+188 -> 195
+362 -> 379
+104 -> 102
+320 -> 319
+84 -> 82
+228 -> 235
+40 -> 49
+79 -> 77
+393 -> 391
+260 -> 259
+270 -> 269
+59 -> 50
+233 -> 240
+325 -> 324
+238 -> 245
+150 -> 149
+32 -> 25
+54 -> 45
+265 -> 264
+175 -> 168
+193 -> 200
+215 -> 208
+367 -> 384
+27 -> 20
+165 -> 164
+388 -> 386
+573 -> 568
+62 -> 55
+60 -> 67
+550 -> 544
+170 -> 163
+198 -> 205
+210 -> 203
+570 -> 564
+65 -> 74
+413 -> 411
+250 -> 243
+383 -> 381
+566 -> 560
+109 -> 107
+548 -> 554
+580 -> 572
+145 -> 144
+30 -> 37
+418 -> 416
+369 -> 352
+24 -> 15
+562 -> 556
+303 -> 301
+558 -> 552
+378 -> 376
+140 -> 139
+165 -> 158
+175 -> 174
+248 -> 255
+423 -> 421
+35 -> 42
+170 -> 169
+160 -> 153
+244 -> 238
+578 -> 569
+412 -> 429
+373 -> 371
+179 -> 180
+424 -> 407
+400 -> 389
+428 -> 426
+308 -> 306
+433 -> 431
+368 -> 366
+70 -> 79
+135 -> 134
+313 -> 311
+57 -> 59
+576 -> 565
+239 -> 233
+188 -> 194
+318 -> 316
+323 -> 321
+253 -> 260
+574 -> 561
+189 -> 183
+330 -> 329
+184 -> 185
+193 -> 199
+19 -> 10
+516 -> 533
+258 -> 265
+571 -> 557
+234 -> 228
+114 -> 112
+521 -> 538
+54 -> 52
+155 -> 148
+438 -> 444
+395 -> 367
+47 -> 40
+531 -> 547
+204 -> 198
+443 -> 449
+567 -> 553
+207 -> 219
+417 -> 434
+541 -> 555
+543 -> 526
+551 -> 536
+263 -> 270
+563 -> 549
+448 -> 454
+559 -> 545
+546 -> 539
+573 -> 540
+453 -> 459
+328 -> 326
+209 -> 210
+458 -> 464
+394 -> 405
+214 -> 202
+363 -> 361
+327 -> 344
+450 -> 439
+463 -> 469
+75 -> 84
+364 -> 347
+268 -> 275
+292 -> 310
+334 -> 335
+420 -> 409
+414 -> 425
+468 -> 474
+333 -> 331
+150 -> 143
+359 -> 342
+305 -> 287
+332 -> 349
+338 -> 336
+297 -> 315
+130 -> 123
+113 -> 119
+528 -> 511
+354 -> 337
+145 -> 138
+419 -> 402
+343 -> 341
+523 -> 506
+339 -> 322
+372 -> 400
+125 -> 118
+229 -> 223
+542 -> 534
+302 -> 320
+358 -> 356
+273 -> 280
+224 -> 225
+348 -> 346
+353 -> 351
+300 -> 282
+140 -> 133
+129 -> 130
+135 -> 128
+570 -> 535
+307 -> 325
+473 -> 479
+436 -> 438
+80 -> 89
+14 -> 5
+518 -> 501
+177 -> 189
+390 -> 362
+182 -> 188
+184 -> 172
+214 -> 215
+382 -> 399
+192 -> 204
+295 -> 277
+209 -> 197
+441 -> 443
+193 -> 187
+394 -> 377
+175 -> 162
+267 -> 285
+170 -> 157
+387 -> 404
+207 -> 220
+448 -> 446
+312 -> 330
+566 -> 530
+179 -> 167
+3 -> 0
+165 -> 152
+478 -> 476
+453 -> 451
+290 -> 272
+385 -> 357
+414 -> 397
+458 -> 456
+160 -> 147
+513 -> 496
+124 -> 125
+483 -> 481
+382 -> 410
+115 -> 108
+120 -> 113
+420 -> 392
+562 -> 525
+427 -> 436
+440 -> 412
+415 -> 387
+417 -> 445
+98 -> 104
+432 -> 441
+334 -> 317
+419 -> 430
+437 -> 448
+339 -> 340
+85 -> 94
+477 -> 488
+463 -> 461
+450 -> 422
+473 -> 471
+99 -> 93
+212 -> 224
+468 -> 466
+278 -> 267
+109 -> 103
+273 -> 262
+258 -> 247
+217 -> 229
+442 -> 453
+268 -> 257
+88 -> 85
+450 -> 433
+486 -> 477
+478 -> 484
+155 -> 142
+483 -> 472
+283 -> 290
+491 -> 487
+417 -> 428
+482 -> 493
+83 -> 80
+435 -> 424
+263 -> 252
+253 -> 242
+403 -> 420
+9 -> 8
+447 -> 458
+408 -> 414
+415 -> 398
+537 -> 529
+78 -> 75
+393 -> 382
+497 -> 508
+30 -> 33
+394 -> 388
+440 -> 423
+435 -> 418
+363 -> 369
+359 -> 353
+48 -> 54
+419 -> 413
+18 -> 24
+558 -> 520
+510 -> 550
+73 -> 70
+32 -> 28
+503 -> 492
+115 -> 114
+548 -> 515
+354 -> 348
+57 -> 53
+38 -> 35
+19 -> 13
+372 -> 383
+68 -> 65
+532 -> 524
+47 -> 43
+222 -> 234
+395 -> 378
+60 -> 63
+364 -> 358
+427 -> 455
+521 -> 517
+390 -> 373
+385 -> 368
+546 -> 505
+62 -> 58
+343 -> 332
+528 -> 507
+248 -> 237
+295 -> 288
+516 -> 512
+531 -> 527
+452 -> 463
+542 -> 500
+543 -> 522
+27 -> 23
+338 -> 327
+135 -> 122
+513 -> 502
+244 -> 232
+239 -> 227
+432 -> 460
+150 -> 137
+129 -> 117
+90 -> 99
+585 -> 573
+498 -> 504
+127 -> 140
+4 -> 3
+437 -> 465
+483 -> 489
+110 -> 109
+486 -> 494
+478 -> 467
+482 -> 499
+300 -> 293
+145 -> 132
+473 -> 462
+380 -> 363
+468 -> 457
+333 -> 339
+584 -> 570
+559 -> 537
+442 -> 470
+354 -> 350
+298 -> 305
+334 -> 328
+323 -> 312
+360 -> 364
+338 -> 345
+359 -> 355
+303 -> 292
+318 -> 307
+105 -> 98
+297 -> 308
+503 -> 509
+497 -> 514
+313 -> 302
+541 -> 532
+447 -> 475
+546 -> 567
+563 -> 542
+510 -> 571
+583 -> 566
+548 -> 574
+551 -> 519
+558 -> 576
diff --git a/examples/U5.aln1.fasta.probs b/examples/U5.aln1.fasta.probs
new file mode 100644
index 0000000..a7829ab
--- /dev/null
+++ b/examples/U5.aln1.fasta.probs
@@ -0,0 +1,5984 @@
+; Sparse posterior probability matrix for sequences 0 and 1
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (1, 0) => 0.955781
+(0, 1) ~ (1, 0) => 0.0190555
+(0, 1) ~ (1, 1) => 0.912252
+(0, 1) ~ (1, 2) => 0.0105248
+(0, 1) ~ (1, 3) => 0.0133075
+(0, 2) ~ (1, 1) => 0.0209977
+(0, 2) ~ (1, 2) => 0.874424
+(0, 2) ~ (1, 3) => 0.0154671
+(0, 2) ~ (1, 4) => 0.0226548
+(0, 3) ~ (1, 1) => 0.0196753
+(0, 3) ~ (1, 2) => 0.0273041
+(0, 3) ~ (1, 3) => 0.726734
+(0, 3) ~ (1, 4) => 0.0157996
+(0, 3) ~ (1, 5) => 0.0953547
+(0, 4) ~ (1, 2) => 0.0319297
+(0, 4) ~ (1, 3) => 0.067984
+(0, 4) ~ (1, 4) => 0.680085
+(0, 4) ~ (1, 5) => 0.0116951
+(0, 4) ~ (1, 6) => 0.112408
+(0, 5) ~ (1, 3) => 0.0407208
+(0, 5) ~ (1, 4) => 0.0682074
+(0, 5) ~ (1, 5) => 0.647314
+(0, 5) ~ (1, 6) => 0.0131494
+(0, 5) ~ (1, 7) => 0.132174
+(0, 6) ~ (1, 4) => 0.0520418
+(0, 6) ~ (1, 5) => 0.0631816
+(0, 6) ~ (1, 6) => 0.569612
+(0, 6) ~ (1, 7) => 0.0161404
+(0, 6) ~ (1, 8) => 0.148254
+(0, 6) ~ (1, 9) => 0.0102426
+(0, 7) ~ (1, 5) => 0.067176
+(0, 7) ~ (1, 6) => 0.0678155
+(0, 7) ~ (1, 7) => 0.408404
+(0, 7) ~ (1, 8) => 0.0378794
+(0, 7) ~ (1, 9) => 0.158665
+(0, 7) ~ (1, 10) => 0.011368
+(0, 8) ~ (1, 6) => 0.118383
+(0, 8) ~ (1, 7) => 0.0637549
+(0, 8) ~ (1, 8) => 0.373476
+(0, 8) ~ (1, 9) => 0.0398726
+(0, 8) ~ (1, 10) => 0.139781
+(0, 8) ~ (1, 11) => 0.0156673
+(0, 9) ~ (1, 7) => 0.236134
+(0, 9) ~ (1, 8) => 0.0512678
+(0, 9) ~ (1, 9) => 0.342077
+(0, 9) ~ (1, 10) => 0.0401088
+(0, 9) ~ (1, 11) => 0.116978
+(0, 9) ~ (1, 12) => 0.0204481
+(0, 10) ~ (1, 8) => 0.272716
+(0, 10) ~ (1, 9) => 0.0392182
+(0, 10) ~ (1, 10) => 0.283308
+(0, 10) ~ (1, 11) => 0.0364696
+(0, 10) ~ (1, 12) => 0.071815
+(0, 10) ~ (1, 13) => 0.0236613
+(0, 11) ~ (1, 9) => 0.315187
+(0, 11) ~ (1, 10) => 0.0132011
+(0, 11) ~ (1, 11) => 0.218109
+(0, 11) ~ (1, 12) => 0.0246686
+(0, 11) ~ (1, 13) => 0.0253074
+(0, 11) ~ (1, 14) => 0.0274044
+(0, 12) ~ (1, 7) => 0.0102384
+(0, 12) ~ (1, 10) => 0.423171
+(0, 12) ~ (1, 11) => 0.0146818
+(0, 12) ~ (1, 12) => 0.161497
+(0, 12) ~ (1, 13) => 0.0228265
+(0, 12) ~ (1, 15) => 0.0233721
+(0, 13) ~ (1, 11) => 0.507985
+(0, 13) ~ (1, 13) => 0.104007
+(0, 13) ~ (1, 14) => 0.0187096
+(0, 13) ~ (1, 16) => 0.0218637
+(0, 14) ~ (1, 12) => 0.6349
+(0, 14) ~ (1, 14) => 0.0805833
+(0, 14) ~ (1, 15) => 0.0104555
+(0, 14) ~ (1, 17) => 0.0160535
+(0, 15) ~ (1, 13) => 0.75582
+(0, 15) ~ (1, 15) => 0.0792743
+(0, 15) ~ (1, 18) => 0.0119581
+(0, 16) ~ (1, 14) => 0.833899
+(0, 16) ~ (1, 16) => 0.0807219
+(0, 17) ~ (1, 15) => 0.855765
+(0, 17) ~ (1, 17) => 0.0759621
+(0, 18) ~ (1, 16) => 0.856102
+(0, 18) ~ (1, 17) => 0.0176095
+(0, 18) ~ (1, 18) => 0.0562912
+(0, 19) ~ (1, 17) => 0.866292
+(0, 19) ~ (1, 18) => 0.0194196
+(0, 19) ~ (1, 19) => 0.0474252
+(0, 20) ~ (1, 18) => 0.889104
+(0, 20) ~ (1, 19) => 0.0193283
+(0, 20) ~ (1, 20) => 0.0254255
+(0, 21) ~ (1, 19) => 0.90256
+(0, 21) ~ (1, 20) => 0.0158611
+(0, 22) ~ (1, 20) => 0.939409
+(0, 23) ~ (1, 21) => 0.98546
+(0, 24) ~ (1, 22) => 0.993083
+(0, 25) ~ (1, 23) => 0.995994
+(0, 26) ~ (1, 24) => 0.996037
+(0, 27) ~ (1, 25) => 0.994532
+(0, 28) ~ (1, 26) => 0.994573
+(0, 29) ~ (1, 27) => 0.995833
+(0, 30) ~ (1, 28) => 0.996636
+(0, 31) ~ (1, 29) => 0.998186
+(0, 32) ~ (1, 30) => 0.999387
+(0, 33) ~ (1, 31) => 0.999406
+(0, 34) ~ (1, 32) => 0.999465
+(0, 35) ~ (1, 33) => 0.99963
+(0, 36) ~ (1, 34) => 0.99986
+(0, 37) ~ (1, 35) => 0.999892
+(0, 38) ~ (1, 36) => 0.999828
+(0, 39) ~ (1, 37) => 0.999812
+(0, 40) ~ (1, 38) => 0.999558
+(0, 41) ~ (1, 39) => 0.999374
+(0, 42) ~ (1, 40) => 0.999371
+(0, 43) ~ (1, 41) => 0.999548
+(0, 44) ~ (1, 42) => 0.999853
+(0, 45) ~ (1, 43) => 0.999923
+(0, 46) ~ (1, 44) => 0.999877
+(0, 47) ~ (1, 45) => 0.9998
+(0, 48) ~ (1, 46) => 0.999748
+(0, 49) ~ (1, 47) => 0.999717
+(0, 50) ~ (1, 48) => 0.999573
+(0, 51) ~ (1, 49) => 0.998869
+(0, 52) ~ (1, 50) => 0.997224
+(0, 53) ~ (1, 51) => 0.995993
+(0, 54) ~ (1, 52) => 0.994468
+(0, 55) ~ (1, 53) => 0.991632
+(0, 56) ~ (1, 54) => 0.985606
+(0, 57) ~ (1, 55) => 0.944177
+(0, 58) ~ (1, 55) => 0.0265006
+(0, 58) ~ (1, 56) => 0.87153
+(0, 59) ~ (1, 56) => 0.0720967
+(0, 59) ~ (1, 57) => 0.608071
+(0, 60) ~ (1, 55) => 0.0101286
+(0, 60) ~ (1, 57) => 0.27671
+(0, 60) ~ (1, 58) => 0.312061
+(0, 60) ~ (1, 59) => 0.0232169
+(0, 60) ~ (1, 71) => 0.0120082
+(0, 61) ~ (1, 56) => 0.0182258
+(0, 61) ~ (1, 58) => 0.479357
+(0, 61) ~ (1, 59) => 0.169536
+(0, 61) ~ (1, 60) => 0.021815
+(0, 61) ~ (1, 72) => 0.0235455
+(0, 62) ~ (1, 57) => 0.0334257
+(0, 62) ~ (1, 59) => 0.57027
+(0, 62) ~ (1, 60) => 0.1132
+(0, 62) ~ (1, 61) => 0.0205684
+(0, 62) ~ (1, 73) => 0.0261783
+(0, 63) ~ (1, 58) => 0.0465739
+(0, 63) ~ (1, 60) => 0.603604
+(0, 63) ~ (1, 61) => 0.0937682
+(0, 63) ~ (1, 62) => 0.0196152
+(0, 63) ~ (1, 74) => 0.0267622
+(0, 64) ~ (1, 58) => 0.0227045
+(0, 64) ~ (1, 59) => 0.0496802
+(0, 64) ~ (1, 61) => 0.61879
+(0, 64) ~ (1, 62) => 0.0604561
+(0, 64) ~ (1, 63) => 0.0131166
+(0, 64) ~ (1, 75) => 0.0276561
+(0, 65) ~ (1, 57) => 0.0279173
+(0, 65) ~ (1, 59) => 0.038821
+(0, 65) ~ (1, 60) => 0.0374689
+(0, 65) ~ (1, 62) => 0.663667
+(0, 65) ~ (1, 63) => 0.0316686
+(0, 65) ~ (1, 64) => 0.0105141
+(0, 65) ~ (1, 76) => 0.0279244
+(0, 66) ~ (1, 58) => 0.0457541
+(0, 66) ~ (1, 60) => 0.0361892
+(0, 66) ~ (1, 61) => 0.0277136
+(0, 66) ~ (1, 62) => 0.0102296
+(0, 66) ~ (1, 63) => 0.730059
+(0, 66) ~ (1, 64) => 0.018464
+(0, 66) ~ (1, 65) => 0.0107454
+(0, 66) ~ (1, 77) => 0.027747
+(0, 67) ~ (1, 59) => 0.0512618
+(0, 67) ~ (1, 61) => 0.0298039
+(0, 67) ~ (1, 62) => 0.0160453
+(0, 67) ~ (1, 64) => 0.784292
+(0, 67) ~ (1, 66) => 0.012218
+(0, 67) ~ (1, 78) => 0.0277513
+(0, 68) ~ (1, 60) => 0.058744
+(0, 68) ~ (1, 62) => 0.0209999
+(0, 68) ~ (1, 65) => 0.843451
+(0, 68) ~ (1, 67) => 0.0118981
+(0, 68) ~ (1, 79) => 0.027428
+(0, 69) ~ (1, 61) => 0.0549642
+(0, 69) ~ (1, 66) => 0.871347
+(0, 69) ~ (1, 68) => 0.0110099
+(0, 69) ~ (1, 80) => 0.0276431
+(0, 70) ~ (1, 62) => 0.0551212
+(0, 70) ~ (1, 67) => 0.876962
+(0, 70) ~ (1, 69) => 0.0103075
+(0, 70) ~ (1, 81) => 0.027496
+(0, 71) ~ (1, 63) => 0.0539286
+(0, 71) ~ (1, 68) => 0.878775
+(0, 71) ~ (1, 82) => 0.0265814
+(0, 72) ~ (1, 64) => 0.0506046
+(0, 72) ~ (1, 69) => 0.878268
+(0, 72) ~ (1, 83) => 0.0255172
+(0, 73) ~ (1, 65) => 0.04286
+(0, 73) ~ (1, 69) => 0.0175811
+(0, 73) ~ (1, 70) => 0.852129
+(0, 73) ~ (1, 84) => 0.0213315
+(0, 74) ~ (1, 66) => 0.0375082
+(0, 74) ~ (1, 70) => 0.0559184
+(0, 74) ~ (1, 71) => 0.795584
+(0, 74) ~ (1, 85) => 0.0202562
+(0, 75) ~ (1, 67) => 0.0124091
+(0, 75) ~ (1, 71) => 0.142514
+(0, 75) ~ (1, 72) => 0.72986
+(0, 75) ~ (1, 86) => 0.0195303
+(0, 76) ~ (1, 72) => 0.202453
+(0, 76) ~ (1, 73) => 0.45246
+(0, 76) ~ (1, 74) => 0.0123025
+(0, 76) ~ (1, 87) => 0.0155426
+(0, 76) ~ (1, 92) => 0.010213
+(0, 77) ~ (1, 73) => 0.457994
+(0, 77) ~ (1, 74) => 0.329742
+(0, 77) ~ (1, 75) => 0.012425
+(0, 77) ~ (1, 93) => 0.0188961
+(0, 78) ~ (1, 72) => 0.011573
+(0, 78) ~ (1, 74) => 0.563981
+(0, 78) ~ (1, 75) => 0.274704
+(0, 78) ~ (1, 94) => 0.0209174
+(0, 79) ~ (1, 73) => 0.0160841
+(0, 79) ~ (1, 75) => 0.615566
+(0, 79) ~ (1, 76) => 0.252635
+(0, 79) ~ (1, 95) => 0.0210412
+(0, 80) ~ (1, 74) => 0.0158497
+(0, 80) ~ (1, 75) => 0.0153541
+(0, 80) ~ (1, 76) => 0.636336
+(0, 80) ~ (1, 77) => 0.18752
+(0, 80) ~ (1, 96) => 0.0200879
+(0, 81) ~ (1, 75) => 0.0110017
+(0, 81) ~ (1, 76) => 0.0218454
+(0, 81) ~ (1, 77) => 0.681897
+(0, 81) ~ (1, 78) => 0.159055
+(0, 81) ~ (1, 97) => 0.0191894
+(0, 82) ~ (1, 77) => 0.0489473
+(0, 82) ~ (1, 78) => 0.666442
+(0, 82) ~ (1, 79) => 0.158616
+(0, 82) ~ (1, 98) => 0.0190439
+(0, 83) ~ (1, 78) => 0.0950423
+(0, 83) ~ (1, 79) => 0.664043
+(0, 83) ~ (1, 80) => 0.151967
+(0, 83) ~ (1, 99) => 0.0181822
+(0, 84) ~ (1, 79) => 0.101157
+(0, 84) ~ (1, 80) => 0.666437
+(0, 84) ~ (1, 81) => 0.140836
+(0, 84) ~ (1, 98) => 0.0111528
+(0, 84) ~ (1, 100) => 0.0175403
+(0, 85) ~ (1, 80) => 0.112392
+(0, 85) ~ (1, 81) => 0.663204
+(0, 85) ~ (1, 82) => 0.134625
+(0, 85) ~ (1, 99) => 0.0155553
+(0, 85) ~ (1, 101) => 0.0175376
+(0, 86) ~ (1, 81) => 0.118388
+(0, 86) ~ (1, 82) => 0.666099
+(0, 86) ~ (1, 83) => 0.124511
+(0, 86) ~ (1, 100) => 0.0205257
+(0, 86) ~ (1, 102) => 0.0179841
+(0, 87) ~ (1, 82) => 0.109186
+(0, 87) ~ (1, 83) => 0.68696
+(0, 87) ~ (1, 84) => 0.0648237
+(0, 87) ~ (1, 101) => 0.0216128
+(0, 87) ~ (1, 103) => 0.0174105
+(0, 88) ~ (1, 83) => 0.0885205
+(0, 88) ~ (1, 84) => 0.768023
+(0, 88) ~ (1, 85) => 0.0537249
+(0, 88) ~ (1, 102) => 0.0247279
+(0, 88) ~ (1, 104) => 0.0168926
+(0, 89) ~ (1, 84) => 0.0608595
+(0, 89) ~ (1, 85) => 0.798675
+(0, 89) ~ (1, 86) => 0.0592958
+(0, 89) ~ (1, 103) => 0.0252848
+(0, 89) ~ (1, 105) => 0.0135127
+(0, 90) ~ (1, 85) => 0.0395198
+(0, 90) ~ (1, 86) => 0.823114
+(0, 90) ~ (1, 87) => 0.0573967
+(0, 90) ~ (1, 104) => 0.0232005
+(0, 90) ~ (1, 105) => 0.0117404
+(0, 90) ~ (1, 106) => 0.010847
+(0, 91) ~ (1, 86) => 0.0339333
+(0, 91) ~ (1, 87) => 0.824811
+(0, 91) ~ (1, 88) => 0.0581789
+(0, 91) ~ (1, 105) => 0.0216241
+(0, 91) ~ (1, 106) => 0.0187687
+(0, 92) ~ (1, 87) => 0.0311315
+(0, 92) ~ (1, 88) => 0.82324
+(0, 92) ~ (1, 89) => 0.0582241
+(0, 92) ~ (1, 106) => 0.0196918
+(0, 92) ~ (1, 107) => 0.02349
+(0, 93) ~ (1, 88) => 0.027998
+(0, 93) ~ (1, 89) => 0.820855
+(0, 93) ~ (1, 90) => 0.0578087
+(0, 93) ~ (1, 107) => 0.0173348
+(0, 93) ~ (1, 108) => 0.028051
+(0, 94) ~ (1, 89) => 0.0242389
+(0, 94) ~ (1, 90) => 0.816347
+(0, 94) ~ (1, 91) => 0.0564935
+(0, 94) ~ (1, 108) => 0.0133212
+(0, 94) ~ (1, 109) => 0.0355269
+(0, 95) ~ (1, 90) => 0.0187092
+(0, 95) ~ (1, 91) => 0.806331
+(0, 95) ~ (1, 92) => 0.0527142
+(0, 95) ~ (1, 94) => 0.0102272
+(0, 95) ~ (1, 110) => 0.0557606
+(0, 96) ~ (1, 91) => 0.0116151
+(0, 96) ~ (1, 92) => 0.790989
+(0, 96) ~ (1, 93) => 0.0522624
+(0, 96) ~ (1, 95) => 0.0155777
+(0, 96) ~ (1, 111) => 0.0698909
+(0, 97) ~ (1, 92) => 0.0103297
+(0, 97) ~ (1, 93) => 0.759073
+(0, 97) ~ (1, 94) => 0.0471455
+(0, 97) ~ (1, 96) => 0.0189512
+(0, 97) ~ (1, 112) => 0.0779562
+(0, 98) ~ (1, 94) => 0.735282
+(0, 98) ~ (1, 95) => 0.0431647
+(0, 98) ~ (1, 97) => 0.0223802
+(0, 98) ~ (1, 113) => 0.0825924
+(0, 99) ~ (1, 95) => 0.617237
+(0, 99) ~ (1, 96) => 0.0472389
+(0, 99) ~ (1, 97) => 0.0140068
+(0, 99) ~ (1, 98) => 0.0406061
+(0, 99) ~ (1, 99) => 0.0107393
+(0, 99) ~ (1, 101) => 0.0100058
+(0, 99) ~ (1, 105) => 0.0159537
+(0, 99) ~ (1, 106) => 0.0256216
+(0, 99) ~ (1, 110) => 0.0111619
+(0, 99) ~ (1, 114) => 0.101145
+(0, 100) ~ (1, 95) => 0.0137526
+(0, 100) ~ (1, 96) => 0.534565
+(0, 100) ~ (1, 97) => 0.0514532
+(0, 100) ~ (1, 98) => 0.0211864
+(0, 100) ~ (1, 99) => 0.0473042
+(0, 100) ~ (1, 102) => 0.0204327
+(0, 100) ~ (1, 106) => 0.0201189
+(0, 100) ~ (1, 107) => 0.0344597
+(0, 100) ~ (1, 111) => 0.0132619
+(0, 100) ~ (1, 113) => 0.0102198
+(0, 100) ~ (1, 115) => 0.123609
+(0, 100) ~ (1, 116) => 0.0112084
+(0, 101) ~ (1, 97) => 0.230517
+(0, 101) ~ (1, 98) => 0.0372257
+(0, 101) ~ (1, 99) => 0.0634879
+(0, 101) ~ (1, 100) => 0.0953402
+(0, 101) ~ (1, 101) => 0.0176806
+(0, 101) ~ (1, 102) => 0.0134453
+(0, 101) ~ (1, 103) => 0.0928785
+(0, 101) ~ (1, 107) => 0.0453404
+(0, 101) ~ (1, 108) => 0.0819846
+(0, 101) ~ (1, 109) => 0.0118031
+(0, 101) ~ (1, 112) => 0.0108352
+(0, 101) ~ (1, 113) => 0.0190053
+(0, 101) ~ (1, 116) => 0.139159
+(0, 101) ~ (1, 117) => 0.0284953
+(0, 102) ~ (1, 98) => 0.0434527
+(0, 102) ~ (1, 99) => 0.0245287
+(0, 102) ~ (1, 100) => 0.0999212
+(0, 102) ~ (1, 101) => 0.144747
+(0, 102) ~ (1, 102) => 0.0255465
+(0, 102) ~ (1, 103) => 0.0218414
+(0, 102) ~ (1, 104) => 0.0979418
+(0, 102) ~ (1, 108) => 0.0712781
+(0, 102) ~ (1, 109) => 0.080708
+(0, 102) ~ (1, 110) => 0.0182407
+(0, 102) ~ (1, 114) => 0.0342098
+(0, 102) ~ (1, 117) => 0.158208
+(0, 102) ~ (1, 118) => 0.0498651
+(0, 103) ~ (1, 100) => 0.0246746
+(0, 103) ~ (1, 101) => 0.0873146
+(0, 103) ~ (1, 102) => 0.133846
+(0, 103) ~ (1, 103) => 0.0118895
+(0, 103) ~ (1, 104) => 0.0315775
+(0, 103) ~ (1, 105) => 0.0616888
+(0, 103) ~ (1, 109) => 0.116685
+(0, 103) ~ (1, 110) => 0.0488048
+(0, 103) ~ (1, 111) => 0.0531044
+(0, 103) ~ (1, 113) => 0.0107438
+(0, 103) ~ (1, 115) => 0.0630268
+(0, 103) ~ (1, 117) => 0.010401
+(0, 103) ~ (1, 118) => 0.149638
+(0, 103) ~ (1, 119) => 0.0471877
+(0, 104) ~ (1, 101) => 0.0136559
+(0, 104) ~ (1, 102) => 0.0327547
+(0, 104) ~ (1, 103) => 0.0753044
+(0, 104) ~ (1, 105) => 0.0268471
+(0, 104) ~ (1, 106) => 0.0610189
+(0, 104) ~ (1, 110) => 0.123405
+(0, 104) ~ (1, 111) => 0.0433962
+(0, 104) ~ (1, 112) => 0.11614
+(0, 104) ~ (1, 113) => 0.0286055
+(0, 104) ~ (1, 114) => 0.022368
+(0, 104) ~ (1, 116) => 0.115763
+(0, 104) ~ (1, 119) => 0.0460151
+(0, 104) ~ (1, 120) => 0.0395558
+(0, 105) ~ (1, 102) => 0.0111706
+(0, 105) ~ (1, 103) => 0.0162446
+(0, 105) ~ (1, 104) => 0.0338363
+(0, 105) ~ (1, 106) => 0.0149514
+(0, 105) ~ (1, 107) => 0.0518803
+(0, 105) ~ (1, 111) => 0.114171
+(0, 105) ~ (1, 112) => 0.0411473
+(0, 105) ~ (1, 113) => 0.149986
+(0, 105) ~ (1, 114) => 0.0495592
+(0, 105) ~ (1, 115) => 0.0353493
+(0, 105) ~ (1, 117) => 0.146158
+(0, 105) ~ (1, 120) => 0.0280593
+(0, 106) ~ (1, 103) => 0.0128672
+(0, 106) ~ (1, 105) => 0.0189441
+(0, 106) ~ (1, 108) => 0.0482931
+(0, 106) ~ (1, 112) => 0.0703195
+(0, 106) ~ (1, 113) => 0.0452992
+(0, 106) ~ (1, 114) => 0.150449
+(0, 106) ~ (1, 115) => 0.0507409
+(0, 106) ~ (1, 116) => 0.0333239
+(0, 106) ~ (1, 118) => 0.241952
+(0, 107) ~ (1, 104) => 0.0172431
+(0, 107) ~ (1, 109) => 0.046614
+(0, 107) ~ (1, 113) => 0.0286193
+(0, 107) ~ (1, 114) => 0.0189649
+(0, 107) ~ (1, 115) => 0.0817706
+(0, 107) ~ (1, 117) => 0.031447
+(0, 107) ~ (1, 118) => 0.0145906
+(0, 107) ~ (1, 119) => 0.592633
+(0, 108) ~ (1, 105) => 0.0151487
+(0, 108) ~ (1, 110) => 0.0403175
+(0, 108) ~ (1, 114) => 0.022777
+(0, 108) ~ (1, 115) => 0.0161006
+(0, 108) ~ (1, 116) => 0.0741007
+(0, 108) ~ (1, 118) => 0.0212062
+(0, 108) ~ (1, 119) => 0.0109562
+(0, 108) ~ (1, 120) => 0.676778
+
+; gap posteriors
+(0, 0) ~ (1, -1) => 0.0442191
+(0, 1) ~ (1, -1) => 0.0448606
+(0, 2) ~ (1, -1) => 0.0664562
+(0, 3) ~ (1, -1) => 0.115133
+(0, 4) ~ (1, -1) => 0.0958986
+(0, 5) ~ (1, -1) => 0.0984342
+(0, 6) ~ (1, -1) => 0.140528
+(0, 7) ~ (1, -1) => 0.248691
+(0, 8) ~ (1, -1) => 0.249066
+(0, 9) ~ (1, -1) => 0.192987
+(0, 10) ~ (1, -1) => 0.272812
+(0, 11) ~ (1, -1) => 0.376122
+(0, 12) ~ (1, -1) => 0.344213
+(0, 13) ~ (1, -1) => 0.347435
+(0, 14) ~ (1, -1) => 0.258008
+(0, 15) ~ (1, -1) => 0.152947
+(0, 16) ~ (1, -1) => 0.0853793
+(0, 17) ~ (1, -1) => 0.068273
+(0, 18) ~ (1, -1) => 0.0699971
+(0, 19) ~ (1, -1) => 0.0668631
+(0, 20) ~ (1, -1) => 0.0661417
+(0, 21) ~ (1, -1) => 0.0815793
+(0, 22) ~ (1, -1) => 0.0605909
+(0, 23) ~ (1, -1) => 0.0145403
+(0, 24) ~ (1, -1) => 0.00691658
+(0, 25) ~ (1, -1) => 0.00400645
+(0, 26) ~ (1, -1) => 0.00396299
+(0, 27) ~ (1, -1) => 0.00546825
+(0, 28) ~ (1, -1) => 0.00542748
+(0, 29) ~ (1, -1) => 0.00416726
+(0, 30) ~ (1, -1) => 0.00336421
+(0, 31) ~ (1, -1) => 0.00181377
+(0, 32) ~ (1, -1) => 0.000612557
+(0, 33) ~ (1, -1) => 0.000594258
+(0, 34) ~ (1, -1) => 0.000535309
+(0, 35) ~ (1, -1) => 0.000370204
+(0, 36) ~ (1, -1) => 0.000140488
+(0, 37) ~ (1, -1) => 0.000108242
+(0, 38) ~ (1, -1) => 0.000171959
+(0, 39) ~ (1, -1) => 0.000187516
+(0, 40) ~ (1, -1) => 0.000442266
+(0, 41) ~ (1, -1) => 0.000625849
+(0, 42) ~ (1, -1) => 0.000629306
+(0, 43) ~ (1, -1) => 0.000451684
+(0, 44) ~ (1, -1) => 0.000146925
+(0, 45) ~ (1, -1) => 0.0001
+(0, 46) ~ (1, -1) => 0.000122845
+(0, 47) ~ (1, -1) => 0.000199974
+(0, 48) ~ (1, -1) => 0.000251591
+(0, 49) ~ (1, -1) => 0.000282645
+(0, 50) ~ (1, -1) => 0.000427306
+(0, 51) ~ (1, -1) => 0.00113058
+(0, 52) ~ (1, -1) => 0.00277579
+(0, 53) ~ (1, -1) => 0.0040071
+(0, 54) ~ (1, -1) => 0.00553179
+(0, 55) ~ (1, -1) => 0.00836772
+(0, 56) ~ (1, -1) => 0.0143945
+(0, 57) ~ (1, -1) => 0.0558231
+(0, 58) ~ (1, -1) => 0.101969
+(0, 59) ~ (1, -1) => 0.319832
+(0, 60) ~ (1, -1) => 0.365875
+(0, 61) ~ (1, -1) => 0.287521
+(0, 62) ~ (1, -1) => 0.236358
+(0, 63) ~ (1, -1) => 0.209676
+(0, 64) ~ (1, -1) => 0.207596
+(0, 65) ~ (1, -1) => 0.162018
+(0, 66) ~ (1, -1) => 0.0930976
+(0, 67) ~ (1, -1) => 0.0786276
+(0, 68) ~ (1, -1) => 0.0374794
+(0, 69) ~ (1, -1) => 0.035036
+(0, 70) ~ (1, -1) => 0.0301134
+(0, 71) ~ (1, -1) => 0.0407152
+(0, 72) ~ (1, -1) => 0.0456103
+(0, 73) ~ (1, -1) => 0.0660981
+(0, 74) ~ (1, -1) => 0.0907334
+(0, 75) ~ (1, -1) => 0.0956865
+(0, 76) ~ (1, -1) => 0.307029
+(0, 77) ~ (1, -1) => 0.180943
+(0, 78) ~ (1, -1) => 0.128825
+(0, 79) ~ (1, -1) => 0.0946744
+(0, 80) ~ (1, -1) => 0.124853
+(0, 81) ~ (1, -1) => 0.107012
+(0, 82) ~ (1, -1) => 0.10695
+(0, 83) ~ (1, -1) => 0.0707652
+(0, 84) ~ (1, -1) => 0.062877
+(0, 85) ~ (1, -1) => 0.0566865
+(0, 86) ~ (1, -1) => 0.052492
+(0, 87) ~ (1, -1) => 0.100007
+(0, 88) ~ (1, -1) => 0.048111
+(0, 89) ~ (1, -1) => 0.0423725
+(0, 90) ~ (1, -1) => 0.0341812
+(0, 91) ~ (1, -1) => 0.0426841
+(0, 92) ~ (1, -1) => 0.0442227
+(0, 93) ~ (1, -1) => 0.0479523
+(0, 94) ~ (1, -1) => 0.0540726
+(0, 95) ~ (1, -1) => 0.0562578
+(0, 96) ~ (1, -1) => 0.0596652
+(0, 97) ~ (1, -1) => 0.0865443
+(0, 98) ~ (1, -1) => 0.116581
+(0, 99) ~ (1, -1) => 0.106284
+(0, 100) ~ (1, -1) => 0.0984284
+(0, 101) ~ (1, -1) => 0.112802
+(0, 102) ~ (1, -1) => 0.129511
+(0, 103) ~ (1, -1) => 0.149417
+(0, 104) ~ (1, -1) => 0.25517
+(0, 105) ~ (1, -1) => 0.307486
+(0, 106) ~ (1, -1) => 0.327812
+(0, 107) ~ (1, -1) => 0.168117
+(0, 108) ~ (1, -1) => 0.122615
+
+(0, -1) ~ (1, 0) => 0.0251636
+(0, -1) ~ (1, 1) => 0.0470754
+(0, -1) ~ (1, 2) => 0.0558171
+(0, -1) ~ (1, 3) => 0.135787
+(0, -1) ~ (1, 4) => 0.161212
+(0, -1) ~ (1, 5) => 0.115278
+(0, -1) ~ (1, 6) => 0.118633
+(0, -1) ~ (1, 7) => 0.133154
+(0, -1) ~ (1, 8) => 0.116408
+(0, -1) ~ (1, 9) => 0.0947371
+(0, -1) ~ (1, 10) => 0.0890624
+(0, -1) ~ (1, 11) => 0.0901092
+(0, -1) ~ (1, 12) => 0.0866719
+(0, -1) ~ (1, 13) => 0.0683777
+(0, -1) ~ (1, 14) => 0.0394039
+(0, -1) ~ (1, 15) => 0.0311331
+(0, -1) ~ (1, 16) => 0.0413123
+(0, -1) ~ (1, 17) => 0.0240828
+(0, -1) ~ (1, 18) => 0.0232266
+(0, -1) ~ (1, 19) => 0.0306869
+(0, -1) ~ (1, 20) => 0.0193044
+(0, -1) ~ (1, 21) => 0.0145403
+(0, -1) ~ (1, 22) => 0.00691658
+(0, -1) ~ (1, 23) => 0.00400645
+(0, -1) ~ (1, 24) => 0.00396299
+(0, -1) ~ (1, 25) => 0.00546825
+(0, -1) ~ (1, 26) => 0.00542748
+(0, -1) ~ (1, 27) => 0.00416726
+(0, -1) ~ (1, 28) => 0.00336421
+(0, -1) ~ (1, 29) => 0.00181377
+(0, -1) ~ (1, 30) => 0.000612557
+(0, -1) ~ (1, 31) => 0.000594258
+(0, -1) ~ (1, 32) => 0.000535309
+(0, -1) ~ (1, 33) => 0.000370204
+(0, -1) ~ (1, 34) => 0.000140488
+(0, -1) ~ (1, 35) => 0.000108242
+(0, -1) ~ (1, 36) => 0.000171959
+(0, -1) ~ (1, 37) => 0.000187516
+(0, -1) ~ (1, 38) => 0.000442266
+(0, -1) ~ (1, 39) => 0.000625849
+(0, -1) ~ (1, 40) => 0.000629306
+(0, -1) ~ (1, 41) => 0.000451684
+(0, -1) ~ (1, 42) => 0.000146925
+(0, -1) ~ (1, 43) => 0.0001
+(0, -1) ~ (1, 44) => 0.000122845
+(0, -1) ~ (1, 45) => 0.000199974
+(0, -1) ~ (1, 46) => 0.000251591
+(0, -1) ~ (1, 47) => 0.000282645
+(0, -1) ~ (1, 48) => 0.000427306
+(0, -1) ~ (1, 49) => 0.00113058
+(0, -1) ~ (1, 50) => 0.00277579
+(0, -1) ~ (1, 51) => 0.0040071
+(0, -1) ~ (1, 52) => 0.00553179
+(0, -1) ~ (1, 53) => 0.00836772
+(0, -1) ~ (1, 54) => 0.0143945
+(0, -1) ~ (1, 55) => 0.019194
+(0, -1) ~ (1, 56) => 0.0381474
+(0, -1) ~ (1, 57) => 0.0538763
+(0, -1) ~ (1, 58) => 0.0935495
+(0, -1) ~ (1, 59) => 0.0972144
+(0, -1) ~ (1, 60) => 0.128978
+(0, -1) ~ (1, 61) => 0.154392
+(0, -1) ~ (1, 62) => 0.153865
+(0, -1) ~ (1, 63) => 0.171227
+(0, -1) ~ (1, 64) => 0.136125
+(0, -1) ~ (1, 65) => 0.102944
+(0, -1) ~ (1, 66) => 0.0789269
+(0, -1) ~ (1, 67) => 0.098731
+(0, -1) ~ (1, 68) => 0.110215
+(0, -1) ~ (1, 69) => 0.0938435
+(0, -1) ~ (1, 70) => 0.0919522
+(0, -1) ~ (1, 71) => 0.0498935
+(0, -1) ~ (1, 72) => 0.0325683
+(0, -1) ~ (1, 73) => 0.0472838
+(0, -1) ~ (1, 74) => 0.0513622
+(0, -1) ~ (1, 75) => 0.0432935
+(0, -1) ~ (1, 76) => 0.0612597
+(0, -1) ~ (1, 77) => 0.0538893
+(0, -1) ~ (1, 78) => 0.0517092
+(0, -1) ~ (1, 79) => 0.0487552
+(0, -1) ~ (1, 80) => 0.0415613
+(0, -1) ~ (1, 81) => 0.0500764
+(0, -1) ~ (1, 82) => 0.0635084
+(0, -1) ~ (1, 83) => 0.0744907
+(0, -1) ~ (1, 84) => 0.0849623
+(0, -1) ~ (1, 85) => 0.0878246
+(0, -1) ~ (1, 86) => 0.0641261
+(0, -1) ~ (1, 87) => 0.0711183
+(0, -1) ~ (1, 88) => 0.0905832
+(0, -1) ~ (1, 89) => 0.0966819
+(0, -1) ~ (1, 90) => 0.107135
+(0, -1) ~ (1, 91) => 0.12556
+(0, -1) ~ (1, 92) => 0.135754
+(0, -1) ~ (1, 93) => 0.169768
+(0, -1) ~ (1, 94) => 0.186428
+(0, -1) ~ (1, 95) => 0.289226
+(0, -1) ~ (1, 96) => 0.379157
+(0, -1) ~ (1, 97) => 0.662453
+(0, -1) ~ (1, 98) => 0.827332
+(0, -1) ~ (1, 99) => 0.820202
+(0, -1) ~ (1, 100) => 0.741998
+(0, -1) ~ (1, 101) => 0.687446
+(0, -1) ~ (1, 102) => 0.720092
+(0, -1) ~ (1, 103) => 0.726279
+(0, -1) ~ (1, 104) => 0.779308
+(0, -1) ~ (1, 105) => 0.814541
+(0, -1) ~ (1, 106) => 0.828982
+(0, -1) ~ (1, 107) => 0.827495
+(0, -1) ~ (1, 108) => 0.757072
+(0, -1) ~ (1, 109) => 0.708663
+(0, -1) ~ (1, 110) => 0.702309
+(0, -1) ~ (1, 111) => 0.706176
+(0, -1) ~ (1, 112) => 0.683602
+(0, -1) ~ (1, 113) => 0.624928
+(0, -1) ~ (1, 114) => 0.600527
+(0, -1) ~ (1, 115) => 0.629403
+(0, -1) ~ (1, 116) => 0.626445
+(0, -1) ~ (1, 117) => 0.62529
+(0, -1) ~ (1, 118) => 0.522749
+(0, -1) ~ (1, 119) => 0.303208
+(0, -1) ~ (1, 120) => 0.255607
+
+; Sparse posterior probability matrix for sequences 0 and 2
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (2, 0) => 0.13347
+(0, 0) ~ (2, 1) => 0.859029
+(0, 1) ~ (2, 1) => 0.0182693
+(0, 1) ~ (2, 2) => 0.974051
+(0, 2) ~ (2, 3) => 0.994328
+(0, 3) ~ (2, 4) => 0.998345
+(0, 4) ~ (2, 5) => 0.999238
+(0, 5) ~ (2, 6) => 0.999476
+(0, 6) ~ (2, 7) => 0.999192
+(0, 7) ~ (2, 8) => 0.998642
+(0, 8) ~ (2, 9) => 0.996309
+(0, 9) ~ (2, 10) => 0.996466
+(0, 10) ~ (2, 11) => 0.997562
+(0, 11) ~ (2, 12) => 0.999201
+(0, 12) ~ (2, 13) => 0.999098
+(0, 13) ~ (2, 14) => 0.998934
+(0, 14) ~ (2, 15) => 0.996929
+(0, 15) ~ (2, 16) => 0.991021
+(0, 16) ~ (2, 17) => 0.981556
+(0, 17) ~ (2, 18) => 0.921234
+(0, 17) ~ (2, 19) => 0.0191206
+(0, 18) ~ (2, 19) => 0.669417
+(0, 18) ~ (2, 20) => 0.04944
+(0, 19) ~ (2, 20) => 0.217216
+(0, 19) ~ (2, 21) => 0.0494654
+(0, 20) ~ (2, 19) => 0.0763835
+(0, 20) ~ (2, 21) => 0.152628
+(0, 20) ~ (2, 22) => 0.0299022
+(0, 21) ~ (2, 19) => 0.0216768
+(0, 21) ~ (2, 20) => 0.46137
+(0, 21) ~ (2, 22) => 0.0548227
+(0, 21) ~ (2, 23) => 0.0167674
+(0, 22) ~ (2, 21) => 0.542275
+(0, 22) ~ (2, 24) => 0.0103477
+(0, 23) ~ (2, 18) => 0.026181
+(0, 23) ~ (2, 20) => 0.0132822
+(0, 23) ~ (2, 22) => 0.60977
+(0, 24) ~ (2, 18) => 0.0126957
+(0, 24) ~ (2, 19) => 0.136091
+(0, 24) ~ (2, 20) => 0.011321
+(0, 24) ~ (2, 21) => 0.016028
+(0, 24) ~ (2, 23) => 0.352329
+(0, 25) ~ (2, 19) => 0.0235385
+(0, 25) ~ (2, 20) => 0.161705
+(0, 25) ~ (2, 21) => 0.0109455
+(0, 25) ~ (2, 22) => 0.0677881
+(0, 25) ~ (2, 23) => 0.0134744
+(0, 25) ~ (2, 24) => 0.26465
+(0, 26) ~ (2, 20) => 0.0256202
+(0, 26) ~ (2, 21) => 0.0310658
+(0, 26) ~ (2, 23) => 0.535806
+(0, 26) ~ (2, 25) => 0.238174
+(0, 27) ~ (2, 21) => 0.015557
+(0, 27) ~ (2, 22) => 0.0146573
+(0, 27) ~ (2, 24) => 0.670523
+(0, 27) ~ (2, 26) => 0.208743
+(0, 28) ~ (2, 23) => 0.0142464
+(0, 28) ~ (2, 25) => 0.726461
+(0, 28) ~ (2, 27) => 0.11989
+(0, 29) ~ (2, 24) => 0.011089
+(0, 29) ~ (2, 26) => 0.7621
+(0, 29) ~ (2, 28) => 0.03191
+(0, 30) ~ (2, 27) => 0.862484
+(0, 31) ~ (2, 28) => 0.958084
+(0, 32) ~ (2, 29) => 0.993327
+(0, 33) ~ (2, 30) => 0.994226
+(0, 34) ~ (2, 31) => 0.995296
+(0, 35) ~ (2, 32) => 0.995921
+(0, 36) ~ (2, 33) => 0.997086
+(0, 37) ~ (2, 34) => 0.999681
+(0, 38) ~ (2, 35) => 0.999349
+(0, 39) ~ (2, 36) => 0.998953
+(0, 40) ~ (2, 37) => 0.99242
+(0, 41) ~ (2, 38) => 0.986219
+(0, 42) ~ (2, 38) => 0.0109901
+(0, 42) ~ (2, 39) => 0.980183
+(0, 43) ~ (2, 39) => 0.0159384
+(0, 43) ~ (2, 40) => 0.974269
+(0, 44) ~ (2, 40) => 0.0207285
+(0, 44) ~ (2, 41) => 0.958618
+(0, 45) ~ (2, 41) => 0.036216
+(0, 45) ~ (2, 42) => 0.889383
+(0, 46) ~ (2, 42) => 0.101968
+(0, 46) ~ (2, 43) => 0.853718
+(0, 47) ~ (2, 43) => 0.13459
+(0, 47) ~ (2, 44) => 0.745057
+(0, 48) ~ (2, 44) => 0.235842
+(0, 48) ~ (2, 45) => 0.635304
+(0, 49) ~ (2, 44) => 0.0134665
+(0, 49) ~ (2, 45) => 0.334652
+(0, 49) ~ (2, 46) => 0.534847
+(0, 50) ~ (2, 45) => 0.0204611
+(0, 50) ~ (2, 46) => 0.434325
+(0, 50) ~ (2, 47) => 0.243132
+(0, 51) ~ (2, 46) => 0.014603
+(0, 51) ~ (2, 47) => 0.735247
+(0, 51) ~ (2, 48) => 0.14021
+(0, 52) ~ (2, 48) => 0.844699
+(0, 52) ~ (2, 49) => 0.106662
+(0, 53) ~ (2, 49) => 0.878277
+(0, 53) ~ (2, 50) => 0.0729474
+(0, 54) ~ (2, 50) => 0.912487
+(0, 54) ~ (2, 51) => 0.0378245
+(0, 55) ~ (2, 51) => 0.94663
+(0, 55) ~ (2, 52) => 0.0359206
+(0, 56) ~ (2, 52) => 0.933448
+(0, 56) ~ (2, 53) => 0.0379663
+(0, 57) ~ (2, 53) => 0.928829
+(0, 57) ~ (2, 54) => 0.0401115
+(0, 58) ~ (2, 52) => 0.017165
+(0, 58) ~ (2, 54) => 0.921743
+(0, 58) ~ (2, 55) => 0.0130406
+(0, 59) ~ (2, 53) => 0.0224117
+(0, 59) ~ (2, 55) => 0.949528
+(0, 60) ~ (2, 54) => 0.0269787
+(0, 60) ~ (2, 56) => 0.959117
+(0, 61) ~ (2, 55) => 0.026664
+(0, 61) ~ (2, 57) => 0.965343
+(0, 62) ~ (2, 56) => 0.0256537
+(0, 62) ~ (2, 58) => 0.967762
+(0, 63) ~ (2, 57) => 0.0243379
+(0, 63) ~ (2, 59) => 0.967454
+(0, 64) ~ (2, 58) => 0.0225511
+(0, 64) ~ (2, 60) => 0.963716
+(0, 65) ~ (2, 59) => 0.0186428
+(0, 65) ~ (2, 61) => 0.958363
+(0, 66) ~ (2, 60) => 0.0177682
+(0, 66) ~ (2, 61) => 0.0123755
+(0, 66) ~ (2, 62) => 0.923611
+(0, 66) ~ (2, 63) => 0.0145654
+(0, 67) ~ (2, 61) => 0.0172152
+(0, 67) ~ (2, 62) => 0.0241255
+(0, 67) ~ (2, 63) => 0.827221
+(0, 67) ~ (2, 64) => 0.0740666
+(0, 67) ~ (2, 65) => 0.0141576
+(0, 68) ~ (2, 62) => 0.0182574
+(0, 68) ~ (2, 63) => 0.0337703
+(0, 68) ~ (2, 64) => 0.80243
+(0, 68) ~ (2, 65) => 0.0792221
+(0, 69) ~ (2, 63) => 0.0257667
+(0, 69) ~ (2, 64) => 0.0390069
+(0, 69) ~ (2, 65) => 0.784852
+(0, 69) ~ (2, 66) => 0.0832024
+(0, 70) ~ (2, 64) => 0.0346207
+(0, 70) ~ (2, 65) => 0.0348889
+(0, 70) ~ (2, 66) => 0.612149
+(0, 70) ~ (2, 67) => 0.0664532
+(0, 71) ~ (2, 65) => 0.0470558
+(0, 71) ~ (2, 66) => 0.0210357
+(0, 71) ~ (2, 67) => 0.440304
+(0, 71) ~ (2, 68) => 0.0594009
+(0, 72) ~ (2, 66) => 0.228487
+(0, 72) ~ (2, 67) => 0.0292197
+(0, 72) ~ (2, 68) => 0.262116
+(0, 72) ~ (2, 69) => 0.0244334
+(0, 73) ~ (2, 67) => 0.418465
+(0, 73) ~ (2, 68) => 0.0459949
+(0, 73) ~ (2, 69) => 0.0181661
+(0, 73) ~ (2, 70) => 0.0163759
+(0, 74) ~ (2, 68) => 0.593541
+(0, 74) ~ (2, 69) => 0.0329988
+(0, 75) ~ (2, 69) => 0.90526
+(0, 76) ~ (2, 70) => 0.959444
+(0, 77) ~ (2, 71) => 0.988058
+(0, 78) ~ (2, 72) => 0.992381
+(0, 79) ~ (2, 73) => 0.994517
+(0, 80) ~ (2, 74) => 0.986031
+(0, 81) ~ (2, 75) => 0.97584
+(0, 82) ~ (2, 76) => 0.968404
+(0, 83) ~ (2, 77) => 0.948204
+(0, 83) ~ (2, 78) => 0.0236257
+(0, 84) ~ (2, 78) => 0.889931
+(0, 84) ~ (2, 79) => 0.0723983
+(0, 85) ~ (2, 79) => 0.880713
+(0, 85) ~ (2, 80) => 0.0784834
+(0, 86) ~ (2, 80) => 0.848714
+(0, 86) ~ (2, 81) => 0.0889068
+(0, 87) ~ (2, 81) => 0.845122
+(0, 87) ~ (2, 82) => 0.0375461
+(0, 88) ~ (2, 82) => 0.891827
+(0, 88) ~ (2, 83) => 0.0349059
+(0, 89) ~ (2, 83) => 0.890069
+(0, 89) ~ (2, 84) => 0.0362772
+(0, 90) ~ (2, 84) => 0.86254
+(0, 90) ~ (2, 85) => 0.037994
+(0, 90) ~ (2, 89) => 0.0114329
+(0, 90) ~ (2, 96) => 0.0113355
+(0, 90) ~ (2, 102) => 0.0173901
+(0, 91) ~ (2, 85) => 0.766973
+(0, 91) ~ (2, 86) => 0.0504965
+(0, 91) ~ (2, 87) => 0.0135434
+(0, 91) ~ (2, 88) => 0.0102145
+(0, 91) ~ (2, 90) => 0.0219673
+(0, 91) ~ (2, 97) => 0.0454084
+(0, 91) ~ (2, 99) => 0.0121022
+(0, 91) ~ (2, 103) => 0.0195584
+(0, 92) ~ (2, 86) => 0.670179
+(0, 92) ~ (2, 87) => 0.0598819
+(0, 92) ~ (2, 88) => 0.0196568
+(0, 92) ~ (2, 89) => 0.0143779
+(0, 92) ~ (2, 91) => 0.0308706
+(0, 92) ~ (2, 97) => 0.0113944
+(0, 92) ~ (2, 98) => 0.0794772
+(0, 92) ~ (2, 100) => 0.017191
+(0, 92) ~ (2, 104) => 0.0216945
+(0, 93) ~ (2, 87) => 0.521868
+(0, 93) ~ (2, 88) => 0.0618575
+(0, 93) ~ (2, 89) => 0.0198052
+(0, 93) ~ (2, 90) => 0.0125906
+(0, 93) ~ (2, 92) => 0.109223
+(0, 93) ~ (2, 93) => 0.0108269
+(0, 93) ~ (2, 97) => 0.0173647
+(0, 93) ~ (2, 98) => 0.0153931
+(0, 93) ~ (2, 99) => 0.11493
+(0, 93) ~ (2, 101) => 0.0219698
+(0, 93) ~ (2, 105) => 0.0222753
+(0, 94) ~ (2, 87) => 0.0100653
+(0, 94) ~ (2, 88) => 0.375799
+(0, 94) ~ (2, 89) => 0.0594088
+(0, 94) ~ (2, 90) => 0.0151489
+(0, 94) ~ (2, 92) => 0.0105044
+(0, 94) ~ (2, 93) => 0.186994
+(0, 94) ~ (2, 94) => 0.0104094
+(0, 94) ~ (2, 98) => 0.0303462
+(0, 94) ~ (2, 99) => 0.0175566
+(0, 94) ~ (2, 100) => 0.151839
+(0, 94) ~ (2, 102) => 0.0263854
+(0, 94) ~ (2, 104) => 0.0104285
+(0, 94) ~ (2, 106) => 0.0225624
+(0, 95) ~ (2, 89) => 0.2161
+(0, 95) ~ (2, 90) => 0.0505557
+(0, 95) ~ (2, 92) => 0.01104
+(0, 95) ~ (2, 93) => 0.010377
+(0, 95) ~ (2, 94) => 0.262304
+(0, 95) ~ (2, 99) => 0.0400939
+(0, 95) ~ (2, 100) => 0.0155669
+(0, 95) ~ (2, 101) => 0.185858
+(0, 95) ~ (2, 103) => 0.0722747
+(0, 95) ~ (2, 104) => 0.0142828
+(0, 95) ~ (2, 107) => 0.0176944
+(0, 96) ~ (2, 90) => 0.0652454
+(0, 96) ~ (2, 91) => 0.0380874
+(0, 96) ~ (2, 93) => 0.010382
+(0, 96) ~ (2, 95) => 0.335616
+(0, 96) ~ (2, 100) => 0.047049
+(0, 96) ~ (2, 102) => 0.219643
+(0, 96) ~ (2, 104) => 0.117787
+(0, 96) ~ (2, 108) => 0.0112672
+(0, 97) ~ (2, 91) => 0.0158469
+(0, 97) ~ (2, 92) => 0.0312256
+(0, 97) ~ (2, 94) => 0.0126311
+(0, 97) ~ (2, 96) => 0.0817213
+(0, 97) ~ (2, 97) => 0.0169875
+(0, 97) ~ (2, 98) => 0.0146479
+(0, 97) ~ (2, 99) => 0.0182118
+(0, 97) ~ (2, 100) => 0.0141674
+(0, 97) ~ (2, 101) => 0.106773
+(0, 97) ~ (2, 103) => 0.172614
+(0, 97) ~ (2, 104) => 0.0171756
+(0, 97) ~ (2, 105) => 0.388809
+(0, 97) ~ (2, 106) => 0.0117474
+(0, 98) ~ (2, 93) => 0.0224562
+(0, 98) ~ (2, 95) => 0.0111021
+(0, 98) ~ (2, 97) => 0.0487443
+(0, 98) ~ (2, 98) => 0.01161
+(0, 98) ~ (2, 99) => 0.0107129
+(0, 98) ~ (2, 100) => 0.0139255
+(0, 98) ~ (2, 102) => 0.119014
+(0, 98) ~ (2, 104) => 0.116036
+(0, 98) ~ (2, 105) => 0.0158865
+(0, 98) ~ (2, 106) => 0.527116
+(0, 99) ~ (2, 94) => 0.0162243
+(0, 99) ~ (2, 98) => 0.0240906
+(0, 99) ~ (2, 103) => 0.0607398
+(0, 99) ~ (2, 105) => 0.0608477
+(0, 99) ~ (2, 106) => 0.0118267
+(0, 99) ~ (2, 107) => 0.745883
+(0, 100) ~ (2, 95) => 0.0101757
+(0, 100) ~ (2, 108) => 0.958018
+(0, 101) ~ (2, 109) => 0.978585
+(0, 102) ~ (2, 110) => 0.986513
+(0, 103) ~ (2, 111) => 0.986351
+(0, 104) ~ (2, 112) => 0.985981
+(0, 105) ~ (2, 113) => 0.991188
+(0, 106) ~ (2, 114) => 0.993165
+(0, 107) ~ (2, 115) => 0.993857
+(0, 108) ~ (2, 116) => 0.996177
+
+; gap posteriors
+(0, 0) ~ (2, -1) => 0.00750101
+(0, 1) ~ (2, -1) => 0.00767988
+(0, 2) ~ (2, -1) => 0.00567204
+(0, 3) ~ (2, -1) => 0.00165546
+(0, 4) ~ (2, -1) => 0.000762343
+(0, 5) ~ (2, -1) => 0.000523686
+(0, 6) ~ (2, -1) => 0.000807822
+(0, 7) ~ (2, -1) => 0.00135761
+(0, 8) ~ (2, -1) => 0.00369143
+(0, 9) ~ (2, -1) => 0.00353408
+(0, 10) ~ (2, -1) => 0.00243783
+(0, 11) ~ (2, -1) => 0.000798643
+(0, 12) ~ (2, -1) => 0.000902474
+(0, 13) ~ (2, -1) => 0.00106609
+(0, 14) ~ (2, -1) => 0.00307125
+(0, 15) ~ (2, -1) => 0.00897861
+(0, 16) ~ (2, -1) => 0.0184444
+(0, 17) ~ (2, -1) => 0.0596452
+(0, 18) ~ (2, -1) => 0.281143
+(0, 19) ~ (2, -1) => 0.733318
+(0, 20) ~ (2, -1) => 0.741087
+(0, 21) ~ (2, -1) => 0.445363
+(0, 22) ~ (2, -1) => 0.447377
+(0, 23) ~ (2, -1) => 0.350767
+(0, 24) ~ (2, -1) => 0.471535
+(0, 25) ~ (2, -1) => 0.457899
+(0, 26) ~ (2, -1) => 0.169334
+(0, 27) ~ (2, -1) => 0.0905196
+(0, 28) ~ (2, -1) => 0.139402
+(0, 29) ~ (2, -1) => 0.194901
+(0, 30) ~ (2, -1) => 0.137516
+(0, 31) ~ (2, -1) => 0.0419161
+(0, 32) ~ (2, -1) => 0.0066734
+(0, 33) ~ (2, -1) => 0.00577378
+(0, 34) ~ (2, -1) => 0.00470376
+(0, 35) ~ (2, -1) => 0.00407916
+(0, 36) ~ (2, -1) => 0.00291401
+(0, 37) ~ (2, -1) => 0.000319362
+(0, 38) ~ (2, -1) => 0.000650764
+(0, 39) ~ (2, -1) => 0.00104707
+(0, 40) ~ (2, -1) => 0.00757957
+(0, 41) ~ (2, -1) => 0.0137811
+(0, 42) ~ (2, -1) => 0.00882703
+(0, 43) ~ (2, -1) => 0.00979227
+(0, 44) ~ (2, -1) => 0.0206531
+(0, 45) ~ (2, -1) => 0.0744011
+(0, 46) ~ (2, -1) => 0.0443142
+(0, 47) ~ (2, -1) => 0.120352
+(0, 48) ~ (2, -1) => 0.128854
+(0, 49) ~ (2, -1) => 0.117034
+(0, 50) ~ (2, -1) => 0.302082
+(0, 51) ~ (2, -1) => 0.10994
+(0, 52) ~ (2, -1) => 0.0486389
+(0, 53) ~ (2, -1) => 0.0487757
+(0, 54) ~ (2, -1) => 0.0496887
+(0, 55) ~ (2, -1) => 0.0174489
+(0, 56) ~ (2, -1) => 0.0285855
+(0, 57) ~ (2, -1) => 0.0310597
+(0, 58) ~ (2, -1) => 0.0480516
+(0, 59) ~ (2, -1) => 0.0280604
+(0, 60) ~ (2, -1) => 0.0139043
+(0, 61) ~ (2, -1) => 0.00799346
+(0, 62) ~ (2, -1) => 0.00658476
+(0, 63) ~ (2, -1) => 0.00820857
+(0, 64) ~ (2, -1) => 0.0137333
+(0, 65) ~ (2, -1) => 0.0229944
+(0, 66) ~ (2, -1) => 0.0316797
+(0, 67) ~ (2, -1) => 0.0432139
+(0, 68) ~ (2, -1) => 0.0663205
+(0, 69) ~ (2, -1) => 0.0671719
+(0, 70) ~ (2, -1) => 0.251888
+(0, 71) ~ (2, -1) => 0.432204
+(0, 72) ~ (2, -1) => 0.455744
+(0, 73) ~ (2, -1) => 0.500998
+(0, 74) ~ (2, -1) => 0.37346
+(0, 75) ~ (2, -1) => 0.0947401
+(0, 76) ~ (2, -1) => 0.0405555
+(0, 77) ~ (2, -1) => 0.0119422
+(0, 78) ~ (2, -1) => 0.00761926
+(0, 79) ~ (2, -1) => 0.00548255
+(0, 80) ~ (2, -1) => 0.0139688
+(0, 81) ~ (2, -1) => 0.0241596
+(0, 82) ~ (2, -1) => 0.0315956
+(0, 83) ~ (2, -1) => 0.0281707
+(0, 84) ~ (2, -1) => 0.0376709
+(0, 85) ~ (2, -1) => 0.0408035
+(0, 86) ~ (2, -1) => 0.0623792
+(0, 87) ~ (2, -1) => 0.117332
+(0, 88) ~ (2, -1) => 0.0732673
+(0, 89) ~ (2, -1) => 0.0736542
+(0, 90) ~ (2, -1) => 0.0593072
+(0, 91) ~ (2, -1) => 0.0597363
+(0, 92) ~ (2, -1) => 0.0752767
+(0, 93) ~ (2, -1) => 0.0718957
+(0, 94) ~ (2, -1) => 0.0725517
+(0, 95) ~ (2, -1) => 0.103853
+(0, 96) ~ (2, -1) => 0.154923
+(0, 97) ~ (2, -1) => 0.0974416
+(0, 98) ~ (2, -1) => 0.103396
+(0, 99) ~ (2, -1) => 0.0803875
+(0, 100) ~ (2, -1) => 0.0318059
+(0, 101) ~ (2, -1) => 0.0214149
+(0, 102) ~ (2, -1) => 0.0134872
+(0, 103) ~ (2, -1) => 0.0136493
+(0, 104) ~ (2, -1) => 0.014019
+(0, 105) ~ (2, -1) => 0.00881171
+(0, 106) ~ (2, -1) => 0.0068351
+(0, 107) ~ (2, -1) => 0.00614262
+(0, 108) ~ (2, -1) => 0.00382251
+
+(0, -1) ~ (2, 0) => 0.86653
+(0, -1) ~ (2, 1) => 0.122701
+(0, -1) ~ (2, 2) => 0.0259492
+(0, -1) ~ (2, 3) => 0.00567204
+(0, -1) ~ (2, 4) => 0.00165546
+(0, -1) ~ (2, 5) => 0.000762343
+(0, -1) ~ (2, 6) => 0.000523686
+(0, -1) ~ (2, 7) => 0.000807822
+(0, -1) ~ (2, 8) => 0.00135761
+(0, -1) ~ (2, 9) => 0.00369143
+(0, -1) ~ (2, 10) => 0.00353408
+(0, -1) ~ (2, 11) => 0.00243783
+(0, -1) ~ (2, 12) => 0.000798643
+(0, -1) ~ (2, 13) => 0.000902474
+(0, -1) ~ (2, 14) => 0.00106609
+(0, -1) ~ (2, 15) => 0.00307125
+(0, -1) ~ (2, 16) => 0.00897861
+(0, -1) ~ (2, 17) => 0.0184444
+(0, -1) ~ (2, 18) => 0.0398891
+(0, -1) ~ (2, 19) => 0.0537728
+(0, -1) ~ (2, 20) => 0.0600455
+(0, -1) ~ (2, 21) => 0.182036
+(0, -1) ~ (2, 22) => 0.22306
+(0, -1) ~ (2, 23) => 0.0673764
+(0, -1) ~ (2, 24) => 0.0433901
+(0, -1) ~ (2, 25) => 0.0353646
+(0, -1) ~ (2, 26) => 0.0291569
+(0, -1) ~ (2, 27) => 0.0176267
+(0, -1) ~ (2, 28) => 0.0100061
+(0, -1) ~ (2, 29) => 0.0066734
+(0, -1) ~ (2, 30) => 0.00577378
+(0, -1) ~ (2, 31) => 0.00470376
+(0, -1) ~ (2, 32) => 0.00407916
+(0, -1) ~ (2, 33) => 0.00291401
+(0, -1) ~ (2, 34) => 0.000319362
+(0, -1) ~ (2, 35) => 0.000650764
+(0, -1) ~ (2, 36) => 0.00104707
+(0, -1) ~ (2, 37) => 0.00757957
+(0, -1) ~ (2, 38) => 0.00279102
+(0, -1) ~ (2, 39) => 0.00387865
+(0, -1) ~ (2, 40) => 0.00500218
+(0, -1) ~ (2, 41) => 0.00516551
+(0, -1) ~ (2, 42) => 0.00864945
+(0, -1) ~ (2, 43) => 0.0116915
+(0, -1) ~ (2, 44) => 0.00563445
+(0, -1) ~ (2, 45) => 0.0095823
+(0, -1) ~ (2, 46) => 0.0162249
+(0, -1) ~ (2, 47) => 0.021621
+(0, -1) ~ (2, 48) => 0.0150912
+(0, -1) ~ (2, 49) => 0.015061
+(0, -1) ~ (2, 50) => 0.0145659
+(0, -1) ~ (2, 51) => 0.015545
+(0, -1) ~ (2, 52) => 0.0134663
+(0, -1) ~ (2, 53) => 0.0107932
+(0, -1) ~ (2, 54) => 0.0111669
+(0, -1) ~ (2, 55) => 0.0107675
+(0, -1) ~ (2, 56) => 0.0152293
+(0, -1) ~ (2, 57) => 0.0103196
+(0, -1) ~ (2, 58) => 0.00968737
+(0, -1) ~ (2, 59) => 0.0139037
+(0, -1) ~ (2, 60) => 0.0185162
+(0, -1) ~ (2, 61) => 0.0120465
+(0, -1) ~ (2, 62) => 0.034006
+(0, -1) ~ (2, 63) => 0.0986763
+(0, -1) ~ (2, 64) => 0.0498759
+(0, -1) ~ (2, 65) => 0.0398235
+(0, -1) ~ (2, 66) => 0.0551264
+(0, -1) ~ (2, 67) => 0.0455586
+(0, -1) ~ (2, 68) => 0.0389465
+(0, -1) ~ (2, 69) => 0.0191418
+(0, -1) ~ (2, 70) => 0.0241796
+(0, -1) ~ (2, 71) => 0.0119422
+(0, -1) ~ (2, 72) => 0.00761926
+(0, -1) ~ (2, 73) => 0.00548255
+(0, -1) ~ (2, 74) => 0.0139688
+(0, -1) ~ (2, 75) => 0.0241596
+(0, -1) ~ (2, 76) => 0.0315956
+(0, -1) ~ (2, 77) => 0.0517964
+(0, -1) ~ (2, 78) => 0.0864435
+(0, -1) ~ (2, 79) => 0.0468885
+(0, -1) ~ (2, 80) => 0.0728027
+(0, -1) ~ (2, 81) => 0.0659714
+(0, -1) ~ (2, 82) => 0.0706271
+(0, -1) ~ (2, 83) => 0.0750254
+(0, -1) ~ (2, 84) => 0.101183
+(0, -1) ~ (2, 85) => 0.195033
+(0, -1) ~ (2, 86) => 0.279325
+(0, -1) ~ (2, 87) => 0.394641
+(0, -1) ~ (2, 88) => 0.532472
+(0, -1) ~ (2, 89) => 0.678875
+(0, -1) ~ (2, 90) => 0.834492
+(0, -1) ~ (2, 91) => 0.915195
+(0, -1) ~ (2, 92) => 0.838007
+(0, -1) ~ (2, 93) => 0.758964
+(0, -1) ~ (2, 94) => 0.698432
+(0, -1) ~ (2, 95) => 0.643107
+(0, -1) ~ (2, 96) => 0.906943
+(0, -1) ~ (2, 97) => 0.860101
+(0, -1) ~ (2, 98) => 0.824435
+(0, -1) ~ (2, 99) => 0.786393
+(0, -1) ~ (2, 100) => 0.740261
+(0, -1) ~ (2, 101) => 0.6854
+(0, -1) ~ (2, 102) => 0.617567
+(0, -1) ~ (2, 103) => 0.674813
+(0, -1) ~ (2, 104) => 0.702595
+(0, -1) ~ (2, 105) => 0.512181
+(0, -1) ~ (2, 106) => 0.426748
+(0, -1) ~ (2, 107) => 0.236422
+(0, -1) ~ (2, 108) => 0.0307145
+(0, -1) ~ (2, 109) => 0.0214149
+(0, -1) ~ (2, 110) => 0.0134872
+(0, -1) ~ (2, 111) => 0.0136493
+(0, -1) ~ (2, 112) => 0.014019
+(0, -1) ~ (2, 113) => 0.00881171
+(0, -1) ~ (2, 114) => 0.0068351
+(0, -1) ~ (2, 115) => 0.00614262
+(0, -1) ~ (2, 116) => 0.00382251
+
+; Sparse posterior probability matrix for sequences 0 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (3, 0) => 0.991867
+(0, 1) ~ (3, 1) => 0.974115
+(0, 2) ~ (3, 2) => 0.961081
+(0, 3) ~ (3, 1) => 0.014365
+(0, 3) ~ (3, 3) => 0.945116
+(0, 4) ~ (3, 2) => 0.024977
+(0, 4) ~ (3, 4) => 0.921852
+(0, 5) ~ (3, 3) => 0.0349324
+(0, 5) ~ (3, 5) => 0.908765
+(0, 6) ~ (3, 4) => 0.0443889
+(0, 6) ~ (3, 6) => 0.898018
+(0, 7) ~ (3, 5) => 0.0482922
+(0, 7) ~ (3, 7) => 0.872846
+(0, 8) ~ (3, 6) => 0.0540385
+(0, 8) ~ (3, 8) => 0.857428
+(0, 9) ~ (3, 7) => 0.0699503
+(0, 9) ~ (3, 9) => 0.841362
+(0, 10) ~ (3, 8) => 0.0834428
+(0, 10) ~ (3, 10) => 0.831451
+(0, 11) ~ (3, 9) => 0.0969963
+(0, 11) ~ (3, 11) => 0.816566
+(0, 11) ~ (3, 14) => 0.0124248
+(0, 12) ~ (3, 10) => 0.109624
+(0, 12) ~ (3, 12) => 0.804971
+(0, 12) ~ (3, 13) => 0.0102351
+(0, 12) ~ (3, 15) => 0.0121488
+(0, 13) ~ (3, 11) => 0.119702
+(0, 13) ~ (3, 13) => 0.795845
+(0, 13) ~ (3, 14) => 0.011362
+(0, 13) ~ (3, 16) => 0.0116506
+(0, 14) ~ (3, 12) => 0.130479
+(0, 14) ~ (3, 14) => 0.786263
+(0, 15) ~ (3, 13) => 0.143877
+(0, 15) ~ (3, 15) => 0.788794
+(0, 16) ~ (3, 14) => 0.161463
+(0, 16) ~ (3, 16) => 0.792121
+(0, 17) ~ (3, 15) => 0.165109
+(0, 17) ~ (3, 17) => 0.766247
+(0, 17) ~ (3, 18) => 0.0113069
+(0, 18) ~ (3, 16) => 0.164137
+(0, 18) ~ (3, 18) => 0.714271
+(0, 18) ~ (3, 19) => 0.0151941
+(0, 19) ~ (3, 17) => 0.185587
+(0, 19) ~ (3, 18) => 0.0146845
+(0, 19) ~ (3, 19) => 0.592247
+(0, 19) ~ (3, 20) => 0.0116545
+(0, 20) ~ (3, 18) => 0.231775
+(0, 20) ~ (3, 19) => 0.0257255
+(0, 20) ~ (3, 20) => 0.324196
+(0, 21) ~ (3, 19) => 0.339297
+(0, 21) ~ (3, 20) => 0.0301383
+(0, 21) ~ (3, 21) => 0.0666182
+(0, 22) ~ (3, 20) => 0.60957
+(0, 22) ~ (3, 21) => 0.0104292
+(0, 22) ~ (3, 22) => 0.0192422
+(0, 23) ~ (3, 21) => 0.902166
+(0, 24) ~ (3, 22) => 0.95988
+(0, 25) ~ (3, 23) => 0.984829
+(0, 26) ~ (3, 24) => 0.987869
+(0, 27) ~ (3, 25) => 0.988073
+(0, 28) ~ (3, 26) => 0.989046
+(0, 29) ~ (3, 27) => 0.991758
+(0, 30) ~ (3, 28) => 0.99358
+(0, 31) ~ (3, 29) => 0.997051
+(0, 32) ~ (3, 30) => 0.999062
+(0, 33) ~ (3, 31) => 0.999254
+(0, 34) ~ (3, 32) => 0.999402
+(0, 35) ~ (3, 33) => 0.9996
+(0, 36) ~ (3, 34) => 0.999838
+(0, 37) ~ (3, 35) => 0.999856
+(0, 38) ~ (3, 36) => 0.999821
+(0, 39) ~ (3, 37) => 0.999812
+(0, 40) ~ (3, 38) => 0.999612
+(0, 41) ~ (3, 39) => 0.999465
+(0, 42) ~ (3, 40) => 0.999461
+(0, 43) ~ (3, 41) => 0.999602
+(0, 44) ~ (3, 42) => 0.99985
+(0, 45) ~ (3, 43) => 0.999937
+(0, 46) ~ (3, 44) => 0.999857
+(0, 47) ~ (3, 45) => 0.999718
+(0, 48) ~ (3, 46) => 0.999626
+(0, 49) ~ (3, 47) => 0.999585
+(0, 50) ~ (3, 48) => 0.999493
+(0, 51) ~ (3, 49) => 0.998941
+(0, 52) ~ (3, 50) => 0.998031
+(0, 53) ~ (3, 51) => 0.99748
+(0, 54) ~ (3, 52) => 0.996233
+(0, 55) ~ (3, 53) => 0.9949
+(0, 56) ~ (3, 54) => 0.989551
+(0, 57) ~ (3, 55) => 0.955213
+(0, 57) ~ (3, 57) => 0.0136794
+(0, 58) ~ (3, 56) => 0.907935
+(0, 58) ~ (3, 58) => 0.0253974
+(0, 59) ~ (3, 57) => 0.727875
+(0, 59) ~ (3, 59) => 0.0331362
+(0, 60) ~ (3, 57) => 0.0146408
+(0, 60) ~ (3, 58) => 0.485344
+(0, 60) ~ (3, 59) => 0.0120704
+(0, 60) ~ (3, 60) => 0.0337401
+(0, 60) ~ (3, 69) => 0.0158254
+(0, 61) ~ (3, 56) => 0.0171183
+(0, 61) ~ (3, 58) => 0.0220779
+(0, 61) ~ (3, 59) => 0.350409
+(0, 61) ~ (3, 61) => 0.0259184
+(0, 61) ~ (3, 70) => 0.0250855
+(0, 62) ~ (3, 57) => 0.0420222
+(0, 62) ~ (3, 59) => 0.0193769
+(0, 62) ~ (3, 60) => 0.284863
+(0, 62) ~ (3, 62) => 0.0134591
+(0, 62) ~ (3, 71) => 0.027765
+(0, 63) ~ (3, 57) => 0.0238364
+(0, 63) ~ (3, 58) => 0.0631463
+(0, 63) ~ (3, 61) => 0.217285
+(0, 63) ~ (3, 72) => 0.0362992
+(0, 64) ~ (3, 56) => 0.0152465
+(0, 64) ~ (3, 58) => 0.0927079
+(0, 64) ~ (3, 59) => 0.0668901
+(0, 64) ~ (3, 62) => 0.139885
+(0, 64) ~ (3, 73) => 0.0411432
+(0, 64) ~ (3, 75) => 0.0113381
+(0, 65) ~ (3, 57) => 0.104605
+(0, 65) ~ (3, 59) => 0.171434
+(0, 65) ~ (3, 60) => 0.0560972
+(0, 65) ~ (3, 63) => 0.115796
+(0, 65) ~ (3, 74) => 0.0416983
+(0, 65) ~ (3, 76) => 0.0169663
+(0, 66) ~ (3, 58) => 0.194882
+(0, 66) ~ (3, 60) => 0.2015
+(0, 66) ~ (3, 61) => 0.0430429
+(0, 66) ~ (3, 64) => 0.0497717
+(0, 66) ~ (3, 75) => 0.044634
+(0, 66) ~ (3, 77) => 0.0208961
+(0, 67) ~ (3, 59) => 0.235583
+(0, 67) ~ (3, 61) => 0.293474
+(0, 67) ~ (3, 62) => 0.0261363
+(0, 67) ~ (3, 65) => 0.0381385
+(0, 67) ~ (3, 76) => 0.0404211
+(0, 67) ~ (3, 78) => 0.0342904
+(0, 68) ~ (3, 60) => 0.303049
+(0, 68) ~ (3, 62) => 0.373825
+(0, 68) ~ (3, 63) => 0.027698
+(0, 68) ~ (3, 64) => 0.0133455
+(0, 68) ~ (3, 66) => 0.0221875
+(0, 68) ~ (3, 74) => 0.010068
+(0, 68) ~ (3, 77) => 0.0411259
+(0, 68) ~ (3, 79) => 0.0399721
+(0, 69) ~ (3, 61) => 0.312766
+(0, 69) ~ (3, 63) => 0.385471
+(0, 69) ~ (3, 64) => 0.031448
+(0, 69) ~ (3, 65) => 0.0114137
+(0, 69) ~ (3, 78) => 0.0244809
+(0, 69) ~ (3, 80) => 0.0719196
+(0, 70) ~ (3, 62) => 0.312942
+(0, 70) ~ (3, 64) => 0.42824
+(0, 70) ~ (3, 65) => 0.0428359
+(0, 70) ~ (3, 81) => 0.0954376
+(0, 71) ~ (3, 63) => 0.261022
+(0, 71) ~ (3, 65) => 0.405952
+(0, 71) ~ (3, 66) => 0.141716
+(0, 71) ~ (3, 82) => 0.09836
+(0, 72) ~ (3, 64) => 0.215664
+(0, 72) ~ (3, 66) => 0.315336
+(0, 72) ~ (3, 67) => 0.315479
+(0, 72) ~ (3, 83) => 0.0997662
+(0, 73) ~ (3, 65) => 0.157186
+(0, 73) ~ (3, 67) => 0.296916
+(0, 73) ~ (3, 68) => 0.392722
+(0, 73) ~ (3, 84) => 0.0987119
+(0, 74) ~ (3, 66) => 0.0480228
+(0, 74) ~ (3, 68) => 0.292354
+(0, 74) ~ (3, 69) => 0.503763
+(0, 74) ~ (3, 85) => 0.0971298
+(0, 75) ~ (3, 67) => 0.0215303
+(0, 75) ~ (3, 69) => 0.271876
+(0, 75) ~ (3, 70) => 0.539216
+(0, 75) ~ (3, 72) => 0.0134451
+(0, 75) ~ (3, 86) => 0.0891791
+(0, 75) ~ (3, 91) => 0.0105919
+(0, 76) ~ (3, 68) => 0.019059
+(0, 76) ~ (3, 70) => 0.243047
+(0, 76) ~ (3, 71) => 0.556662
+(0, 76) ~ (3, 73) => 0.0163024
+(0, 76) ~ (3, 87) => 0.056616
+(0, 76) ~ (3, 92) => 0.0368875
+(0, 77) ~ (3, 69) => 0.0173785
+(0, 77) ~ (3, 71) => 0.222453
+(0, 77) ~ (3, 72) => 0.558701
+(0, 77) ~ (3, 73) => 0.0102431
+(0, 77) ~ (3, 74) => 0.0218837
+(0, 77) ~ (3, 88) => 0.0181105
+(0, 77) ~ (3, 93) => 0.0634052
+(0, 78) ~ (3, 70) => 0.0178464
+(0, 78) ~ (3, 72) => 0.217009
+(0, 78) ~ (3, 73) => 0.563099
+(0, 78) ~ (3, 75) => 0.0244981
+(0, 78) ~ (3, 89) => 0.0102946
+(0, 78) ~ (3, 94) => 0.066627
+(0, 78) ~ (3, 105) => 0.0101852
+(0, 79) ~ (3, 71) => 0.0123995
+(0, 79) ~ (3, 73) => 0.182787
+(0, 79) ~ (3, 74) => 0.599869
+(0, 79) ~ (3, 76) => 0.0226281
+(0, 79) ~ (3, 81) => 0.0106908
+(0, 79) ~ (3, 95) => 0.0650684
+(0, 79) ~ (3, 106) => 0.0155031
+(0, 80) ~ (3, 72) => 0.0112811
+(0, 80) ~ (3, 74) => 0.087327
+(0, 80) ~ (3, 75) => 0.684033
+(0, 80) ~ (3, 76) => 0.0113438
+(0, 80) ~ (3, 77) => 0.0148334
+(0, 80) ~ (3, 82) => 0.0148941
+(0, 80) ~ (3, 96) => 0.0573306
+(0, 80) ~ (3, 107) => 0.0274085
+(0, 81) ~ (3, 74) => 0.0144068
+(0, 81) ~ (3, 75) => 0.0201001
+(0, 81) ~ (3, 76) => 0.751018
+(0, 81) ~ (3, 77) => 0.0171833
+(0, 81) ~ (3, 83) => 0.0168698
+(0, 81) ~ (3, 97) => 0.0547837
+(0, 81) ~ (3, 108) => 0.0340277
+(0, 82) ~ (3, 75) => 0.0103497
+(0, 82) ~ (3, 76) => 0.0115249
+(0, 82) ~ (3, 77) => 0.77672
+(0, 82) ~ (3, 78) => 0.0103467
+(0, 82) ~ (3, 84) => 0.0166738
+(0, 82) ~ (3, 98) => 0.0535908
+(0, 82) ~ (3, 109) => 0.0352399
+(0, 83) ~ (3, 78) => 0.811445
+(0, 83) ~ (3, 85) => 0.0156155
+(0, 83) ~ (3, 99) => 0.0532808
+(0, 83) ~ (3, 110) => 0.0358514
+(0, 84) ~ (3, 79) => 0.822349
+(0, 84) ~ (3, 86) => 0.0128328
+(0, 84) ~ (3, 100) => 0.0516994
+(0, 84) ~ (3, 111) => 0.0360597
+(0, 85) ~ (3, 80) => 0.840365
+(0, 85) ~ (3, 101) => 0.0511545
+(0, 85) ~ (3, 112) => 0.0357699
+(0, 86) ~ (3, 81) => 0.848328
+(0, 86) ~ (3, 102) => 0.0509413
+(0, 86) ~ (3, 113) => 0.0357834
+(0, 87) ~ (3, 82) => 0.845725
+(0, 87) ~ (3, 103) => 0.0532815
+(0, 87) ~ (3, 114) => 0.0358498
+(0, 88) ~ (3, 83) => 0.839716
+(0, 88) ~ (3, 104) => 0.0584378
+(0, 88) ~ (3, 115) => 0.0360585
+(0, 89) ~ (3, 84) => 0.7526
+(0, 89) ~ (3, 85) => 0.0599529
+(0, 89) ~ (3, 86) => 0.0296563
+(0, 89) ~ (3, 105) => 0.059679
+(0, 89) ~ (3, 116) => 0.0349406
+(0, 90) ~ (3, 85) => 0.728871
+(0, 90) ~ (3, 86) => 0.0708182
+(0, 90) ~ (3, 87) => 0.034256
+(0, 90) ~ (3, 106) => 0.0622201
+(0, 90) ~ (3, 117) => 0.0326939
+(0, 91) ~ (3, 86) => 0.668594
+(0, 91) ~ (3, 87) => 0.0784444
+(0, 91) ~ (3, 88) => 0.0558643
+(0, 91) ~ (3, 100) => 0.0101903
+(0, 91) ~ (3, 107) => 0.0632142
+(0, 91) ~ (3, 118) => 0.0252447
+(0, 92) ~ (3, 87) => 0.629973
+(0, 92) ~ (3, 88) => 0.0795967
+(0, 92) ~ (3, 89) => 0.0669656
+(0, 92) ~ (3, 90) => 0.0101919
+(0, 92) ~ (3, 100) => 0.0144457
+(0, 92) ~ (3, 108) => 0.0630319
+(0, 92) ~ (3, 119) => 0.0183905
+(0, 93) ~ (3, 88) => 0.583995
+(0, 93) ~ (3, 89) => 0.0787383
+(0, 93) ~ (3, 90) => 0.0769678
+(0, 93) ~ (3, 91) => 0.0115219
+(0, 93) ~ (3, 94) => 0.011943
+(0, 93) ~ (3, 101) => 0.0197777
+(0, 93) ~ (3, 105) => 0.0200286
+(0, 93) ~ (3, 109) => 0.065146
+(0, 93) ~ (3, 110) => 0.0101183
+(0, 93) ~ (3, 120) => 0.0127699
+(0, 94) ~ (3, 89) => 0.531055
+(0, 94) ~ (3, 90) => 0.0753495
+(0, 94) ~ (3, 91) => 0.085714
+(0, 94) ~ (3, 92) => 0.011579
+(0, 94) ~ (3, 95) => 0.0215582
+(0, 94) ~ (3, 102) => 0.024578
+(0, 94) ~ (3, 106) => 0.030443
+(0, 94) ~ (3, 107) => 0.0115912
+(0, 94) ~ (3, 110) => 0.0659741
+(0, 94) ~ (3, 111) => 0.0132391
+(0, 95) ~ (3, 88) => 0.0102005
+(0, 95) ~ (3, 90) => 0.442012
+(0, 95) ~ (3, 91) => 0.0663616
+(0, 95) ~ (3, 92) => 0.0907712
+(0, 95) ~ (3, 94) => 0.011365
+(0, 95) ~ (3, 96) => 0.0501476
+(0, 95) ~ (3, 103) => 0.0281384
+(0, 95) ~ (3, 105) => 0.0107482
+(0, 95) ~ (3, 107) => 0.0484393
+(0, 95) ~ (3, 108) => 0.0151439
+(0, 95) ~ (3, 111) => 0.0685351
+(0, 95) ~ (3, 112) => 0.01832
+(0, 96) ~ (3, 89) => 0.0111218
+(0, 96) ~ (3, 91) => 0.28779
+(0, 96) ~ (3, 92) => 0.0413488
+(0, 96) ~ (3, 93) => 0.0870736
+(0, 96) ~ (3, 95) => 0.0147642
+(0, 96) ~ (3, 96) => 0.0108115
+(0, 96) ~ (3, 97) => 0.132779
+(0, 96) ~ (3, 98) => 0.0127242
+(0, 96) ~ (3, 104) => 0.0392315
+(0, 96) ~ (3, 106) => 0.0117491
+(0, 96) ~ (3, 108) => 0.0648507
+(0, 96) ~ (3, 109) => 0.0237535
+(0, 96) ~ (3, 112) => 0.0743493
+(0, 96) ~ (3, 113) => 0.032238
+(0, 96) ~ (3, 115) => 0.0101208
+(0, 97) ~ (3, 90) => 0.0254378
+(0, 97) ~ (3, 92) => 0.25068
+(0, 97) ~ (3, 93) => 0.0376745
+(0, 97) ~ (3, 94) => 0.0619782
+(0, 97) ~ (3, 98) => 0.1498
+(0, 97) ~ (3, 99) => 0.0100059
+(0, 97) ~ (3, 105) => 0.0468964
+(0, 97) ~ (3, 107) => 0.0130706
+(0, 97) ~ (3, 109) => 0.0772233
+(0, 97) ~ (3, 110) => 0.0446944
+(0, 97) ~ (3, 113) => 0.0717253
+(0, 97) ~ (3, 114) => 0.0361129
+(0, 97) ~ (3, 116) => 0.0149417
+(0, 98) ~ (3, 91) => 0.0378831
+(0, 98) ~ (3, 93) => 0.184411
+(0, 98) ~ (3, 94) => 0.0403483
+(0, 98) ~ (3, 95) => 0.0377974
+(0, 98) ~ (3, 99) => 0.191259
+(0, 98) ~ (3, 106) => 0.0494657
+(0, 98) ~ (3, 108) => 0.0113081
+(0, 98) ~ (3, 110) => 0.0838197
+(0, 98) ~ (3, 111) => 0.0728766
+(0, 98) ~ (3, 114) => 0.0736242
+(0, 98) ~ (3, 115) => 0.0407857
+(0, 98) ~ (3, 116) => 0.0141635
+(0, 98) ~ (3, 117) => 0.0207971
+(0, 99) ~ (3, 92) => 0.0467466
+(0, 99) ~ (3, 94) => 0.162349
+(0, 99) ~ (3, 95) => 0.0326715
+(0, 99) ~ (3, 96) => 0.0294381
+(0, 99) ~ (3, 97) => 0.010125
+(0, 99) ~ (3, 100) => 0.196725
+(0, 99) ~ (3, 107) => 0.0417373
+(0, 99) ~ (3, 109) => 0.016544
+(0, 99) ~ (3, 111) => 0.0776338
+(0, 99) ~ (3, 112) => 0.0808213
+(0, 99) ~ (3, 115) => 0.0625637
+(0, 99) ~ (3, 116) => 0.0728052
+(0, 99) ~ (3, 117) => 0.0153595
+(0, 99) ~ (3, 118) => 0.020623
+(0, 100) ~ (3, 93) => 0.0522395
+(0, 100) ~ (3, 95) => 0.14318
+(0, 100) ~ (3, 96) => 0.0294341
+(0, 100) ~ (3, 97) => 0.0258355
+(0, 100) ~ (3, 98) => 0.0137276
+(0, 100) ~ (3, 101) => 0.192967
+(0, 100) ~ (3, 108) => 0.0233295
+(0, 100) ~ (3, 110) => 0.0184516
+(0, 100) ~ (3, 112) => 0.0706635
+(0, 100) ~ (3, 113) => 0.100264
+(0, 100) ~ (3, 115) => 0.0100613
+(0, 100) ~ (3, 116) => 0.0562208
+(0, 100) ~ (3, 117) => 0.109408
+(0, 100) ~ (3, 118) => 0.0142399
+(0, 100) ~ (3, 119) => 0.0199222
+(0, 101) ~ (3, 94) => 0.0502431
+(0, 101) ~ (3, 96) => 0.0865531
+(0, 101) ~ (3, 97) => 0.0151774
+(0, 101) ~ (3, 98) => 0.0104691
+(0, 101) ~ (3, 99) => 0.0138871
+(0, 101) ~ (3, 102) => 0.223103
+(0, 101) ~ (3, 106) => 0.0122098
+(0, 101) ~ (3, 111) => 0.0248912
+(0, 101) ~ (3, 113) => 0.0435809
+(0, 101) ~ (3, 114) => 0.105325
+(0, 101) ~ (3, 116) => 0.0138169
+(0, 101) ~ (3, 117) => 0.0533272
+(0, 101) ~ (3, 118) => 0.197682
+(0, 101) ~ (3, 119) => 0.0174761
+(0, 101) ~ (3, 120) => 0.0208059
+(0, 102) ~ (3, 95) => 0.0382806
+(0, 102) ~ (3, 97) => 0.0577083
+(0, 102) ~ (3, 103) => 0.266776
+(0, 102) ~ (3, 107) => 0.0127087
+(0, 102) ~ (3, 112) => 0.0227507
+(0, 102) ~ (3, 114) => 0.0359802
+(0, 102) ~ (3, 115) => 0.0927652
+(0, 102) ~ (3, 117) => 0.0105106
+(0, 102) ~ (3, 118) => 0.0358772
+(0, 102) ~ (3, 119) => 0.22904
+(0, 102) ~ (3, 120) => 0.040913
+(0, 102) ~ (3, 121) => 0.0362747
+(0, 103) ~ (3, 96) => 0.0317339
+(0, 103) ~ (3, 98) => 0.0418883
+(0, 103) ~ (3, 104) => 0.268866
+(0, 103) ~ (3, 108) => 0.0220587
+(0, 103) ~ (3, 113) => 0.0213385
+(0, 103) ~ (3, 115) => 0.0468599
+(0, 103) ~ (3, 116) => 0.0642117
+(0, 103) ~ (3, 118) => 0.0239171
+(0, 103) ~ (3, 119) => 0.045325
+(0, 103) ~ (3, 120) => 0.221968
+(0, 103) ~ (3, 121) => 0.0432267
+(0, 103) ~ (3, 122) => 0.0351748
+(0, 104) ~ (3, 97) => 0.0243852
+(0, 104) ~ (3, 99) => 0.0245661
+(0, 104) ~ (3, 105) => 0.234761
+(0, 104) ~ (3, 109) => 0.0211158
+(0, 104) ~ (3, 114) => 0.0181447
+(0, 104) ~ (3, 116) => 0.0436209
+(0, 104) ~ (3, 117) => 0.0590502
+(0, 104) ~ (3, 119) => 0.0847257
+(0, 104) ~ (3, 120) => 0.0343696
+(0, 104) ~ (3, 121) => 0.143275
+(0, 104) ~ (3, 122) => 0.0176062
+(0, 104) ~ (3, 123) => 0.0299903
+(0, 105) ~ (3, 98) => 0.0206177
+(0, 105) ~ (3, 106) => 0.164928
+(0, 105) ~ (3, 110) => 0.0129426
+(0, 105) ~ (3, 111) => 0.011612
+(0, 105) ~ (3, 112) => 0.0172103
+(0, 105) ~ (3, 113) => 0.0189059
+(0, 105) ~ (3, 115) => 0.0129021
+(0, 105) ~ (3, 117) => 0.0353416
+(0, 105) ~ (3, 118) => 0.0512569
+(0, 105) ~ (3, 119) => 0.0126678
+(0, 105) ~ (3, 120) => 0.211911
+(0, 105) ~ (3, 121) => 0.0210921
+(0, 105) ~ (3, 122) => 0.048548
+(0, 105) ~ (3, 123) => 0.0121027
+(0, 106) ~ (3, 107) => 0.124204
+(0, 106) ~ (3, 112) => 0.0138327
+(0, 106) ~ (3, 113) => 0.0152609
+(0, 106) ~ (3, 114) => 0.0181298
+(0, 106) ~ (3, 118) => 0.0305098
+(0, 106) ~ (3, 119) => 0.0468182
+(0, 106) ~ (3, 120) => 0.0163132
+(0, 106) ~ (3, 121) => 0.396034
+(0, 106) ~ (3, 123) => 0.0317564
+(0, 107) ~ (3, 108) => 0.111968
+(0, 107) ~ (3, 115) => 0.0187075
+(0, 107) ~ (3, 119) => 0.0276148
+(0, 107) ~ (3, 120) => 0.0417804
+(0, 107) ~ (3, 121) => 0.0204929
+(0, 107) ~ (3, 122) => 0.621408
+(0, 108) ~ (3, 109) => 0.0952417
+(0, 108) ~ (3, 116) => 0.0159129
+(0, 108) ~ (3, 120) => 0.0217687
+(0, 108) ~ (3, 121) => 0.0332801
+(0, 108) ~ (3, 122) => 0.0177422
+(0, 108) ~ (3, 123) => 0.69857
+
+; gap posteriors
+(0, 0) ~ (3, -1) => 0.00813264
+(0, 1) ~ (3, -1) => 0.0258849
+(0, 2) ~ (3, -1) => 0.0389194
+(0, 3) ~ (3, -1) => 0.0405192
+(0, 4) ~ (3, -1) => 0.0531709
+(0, 5) ~ (3, -1) => 0.0563022
+(0, 6) ~ (3, -1) => 0.0575928
+(0, 7) ~ (3, -1) => 0.0788615
+(0, 8) ~ (3, -1) => 0.0885333
+(0, 9) ~ (3, -1) => 0.088688
+(0, 10) ~ (3, -1) => 0.0851059
+(0, 11) ~ (3, -1) => 0.0740128
+(0, 12) ~ (3, -1) => 0.0630217
+(0, 13) ~ (3, -1) => 0.0614411
+(0, 14) ~ (3, -1) => 0.0832577
+(0, 15) ~ (3, -1) => 0.0673295
+(0, 16) ~ (3, -1) => 0.0464157
+(0, 17) ~ (3, -1) => 0.0573365
+(0, 18) ~ (3, -1) => 0.106397
+(0, 19) ~ (3, -1) => 0.195827
+(0, 20) ~ (3, -1) => 0.418303
+(0, 21) ~ (3, -1) => 0.563946
+(0, 22) ~ (3, -1) => 0.360759
+(0, 23) ~ (3, -1) => 0.0978343
+(0, 24) ~ (3, -1) => 0.0401203
+(0, 25) ~ (3, -1) => 0.0151714
+(0, 26) ~ (3, -1) => 0.0121314
+(0, 27) ~ (3, -1) => 0.0119274
+(0, 28) ~ (3, -1) => 0.0109543
+(0, 29) ~ (3, -1) => 0.00824177
+(0, 30) ~ (3, -1) => 0.00641978
+(0, 31) ~ (3, -1) => 0.0029487
+(0, 32) ~ (3, -1) => 0.000938058
+(0, 33) ~ (3, -1) => 0.000746369
+(0, 34) ~ (3, -1) => 0.000598431
+(0, 35) ~ (3, -1) => 0.000399947
+(0, 36) ~ (3, -1) => 0.000161827
+(0, 37) ~ (3, -1) => 0.000144482
+(0, 38) ~ (3, -1) => 0.000179291
+(0, 39) ~ (3, -1) => 0.000188351
+(0, 40) ~ (3, -1) => 0.000388086
+(0, 41) ~ (3, -1) => 0.000535131
+(0, 42) ~ (3, -1) => 0.000538945
+(0, 43) ~ (3, -1) => 0.000398278
+(0, 44) ~ (3, -1) => 0.000149846
+(0, 45) ~ (3, -1) => 0.0001
+(0, 46) ~ (3, -1) => 0.000142753
+(0, 47) ~ (3, -1) => 0.000281751
+(0, 48) ~ (3, -1) => 0.000373542
+(0, 49) ~ (3, -1) => 0.000415087
+(0, 50) ~ (3, -1) => 0.000506997
+(0, 51) ~ (3, -1) => 0.00105882
+(0, 52) ~ (3, -1) => 0.0019685
+(0, 53) ~ (3, -1) => 0.00251979
+(0, 54) ~ (3, -1) => 0.00376737
+(0, 55) ~ (3, -1) => 0.00510007
+(0, 56) ~ (3, -1) => 0.0104493
+(0, 57) ~ (3, -1) => 0.031108
+(0, 58) ~ (3, -1) => 0.0666679
+(0, 59) ~ (3, -1) => 0.238989
+(0, 60) ~ (3, -1) => 0.438379
+(0, 61) ~ (3, -1) => 0.559391
+(0, 62) ~ (3, -1) => 0.612514
+(0, 63) ~ (3, -1) => 0.659433
+(0, 64) ~ (3, -1) => 0.632789
+(0, 65) ~ (3, -1) => 0.493403
+(0, 66) ~ (3, -1) => 0.445273
+(0, 67) ~ (3, -1) => 0.331957
+(0, 68) ~ (3, -1) => 0.168729
+(0, 69) ~ (3, -1) => 0.162501
+(0, 70) ~ (3, -1) => 0.120545
+(0, 71) ~ (3, -1) => 0.0929495
+(0, 72) ~ (3, -1) => 0.0537543
+(0, 73) ~ (3, -1) => 0.0544643
+(0, 74) ~ (3, -1) => 0.0587308
+(0, 75) ~ (3, -1) => 0.0541616
+(0, 76) ~ (3, -1) => 0.0714257
+(0, 77) ~ (3, -1) => 0.0878251
+(0, 78) ~ (3, -1) => 0.0904407
+(0, 79) ~ (3, -1) => 0.0910551
+(0, 80) ~ (3, -1) => 0.0915482
+(0, 81) ~ (3, -1) => 0.0916103
+(0, 82) ~ (3, -1) => 0.085554
+(0, 83) ~ (3, -1) => 0.0838077
+(0, 84) ~ (3, -1) => 0.0770595
+(0, 85) ~ (3, -1) => 0.0727105
+(0, 86) ~ (3, -1) => 0.0649474
+(0, 87) ~ (3, -1) => 0.0651438
+(0, 88) ~ (3, -1) => 0.0657876
+(0, 89) ~ (3, -1) => 0.0631709
+(0, 90) ~ (3, -1) => 0.0711407
+(0, 91) ~ (3, -1) => 0.0984477
+(0, 92) ~ (3, -1) => 0.117405
+(0, 93) ~ (3, -1) => 0.108994
+(0, 94) ~ (3, -1) => 0.128919
+(0, 95) ~ (3, -1) => 0.139817
+(0, 96) ~ (3, -1) => 0.145293
+(0, 97) ~ (3, -1) => 0.159759
+(0, 98) ~ (3, -1) => 0.141462
+(0, 99) ~ (3, -1) => 0.133857
+(0, 100) ~ (3, -1) => 0.120057
+(0, 101) ~ (3, -1) => 0.111452
+(0, 102) ~ (3, -1) => 0.120415
+(0, 103) ~ (3, -1) => 0.133431
+(0, 104) ~ (3, -1) => 0.26439
+(0, 105) ~ (3, -1) => 0.347961
+(0, 106) ~ (3, -1) => 0.30714
+(0, 107) ~ (3, -1) => 0.158028
+(0, 108) ~ (3, -1) => 0.117485
+
+(0, -1) ~ (3, 0) => 0.00813264
+(0, -1) ~ (3, 1) => 0.01152
+(0, -1) ~ (3, 2) => 0.0139424
+(0, -1) ~ (3, 3) => 0.0199518
+(0, -1) ~ (3, 4) => 0.033759
+(0, -1) ~ (3, 5) => 0.0429425
+(0, -1) ~ (3, 6) => 0.0479432
+(0, -1) ~ (3, 7) => 0.0572033
+(0, -1) ~ (3, 8) => 0.059129
+(0, -1) ~ (3, 9) => 0.061642
+(0, -1) ~ (3, 10) => 0.0589249
+(0, -1) ~ (3, 11) => 0.0637322
+(0, -1) ~ (3, 12) => 0.0645505
+(0, -1) ~ (3, 13) => 0.0500437
+(0, -1) ~ (3, 14) => 0.0284864
+(0, -1) ~ (3, 15) => 0.0339478
+(0, -1) ~ (3, 16) => 0.0320911
+(0, -1) ~ (3, 17) => 0.0481662
+(0, -1) ~ (3, 18) => 0.0279616
+(0, -1) ~ (3, 19) => 0.0275358
+(0, -1) ~ (3, 20) => 0.0244409
+(0, -1) ~ (3, 21) => 0.020787
+(0, -1) ~ (3, 22) => 0.0208781
+(0, -1) ~ (3, 23) => 0.0151714
+(0, -1) ~ (3, 24) => 0.0121314
+(0, -1) ~ (3, 25) => 0.0119274
+(0, -1) ~ (3, 26) => 0.0109543
+(0, -1) ~ (3, 27) => 0.00824177
+(0, -1) ~ (3, 28) => 0.00641978
+(0, -1) ~ (3, 29) => 0.0029487
+(0, -1) ~ (3, 30) => 0.000938058
+(0, -1) ~ (3, 31) => 0.000746369
+(0, -1) ~ (3, 32) => 0.000598431
+(0, -1) ~ (3, 33) => 0.000399947
+(0, -1) ~ (3, 34) => 0.000161827
+(0, -1) ~ (3, 35) => 0.000144482
+(0, -1) ~ (3, 36) => 0.000179291
+(0, -1) ~ (3, 37) => 0.000188351
+(0, -1) ~ (3, 38) => 0.000388086
+(0, -1) ~ (3, 39) => 0.000535131
+(0, -1) ~ (3, 40) => 0.000538945
+(0, -1) ~ (3, 41) => 0.000398278
+(0, -1) ~ (3, 42) => 0.000149846
+(0, -1) ~ (3, 43) => 0.0001
+(0, -1) ~ (3, 44) => 0.000142753
+(0, -1) ~ (3, 45) => 0.000281751
+(0, -1) ~ (3, 46) => 0.000373542
+(0, -1) ~ (3, 47) => 0.000415087
+(0, -1) ~ (3, 48) => 0.000506997
+(0, -1) ~ (3, 49) => 0.00105882
+(0, -1) ~ (3, 50) => 0.0019685
+(0, -1) ~ (3, 51) => 0.00251979
+(0, -1) ~ (3, 52) => 0.00376737
+(0, -1) ~ (3, 53) => 0.00510007
+(0, -1) ~ (3, 54) => 0.0104493
+(0, -1) ~ (3, 55) => 0.0447875
+(0, -1) ~ (3, 56) => 0.0597006
+(0, -1) ~ (3, 57) => 0.0733408
+(0, -1) ~ (3, 58) => 0.116444
+(0, -1) ~ (3, 59) => 0.111101
+(0, -1) ~ (3, 60) => 0.12075
+(0, -1) ~ (3, 61) => 0.107515
+(0, -1) ~ (3, 62) => 0.133753
+(0, -1) ~ (3, 63) => 0.210013
+(0, -1) ~ (3, 64) => 0.261531
+(0, -1) ~ (3, 65) => 0.344473
+(0, -1) ~ (3, 66) => 0.472737
+(0, -1) ~ (3, 67) => 0.366075
+(0, -1) ~ (3, 68) => 0.295865
+(0, -1) ~ (3, 69) => 0.191157
+(0, -1) ~ (3, 70) => 0.174805
+(0, -1) ~ (3, 71) => 0.180721
+(0, -1) ~ (3, 72) => 0.163264
+(0, -1) ~ (3, 73) => 0.186426
+(0, -1) ~ (3, 74) => 0.224748
+(0, -1) ~ (3, 75) => 0.205047
+(0, -1) ~ (3, 76) => 0.146098
+(0, -1) ~ (3, 77) => 0.129241
+(0, -1) ~ (3, 78) => 0.119438
+(0, -1) ~ (3, 79) => 0.137679
+(0, -1) ~ (3, 80) => 0.0877153
+(0, -1) ~ (3, 81) => 0.0455436
+(0, -1) ~ (3, 82) => 0.041021
+(0, -1) ~ (3, 83) => 0.0436479
+(0, -1) ~ (3, 84) => 0.132014
+(0, -1) ~ (3, 85) => 0.0984307
+(0, -1) ~ (3, 86) => 0.128919
+(0, -1) ~ (3, 87) => 0.20071
+(0, -1) ~ (3, 88) => 0.252233
+(0, -1) ~ (3, 89) => 0.301824
+(0, -1) ~ (3, 90) => 0.370041
+(0, -1) ~ (3, 91) => 0.500137
+(0, -1) ~ (3, 92) => 0.521987
+(0, -1) ~ (3, 93) => 0.575197
+(0, -1) ~ (3, 94) => 0.595146
+(0, -1) ~ (3, 95) => 0.64668
+(0, -1) ~ (3, 96) => 0.704551
+(0, -1) ~ (3, 97) => 0.679206
+(0, -1) ~ (3, 98) => 0.697182
+(0, -1) ~ (3, 99) => 0.707001
+(0, -1) ~ (3, 100) => 0.72694
+(0, -1) ~ (3, 101) => 0.736101
+(0, -1) ~ (3, 102) => 0.701378
+(0, -1) ~ (3, 103) => 0.651804
+(0, -1) ~ (3, 104) => 0.633464
+(0, -1) ~ (3, 105) => 0.617702
+(0, -1) ~ (3, 106) => 0.653481
+(0, -1) ~ (3, 107) => 0.657626
+(0, -1) ~ (3, 108) => 0.654281
+(0, -1) ~ (3, 109) => 0.665736
+(0, -1) ~ (3, 110) => 0.728148
+(0, -1) ~ (3, 111) => 0.695153
+(0, -1) ~ (3, 112) => 0.666282
+(0, -1) ~ (3, 113) => 0.660904
+(0, -1) ~ (3, 114) => 0.676833
+(0, -1) ~ (3, 115) => 0.669175
+(0, -1) ~ (3, 116) => 0.669366
+(0, -1) ~ (3, 117) => 0.663512
+(0, -1) ~ (3, 118) => 0.600649
+(0, -1) ~ (3, 119) => 0.49802
+(0, -1) ~ (3, 120) => 0.3774
+(0, -1) ~ (3, 121) => 0.306325
+(0, -1) ~ (3, 122) => 0.259521
+(0, -1) ~ (3, 123) => 0.227581
+
+; Sparse posterior probability matrix for sequences 0 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (4, 0) => 0.0685493
+(0, 0) ~ (4, 1) => 0.928174
+(0, 1) ~ (4, 2) => 0.990694
+(0, 2) ~ (4, 3) => 0.999008
+(0, 3) ~ (4, 4) => 0.999664
+(0, 4) ~ (4, 5) => 0.999885
+(0, 5) ~ (4, 6) => 0.999936
+(0, 6) ~ (4, 7) => 0.999927
+(0, 7) ~ (4, 8) => 0.999926
+(0, 8) ~ (4, 9) => 0.999752
+(0, 9) ~ (4, 10) => 0.999633
+(0, 10) ~ (4, 11) => 0.999691
+(0, 11) ~ (4, 12) => 0.999873
+(0, 12) ~ (4, 13) => 0.999844
+(0, 13) ~ (4, 14) => 0.999783
+(0, 14) ~ (4, 15) => 0.998772
+(0, 15) ~ (4, 16) => 0.997554
+(0, 16) ~ (4, 17) => 0.993503
+(0, 17) ~ (4, 18) => 0.93804
+(0, 17) ~ (4, 19) => 0.0363687
+(0, 17) ~ (4, 20) => 0.0117184
+(0, 18) ~ (4, 19) => 0.573393
+(0, 18) ~ (4, 20) => 0.281092
+(0, 19) ~ (4, 20) => 0.399574
+(0, 19) ~ (4, 21) => 0.23041
+(0, 20) ~ (4, 19) => 0.0191132
+(0, 20) ~ (4, 21) => 0.209082
+(0, 20) ~ (4, 22) => 0.148643
+(0, 21) ~ (4, 19) => 0.105571
+(0, 21) ~ (4, 20) => 0.166341
+(0, 21) ~ (4, 22) => 0.0124598
+(0, 21) ~ (4, 23) => 0.141672
+(0, 22) ~ (4, 21) => 0.544217
+(0, 22) ~ (4, 24) => 0.1303
+(0, 23) ~ (4, 22) => 0.828868
+(0, 23) ~ (4, 25) => 0.0156221
+(0, 24) ~ (4, 23) => 0.853434
+(0, 25) ~ (4, 24) => 0.864326
+(0, 26) ~ (4, 25) => 0.98019
+(0, 27) ~ (4, 26) => 0.997835
+(0, 28) ~ (4, 27) => 0.998673
+(0, 29) ~ (4, 28) => 0.999198
+(0, 30) ~ (4, 29) => 0.999648
+(0, 31) ~ (4, 30) => 0.999915
+(0, 32) ~ (4, 31) => 0.999919
+(0, 33) ~ (4, 32) => 0.999554
+(0, 34) ~ (4, 33) => 0.999314
+(0, 35) ~ (4, 34) => 0.999256
+(0, 36) ~ (4, 35) => 0.998656
+(0, 37) ~ (4, 36) => 0.996646
+(0, 38) ~ (4, 37) => 0.997332
+(0, 39) ~ (4, 38) => 0.997869
+(0, 40) ~ (4, 39) => 0.997757
+(0, 41) ~ (4, 40) => 0.997212
+(0, 42) ~ (4, 41) => 0.996675
+(0, 43) ~ (4, 42) => 0.995236
+(0, 44) ~ (4, 43) => 0.995604
+(0, 45) ~ (4, 44) => 0.98826
+(0, 46) ~ (4, 45) => 0.98982
+(0, 47) ~ (4, 46) => 0.997883
+(0, 48) ~ (4, 47) => 0.998663
+(0, 49) ~ (4, 48) => 0.999265
+(0, 50) ~ (4, 49) => 0.999919
+(0, 51) ~ (4, 50) => 0.999945
+(0, 52) ~ (4, 51) => 0.999731
+(0, 53) ~ (4, 52) => 0.99962
+(0, 54) ~ (4, 53) => 0.99971
+(0, 55) ~ (4, 54) => 0.999883
+(0, 56) ~ (4, 55) => 0.99991
+(0, 57) ~ (4, 56) => 0.999979
+(0, 58) ~ (4, 57) => 0.999982
+(0, 59) ~ (4, 58) => 0.999912
+(0, 60) ~ (4, 59) => 0.999889
+(0, 61) ~ (4, 60) => 0.999927
+(0, 62) ~ (4, 61) => 0.999917
+(0, 63) ~ (4, 62) => 0.99991
+(0, 64) ~ (4, 63) => 0.999789
+(0, 65) ~ (4, 64) => 0.999673
+(0, 66) ~ (4, 65) => 0.997048
+(0, 67) ~ (4, 66) => 0.993512
+(0, 68) ~ (4, 67) => 0.957964
+(0, 68) ~ (4, 68) => 0.0367749
+(0, 69) ~ (4, 68) => 0.525538
+(0, 69) ~ (4, 69) => 0.46585
+(0, 70) ~ (4, 69) => 0.079997
+(0, 70) ~ (4, 70) => 0.893719
+(0, 71) ~ (4, 70) => 0.0332981
+(0, 71) ~ (4, 71) => 0.926287
+(0, 72) ~ (4, 70) => 0.0138136
+(0, 72) ~ (4, 71) => 0.0203423
+(0, 72) ~ (4, 72) => 0.923354
+(0, 73) ~ (4, 71) => 0.014364
+(0, 73) ~ (4, 72) => 0.0183578
+(0, 73) ~ (4, 73) => 0.502176
+(0, 74) ~ (4, 71) => 0.0113816
+(0, 74) ~ (4, 74) => 0.0798016
+(0, 75) ~ (4, 72) => 0.0316094
+(0, 75) ~ (4, 75) => 0.0406294
+(0, 76) ~ (4, 73) => 0.485605
+(0, 77) ~ (4, 74) => 0.917435
+(0, 78) ~ (4, 75) => 0.957652
+(0, 79) ~ (4, 76) => 0.997743
+(0, 80) ~ (4, 77) => 0.998173
+(0, 81) ~ (4, 78) => 0.994806
+(0, 82) ~ (4, 79) => 0.921947
+(0, 82) ~ (4, 80) => 0.0775773
+(0, 83) ~ (4, 80) => 0.848199
+(0, 83) ~ (4, 81) => 0.149434
+(0, 84) ~ (4, 81) => 0.842274
+(0, 84) ~ (4, 82) => 0.154807
+(0, 85) ~ (4, 82) => 0.836848
+(0, 85) ~ (4, 83) => 0.160303
+(0, 86) ~ (4, 83) => 0.831399
+(0, 86) ~ (4, 84) => 0.159048
+(0, 87) ~ (4, 84) => 0.838789
+(0, 87) ~ (4, 85) => 0.1022
+(0, 88) ~ (4, 85) => 0.89583
+(0, 88) ~ (4, 86) => 0.0948958
+(0, 89) ~ (4, 86) => 0.89989
+(0, 89) ~ (4, 87) => 0.0977824
+(0, 90) ~ (4, 87) => 0.896267
+(0, 90) ~ (4, 88) => 0.100007
+(0, 91) ~ (4, 88) => 0.843611
+(0, 91) ~ (4, 89) => 0.142713
+(0, 92) ~ (4, 89) => 0.786196
+(0, 92) ~ (4, 90) => 0.184553
+(0, 93) ~ (4, 90) => 0.71564
+(0, 93) ~ (4, 91) => 0.224687
+(0, 93) ~ (4, 92) => 0.0109676
+(0, 93) ~ (4, 98) => 0.0273412
+(0, 94) ~ (4, 91) => 0.575572
+(0, 94) ~ (4, 92) => 0.258137
+(0, 94) ~ (4, 99) => 0.117471
+(0, 95) ~ (4, 92) => 0.425969
+(0, 95) ~ (4, 93) => 0.284325
+(0, 95) ~ (4, 100) => 0.206556
+(0, 96) ~ (4, 93) => 0.0253261
+(0, 96) ~ (4, 94) => 0.2962
+(0, 96) ~ (4, 96) => 0.0581775
+(0, 96) ~ (4, 97) => 0.0205122
+(0, 96) ~ (4, 101) => 0.29298
+(0, 97) ~ (4, 91) => 0.0207503
+(0, 97) ~ (4, 93) => 0.0350199
+(0, 97) ~ (4, 95) => 0.0997539
+(0, 97) ~ (4, 97) => 0.0347398
+(0, 97) ~ (4, 98) => 0.0594673
+(0, 97) ~ (4, 99) => 0.0201582
+(0, 97) ~ (4, 100) => 0.0390003
+(0, 97) ~ (4, 102) => 0.260646
+(0, 97) ~ (4, 103) => 0.149235
+(0, 98) ~ (4, 92) => 0.0395182
+(0, 98) ~ (4, 94) => 0.0272065
+(0, 98) ~ (4, 95) => 0.0258033
+(0, 98) ~ (4, 96) => 0.0704728
+(0, 98) ~ (4, 98) => 0.0234196
+(0, 98) ~ (4, 99) => 0.0750239
+(0, 98) ~ (4, 101) => 0.0400529
+(0, 98) ~ (4, 103) => 0.200792
+(0, 98) ~ (4, 104) => 0.20384
+(0, 99) ~ (4, 93) => 0.219145
+(0, 99) ~ (4, 95) => 0.0228627
+(0, 99) ~ (4, 97) => 0.0279184
+(0, 99) ~ (4, 99) => 0.0200692
+(0, 99) ~ (4, 100) => 0.106985
+(0, 99) ~ (4, 102) => 0.03746
+(0, 99) ~ (4, 103) => 0.0219254
+(0, 99) ~ (4, 104) => 0.107637
+(0, 99) ~ (4, 105) => 0.349067
+(0, 100) ~ (4, 94) => 0.225204
+(0, 100) ~ (4, 96) => 0.0274896
+(0, 100) ~ (4, 101) => 0.104691
+(0, 100) ~ (4, 105) => 0.015137
+(0, 100) ~ (4, 106) => 0.547125
+(0, 101) ~ (4, 95) => 0.206583
+(0, 101) ~ (4, 96) => 0.0333389
+(0, 101) ~ (4, 97) => 0.0164481
+(0, 101) ~ (4, 102) => 0.0894267
+(0, 101) ~ (4, 103) => 0.0102073
+(0, 101) ~ (4, 107) => 0.574461
+(0, 102) ~ (4, 96) => 0.0215192
+(0, 102) ~ (4, 97) => 0.175344
+(0, 102) ~ (4, 98) => 0.0304785
+(0, 102) ~ (4, 103) => 0.0868121
+(0, 102) ~ (4, 104) => 0.0306793
+(0, 102) ~ (4, 108) => 0.626721
+(0, 103) ~ (4, 97) => 0.0199041
+(0, 103) ~ (4, 98) => 0.173549
+(0, 103) ~ (4, 99) => 0.0240597
+(0, 103) ~ (4, 104) => 0.097902
+(0, 103) ~ (4, 105) => 0.0299256
+(0, 103) ~ (4, 109) => 0.631448
+(0, 104) ~ (4, 98) => 0.0118278
+(0, 104) ~ (4, 99) => 0.151768
+(0, 104) ~ (4, 100) => 0.0294297
+(0, 104) ~ (4, 105) => 0.0955867
+(0, 104) ~ (4, 110) => 0.671125
+(0, 105) ~ (4, 101) => 0.0174874
+(0, 105) ~ (4, 106) => 0.0843662
+(0, 105) ~ (4, 111) => 0.88025
+(0, 106) ~ (4, 107) => 0.058373
+(0, 106) ~ (4, 112) => 0.935492
+(0, 107) ~ (4, 108) => 0.0317586
+(0, 107) ~ (4, 113) => 0.967148
+(0, 108) ~ (4, 114) => 0.994341
+
+; gap posteriors
+(0, 0) ~ (4, -1) => 0.00327629
+(0, 1) ~ (4, -1) => 0.0093056
+(0, 2) ~ (4, -1) => 0.000991702
+(0, 3) ~ (4, -1) => 0.00033617
+(0, 4) ~ (4, -1) => 0.00011462
+(0, 5) ~ (4, -1) => 0.0001
+(0, 6) ~ (4, -1) => 0.0001
+(0, 7) ~ (4, -1) => 0.0001
+(0, 8) ~ (4, -1) => 0.000248313
+(0, 9) ~ (4, -1) => 0.000366569
+(0, 10) ~ (4, -1) => 0.000309169
+(0, 11) ~ (4, -1) => 0.00012666
+(0, 12) ~ (4, -1) => 0.000156105
+(0, 13) ~ (4, -1) => 0.000217438
+(0, 14) ~ (4, -1) => 0.00122839
+(0, 15) ~ (4, -1) => 0.00244635
+(0, 16) ~ (4, -1) => 0.00649691
+(0, 17) ~ (4, -1) => 0.0138724
+(0, 18) ~ (4, -1) => 0.145515
+(0, 19) ~ (4, -1) => 0.370016
+(0, 20) ~ (4, -1) => 0.623162
+(0, 21) ~ (4, -1) => 0.573956
+(0, 22) ~ (4, -1) => 0.325482
+(0, 23) ~ (4, -1) => 0.15551
+(0, 24) ~ (4, -1) => 0.146566
+(0, 25) ~ (4, -1) => 0.135674
+(0, 26) ~ (4, -1) => 0.0198103
+(0, 27) ~ (4, -1) => 0.00216538
+(0, 28) ~ (4, -1) => 0.00132662
+(0, 29) ~ (4, -1) => 0.0008021
+(0, 30) ~ (4, -1) => 0.000351548
+(0, 31) ~ (4, -1) => 0.0001
+(0, 32) ~ (4, -1) => 0.0001
+(0, 33) ~ (4, -1) => 0.000446498
+(0, 34) ~ (4, -1) => 0.00068593
+(0, 35) ~ (4, -1) => 0.000744045
+(0, 36) ~ (4, -1) => 0.00134385
+(0, 37) ~ (4, -1) => 0.00335401
+(0, 38) ~ (4, -1) => 0.00266784
+(0, 39) ~ (4, -1) => 0.00213093
+(0, 40) ~ (4, -1) => 0.00224334
+(0, 41) ~ (4, -1) => 0.00278765
+(0, 42) ~ (4, -1) => 0.00332457
+(0, 43) ~ (4, -1) => 0.00476408
+(0, 44) ~ (4, -1) => 0.00439626
+(0, 45) ~ (4, -1) => 0.0117399
+(0, 46) ~ (4, -1) => 0.0101799
+(0, 47) ~ (4, -1) => 0.00211692
+(0, 48) ~ (4, -1) => 0.00133735
+(0, 49) ~ (4, -1) => 0.000734568
+(0, 50) ~ (4, -1) => 0.0001
+(0, 51) ~ (4, -1) => 0.0001
+(0, 52) ~ (4, -1) => 0.000268519
+(0, 53) ~ (4, -1) => 0.000380456
+(0, 54) ~ (4, -1) => 0.000289798
+(0, 55) ~ (4, -1) => 0.000117421
+(0, 56) ~ (4, -1) => 0.0001
+(0, 57) ~ (4, -1) => 0.0001
+(0, 58) ~ (4, -1) => 0.0001
+(0, 59) ~ (4, -1) => 0.0001
+(0, 60) ~ (4, -1) => 0.000110865
+(0, 61) ~ (4, -1) => 0.0001
+(0, 62) ~ (4, -1) => 0.0001
+(0, 63) ~ (4, -1) => 0.0001
+(0, 64) ~ (4, -1) => 0.000210643
+(0, 65) ~ (4, -1) => 0.000327051
+(0, 66) ~ (4, -1) => 0.00295168
+(0, 67) ~ (4, -1) => 0.00648785
+(0, 68) ~ (4, -1) => 0.00526083
+(0, 69) ~ (4, -1) => 0.0086123
+(0, 70) ~ (4, -1) => 0.0262842
+(0, 71) ~ (4, -1) => 0.0404147
+(0, 72) ~ (4, -1) => 0.0424904
+(0, 73) ~ (4, -1) => 0.465102
+(0, 74) ~ (4, -1) => 0.908817
+(0, 75) ~ (4, -1) => 0.927761
+(0, 76) ~ (4, -1) => 0.514395
+(0, 77) ~ (4, -1) => 0.0825648
+(0, 78) ~ (4, -1) => 0.0423482
+(0, 79) ~ (4, -1) => 0.00225741
+(0, 80) ~ (4, -1) => 0.00182718
+(0, 81) ~ (4, -1) => 0.00519449
+(0, 82) ~ (4, -1) => 0.000475489
+(0, 83) ~ (4, -1) => 0.00236666
+(0, 84) ~ (4, -1) => 0.00291917
+(0, 85) ~ (4, -1) => 0.00284842
+(0, 86) ~ (4, -1) => 0.00955321
+(0, 87) ~ (4, -1) => 0.0590103
+(0, 88) ~ (4, -1) => 0.00927406
+(0, 89) ~ (4, -1) => 0.00232802
+(0, 90) ~ (4, -1) => 0.0037252
+(0, 91) ~ (4, -1) => 0.0136756
+(0, 92) ~ (4, -1) => 0.0292517
+(0, 93) ~ (4, -1) => 0.0213637
+(0, 94) ~ (4, -1) => 0.0488198
+(0, 95) ~ (4, -1) => 0.0831507
+(0, 96) ~ (4, -1) => 0.306804
+(0, 97) ~ (4, -1) => 0.281228
+(0, 98) ~ (4, -1) => 0.293871
+(0, 99) ~ (4, -1) => 0.0869304
+(0, 100) ~ (4, -1) => 0.0803542
+(0, 101) ~ (4, -1) => 0.0695347
+(0, 102) ~ (4, -1) => 0.0284455
+(0, 103) ~ (4, -1) => 0.0232119
+(0, 104) ~ (4, -1) => 0.0402629
+(0, 105) ~ (4, -1) => 0.0178959
+(0, 106) ~ (4, -1) => 0.00613475
+(0, 107) ~ (4, -1) => 0.00109333
+(0, 108) ~ (4, -1) => 0.00565946
+
+(0, -1) ~ (4, 0) => 0.931451
+(0, -1) ~ (4, 1) => 0.0718256
+(0, -1) ~ (4, 2) => 0.0093056
+(0, -1) ~ (4, 3) => 0.000991702
+(0, -1) ~ (4, 4) => 0.00033617
+(0, -1) ~ (4, 5) => 0.00011462
+(0, -1) ~ (4, 6) => 0.0001
+(0, -1) ~ (4, 7) => 0.0001
+(0, -1) ~ (4, 8) => 0.0001
+(0, -1) ~ (4, 9) => 0.000248313
+(0, -1) ~ (4, 10) => 0.000366569
+(0, -1) ~ (4, 11) => 0.000309169
+(0, -1) ~ (4, 12) => 0.00012666
+(0, -1) ~ (4, 13) => 0.000156105
+(0, -1) ~ (4, 14) => 0.000217438
+(0, -1) ~ (4, 15) => 0.00122839
+(0, -1) ~ (4, 16) => 0.00244635
+(0, -1) ~ (4, 17) => 0.00649691
+(0, -1) ~ (4, 18) => 0.0619596
+(0, -1) ~ (4, 19) => 0.265554
+(0, -1) ~ (4, 20) => 0.141275
+(0, -1) ~ (4, 21) => 0.01629
+(0, -1) ~ (4, 22) => 0.0100297
+(0, -1) ~ (4, 23) => 0.0048942
+(0, -1) ~ (4, 24) => 0.0053736
+(0, -1) ~ (4, 25) => 0.00418812
+(0, -1) ~ (4, 26) => 0.00216538
+(0, -1) ~ (4, 27) => 0.00132662
+(0, -1) ~ (4, 28) => 0.0008021
+(0, -1) ~ (4, 29) => 0.000351548
+(0, -1) ~ (4, 30) => 0.0001
+(0, -1) ~ (4, 31) => 0.0001
+(0, -1) ~ (4, 32) => 0.000446498
+(0, -1) ~ (4, 33) => 0.00068593
+(0, -1) ~ (4, 34) => 0.000744045
+(0, -1) ~ (4, 35) => 0.00134385
+(0, -1) ~ (4, 36) => 0.00335401
+(0, -1) ~ (4, 37) => 0.00266784
+(0, -1) ~ (4, 38) => 0.00213093
+(0, -1) ~ (4, 39) => 0.00224334
+(0, -1) ~ (4, 40) => 0.00278765
+(0, -1) ~ (4, 41) => 0.00332457
+(0, -1) ~ (4, 42) => 0.00476408
+(0, -1) ~ (4, 43) => 0.00439626
+(0, -1) ~ (4, 44) => 0.0117399
+(0, -1) ~ (4, 45) => 0.0101799
+(0, -1) ~ (4, 46) => 0.00211692
+(0, -1) ~ (4, 47) => 0.00133735
+(0, -1) ~ (4, 48) => 0.000734568
+(0, -1) ~ (4, 49) => 0.0001
+(0, -1) ~ (4, 50) => 0.0001
+(0, -1) ~ (4, 51) => 0.000268519
+(0, -1) ~ (4, 52) => 0.000380456
+(0, -1) ~ (4, 53) => 0.000289798
+(0, -1) ~ (4, 54) => 0.000117421
+(0, -1) ~ (4, 55) => 0.0001
+(0, -1) ~ (4, 56) => 0.0001
+(0, -1) ~ (4, 57) => 0.0001
+(0, -1) ~ (4, 58) => 0.0001
+(0, -1) ~ (4, 59) => 0.000110865
+(0, -1) ~ (4, 60) => 0.0001
+(0, -1) ~ (4, 61) => 0.0001
+(0, -1) ~ (4, 62) => 0.0001
+(0, -1) ~ (4, 63) => 0.000210643
+(0, -1) ~ (4, 64) => 0.000327051
+(0, -1) ~ (4, 65) => 0.00295168
+(0, -1) ~ (4, 66) => 0.00648785
+(0, -1) ~ (4, 67) => 0.0420357
+(0, -1) ~ (4, 68) => 0.437688
+(0, -1) ~ (4, 69) => 0.454153
+(0, -1) ~ (4, 70) => 0.0591694
+(0, -1) ~ (4, 71) => 0.0276248
+(0, -1) ~ (4, 72) => 0.0266792
+(0, -1) ~ (4, 73) => 0.012219
+(0, -1) ~ (4, 74) => 0.00276321
+(0, -1) ~ (4, 75) => 0.00171882
+(0, -1) ~ (4, 76) => 0.00225741
+(0, -1) ~ (4, 77) => 0.00182718
+(0, -1) ~ (4, 78) => 0.00519449
+(0, -1) ~ (4, 79) => 0.0780528
+(0, -1) ~ (4, 80) => 0.0742232
+(0, -1) ~ (4, 81) => 0.00829262
+(0, -1) ~ (4, 82) => 0.00834453
+(0, -1) ~ (4, 83) => 0.00829756
+(0, -1) ~ (4, 84) => 0.00216293
+(0, -1) ~ (4, 85) => 0.0019694
+(0, -1) ~ (4, 86) => 0.00521463
+(0, -1) ~ (4, 87) => 0.00595015
+(0, -1) ~ (4, 88) => 0.0563815
+(0, -1) ~ (4, 89) => 0.0710911
+(0, -1) ~ (4, 90) => 0.0998072
+(0, -1) ~ (4, 91) => 0.17899
+(0, -1) ~ (4, 92) => 0.265408
+(0, -1) ~ (4, 93) => 0.436184
+(0, -1) ~ (4, 94) => 0.45139
+(0, -1) ~ (4, 95) => 0.644997
+(0, -1) ~ (4, 96) => 0.789002
+(0, -1) ~ (4, 97) => 0.705133
+(0, -1) ~ (4, 98) => 0.673917
+(0, -1) ~ (4, 99) => 0.59145
+(0, -1) ~ (4, 100) => 0.618029
+(0, -1) ~ (4, 101) => 0.544789
+(0, -1) ~ (4, 102) => 0.612467
+(0, -1) ~ (4, 103) => 0.531028
+(0, -1) ~ (4, 104) => 0.559942
+(0, -1) ~ (4, 105) => 0.510284
+(0, -1) ~ (4, 106) => 0.368509
+(0, -1) ~ (4, 107) => 0.367166
+(0, -1) ~ (4, 108) => 0.34152
+(0, -1) ~ (4, 109) => 0.368552
+(0, -1) ~ (4, 110) => 0.328875
+(0, -1) ~ (4, 111) => 0.11975
+(0, -1) ~ (4, 112) => 0.0645077
+(0, -1) ~ (4, 113) => 0.0328519
+(0, -1) ~ (4, 114) => 0.00565946
+
+; Sparse posterior probability matrix for sequences 1 and 2
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (2, 0) => 0.929384
+(1, 0) ~ (2, 1) => 0.0172915
+(1, 1) ~ (2, 0) => 0.042805
+(1, 1) ~ (2, 1) => 0.82223
+(1, 1) ~ (2, 2) => 0.0354121
+(1, 2) ~ (2, 1) => 0.117478
+(1, 2) ~ (2, 2) => 0.724091
+(1, 2) ~ (2, 3) => 0.0611122
+(1, 3) ~ (2, 1) => 0.0108887
+(1, 3) ~ (2, 2) => 0.176789
+(1, 3) ~ (2, 3) => 0.635821
+(1, 3) ~ (2, 4) => 0.0793803
+(1, 3) ~ (2, 5) => 0.0106468
+(1, 4) ~ (2, 2) => 0.014396
+(1, 4) ~ (2, 3) => 0.236936
+(1, 4) ~ (2, 4) => 0.425423
+(1, 4) ~ (2, 5) => 0.0908381
+(1, 5) ~ (2, 4) => 0.432597
+(1, 5) ~ (2, 5) => 0.253413
+(1, 5) ~ (2, 6) => 0.144982
+(1, 6) ~ (2, 3) => 0.011298
+(1, 6) ~ (2, 4) => 0.0108901
+(1, 6) ~ (2, 5) => 0.545752
+(1, 6) ~ (2, 6) => 0.203459
+(1, 6) ~ (2, 7) => 0.148368
+(1, 7) ~ (2, 4) => 0.0159126
+(1, 7) ~ (2, 5) => 0.0109725
+(1, 7) ~ (2, 6) => 0.590091
+(1, 7) ~ (2, 7) => 0.176868
+(1, 7) ~ (2, 8) => 0.139487
+(1, 8) ~ (2, 5) => 0.0177648
+(1, 8) ~ (2, 6) => 0.0153628
+(1, 8) ~ (2, 7) => 0.611807
+(1, 8) ~ (2, 8) => 0.17702
+(1, 8) ~ (2, 9) => 0.140628
+(1, 9) ~ (2, 6) => 0.0187358
+(1, 9) ~ (2, 7) => 0.0215531
+(1, 9) ~ (2, 8) => 0.608021
+(1, 9) ~ (2, 9) => 0.162484
+(1, 9) ~ (2, 10) => 0.151334
+(1, 10) ~ (2, 7) => 0.020771
+(1, 10) ~ (2, 8) => 0.0233651
+(1, 10) ~ (2, 9) => 0.577406
+(1, 10) ~ (2, 10) => 0.157481
+(1, 10) ~ (2, 11) => 0.165292
+(1, 11) ~ (2, 8) => 0.0288916
+(1, 11) ~ (2, 9) => 0.0393763
+(1, 11) ~ (2, 10) => 0.564113
+(1, 11) ~ (2, 11) => 0.138604
+(1, 11) ~ (2, 12) => 0.171836
+(1, 12) ~ (2, 9) => 0.034084
+(1, 12) ~ (2, 10) => 0.0539404
+(1, 12) ~ (2, 11) => 0.555499
+(1, 12) ~ (2, 12) => 0.116379
+(1, 12) ~ (2, 13) => 0.183315
+(1, 13) ~ (2, 10) => 0.0353222
+(1, 13) ~ (2, 11) => 0.0690026
+(1, 13) ~ (2, 12) => 0.541904
+(1, 13) ~ (2, 13) => 0.116402
+(1, 13) ~ (2, 14) => 0.18681
+(1, 14) ~ (2, 11) => 0.0366529
+(1, 14) ~ (2, 12) => 0.0837644
+(1, 14) ~ (2, 13) => 0.530111
+(1, 14) ~ (2, 14) => 0.112121
+(1, 14) ~ (2, 15) => 0.191987
+(1, 15) ~ (2, 12) => 0.0368112
+(1, 15) ~ (2, 13) => 0.0909817
+(1, 15) ~ (2, 14) => 0.516477
+(1, 15) ~ (2, 15) => 0.0998659
+(1, 15) ~ (2, 16) => 0.195886
+(1, 16) ~ (2, 13) => 0.0422695
+(1, 16) ~ (2, 14) => 0.0931167
+(1, 16) ~ (2, 15) => 0.529851
+(1, 16) ~ (2, 16) => 0.0854771
+(1, 16) ~ (2, 17) => 0.197269
+(1, 17) ~ (2, 14) => 0.047089
+(1, 17) ~ (2, 15) => 0.0862661
+(1, 17) ~ (2, 16) => 0.541963
+(1, 17) ~ (2, 17) => 0.0677278
+(1, 17) ~ (2, 18) => 0.188521
+(1, 18) ~ (2, 15) => 0.0598441
+(1, 18) ~ (2, 16) => 0.0809816
+(1, 18) ~ (2, 17) => 0.556476
+(1, 18) ~ (2, 18) => 0.054198
+(1, 18) ~ (2, 19) => 0.172556
+(1, 19) ~ (2, 16) => 0.0646571
+(1, 19) ~ (2, 17) => 0.0327956
+(1, 19) ~ (2, 18) => 0.628362
+(1, 19) ~ (2, 19) => 0.0491989
+(1, 19) ~ (2, 20) => 0.164817
+(1, 20) ~ (2, 17) => 0.0717264
+(1, 20) ~ (2, 18) => 0.0195883
+(1, 20) ~ (2, 19) => 0.659299
+(1, 20) ~ (2, 20) => 0.0571077
+(1, 20) ~ (2, 21) => 0.149894
+(1, 21) ~ (2, 18) => 0.0761979
+(1, 21) ~ (2, 19) => 0.0148386
+(1, 21) ~ (2, 20) => 0.645614
+(1, 21) ~ (2, 21) => 0.0799899
+(1, 21) ~ (2, 22) => 0.137739
+(1, 22) ~ (2, 19) => 0.0811823
+(1, 22) ~ (2, 20) => 0.0184858
+(1, 22) ~ (2, 21) => 0.637586
+(1, 22) ~ (2, 22) => 0.0943935
+(1, 22) ~ (2, 23) => 0.112445
+(1, 23) ~ (2, 20) => 0.0780335
+(1, 23) ~ (2, 21) => 0.0244514
+(1, 23) ~ (2, 22) => 0.627977
+(1, 23) ~ (2, 23) => 0.114202
+(1, 23) ~ (2, 24) => 0.0991161
+(1, 24) ~ (2, 21) => 0.0680447
+(1, 24) ~ (2, 22) => 0.0257657
+(1, 24) ~ (2, 23) => 0.651617
+(1, 24) ~ (2, 24) => 0.116749
+(1, 24) ~ (2, 25) => 0.0870513
+(1, 25) ~ (2, 22) => 0.0544461
+(1, 25) ~ (2, 23) => 0.0362847
+(1, 25) ~ (2, 24) => 0.665073
+(1, 25) ~ (2, 25) => 0.120222
+(1, 25) ~ (2, 26) => 0.06589
+(1, 26) ~ (2, 23) => 0.0409649
+(1, 26) ~ (2, 24) => 0.049384
+(1, 26) ~ (2, 25) => 0.675642
+(1, 26) ~ (2, 26) => 0.125412
+(1, 26) ~ (2, 27) => 0.0454847
+(1, 27) ~ (2, 24) => 0.033542
+(1, 27) ~ (2, 25) => 0.0504847
+(1, 27) ~ (2, 26) => 0.705335
+(1, 27) ~ (2, 27) => 0.11588
+(1, 27) ~ (2, 28) => 0.0288436
+(1, 28) ~ (2, 25) => 0.0269162
+(1, 28) ~ (2, 26) => 0.0472427
+(1, 28) ~ (2, 27) => 0.748173
+(1, 28) ~ (2, 28) => 0.0833733
+(1, 28) ~ (2, 29) => 0.0189231
+(1, 29) ~ (2, 26) => 0.0218824
+(1, 29) ~ (2, 27) => 0.0261292
+(1, 29) ~ (2, 28) => 0.827432
+(1, 29) ~ (2, 29) => 0.0460351
+(1, 29) ~ (2, 30) => 0.0183381
+(1, 30) ~ (2, 27) => 0.0158313
+(1, 30) ~ (2, 28) => 0.0195295
+(1, 30) ~ (2, 29) => 0.886837
+(1, 30) ~ (2, 30) => 0.0386063
+(1, 30) ~ (2, 31) => 0.0154692
+(1, 31) ~ (2, 28) => 0.0105547
+(1, 31) ~ (2, 30) => 0.914645
+(1, 31) ~ (2, 31) => 0.0333228
+(1, 31) ~ (2, 32) => 0.013625
+(1, 32) ~ (2, 31) => 0.930864
+(1, 32) ~ (2, 32) => 0.0270294
+(1, 32) ~ (2, 33) => 0.0116473
+(1, 33) ~ (2, 32) => 0.942938
+(1, 33) ~ (2, 33) => 0.0200568
+(1, 34) ~ (2, 33) => 0.95557
+(1, 35) ~ (2, 34) => 0.973041
+(1, 36) ~ (2, 35) => 0.968987
+(1, 36) ~ (2, 36) => 0.0107443
+(1, 37) ~ (2, 36) => 0.964048
+(1, 37) ~ (2, 37) => 0.0117784
+(1, 38) ~ (2, 37) => 0.948846
+(1, 38) ~ (2, 38) => 0.0119975
+(1, 39) ~ (2, 37) => 0.0155902
+(1, 39) ~ (2, 38) => 0.933506
+(1, 39) ~ (2, 39) => 0.0116302
+(1, 40) ~ (2, 37) => 0.0112244
+(1, 40) ~ (2, 38) => 0.0228651
+(1, 40) ~ (2, 39) => 0.918937
+(1, 40) ~ (2, 40) => 0.010607
+(1, 41) ~ (2, 38) => 0.018838
+(1, 41) ~ (2, 39) => 0.0290577
+(1, 41) ~ (2, 40) => 0.900594
+(1, 42) ~ (2, 39) => 0.0266084
+(1, 42) ~ (2, 40) => 0.0331291
+(1, 42) ~ (2, 41) => 0.873648
+(1, 43) ~ (2, 40) => 0.04014
+(1, 43) ~ (2, 41) => 0.0407139
+(1, 43) ~ (2, 42) => 0.826359
+(1, 44) ~ (2, 41) => 0.0587632
+(1, 44) ~ (2, 42) => 0.0498568
+(1, 44) ~ (2, 43) => 0.780012
+(1, 45) ~ (2, 42) => 0.0967448
+(1, 45) ~ (2, 43) => 0.0471639
+(1, 45) ~ (2, 44) => 0.703343
+(1, 45) ~ (2, 46) => 0.0127504
+(1, 46) ~ (2, 43) => 0.14613
+(1, 46) ~ (2, 44) => 0.0443921
+(1, 46) ~ (2, 45) => 0.625478
+(1, 46) ~ (2, 46) => 0.0144963
+(1, 46) ~ (2, 47) => 0.0151322
+(1, 47) ~ (2, 44) => 0.223216
+(1, 47) ~ (2, 45) => 0.0329079
+(1, 47) ~ (2, 46) => 0.613432
+(1, 47) ~ (2, 47) => 0.0149047
+(1, 47) ~ (2, 48) => 0.0153323
+(1, 48) ~ (2, 45) => 0.302547
+(1, 48) ~ (2, 46) => 0.035359
+(1, 48) ~ (2, 47) => 0.597552
+(1, 48) ~ (2, 48) => 0.0135077
+(1, 48) ~ (2, 49) => 0.0156507
+(1, 49) ~ (2, 46) => 0.308441
+(1, 49) ~ (2, 47) => 0.043701
+(1, 49) ~ (2, 48) => 0.592943
+(1, 49) ~ (2, 49) => 0.0112589
+(1, 49) ~ (2, 50) => 0.0157552
+(1, 50) ~ (2, 47) => 0.313471
+(1, 50) ~ (2, 48) => 0.0468578
+(1, 50) ~ (2, 49) => 0.591521
+(1, 50) ~ (2, 51) => 0.0161321
+(1, 51) ~ (2, 48) => 0.315013
+(1, 51) ~ (2, 49) => 0.0501163
+(1, 51) ~ (2, 50) => 0.591645
+(1, 51) ~ (2, 52) => 0.0193748
+(1, 52) ~ (2, 49) => 0.313769
+(1, 52) ~ (2, 50) => 0.0496715
+(1, 52) ~ (2, 51) => 0.587646
+(1, 52) ~ (2, 53) => 0.0208746
+(1, 53) ~ (2, 50) => 0.309046
+(1, 53) ~ (2, 51) => 0.0430758
+(1, 53) ~ (2, 52) => 0.603282
+(1, 53) ~ (2, 54) => 0.0202618
+(1, 54) ~ (2, 51) => 0.304874
+(1, 54) ~ (2, 52) => 0.0354613
+(1, 54) ~ (2, 53) => 0.617142
+(1, 54) ~ (2, 55) => 0.0233862
+(1, 55) ~ (2, 52) => 0.298343
+(1, 55) ~ (2, 53) => 0.0210639
+(1, 55) ~ (2, 54) => 0.636886
+(1, 55) ~ (2, 56) => 0.0264612
+(1, 56) ~ (2, 53) => 0.299335
+(1, 56) ~ (2, 54) => 0.015838
+(1, 56) ~ (2, 55) => 0.636192
+(1, 56) ~ (2, 57) => 0.0279195
+(1, 57) ~ (2, 54) => 0.303092
+(1, 57) ~ (2, 55) => 0.0134675
+(1, 57) ~ (2, 56) => 0.63735
+(1, 57) ~ (2, 58) => 0.02958
+(1, 58) ~ (2, 55) => 0.300742
+(1, 58) ~ (2, 56) => 0.0145571
+(1, 58) ~ (2, 57) => 0.629349
+(1, 58) ~ (2, 59) => 0.0293924
+(1, 59) ~ (2, 56) => 0.29945
+(1, 59) ~ (2, 57) => 0.0189903
+(1, 59) ~ (2, 58) => 0.624073
+(1, 59) ~ (2, 60) => 0.0294932
+(1, 60) ~ (2, 57) => 0.289743
+(1, 60) ~ (2, 58) => 0.0291215
+(1, 60) ~ (2, 59) => 0.572471
+(1, 60) ~ (2, 60) => 0.0179927
+(1, 60) ~ (2, 61) => 0.0210304
+(1, 61) ~ (2, 58) => 0.268128
+(1, 61) ~ (2, 59) => 0.0840586
+(1, 61) ~ (2, 60) => 0.494549
+(1, 61) ~ (2, 61) => 0.0459014
+(1, 61) ~ (2, 62) => 0.0186935
+(1, 62) ~ (2, 59) => 0.248421
+(1, 62) ~ (2, 60) => 0.154721
+(1, 62) ~ (2, 61) => 0.361991
+(1, 62) ~ (2, 62) => 0.0684231
+(1, 62) ~ (2, 63) => 0.0173149
+(1, 63) ~ (2, 60) => 0.194387
+(1, 63) ~ (2, 61) => 0.319991
+(1, 63) ~ (2, 62) => 0.305419
+(1, 63) ~ (2, 63) => 0.0750051
+(1, 63) ~ (2, 64) => 0.0144464
+(1, 64) ~ (2, 61) => 0.13873
+(1, 64) ~ (2, 62) => 0.427606
+(1, 64) ~ (2, 63) => 0.269754
+(1, 64) ~ (2, 64) => 0.0710729
+(1, 64) ~ (2, 65) => 0.0133189
+(1, 65) ~ (2, 62) => 0.118507
+(1, 65) ~ (2, 63) => 0.491523
+(1, 65) ~ (2, 64) => 0.229984
+(1, 65) ~ (2, 65) => 0.0694424
+(1, 65) ~ (2, 66) => 0.0122065
+(1, 66) ~ (2, 63) => 0.105104
+(1, 66) ~ (2, 64) => 0.550619
+(1, 66) ~ (2, 65) => 0.203126
+(1, 66) ~ (2, 66) => 0.0680489
+(1, 66) ~ (2, 67) => 0.0110251
+(1, 67) ~ (2, 64) => 0.0940696
+(1, 67) ~ (2, 65) => 0.592731
+(1, 67) ~ (2, 66) => 0.161364
+(1, 67) ~ (2, 67) => 0.0614782
+(1, 67) ~ (2, 68) => 0.0101097
+(1, 68) ~ (2, 65) => 0.0832261
+(1, 68) ~ (2, 66) => 0.649777
+(1, 68) ~ (2, 67) => 0.113081
+(1, 68) ~ (2, 68) => 0.0531234
+(1, 69) ~ (2, 66) => 0.0730256
+(1, 69) ~ (2, 67) => 0.720741
+(1, 69) ~ (2, 68) => 0.0732072
+(1, 69) ~ (2, 69) => 0.0487046
+(1, 70) ~ (2, 67) => 0.0667276
+(1, 70) ~ (2, 68) => 0.779968
+(1, 70) ~ (2, 69) => 0.0432773
+(1, 70) ~ (2, 70) => 0.0467504
+(1, 71) ~ (2, 68) => 0.05794
+(1, 71) ~ (2, 69) => 0.822878
+(1, 71) ~ (2, 70) => 0.0294395
+(1, 71) ~ (2, 71) => 0.0399446
+(1, 72) ~ (2, 69) => 0.0505023
+(1, 72) ~ (2, 70) => 0.848721
+(1, 72) ~ (2, 71) => 0.0138873
+(1, 72) ~ (2, 72) => 0.0413473
+(1, 73) ~ (2, 70) => 0.0399709
+(1, 73) ~ (2, 71) => 0.879818
+(1, 73) ~ (2, 72) => 0.0124191
+(1, 73) ~ (2, 73) => 0.0400373
+(1, 74) ~ (2, 71) => 0.0373395
+(1, 74) ~ (2, 72) => 0.878766
+(1, 74) ~ (2, 73) => 0.0128142
+(1, 74) ~ (2, 74) => 0.0346456
+(1, 74) ~ (2, 75) => 0.0120938
+(1, 75) ~ (2, 72) => 0.0374456
+(1, 75) ~ (2, 73) => 0.882257
+(1, 75) ~ (2, 74) => 0.0160001
+(1, 75) ~ (2, 75) => 0.0262023
+(1, 75) ~ (2, 76) => 0.0141676
+(1, 76) ~ (2, 73) => 0.0411564
+(1, 76) ~ (2, 74) => 0.875654
+(1, 76) ~ (2, 75) => 0.0242115
+(1, 76) ~ (2, 76) => 0.018879
+(1, 76) ~ (2, 77) => 0.0167414
+(1, 77) ~ (2, 74) => 0.040077
+(1, 77) ~ (2, 75) => 0.874955
+(1, 77) ~ (2, 76) => 0.032268
+(1, 77) ~ (2, 77) => 0.0138322
+(1, 77) ~ (2, 78) => 0.0154469
+(1, 78) ~ (2, 75) => 0.0377049
+(1, 78) ~ (2, 76) => 0.873959
+(1, 78) ~ (2, 77) => 0.0387182
+(1, 78) ~ (2, 78) => 0.0117949
+(1, 78) ~ (2, 79) => 0.0138722
+(1, 79) ~ (2, 76) => 0.0343727
+(1, 79) ~ (2, 77) => 0.866346
+(1, 79) ~ (2, 78) => 0.0563503
+(1, 79) ~ (2, 79) => 0.0101123
+(1, 79) ~ (2, 80) => 0.011412
+(1, 80) ~ (2, 77) => 0.0224196
+(1, 80) ~ (2, 78) => 0.873832
+(1, 80) ~ (2, 79) => 0.0621327
+(1, 81) ~ (2, 78) => 0.0189537
+(1, 81) ~ (2, 79) => 0.877208
+(1, 81) ~ (2, 80) => 0.0625152
+(1, 81) ~ (2, 81) => 0.0112804
+(1, 82) ~ (2, 79) => 0.0107597
+(1, 82) ~ (2, 80) => 0.87903
+(1, 82) ~ (2, 81) => 0.0768312
+(1, 82) ~ (2, 82) => 0.0107417
+(1, 83) ~ (2, 81) => 0.814003
+(1, 83) ~ (2, 82) => 0.140112
+(1, 83) ~ (2, 83) => 0.013837
+(1, 84) ~ (2, 81) => 0.0102431
+(1, 84) ~ (2, 82) => 0.748324
+(1, 84) ~ (2, 83) => 0.20077
+(1, 84) ~ (2, 84) => 0.0159829
+(1, 85) ~ (2, 82) => 0.0107817
+(1, 85) ~ (2, 83) => 0.663804
+(1, 85) ~ (2, 84) => 0.266832
+(1, 85) ~ (2, 85) => 0.0258246
+(1, 86) ~ (2, 83) => 0.0202943
+(1, 86) ~ (2, 84) => 0.602306
+(1, 86) ~ (2, 85) => 0.321321
+(1, 86) ~ (2, 86) => 0.0259163
+(1, 87) ~ (2, 84) => 0.0205343
+(1, 87) ~ (2, 85) => 0.583567
+(1, 87) ~ (2, 86) => 0.344478
+(1, 87) ~ (2, 87) => 0.0255732
+(1, 88) ~ (2, 85) => 0.0207033
+(1, 88) ~ (2, 86) => 0.563291
+(1, 88) ~ (2, 87) => 0.365824
+(1, 88) ~ (2, 88) => 0.024726
+(1, 89) ~ (2, 86) => 0.020376
+(1, 89) ~ (2, 87) => 0.543333
+(1, 89) ~ (2, 88) => 0.387105
+(1, 89) ~ (2, 89) => 0.0234993
+(1, 90) ~ (2, 87) => 0.0196373
+(1, 90) ~ (2, 88) => 0.523655
+(1, 90) ~ (2, 89) => 0.40848
+(1, 90) ~ (2, 90) => 0.0218453
+(1, 91) ~ (2, 88) => 0.0184373
+(1, 91) ~ (2, 89) => 0.50363
+(1, 91) ~ (2, 90) => 0.429863
+(1, 91) ~ (2, 91) => 0.0192896
+(1, 92) ~ (2, 89) => 0.0162555
+(1, 92) ~ (2, 90) => 0.479382
+(1, 92) ~ (2, 91) => 0.446559
+(1, 92) ~ (2, 92) => 0.0259362
+(1, 93) ~ (2, 90) => 0.0136455
+(1, 93) ~ (2, 91) => 0.445265
+(1, 93) ~ (2, 92) => 0.476118
+(1, 93) ~ (2, 93) => 0.0305466
+(1, 94) ~ (2, 90) => 0.0107857
+(1, 94) ~ (2, 92) => 0.425591
+(1, 94) ~ (2, 93) => 0.494269
+(1, 94) ~ (2, 94) => 0.0334878
+(1, 95) ~ (2, 91) => 0.0125162
+(1, 95) ~ (2, 93) => 0.404787
+(1, 95) ~ (2, 94) => 0.511392
+(1, 95) ~ (2, 95) => 0.0355268
+(1, 96) ~ (2, 92) => 0.0140145
+(1, 96) ~ (2, 94) => 0.386103
+(1, 96) ~ (2, 95) => 0.53082
+(1, 96) ~ (2, 96) => 0.0334272
+(1, 97) ~ (2, 93) => 0.0157107
+(1, 97) ~ (2, 95) => 0.382154
+(1, 97) ~ (2, 96) => 0.531695
+(1, 97) ~ (2, 97) => 0.0335407
+(1, 98) ~ (2, 94) => 0.0176665
+(1, 98) ~ (2, 96) => 0.34229
+(1, 98) ~ (2, 97) => 0.554646
+(1, 98) ~ (2, 98) => 0.035199
+(1, 99) ~ (2, 95) => 0.0181342
+(1, 99) ~ (2, 96) => 0.0106321
+(1, 99) ~ (2, 97) => 0.343809
+(1, 99) ~ (2, 98) => 0.547122
+(1, 99) ~ (2, 99) => 0.0340438
+(1, 100) ~ (2, 96) => 0.0220976
+(1, 100) ~ (2, 97) => 0.0159121
+(1, 100) ~ (2, 98) => 0.342364
+(1, 100) ~ (2, 99) => 0.535001
+(1, 100) ~ (2, 100) => 0.0311686
+(1, 101) ~ (2, 97) => 0.0225695
+(1, 101) ~ (2, 98) => 0.0228608
+(1, 101) ~ (2, 99) => 0.344719
+(1, 101) ~ (2, 100) => 0.524369
+(1, 101) ~ (2, 101) => 0.0279266
+(1, 102) ~ (2, 98) => 0.0235268
+(1, 102) ~ (2, 99) => 0.030423
+(1, 102) ~ (2, 100) => 0.347359
+(1, 102) ~ (2, 101) => 0.514145
+(1, 102) ~ (2, 102) => 0.0240638
+(1, 103) ~ (2, 99) => 0.0246442
+(1, 103) ~ (2, 100) => 0.0376125
+(1, 103) ~ (2, 101) => 0.349494
+(1, 103) ~ (2, 102) => 0.502752
+(1, 103) ~ (2, 103) => 0.0213362
+(1, 104) ~ (2, 99) => 0.0102728
+(1, 104) ~ (2, 100) => 0.0263118
+(1, 104) ~ (2, 101) => 0.0459499
+(1, 104) ~ (2, 102) => 0.355941
+(1, 104) ~ (2, 103) => 0.479183
+(1, 104) ~ (2, 104) => 0.0196204
+(1, 105) ~ (2, 100) => 0.0114838
+(1, 105) ~ (2, 101) => 0.0279284
+(1, 105) ~ (2, 102) => 0.0529103
+(1, 105) ~ (2, 103) => 0.368635
+(1, 105) ~ (2, 104) => 0.462977
+(1, 105) ~ (2, 105) => 0.0184589
+(1, 106) ~ (2, 101) => 0.012064
+(1, 106) ~ (2, 102) => 0.0272517
+(1, 106) ~ (2, 103) => 0.0677298
+(1, 106) ~ (2, 104) => 0.373441
+(1, 106) ~ (2, 105) => 0.446071
+(1, 106) ~ (2, 106) => 0.0167508
+(1, 107) ~ (2, 102) => 0.0120302
+(1, 107) ~ (2, 103) => 0.0293463
+(1, 107) ~ (2, 104) => 0.0788439
+(1, 107) ~ (2, 105) => 0.376618
+(1, 107) ~ (2, 106) => 0.426185
+(1, 107) ~ (2, 107) => 0.013961
+(1, 108) ~ (2, 103) => 0.0130347
+(1, 108) ~ (2, 104) => 0.0304266
+(1, 108) ~ (2, 105) => 0.0890086
+(1, 108) ~ (2, 106) => 0.374281
+(1, 108) ~ (2, 107) => 0.39512
+(1, 109) ~ (2, 104) => 0.014761
+(1, 109) ~ (2, 105) => 0.0331751
+(1, 109) ~ (2, 106) => 0.107084
+(1, 109) ~ (2, 107) => 0.382677
+(1, 109) ~ (2, 108) => 0.372634
+(1, 110) ~ (2, 105) => 0.0169634
+(1, 110) ~ (2, 106) => 0.0370756
+(1, 110) ~ (2, 107) => 0.126844
+(1, 110) ~ (2, 108) => 0.384733
+(1, 110) ~ (2, 109) => 0.37508
+(1, 111) ~ (2, 106) => 0.018749
+(1, 111) ~ (2, 107) => 0.0386204
+(1, 111) ~ (2, 108) => 0.135027
+(1, 111) ~ (2, 109) => 0.38464
+(1, 111) ~ (2, 110) => 0.383956
+(1, 112) ~ (2, 107) => 0.0217494
+(1, 112) ~ (2, 108) => 0.0426043
+(1, 112) ~ (2, 109) => 0.116077
+(1, 112) ~ (2, 110) => 0.331632
+(1, 112) ~ (2, 111) => 0.438426
+(1, 113) ~ (2, 108) => 0.022966
+(1, 113) ~ (2, 109) => 0.0525866
+(1, 113) ~ (2, 110) => 0.100468
+(1, 113) ~ (2, 111) => 0.323153
+(1, 113) ~ (2, 112) => 0.46567
+(1, 113) ~ (2, 113) => 0.0106273
+(1, 114) ~ (2, 109) => 0.0214981
+(1, 114) ~ (2, 110) => 0.0515125
+(1, 114) ~ (2, 111) => 0.0927562
+(1, 114) ~ (2, 112) => 0.332265
+(1, 114) ~ (2, 113) => 0.468257
+(1, 114) ~ (2, 114) => 0.0109591
+(1, 115) ~ (2, 110) => 0.0148399
+(1, 115) ~ (2, 111) => 0.0555325
+(1, 115) ~ (2, 112) => 0.0947291
+(1, 115) ~ (2, 113) => 0.330329
+(1, 115) ~ (2, 114) => 0.46052
+(1, 116) ~ (2, 111) => 0.0112013
+(1, 116) ~ (2, 112) => 0.0622088
+(1, 116) ~ (2, 113) => 0.087186
+(1, 116) ~ (2, 114) => 0.292609
+(1, 116) ~ (2, 115) => 0.357443
+(1, 117) ~ (2, 113) => 0.0771577
+(1, 117) ~ (2, 114) => 0.0758997
+(1, 117) ~ (2, 115) => 0.222357
+(1, 117) ~ (2, 116) => 0.217988
+(1, 118) ~ (2, 114) => 0.140479
+(1, 118) ~ (2, 115) => 0.0772043
+(1, 118) ~ (2, 116) => 0.149643
+(1, 119) ~ (2, 115) => 0.324141
+(1, 119) ~ (2, 116) => 0.0668753
+(1, 120) ~ (2, 116) => 0.553252
+
+; gap posteriors
+(1, 0) ~ (2, -1) => 0.0533242
+(1, 1) ~ (2, -1) => 0.0995525
+(1, 2) ~ (2, -1) => 0.0973192
+(1, 3) ~ (2, -1) => 0.0864747
+(1, 4) ~ (2, -1) => 0.232407
+(1, 5) ~ (2, -1) => 0.169008
+(1, 6) ~ (2, -1) => 0.0802323
+(1, 7) ~ (2, -1) => 0.0666689
+(1, 8) ~ (2, -1) => 0.0374177
+(1, 9) ~ (2, -1) => 0.0378729
+(1, 10) ~ (2, -1) => 0.0556848
+(1, 11) ~ (2, -1) => 0.0571779
+(1, 12) ~ (2, -1) => 0.0567815
+(1, 13) ~ (2, -1) => 0.0505599
+(1, 14) ~ (2, -1) => 0.0453633
+(1, 15) ~ (2, -1) => 0.059978
+(1, 16) ~ (2, -1) => 0.0520169
+(1, 17) ~ (2, -1) => 0.0684326
+(1, 18) ~ (2, -1) => 0.0759452
+(1, 19) ~ (2, -1) => 0.0601686
+(1, 20) ~ (2, -1) => 0.0423847
+(1, 21) ~ (2, -1) => 0.0456207
+(1, 22) ~ (2, -1) => 0.0559075
+(1, 23) ~ (2, -1) => 0.0562205
+(1, 24) ~ (2, -1) => 0.0507723
+(1, 25) ~ (2, -1) => 0.0580846
+(1, 26) ~ (2, -1) => 0.063112
+(1, 27) ~ (2, -1) => 0.0659144
+(1, 28) ~ (2, -1) => 0.0753717
+(1, 29) ~ (2, -1) => 0.0601827
+(1, 30) ~ (2, -1) => 0.0237265
+(1, 31) ~ (2, -1) => 0.0278529
+(1, 32) ~ (2, -1) => 0.0304594
+(1, 33) ~ (2, -1) => 0.0370054
+(1, 34) ~ (2, -1) => 0.0444305
+(1, 35) ~ (2, -1) => 0.0269588
+(1, 36) ~ (2, -1) => 0.0202682
+(1, 37) ~ (2, -1) => 0.024174
+(1, 38) ~ (2, -1) => 0.0391565
+(1, 39) ~ (2, -1) => 0.0392738
+(1, 40) ~ (2, -1) => 0.0363661
+(1, 41) ~ (2, -1) => 0.0515102
+(1, 42) ~ (2, -1) => 0.066614
+(1, 43) ~ (2, -1) => 0.0927873
+(1, 44) ~ (2, -1) => 0.111368
+(1, 45) ~ (2, -1) => 0.139998
+(1, 46) ~ (2, -1) => 0.154371
+(1, 47) ~ (2, -1) => 0.100207
+(1, 48) ~ (2, -1) => 0.0353831
+(1, 49) ~ (2, -1) => 0.0279008
+(1, 50) ~ (2, -1) => 0.0320188
+(1, 51) ~ (2, -1) => 0.0238514
+(1, 52) ~ (2, -1) => 0.0280386
+(1, 53) ~ (2, -1) => 0.0243347
+(1, 54) ~ (2, -1) => 0.0191365
+(1, 55) ~ (2, -1) => 0.0172464
+(1, 56) ~ (2, -1) => 0.0207147
+(1, 57) ~ (2, -1) => 0.016511
+(1, 58) ~ (2, -1) => 0.0259595
+(1, 59) ~ (2, -1) => 0.0279939
+(1, 60) ~ (2, -1) => 0.0696409
+(1, 61) ~ (2, -1) => 0.0886693
+(1, 62) ~ (2, -1) => 0.149129
+(1, 63) ~ (2, -1) => 0.0907513
+(1, 64) ~ (2, -1) => 0.0795182
+(1, 65) ~ (2, -1) => 0.0783374
+(1, 66) ~ (2, -1) => 0.0620767
+(1, 67) ~ (2, -1) => 0.0802483
+(1, 68) ~ (2, -1) => 0.100793
+(1, 69) ~ (2, -1) => 0.084322
+(1, 70) ~ (2, -1) => 0.0632767
+(1, 71) ~ (2, -1) => 0.049798
+(1, 72) ~ (2, -1) => 0.0455418
+(1, 73) ~ (2, -1) => 0.0277549
+(1, 74) ~ (2, -1) => 0.0243411
+(1, 75) ~ (2, -1) => 0.0239275
+(1, 76) ~ (2, -1) => 0.023358
+(1, 77) ~ (2, -1) => 0.0234212
+(1, 78) ~ (2, -1) => 0.0239506
+(1, 79) ~ (2, -1) => 0.0214072
+(1, 80) ~ (2, -1) => 0.041616
+(1, 81) ~ (2, -1) => 0.0300431
+(1, 82) ~ (2, -1) => 0.0226379
+(1, 83) ~ (2, -1) => 0.0320482
+(1, 84) ~ (2, -1) => 0.0246805
+(1, 85) ~ (2, -1) => 0.032758
+(1, 86) ~ (2, -1) => 0.0301624
+(1, 87) ~ (2, -1) => 0.0258475
+(1, 88) ~ (2, -1) => 0.0254552
+(1, 89) ~ (2, -1) => 0.0256867
+(1, 90) ~ (2, -1) => 0.0263826
+(1, 91) ~ (2, -1) => 0.02878
+(1, 92) ~ (2, -1) => 0.0318665
+(1, 93) ~ (2, -1) => 0.0344249
+(1, 94) ~ (2, -1) => 0.0358664
+(1, 95) ~ (2, -1) => 0.0357784
+(1, 96) ~ (2, -1) => 0.0356352
+(1, 97) ~ (2, -1) => 0.036899
+(1, 98) ~ (2, -1) => 0.0501987
+(1, 99) ~ (2, -1) => 0.0462593
+(1, 100) ~ (2, -1) => 0.0534571
+(1, 101) ~ (2, -1) => 0.0575555
+(1, 102) ~ (2, -1) => 0.0604822
+(1, 103) ~ (2, -1) => 0.0641621
+(1, 104) ~ (2, -1) => 0.0627212
+(1, 105) ~ (2, -1) => 0.0576066
+(1, 106) ~ (2, -1) => 0.0566919
+(1, 107) ~ (2, -1) => 0.0630161
+(1, 108) ~ (2, -1) => 0.0981291
+(1, 109) ~ (2, -1) => 0.0896686
+(1, 110) ~ (2, -1) => 0.0593034
+(1, 111) ~ (2, -1) => 0.0390079
+(1, 112) ~ (2, -1) => 0.0495115
+(1, 113) ~ (2, -1) => 0.0245297
+(1, 114) ~ (2, -1) => 0.022752
+(1, 115) ~ (2, -1) => 0.0440501
+(1, 116) ~ (2, -1) => 0.189352
+(1, 117) ~ (2, -1) => 0.406598
+(1, 118) ~ (2, -1) => 0.632673
+(1, 119) ~ (2, -1) => 0.608984
+(1, 120) ~ (2, -1) => 0.446748
+
+(1, -1) ~ (2, 0) => 0.0278107
+(1, -1) ~ (2, 1) => 0.0321116
+(1, -1) ~ (2, 2) => 0.0493122
+(1, -1) ~ (2, 3) => 0.0548331
+(1, -1) ~ (2, 4) => 0.0357971
+(1, -1) ~ (2, 5) => 0.0706126
+(1, -1) ~ (2, 6) => 0.0273685
+(1, -1) ~ (2, 7) => 0.0206333
+(1, -1) ~ (2, 8) => 0.0232158
+(1, -1) ~ (2, 9) => 0.0460211
+(1, -1) ~ (2, 10) => 0.0378096
+(1, -1) ~ (2, 11) => 0.034949
+(1, -1) ~ (2, 12) => 0.0493049
+(1, -1) ~ (2, 13) => 0.0369203
+(1, -1) ~ (2, 14) => 0.0443864
+(1, -1) ~ (2, 15) => 0.0321862
+(1, -1) ~ (2, 16) => 0.0310346
+(1, -1) ~ (2, 17) => 0.0740055
+(1, -1) ~ (2, 18) => 0.0331325
+(1, -1) ~ (2, 19) => 0.0229255
+(1, -1) ~ (2, 20) => 0.0359412
+(1, -1) ~ (2, 21) => 0.0400348
+(1, -1) ~ (2, 22) => 0.0596792
+(1, -1) ~ (2, 23) => 0.0444861
+(1, -1) ~ (2, 24) => 0.0361366
+(1, -1) ~ (2, 25) => 0.0396835
+(1, -1) ~ (2, 26) => 0.0342379
+(1, -1) ~ (2, 27) => 0.0485015
+(1, -1) ~ (2, 28) => 0.0302664
+(1, -1) ~ (2, 29) => 0.0482048
+(1, -1) ~ (2, 30) => 0.028411
+(1, -1) ~ (2, 31) => 0.0203441
+(1, -1) ~ (2, 32) => 0.016408
+(1, -1) ~ (2, 33) => 0.0127263
+(1, -1) ~ (2, 34) => 0.0269588
+(1, -1) ~ (2, 35) => 0.0310125
+(1, -1) ~ (2, 36) => 0.025208
+(1, -1) ~ (2, 37) => 0.012561
+(1, -1) ~ (2, 38) => 0.0127936
+(1, -1) ~ (2, 39) => 0.0137663
+(1, -1) ~ (2, 40) => 0.0155297
+(1, -1) ~ (2, 41) => 0.0268745
+(1, -1) ~ (2, 42) => 0.0270396
+(1, -1) ~ (2, 43) => 0.0266939
+(1, -1) ~ (2, 44) => 0.0290496
+(1, -1) ~ (2, 45) => 0.039067
+(1, -1) ~ (2, 46) => 0.015521
+(1, -1) ~ (2, 47) => 0.0152388
+(1, -1) ~ (2, 48) => 0.0163464
+(1, -1) ~ (2, 49) => 0.0176841
+(1, -1) ~ (2, 50) => 0.0338828
+(1, -1) ~ (2, 51) => 0.0482727
+(1, -1) ~ (2, 52) => 0.0435395
+(1, -1) ~ (2, 53) => 0.0415836
+(1, -1) ~ (2, 54) => 0.0239226
+(1, -1) ~ (2, 55) => 0.0262116
+(1, -1) ~ (2, 56) => 0.0221824
+(1, -1) ~ (2, 57) => 0.0339982
+(1, -1) ~ (2, 58) => 0.0490972
+(1, -1) ~ (2, 59) => 0.0656571
+(1, -1) ~ (2, 60) => 0.108857
+(1, -1) ~ (2, 61) => 0.112356
+(1, -1) ~ (2, 62) => 0.0613523
+(1, -1) ~ (2, 63) => 0.0412989
+(1, -1) ~ (2, 64) => 0.0398079
+(1, -1) ~ (2, 65) => 0.0381556
+(1, -1) ~ (2, 66) => 0.035578
+(1, -1) ~ (2, 67) => 0.0269479
+(1, -1) ~ (2, 68) => 0.0256518
+(1, -1) ~ (2, 69) => 0.0346379
+(1, -1) ~ (2, 70) => 0.0351177
+(1, -1) ~ (2, 71) => 0.0290109
+(1, -1) ~ (2, 72) => 0.0300224
+(1, -1) ~ (2, 73) => 0.0237351
+(1, -1) ~ (2, 74) => 0.0336235
+(1, -1) ~ (2, 75) => 0.0248329
+(1, -1) ~ (2, 76) => 0.0263534
+(1, -1) ~ (2, 77) => 0.0419431
+(1, -1) ~ (2, 78) => 0.0236225
+(1, -1) ~ (2, 79) => 0.0259155
+(1, -1) ~ (2, 80) => 0.0470433
+(1, -1) ~ (2, 81) => 0.0876422
+(1, -1) ~ (2, 82) => 0.0900412
+(1, -1) ~ (2, 83) => 0.101295
+(1, -1) ~ (2, 84) => 0.094345
+(1, -1) ~ (2, 85) => 0.0485834
+(1, -1) ~ (2, 86) => 0.0459386
+(1, -1) ~ (2, 87) => 0.0456326
+(1, -1) ~ (2, 88) => 0.046077
+(1, -1) ~ (2, 89) => 0.0481353
+(1, -1) ~ (2, 90) => 0.044478
+(1, -1) ~ (2, 91) => 0.07637
+(1, -1) ~ (2, 92) => 0.0583397
+(1, -1) ~ (2, 93) => 0.0546871
+(1, -1) ~ (2, 94) => 0.0513507
+(1, -1) ~ (2, 95) => 0.0333645
+(1, -1) ~ (2, 96) => 0.0598577
+(1, -1) ~ (2, 97) => 0.0295233
+(1, -1) ~ (2, 98) => 0.028928
+(1, -1) ~ (2, 99) => 0.0208968
+(1, -1) ~ (2, 100) => 0.0216952
+(1, -1) ~ (2, 101) => 0.0224925
+(1, -1) ~ (2, 102) => 0.0250516
+(1, -1) ~ (2, 103) => 0.0207347
+(1, -1) ~ (2, 104) => 0.0199305
+(1, -1) ~ (2, 105) => 0.019705
+(1, -1) ~ (2, 106) => 0.0198746
+(1, -1) ~ (2, 107) => 0.0210281
+(1, -1) ~ (2, 108) => 0.0420354
+(1, -1) ~ (2, 109) => 0.0501183
+(1, -1) ~ (2, 110) => 0.117592
+(1, -1) ~ (2, 111) => 0.0789314
+(1, -1) ~ (2, 112) => 0.0451272
+(1, -1) ~ (2, 113) => 0.0264435
+(1, -1) ~ (2, 114) => 0.0195325
+(1, -1) ~ (2, 115) => 0.0188555
+(1, -1) ~ (2, 116) => 0.0122418
+
+; Sparse posterior probability matrix for sequences 1 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (3, 0) => 0.999999
+(1, 1) ~ (3, 1) => 0.999995
+(1, 2) ~ (3, 2) => 0.999985
+(1, 3) ~ (3, 3) => 0.999889
+(1, 4) ~ (3, 4) => 0.999874
+(1, 5) ~ (3, 5) => 0.999873
+(1, 6) ~ (3, 6) => 0.999908
+(1, 7) ~ (3, 7) => 0.999919
+(1, 8) ~ (3, 8) => 0.999934
+(1, 9) ~ (3, 9) => 0.999983
+(1, 10) ~ (3, 10) => 0.999988
+(1, 11) ~ (3, 11) => 0.999982
+(1, 12) ~ (3, 12) => 0.999979
+(1, 13) ~ (3, 13) => 0.99999
+(1, 14) ~ (3, 14) => 0.999999
+(1, 15) ~ (3, 15) => 0.999998
+(1, 16) ~ (3, 16) => 0.999998
+(1, 17) ~ (3, 17) => 0.999988
+(1, 18) ~ (3, 18) => 0.999981
+(1, 19) ~ (3, 19) => 0.999987
+(1, 20) ~ (3, 20) => 0.999996
+(1, 21) ~ (3, 21) => 0.999999
+(1, 22) ~ (3, 22) => 0.999999
+(1, 23) ~ (3, 23) => 0.999997
+(1, 24) ~ (3, 24) => 0.999998
+(1, 25) ~ (3, 25) => 0.999999
+(1, 26) ~ (3, 26) => 0.999998
+(1, 27) ~ (3, 27) => 0.999998
+(1, 28) ~ (3, 28) => 0.999994
+(1, 29) ~ (3, 29) => 0.999993
+(1, 30) ~ (3, 30) => 0.999995
+(1, 31) ~ (3, 31) => 0.999989
+(1, 32) ~ (3, 32) => 0.999987
+(1, 33) ~ (3, 33) => 0.99999
+(1, 34) ~ (3, 34) => 0.999998
+(1, 35) ~ (3, 35) => 0.999999
+(1, 36) ~ (3, 36) => 0.999997
+(1, 37) ~ (3, 37) => 0.999995
+(1, 38) ~ (3, 38) => 0.999985
+(1, 39) ~ (3, 39) => 0.999979
+(1, 40) ~ (3, 40) => 0.999979
+(1, 41) ~ (3, 41) => 0.999986
+(1, 42) ~ (3, 42) => 0.999998
+(1, 43) ~ (3, 43) => 0.999999
+(1, 44) ~ (3, 44) => 0.999998
+(1, 45) ~ (3, 45) => 0.999994
+(1, 46) ~ (3, 46) => 0.999992
+(1, 47) ~ (3, 47) => 0.999993
+(1, 48) ~ (3, 48) => 0.999996
+(1, 49) ~ (3, 49) => 0.999995
+(1, 50) ~ (3, 50) => 0.999996
+(1, 51) ~ (3, 51) => 0.999998
+(1, 52) ~ (3, 52) => 0.999998
+(1, 53) ~ (3, 53) => 0.999999
+(1, 54) ~ (3, 54) => 0.999998
+(1, 55) ~ (3, 55) => 0.999991
+(1, 56) ~ (3, 56) => 0.99998
+(1, 57) ~ (3, 57) => 0.999969
+(1, 58) ~ (3, 58) => 0.999909
+(1, 59) ~ (3, 59) => 0.999842
+(1, 60) ~ (3, 60) => 0.998969
+(1, 61) ~ (3, 61) => 0.998076
+(1, 62) ~ (3, 62) => 0.997816
+(1, 63) ~ (3, 63) => 0.997542
+(1, 64) ~ (3, 64) => 0.997481
+(1, 65) ~ (3, 65) => 0.995098
+(1, 66) ~ (3, 66) => 0.992859
+(1, 67) ~ (3, 67) => 0.992398
+(1, 68) ~ (3, 68) => 0.990694
+(1, 69) ~ (3, 69) => 0.989024
+(1, 70) ~ (3, 70) => 0.988881
+(1, 71) ~ (3, 71) => 0.989309
+(1, 72) ~ (3, 72) => 0.994666
+(1, 73) ~ (3, 73) => 0.997939
+(1, 74) ~ (3, 74) => 0.998304
+(1, 75) ~ (3, 75) => 0.998701
+(1, 76) ~ (3, 76) => 0.999292
+(1, 77) ~ (3, 77) => 0.999526
+(1, 78) ~ (3, 78) => 0.999742
+(1, 79) ~ (3, 79) => 0.999957
+(1, 80) ~ (3, 80) => 0.999988
+(1, 81) ~ (3, 81) => 0.999968
+(1, 82) ~ (3, 82) => 0.999319
+(1, 83) ~ (3, 83) => 0.99909
+(1, 84) ~ (3, 84) => 0.998565
+(1, 85) ~ (3, 85) => 0.998081
+(1, 86) ~ (3, 86) => 0.997952
+(1, 87) ~ (3, 87) => 0.993147
+(1, 88) ~ (3, 88) => 0.98832
+(1, 89) ~ (3, 89) => 0.98352
+(1, 90) ~ (3, 90) => 0.978747
+(1, 90) ~ (3, 91) => 0.0104724
+(1, 91) ~ (3, 91) => 0.964092
+(1, 91) ~ (3, 92) => 0.0128876
+(1, 91) ~ (3, 94) => 0.0203152
+(1, 92) ~ (3, 92) => 0.918312
+(1, 92) ~ (3, 93) => 0.0148008
+(1, 92) ~ (3, 95) => 0.0623527
+(1, 93) ~ (3, 93) => 0.914931
+(1, 93) ~ (3, 94) => 0.0142833
+(1, 93) ~ (3, 96) => 0.0657856
+(1, 94) ~ (3, 94) => 0.911129
+(1, 94) ~ (3, 95) => 0.0145292
+(1, 94) ~ (3, 97) => 0.0688287
+(1, 95) ~ (3, 95) => 0.890973
+(1, 95) ~ (3, 96) => 0.0168189
+(1, 95) ~ (3, 98) => 0.0842572
+(1, 96) ~ (3, 96) => 0.870903
+(1, 96) ~ (3, 97) => 0.0190278
+(1, 96) ~ (3, 99) => 0.0996572
+(1, 97) ~ (3, 97) => 0.820125
+(1, 97) ~ (3, 98) => 0.020595
+(1, 97) ~ (3, 99) => 0.0112229
+(1, 97) ~ (3, 100) => 0.146999
+(1, 98) ~ (3, 98) => 0.141339
+(1, 98) ~ (3, 100) => 0.0142477
+(1, 98) ~ (3, 101) => 0.834142
+(1, 99) ~ (3, 99) => 0.0354982
+(1, 99) ~ (3, 101) => 0.0110733
+(1, 99) ~ (3, 102) => 0.946965
+(1, 100) ~ (3, 103) => 0.985959
+(1, 101) ~ (3, 104) => 0.990537
+(1, 102) ~ (3, 105) => 0.991496
+(1, 103) ~ (3, 106) => 0.996662
+(1, 104) ~ (3, 107) => 0.996451
+(1, 105) ~ (3, 108) => 0.995791
+(1, 106) ~ (3, 109) => 0.995871
+(1, 107) ~ (3, 110) => 0.995709
+(1, 108) ~ (3, 111) => 0.995808
+(1, 109) ~ (3, 112) => 0.995372
+(1, 110) ~ (3, 113) => 0.995488
+(1, 111) ~ (3, 114) => 0.995841
+(1, 112) ~ (3, 115) => 0.996653
+(1, 113) ~ (3, 116) => 0.997334
+(1, 114) ~ (3, 117) => 0.997718
+(1, 115) ~ (3, 118) => 0.998463
+(1, 116) ~ (3, 119) => 0.9992
+(1, 117) ~ (3, 120) => 0.999861
+(1, 118) ~ (3, 121) => 0.999959
+(1, 119) ~ (3, 122) => 0.99998
+(1, 120) ~ (3, 123) => 0.999998
+
+; gap posteriors
+(1, 0) ~ (3, -1) => 0.0001
+(1, 1) ~ (3, -1) => 0.0001
+(1, 2) ~ (3, -1) => 0.0001
+(1, 3) ~ (3, -1) => 0.000110626
+(1, 4) ~ (3, -1) => 0.000126421
+(1, 5) ~ (3, -1) => 0.000127077
+(1, 6) ~ (3, -1) => 0.0001
+(1, 7) ~ (3, -1) => 0.0001
+(1, 8) ~ (3, -1) => 0.0001
+(1, 9) ~ (3, -1) => 0.0001
+(1, 10) ~ (3, -1) => 0.0001
+(1, 11) ~ (3, -1) => 0.0001
+(1, 12) ~ (3, -1) => 0.0001
+(1, 13) ~ (3, -1) => 0.0001
+(1, 14) ~ (3, -1) => 0.0001
+(1, 15) ~ (3, -1) => 0.0001
+(1, 16) ~ (3, -1) => 0.0001
+(1, 17) ~ (3, -1) => 0.0001
+(1, 18) ~ (3, -1) => 0.0001
+(1, 19) ~ (3, -1) => 0.0001
+(1, 20) ~ (3, -1) => 0.0001
+(1, 21) ~ (3, -1) => 0.0001
+(1, 22) ~ (3, -1) => 0.0001
+(1, 23) ~ (3, -1) => 0.0001
+(1, 24) ~ (3, -1) => 0.0001
+(1, 25) ~ (3, -1) => 0.0001
+(1, 26) ~ (3, -1) => 0.0001
+(1, 27) ~ (3, -1) => 0.0001
+(1, 28) ~ (3, -1) => 0.0001
+(1, 29) ~ (3, -1) => 0.0001
+(1, 30) ~ (3, -1) => 0.0001
+(1, 31) ~ (3, -1) => 0.0001
+(1, 32) ~ (3, -1) => 0.0001
+(1, 33) ~ (3, -1) => 0.0001
+(1, 34) ~ (3, -1) => 0.0001
+(1, 35) ~ (3, -1) => 0.0001
+(1, 36) ~ (3, -1) => 0.0001
+(1, 37) ~ (3, -1) => 0.0001
+(1, 38) ~ (3, -1) => 0.0001
+(1, 39) ~ (3, -1) => 0.0001
+(1, 40) ~ (3, -1) => 0.0001
+(1, 41) ~ (3, -1) => 0.0001
+(1, 42) ~ (3, -1) => 0.0001
+(1, 43) ~ (3, -1) => 0.0001
+(1, 44) ~ (3, -1) => 0.0001
+(1, 45) ~ (3, -1) => 0.0001
+(1, 46) ~ (3, -1) => 0.0001
+(1, 47) ~ (3, -1) => 0.0001
+(1, 48) ~ (3, -1) => 0.0001
+(1, 49) ~ (3, -1) => 0.0001
+(1, 50) ~ (3, -1) => 0.0001
+(1, 51) ~ (3, -1) => 0.0001
+(1, 52) ~ (3, -1) => 0.0001
+(1, 53) ~ (3, -1) => 0.0001
+(1, 54) ~ (3, -1) => 0.0001
+(1, 55) ~ (3, -1) => 0.0001
+(1, 56) ~ (3, -1) => 0.0001
+(1, 57) ~ (3, -1) => 0.0001
+(1, 58) ~ (3, -1) => 0.0001
+(1, 59) ~ (3, -1) => 0.000157654
+(1, 60) ~ (3, -1) => 0.00103092
+(1, 61) ~ (3, -1) => 0.00192356
+(1, 62) ~ (3, -1) => 0.00218374
+(1, 63) ~ (3, -1) => 0.00245762
+(1, 64) ~ (3, -1) => 0.00251859
+(1, 65) ~ (3, -1) => 0.00490153
+(1, 66) ~ (3, -1) => 0.00714064
+(1, 67) ~ (3, -1) => 0.00760156
+(1, 68) ~ (3, -1) => 0.00930601
+(1, 69) ~ (3, -1) => 0.0109764
+(1, 70) ~ (3, -1) => 0.0111188
+(1, 71) ~ (3, -1) => 0.0106911
+(1, 72) ~ (3, -1) => 0.00533408
+(1, 73) ~ (3, -1) => 0.00206101
+(1, 74) ~ (3, -1) => 0.00169611
+(1, 75) ~ (3, -1) => 0.00129902
+(1, 76) ~ (3, -1) => 0.000707984
+(1, 77) ~ (3, -1) => 0.000473738
+(1, 78) ~ (3, -1) => 0.000258029
+(1, 79) ~ (3, -1) => 0.0001
+(1, 80) ~ (3, -1) => 0.0001
+(1, 81) ~ (3, -1) => 0.0001
+(1, 82) ~ (3, -1) => 0.000681043
+(1, 83) ~ (3, -1) => 0.000909567
+(1, 84) ~ (3, -1) => 0.00143504
+(1, 85) ~ (3, -1) => 0.00191885
+(1, 86) ~ (3, -1) => 0.00204754
+(1, 87) ~ (3, -1) => 0.00685334
+(1, 88) ~ (3, -1) => 0.0116796
+(1, 89) ~ (3, -1) => 0.0164796
+(1, 90) ~ (3, -1) => 0.0107801
+(1, 91) ~ (3, -1) => 0.00270511
+(1, 92) ~ (3, -1) => 0.00453403
+(1, 93) ~ (3, -1) => 0.00500043
+(1, 94) ~ (3, -1) => 0.00551292
+(1, 95) ~ (3, -1) => 0.00795113
+(1, 96) ~ (3, -1) => 0.0104118
+(1, 97) ~ (3, -1) => 0.00105824
+(1, 98) ~ (3, -1) => 0.0102713
+(1, 99) ~ (3, -1) => 0.00646394
+(1, 100) ~ (3, -1) => 0.0140411
+(1, 101) ~ (3, -1) => 0.00946331
+(1, 102) ~ (3, -1) => 0.00850379
+(1, 103) ~ (3, -1) => 0.00333762
+(1, 104) ~ (3, -1) => 0.0035491
+(1, 105) ~ (3, -1) => 0.0042091
+(1, 106) ~ (3, -1) => 0.00412899
+(1, 107) ~ (3, -1) => 0.00429088
+(1, 108) ~ (3, -1) => 0.00419247
+(1, 109) ~ (3, -1) => 0.0046277
+(1, 110) ~ (3, -1) => 0.00451243
+(1, 111) ~ (3, -1) => 0.00415915
+(1, 112) ~ (3, -1) => 0.00334698
+(1, 113) ~ (3, -1) => 0.00266552
+(1, 114) ~ (3, -1) => 0.00228167
+(1, 115) ~ (3, -1) => 0.00153661
+(1, 116) ~ (3, -1) => 0.000800192
+(1, 117) ~ (3, -1) => 0.000139177
+(1, 118) ~ (3, -1) => 0.0001
+(1, 119) ~ (3, -1) => 0.0001
+(1, 120) ~ (3, -1) => 0.0001
+
+(1, -1) ~ (3, 0) => 0.0001
+(1, -1) ~ (3, 1) => 0.0001
+(1, -1) ~ (3, 2) => 0.0001
+(1, -1) ~ (3, 3) => 0.000110626
+(1, -1) ~ (3, 4) => 0.000126421
+(1, -1) ~ (3, 5) => 0.000127077
+(1, -1) ~ (3, 6) => 0.0001
+(1, -1) ~ (3, 7) => 0.0001
+(1, -1) ~ (3, 8) => 0.0001
+(1, -1) ~ (3, 9) => 0.0001
+(1, -1) ~ (3, 10) => 0.0001
+(1, -1) ~ (3, 11) => 0.0001
+(1, -1) ~ (3, 12) => 0.0001
+(1, -1) ~ (3, 13) => 0.0001
+(1, -1) ~ (3, 14) => 0.0001
+(1, -1) ~ (3, 15) => 0.0001
+(1, -1) ~ (3, 16) => 0.0001
+(1, -1) ~ (3, 17) => 0.0001
+(1, -1) ~ (3, 18) => 0.0001
+(1, -1) ~ (3, 19) => 0.0001
+(1, -1) ~ (3, 20) => 0.0001
+(1, -1) ~ (3, 21) => 0.0001
+(1, -1) ~ (3, 22) => 0.0001
+(1, -1) ~ (3, 23) => 0.0001
+(1, -1) ~ (3, 24) => 0.0001
+(1, -1) ~ (3, 25) => 0.0001
+(1, -1) ~ (3, 26) => 0.0001
+(1, -1) ~ (3, 27) => 0.0001
+(1, -1) ~ (3, 28) => 0.0001
+(1, -1) ~ (3, 29) => 0.0001
+(1, -1) ~ (3, 30) => 0.0001
+(1, -1) ~ (3, 31) => 0.0001
+(1, -1) ~ (3, 32) => 0.0001
+(1, -1) ~ (3, 33) => 0.0001
+(1, -1) ~ (3, 34) => 0.0001
+(1, -1) ~ (3, 35) => 0.0001
+(1, -1) ~ (3, 36) => 0.0001
+(1, -1) ~ (3, 37) => 0.0001
+(1, -1) ~ (3, 38) => 0.0001
+(1, -1) ~ (3, 39) => 0.0001
+(1, -1) ~ (3, 40) => 0.0001
+(1, -1) ~ (3, 41) => 0.0001
+(1, -1) ~ (3, 42) => 0.0001
+(1, -1) ~ (3, 43) => 0.0001
+(1, -1) ~ (3, 44) => 0.0001
+(1, -1) ~ (3, 45) => 0.0001
+(1, -1) ~ (3, 46) => 0.0001
+(1, -1) ~ (3, 47) => 0.0001
+(1, -1) ~ (3, 48) => 0.0001
+(1, -1) ~ (3, 49) => 0.0001
+(1, -1) ~ (3, 50) => 0.0001
+(1, -1) ~ (3, 51) => 0.0001
+(1, -1) ~ (3, 52) => 0.0001
+(1, -1) ~ (3, 53) => 0.0001
+(1, -1) ~ (3, 54) => 0.0001
+(1, -1) ~ (3, 55) => 0.0001
+(1, -1) ~ (3, 56) => 0.0001
+(1, -1) ~ (3, 57) => 0.0001
+(1, -1) ~ (3, 58) => 0.0001
+(1, -1) ~ (3, 59) => 0.000157654
+(1, -1) ~ (3, 60) => 0.00103092
+(1, -1) ~ (3, 61) => 0.00192356
+(1, -1) ~ (3, 62) => 0.00218374
+(1, -1) ~ (3, 63) => 0.00245762
+(1, -1) ~ (3, 64) => 0.00251859
+(1, -1) ~ (3, 65) => 0.00490153
+(1, -1) ~ (3, 66) => 0.00714064
+(1, -1) ~ (3, 67) => 0.00760156
+(1, -1) ~ (3, 68) => 0.00930601
+(1, -1) ~ (3, 69) => 0.0109764
+(1, -1) ~ (3, 70) => 0.0111188
+(1, -1) ~ (3, 71) => 0.0106911
+(1, -1) ~ (3, 72) => 0.00533408
+(1, -1) ~ (3, 73) => 0.00206101
+(1, -1) ~ (3, 74) => 0.00169611
+(1, -1) ~ (3, 75) => 0.00129902
+(1, -1) ~ (3, 76) => 0.000707984
+(1, -1) ~ (3, 77) => 0.000473738
+(1, -1) ~ (3, 78) => 0.000258029
+(1, -1) ~ (3, 79) => 0.0001
+(1, -1) ~ (3, 80) => 0.0001
+(1, -1) ~ (3, 81) => 0.0001
+(1, -1) ~ (3, 82) => 0.000681043
+(1, -1) ~ (3, 83) => 0.000909567
+(1, -1) ~ (3, 84) => 0.00143504
+(1, -1) ~ (3, 85) => 0.00191885
+(1, -1) ~ (3, 86) => 0.00204754
+(1, -1) ~ (3, 87) => 0.00685334
+(1, -1) ~ (3, 88) => 0.0116796
+(1, -1) ~ (3, 89) => 0.0164796
+(1, -1) ~ (3, 90) => 0.0212525
+(1, -1) ~ (3, 91) => 0.0254355
+(1, -1) ~ (3, 92) => 0.0687999
+(1, -1) ~ (3, 93) => 0.0702685
+(1, -1) ~ (3, 94) => 0.0542722
+(1, -1) ~ (3, 95) => 0.0321454
+(1, -1) ~ (3, 96) => 0.0464923
+(1, -1) ~ (3, 97) => 0.0920186
+(1, -1) ~ (3, 98) => 0.753809
+(1, -1) ~ (3, 99) => 0.853622
+(1, -1) ~ (3, 100) => 0.838753
+(1, -1) ~ (3, 101) => 0.154785
+(1, -1) ~ (3, 102) => 0.0530354
+(1, -1) ~ (3, 103) => 0.0140411
+(1, -1) ~ (3, 104) => 0.00946331
+(1, -1) ~ (3, 105) => 0.00850379
+(1, -1) ~ (3, 106) => 0.00333762
+(1, -1) ~ (3, 107) => 0.0035491
+(1, -1) ~ (3, 108) => 0.0042091
+(1, -1) ~ (3, 109) => 0.00412899
+(1, -1) ~ (3, 110) => 0.00429088
+(1, -1) ~ (3, 111) => 0.00419247
+(1, -1) ~ (3, 112) => 0.0046277
+(1, -1) ~ (3, 113) => 0.00451243
+(1, -1) ~ (3, 114) => 0.00415915
+(1, -1) ~ (3, 115) => 0.00334698
+(1, -1) ~ (3, 116) => 0.00266552
+(1, -1) ~ (3, 117) => 0.00228167
+(1, -1) ~ (3, 118) => 0.00153661
+(1, -1) ~ (3, 119) => 0.000800192
+(1, -1) ~ (3, 120) => 0.000139177
+(1, -1) ~ (3, 121) => 0.0001
+(1, -1) ~ (3, 122) => 0.0001
+(1, -1) ~ (3, 123) => 0.0001
+
+; Sparse posterior probability matrix for sequences 1 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (4, 0) => 0.977884
+(1, 0) ~ (4, 1) => 0.0113937
+(1, 1) ~ (4, 1) => 0.927252
+(1, 1) ~ (4, 2) => 0.042153
+(1, 1) ~ (4, 3) => 0.0127747
+(1, 2) ~ (4, 2) => 0.866112
+(1, 2) ~ (4, 3) => 0.0794915
+(1, 2) ~ (4, 4) => 0.0199289
+(1, 3) ~ (4, 2) => 0.0151885
+(1, 3) ~ (4, 3) => 0.837128
+(1, 3) ~ (4, 4) => 0.0859873
+(1, 3) ~ (4, 5) => 0.0305332
+(1, 4) ~ (4, 3) => 0.0232558
+(1, 4) ~ (4, 4) => 0.709573
+(1, 4) ~ (4, 5) => 0.131098
+(1, 4) ~ (4, 6) => 0.0344311
+(1, 5) ~ (4, 4) => 0.0930999
+(1, 5) ~ (4, 5) => 0.500577
+(1, 5) ~ (4, 6) => 0.292823
+(1, 5) ~ (4, 7) => 0.0377882
+(1, 6) ~ (4, 5) => 0.127621
+(1, 6) ~ (4, 6) => 0.431367
+(1, 6) ~ (4, 7) => 0.332032
+(1, 6) ~ (4, 8) => 0.040661
+(1, 7) ~ (4, 5) => 0.0109437
+(1, 7) ~ (4, 6) => 0.150859
+(1, 7) ~ (4, 7) => 0.40042
+(1, 7) ~ (4, 8) => 0.344523
+(1, 7) ~ (4, 9) => 0.037208
+(1, 7) ~ (4, 10) => 0.0137758
+(1, 8) ~ (4, 6) => 0.0141948
+(1, 8) ~ (4, 7) => 0.157869
+(1, 8) ~ (4, 8) => 0.383142
+(1, 8) ~ (4, 9) => 0.364443
+(1, 8) ~ (4, 10) => 0.0264855
+(1, 8) ~ (4, 11) => 0.0150548
+(1, 9) ~ (4, 7) => 0.0181872
+(1, 9) ~ (4, 8) => 0.153559
+(1, 9) ~ (4, 9) => 0.340327
+(1, 9) ~ (4, 10) => 0.415378
+(1, 9) ~ (4, 11) => 0.0162616
+(1, 9) ~ (4, 12) => 0.0181996
+(1, 10) ~ (4, 8) => 0.0188259
+(1, 10) ~ (4, 9) => 0.135392
+(1, 10) ~ (4, 10) => 0.301163
+(1, 10) ~ (4, 11) => 0.477788
+(1, 10) ~ (4, 12) => 0.0106144
+(1, 10) ~ (4, 13) => 0.0225215
+(1, 11) ~ (4, 9) => 0.023909
+(1, 11) ~ (4, 10) => 0.11172
+(1, 11) ~ (4, 11) => 0.256988
+(1, 11) ~ (4, 12) => 0.533917
+(1, 11) ~ (4, 14) => 0.0244303
+(1, 12) ~ (4, 10) => 0.0320822
+(1, 12) ~ (4, 11) => 0.0870719
+(1, 12) ~ (4, 12) => 0.205866
+(1, 12) ~ (4, 13) => 0.601812
+(1, 12) ~ (4, 15) => 0.0267331
+(1, 13) ~ (4, 11) => 0.0403388
+(1, 13) ~ (4, 12) => 0.0565114
+(1, 13) ~ (4, 13) => 0.19847
+(1, 13) ~ (4, 14) => 0.639109
+(1, 13) ~ (4, 16) => 0.0244478
+(1, 14) ~ (4, 12) => 0.0489896
+(1, 14) ~ (4, 13) => 0.030776
+(1, 14) ~ (4, 14) => 0.18741
+(1, 14) ~ (4, 15) => 0.681928
+(1, 14) ~ (4, 17) => 0.0223291
+(1, 15) ~ (4, 13) => 0.0403046
+(1, 15) ~ (4, 15) => 0.10546
+(1, 15) ~ (4, 16) => 0.804874
+(1, 15) ~ (4, 18) => 0.0186135
+(1, 16) ~ (4, 14) => 0.0304188
+(1, 16) ~ (4, 16) => 0.0220845
+(1, 16) ~ (4, 17) => 0.913533
+(1, 16) ~ (4, 19) => 0.0141646
+(1, 17) ~ (4, 15) => 0.0189769
+(1, 17) ~ (4, 18) => 0.949257
+(1, 17) ~ (4, 20) => 0.0120966
+(1, 18) ~ (4, 16) => 0.0145845
+(1, 18) ~ (4, 19) => 0.960677
+(1, 19) ~ (4, 20) => 0.977025
+(1, 20) ~ (4, 21) => 0.981673
+(1, 21) ~ (4, 22) => 0.991124
+(1, 22) ~ (4, 23) => 0.992042
+(1, 23) ~ (4, 24) => 0.989929
+(1, 24) ~ (4, 25) => 0.988962
+(1, 25) ~ (4, 26) => 0.985251
+(1, 26) ~ (4, 27) => 0.985343
+(1, 27) ~ (4, 28) => 0.988626
+(1, 28) ~ (4, 29) => 0.990667
+(1, 29) ~ (4, 30) => 0.994844
+(1, 30) ~ (4, 31) => 0.997848
+(1, 31) ~ (4, 32) => 0.997905
+(1, 32) ~ (4, 33) => 0.997844
+(1, 33) ~ (4, 34) => 0.997943
+(1, 34) ~ (4, 35) => 0.997465
+(1, 35) ~ (4, 36) => 0.996105
+(1, 36) ~ (4, 37) => 0.996256
+(1, 37) ~ (4, 38) => 0.996411
+(1, 38) ~ (4, 39) => 0.99489
+(1, 39) ~ (4, 40) => 0.993005
+(1, 40) ~ (4, 41) => 0.99132
+(1, 41) ~ (4, 42) => 0.988421
+(1, 42) ~ (4, 43) => 0.988646
+(1, 43) ~ (4, 44) => 0.984457
+(1, 44) ~ (4, 45) => 0.985808
+(1, 45) ~ (4, 46) => 0.993604
+(1, 46) ~ (4, 47) => 0.995652
+(1, 47) ~ (4, 48) => 0.997244
+(1, 48) ~ (4, 49) => 0.998742
+(1, 49) ~ (4, 50) => 0.997664
+(1, 50) ~ (4, 51) => 0.996077
+(1, 51) ~ (4, 52) => 0.995295
+(1, 52) ~ (4, 53) => 0.99448
+(1, 53) ~ (4, 54) => 0.992281
+(1, 54) ~ (4, 55) => 0.986835
+(1, 55) ~ (4, 56) => 0.958593
+(1, 55) ~ (4, 57) => 0.0122351
+(1, 56) ~ (4, 57) => 0.912656
+(1, 56) ~ (4, 58) => 0.0316237
+(1, 56) ~ (4, 59) => 0.0149783
+(1, 56) ~ (4, 60) => 0.0103135
+(1, 57) ~ (4, 57) => 0.0125303
+(1, 57) ~ (4, 58) => 0.804
+(1, 57) ~ (4, 59) => 0.0815811
+(1, 57) ~ (4, 60) => 0.0309546
+(1, 57) ~ (4, 61) => 0.0223054
+(1, 57) ~ (4, 62) => 0.0113832
+(1, 58) ~ (4, 58) => 0.0276067
+(1, 58) ~ (4, 59) => 0.625551
+(1, 58) ~ (4, 60) => 0.127137
+(1, 58) ~ (4, 61) => 0.079115
+(1, 58) ~ (4, 62) => 0.0315847
+(1, 58) ~ (4, 63) => 0.0332385
+(1, 59) ~ (4, 59) => 0.0694732
+(1, 59) ~ (4, 60) => 0.477595
+(1, 59) ~ (4, 61) => 0.172867
+(1, 59) ~ (4, 62) => 0.127467
+(1, 59) ~ (4, 63) => 0.0399162
+(1, 59) ~ (4, 64) => 0.0550534
+(1, 60) ~ (4, 60) => 0.0794726
+(1, 60) ~ (4, 61) => 0.390746
+(1, 60) ~ (4, 62) => 0.175175
+(1, 60) ~ (4, 63) => 0.186181
+(1, 60) ~ (4, 64) => 0.0287417
+(1, 60) ~ (4, 65) => 0.0585008
+(1, 61) ~ (4, 61) => 0.0851491
+(1, 61) ~ (4, 62) => 0.326717
+(1, 61) ~ (4, 63) => 0.161672
+(1, 61) ~ (4, 64) => 0.267397
+(1, 61) ~ (4, 65) => 0.0229023
+(1, 61) ~ (4, 66) => 0.0578624
+(1, 62) ~ (4, 62) => 0.0843536
+(1, 62) ~ (4, 63) => 0.269476
+(1, 62) ~ (4, 64) => 0.145737
+(1, 62) ~ (4, 65) => 0.347855
+(1, 62) ~ (4, 66) => 0.0151803
+(1, 62) ~ (4, 67) => 0.0569166
+(1, 63) ~ (4, 63) => 0.0817293
+(1, 63) ~ (4, 64) => 0.240185
+(1, 63) ~ (4, 65) => 0.141333
+(1, 63) ~ (4, 66) => 0.404821
+(1, 63) ~ (4, 68) => 0.0484056
+(1, 64) ~ (4, 64) => 0.0752635
+(1, 64) ~ (4, 65) => 0.205443
+(1, 64) ~ (4, 66) => 0.136682
+(1, 64) ~ (4, 67) => 0.469178
+(1, 64) ~ (4, 69) => 0.0404298
+(1, 65) ~ (4, 65) => 0.0796015
+(1, 65) ~ (4, 66) => 0.190568
+(1, 65) ~ (4, 67) => 0.141085
+(1, 65) ~ (4, 68) => 0.486451
+(1, 65) ~ (4, 70) => 0.037642
+(1, 66) ~ (4, 66) => 0.084771
+(1, 66) ~ (4, 67) => 0.183594
+(1, 66) ~ (4, 68) => 0.121305
+(1, 66) ~ (4, 69) => 0.515682
+(1, 66) ~ (4, 71) => 0.0338117
+(1, 67) ~ (4, 67) => 0.0774368
+(1, 67) ~ (4, 68) => 0.206889
+(1, 67) ~ (4, 69) => 0.0694123
+(1, 67) ~ (4, 70) => 0.518514
+(1, 67) ~ (4, 72) => 0.0309025
+(1, 68) ~ (4, 68) => 0.0485114
+(1, 68) ~ (4, 69) => 0.278791
+(1, 68) ~ (4, 70) => 0.0285533
+(1, 68) ~ (4, 71) => 0.507951
+(1, 68) ~ (4, 73) => 0.0167196
+(1, 69) ~ (4, 69) => 0.0208538
+(1, 69) ~ (4, 70) => 0.364035
+(1, 69) ~ (4, 71) => 0.0150551
+(1, 69) ~ (4, 72) => 0.50623
+(1, 70) ~ (4, 70) => 0.0132906
+(1, 70) ~ (4, 71) => 0.401061
+(1, 70) ~ (4, 72) => 0.0119897
+(1, 70) ~ (4, 73) => 0.444993
+(1, 71) ~ (4, 71) => 0.0121446
+(1, 71) ~ (4, 72) => 0.414208
+(1, 71) ~ (4, 74) => 0.331941
+(1, 72) ~ (4, 73) => 0.500718
+(1, 72) ~ (4, 75) => 0.325486
+(1, 73) ~ (4, 74) => 0.63177
+(1, 73) ~ (4, 76) => 0.285725
+(1, 74) ~ (4, 75) => 0.646166
+(1, 74) ~ (4, 77) => 0.244375
+(1, 75) ~ (4, 76) => 0.696902
+(1, 75) ~ (4, 78) => 0.153691
+(1, 76) ~ (4, 77) => 0.740307
+(1, 76) ~ (4, 79) => 0.127522
+(1, 77) ~ (4, 78) => 0.835523
+(1, 77) ~ (4, 80) => 0.106347
+(1, 78) ~ (4, 79) => 0.861003
+(1, 78) ~ (4, 81) => 0.100757
+(1, 79) ~ (4, 80) => 0.882578
+(1, 79) ~ (4, 82) => 0.093391
+(1, 80) ~ (4, 81) => 0.888871
+(1, 80) ~ (4, 83) => 0.0879499
+(1, 81) ~ (4, 82) => 0.893693
+(1, 81) ~ (4, 84) => 0.0633476
+(1, 82) ~ (4, 83) => 0.901217
+(1, 82) ~ (4, 85) => 0.0368415
+(1, 83) ~ (4, 84) => 0.927765
+(1, 83) ~ (4, 86) => 0.0291429
+(1, 84) ~ (4, 85) => 0.951929
+(1, 84) ~ (4, 87) => 0.0220994
+(1, 85) ~ (4, 86) => 0.957545
+(1, 85) ~ (4, 88) => 0.0202986
+(1, 86) ~ (4, 87) => 0.964921
+(1, 86) ~ (4, 89) => 0.0179408
+(1, 87) ~ (4, 88) => 0.963674
+(1, 87) ~ (4, 90) => 0.0168398
+(1, 88) ~ (4, 89) => 0.962017
+(1, 88) ~ (4, 91) => 0.0156665
+(1, 89) ~ (4, 90) => 0.959668
+(1, 89) ~ (4, 92) => 0.0143567
+(1, 90) ~ (4, 91) => 0.956733
+(1, 90) ~ (4, 93) => 0.0127484
+(1, 91) ~ (4, 92) => 0.951516
+(1, 92) ~ (4, 93) => 0.940599
+(1, 93) ~ (4, 94) => 0.934837
+(1, 94) ~ (4, 95) => 0.92017
+(1, 95) ~ (4, 96) => 0.846902
+(1, 95) ~ (4, 99) => 0.0138299
+(1, 96) ~ (4, 96) => 0.0131069
+(1, 96) ~ (4, 97) => 0.609516
+(1, 96) ~ (4, 100) => 0.0338021
+(1, 97) ~ (4, 94) => 0.0138531
+(1, 97) ~ (4, 96) => 0.0142177
+(1, 97) ~ (4, 97) => 0.0116918
+(1, 97) ~ (4, 98) => 0.502882
+(1, 97) ~ (4, 101) => 0.051098
+(1, 98) ~ (4, 95) => 0.0177879
+(1, 98) ~ (4, 98) => 0.0103423
+(1, 98) ~ (4, 99) => 0.45736
+(1, 98) ~ (4, 100) => 0.0107338
+(1, 98) ~ (4, 101) => 0.0105718
+(1, 98) ~ (4, 102) => 0.0568292
+(1, 99) ~ (4, 95) => 0.0160766
+(1, 99) ~ (4, 96) => 0.0321433
+(1, 99) ~ (4, 99) => 0.0128142
+(1, 99) ~ (4, 100) => 0.37559
+(1, 99) ~ (4, 102) => 0.0148087
+(1, 99) ~ (4, 103) => 0.0615177
+(1, 100) ~ (4, 96) => 0.0430997
+(1, 100) ~ (4, 97) => 0.0693336
+(1, 100) ~ (4, 98) => 0.0107814
+(1, 100) ~ (4, 100) => 0.0107752
+(1, 100) ~ (4, 101) => 0.243737
+(1, 100) ~ (4, 103) => 0.0172233
+(1, 100) ~ (4, 104) => 0.0642069
+(1, 101) ~ (4, 97) => 0.186806
+(1, 101) ~ (4, 98) => 0.0698479
+(1, 101) ~ (4, 101) => 0.0145914
+(1, 101) ~ (4, 102) => 0.169886
+(1, 101) ~ (4, 104) => 0.0198546
+(1, 101) ~ (4, 105) => 0.0549153
+(1, 102) ~ (4, 97) => 0.0264513
+(1, 102) ~ (4, 98) => 0.227328
+(1, 102) ~ (4, 99) => 0.0552972
+(1, 102) ~ (4, 102) => 0.0174065
+(1, 102) ~ (4, 103) => 0.143004
+(1, 102) ~ (4, 104) => 0.0106338
+(1, 102) ~ (4, 105) => 0.0158562
+(1, 102) ~ (4, 106) => 0.0333486
+(1, 103) ~ (4, 97) => 0.0171077
+(1, 103) ~ (4, 98) => 0.02843
+(1, 103) ~ (4, 99) => 0.235013
+(1, 103) ~ (4, 100) => 0.051633
+(1, 103) ~ (4, 103) => 0.021835
+(1, 103) ~ (4, 104) => 0.133981
+(1, 103) ~ (4, 107) => 0.0243301
+(1, 104) ~ (4, 98) => 0.0549373
+(1, 104) ~ (4, 99) => 0.0487433
+(1, 104) ~ (4, 100) => 0.243369
+(1, 104) ~ (4, 101) => 0.0490171
+(1, 104) ~ (4, 104) => 0.023226
+(1, 104) ~ (4, 105) => 0.137571
+(1, 104) ~ (4, 108) => 0.0230147
+(1, 105) ~ (4, 99) => 0.0694195
+(1, 105) ~ (4, 100) => 0.100641
+(1, 105) ~ (4, 101) => 0.305118
+(1, 105) ~ (4, 102) => 0.0501207
+(1, 105) ~ (4, 105) => 0.016448
+(1, 105) ~ (4, 106) => 0.130881
+(1, 105) ~ (4, 109) => 0.0160825
+(1, 106) ~ (4, 100) => 0.0763538
+(1, 106) ~ (4, 101) => 0.13899
+(1, 106) ~ (4, 102) => 0.340276
+(1, 106) ~ (4, 103) => 0.0430469
+(1, 106) ~ (4, 106) => 0.0156467
+(1, 106) ~ (4, 107) => 0.122439
+(1, 106) ~ (4, 110) => 0.0110702
+(1, 107) ~ (4, 101) => 0.0770901
+(1, 107) ~ (4, 102) => 0.165403
+(1, 107) ~ (4, 103) => 0.350391
+(1, 107) ~ (4, 104) => 0.0294617
+(1, 107) ~ (4, 107) => 0.0133297
+(1, 107) ~ (4, 108) => 0.11403
+(1, 108) ~ (4, 102) => 0.0777783
+(1, 108) ~ (4, 103) => 0.175477
+(1, 108) ~ (4, 104) => 0.346006
+(1, 108) ~ (4, 105) => 0.019019
+(1, 108) ~ (4, 108) => 0.0101178
+(1, 108) ~ (4, 109) => 0.112449
+(1, 109) ~ (4, 102) => 0.0115103
+(1, 109) ~ (4, 103) => 0.0754649
+(1, 109) ~ (4, 104) => 0.184384
+(1, 109) ~ (4, 105) => 0.366134
+(1, 109) ~ (4, 106) => 0.0187998
+(1, 109) ~ (4, 108) => 0.0144397
+(1, 109) ~ (4, 109) => 0.0104104
+(1, 109) ~ (4, 110) => 0.0923354
+(1, 110) ~ (4, 102) => 0.0105554
+(1, 110) ~ (4, 103) => 0.018598
+(1, 110) ~ (4, 104) => 0.08482
+(1, 110) ~ (4, 105) => 0.163357
+(1, 110) ~ (4, 106) => 0.354616
+(1, 110) ~ (4, 107) => 0.024419
+(1, 110) ~ (4, 109) => 0.0143632
+(1, 110) ~ (4, 110) => 0.0127876
+(1, 110) ~ (4, 111) => 0.0739786
+(1, 111) ~ (4, 101) => 0.0100543
+(1, 111) ~ (4, 102) => 0.011011
+(1, 111) ~ (4, 103) => 0.0108022
+(1, 111) ~ (4, 104) => 0.0210489
+(1, 111) ~ (4, 105) => 0.107488
+(1, 111) ~ (4, 106) => 0.156468
+(1, 111) ~ (4, 107) => 0.344211
+(1, 111) ~ (4, 108) => 0.028964
+(1, 111) ~ (4, 109) => 0.0157252
+(1, 111) ~ (4, 110) => 0.0153984
+(1, 111) ~ (4, 111) => 0.0146192
+(1, 111) ~ (4, 112) => 0.0620611
+(1, 112) ~ (4, 102) => 0.0101096
+(1, 112) ~ (4, 103) => 0.0153189
+(1, 112) ~ (4, 104) => 0.0115719
+(1, 112) ~ (4, 105) => 0.0241407
+(1, 112) ~ (4, 106) => 0.139366
+(1, 112) ~ (4, 107) => 0.123279
+(1, 112) ~ (4, 108) => 0.317682
+(1, 112) ~ (4, 109) => 0.0394395
+(1, 112) ~ (4, 110) => 0.0329493
+(1, 112) ~ (4, 111) => 0.0169077
+(1, 112) ~ (4, 112) => 0.0108278
+(1, 112) ~ (4, 113) => 0.0203938
+(1, 113) ~ (4, 104) => 0.0169738
+(1, 113) ~ (4, 105) => 0.0145148
+(1, 113) ~ (4, 106) => 0.0328665
+(1, 113) ~ (4, 107) => 0.183794
+(1, 113) ~ (4, 108) => 0.106871
+(1, 113) ~ (4, 109) => 0.306304
+(1, 113) ~ (4, 110) => 0.0499654
+(1, 113) ~ (4, 111) => 0.0489616
+(1, 113) ~ (4, 112) => 0.0182048
+(1, 113) ~ (4, 114) => 0.0126404
+(1, 114) ~ (4, 105) => 0.0196373
+(1, 114) ~ (4, 106) => 0.0189093
+(1, 114) ~ (4, 107) => 0.0348017
+(1, 114) ~ (4, 108) => 0.204208
+(1, 114) ~ (4, 109) => 0.0928616
+(1, 114) ~ (4, 110) => 0.301887
+(1, 114) ~ (4, 111) => 0.0619844
+(1, 114) ~ (4, 112) => 0.0507434
+(1, 115) ~ (4, 106) => 0.0234776
+(1, 115) ~ (4, 107) => 0.0194656
+(1, 115) ~ (4, 108) => 0.0292557
+(1, 115) ~ (4, 109) => 0.225941
+(1, 115) ~ (4, 110) => 0.0822337
+(1, 115) ~ (4, 111) => 0.303419
+(1, 115) ~ (4, 112) => 0.0589514
+(1, 115) ~ (4, 113) => 0.0315397
+(1, 116) ~ (4, 107) => 0.0243382
+(1, 116) ~ (4, 108) => 0.0149195
+(1, 116) ~ (4, 109) => 0.025185
+(1, 116) ~ (4, 110) => 0.255396
+(1, 116) ~ (4, 111) => 0.0752456
+(1, 116) ~ (4, 112) => 0.26281
+(1, 116) ~ (4, 113) => 0.0169398
+(1, 116) ~ (4, 114) => 0.0277386
+(1, 117) ~ (4, 108) => 0.0265524
+(1, 117) ~ (4, 109) => 0.0134732
+(1, 117) ~ (4, 110) => 0.0210341
+(1, 117) ~ (4, 111) => 0.28705
+(1, 117) ~ (4, 112) => 0.0616149
+(1, 117) ~ (4, 113) => 0.185533
+(1, 118) ~ (4, 108) => 0.0118386
+(1, 118) ~ (4, 109) => 0.0187851
+(1, 118) ~ (4, 110) => 0.0101858
+(1, 118) ~ (4, 111) => 0.0125236
+(1, 118) ~ (4, 112) => 0.390933
+(1, 118) ~ (4, 113) => 0.0518968
+(1, 118) ~ (4, 114) => 0.101888
+(1, 119) ~ (4, 113) => 0.641376
+(1, 119) ~ (4, 114) => 0.0313112
+(1, 120) ~ (4, 114) => 0.782546
+
+; gap posteriors
+(1, 0) ~ (4, -1) => 0.010722
+(1, 1) ~ (4, -1) => 0.01782
+(1, 2) ~ (4, -1) => 0.0344675
+(1, 3) ~ (4, -1) => 0.0311629
+(1, 4) ~ (4, -1) => 0.101642
+(1, 5) ~ (4, -1) => 0.0757117
+(1, 6) ~ (4, -1) => 0.0683185
+(1, 7) ~ (4, -1) => 0.0422703
+(1, 8) ~ (4, -1) => 0.038811
+(1, 9) ~ (4, -1) => 0.0380868
+(1, 10) ~ (4, -1) => 0.0336946
+(1, 11) ~ (4, -1) => 0.0490358
+(1, 12) ~ (4, -1) => 0.046435
+(1, 13) ~ (4, -1) => 0.0411231
+(1, 14) ~ (4, -1) => 0.0285672
+(1, 15) ~ (4, -1) => 0.0307478
+(1, 16) ~ (4, -1) => 0.0197996
+(1, 17) ~ (4, -1) => 0.0196693
+(1, 18) ~ (4, -1) => 0.024738
+(1, 19) ~ (4, -1) => 0.0229749
+(1, 20) ~ (4, -1) => 0.0183271
+(1, 21) ~ (4, -1) => 0.00887638
+(1, 22) ~ (4, -1) => 0.00795847
+(1, 23) ~ (4, -1) => 0.0100709
+(1, 24) ~ (4, -1) => 0.0110378
+(1, 25) ~ (4, -1) => 0.0147488
+(1, 26) ~ (4, -1) => 0.0146568
+(1, 27) ~ (4, -1) => 0.0113737
+(1, 28) ~ (4, -1) => 0.0093326
+(1, 29) ~ (4, -1) => 0.0051561
+(1, 30) ~ (4, -1) => 0.00215167
+(1, 31) ~ (4, -1) => 0.00209516
+(1, 32) ~ (4, -1) => 0.00215626
+(1, 33) ~ (4, -1) => 0.00205702
+(1, 34) ~ (4, -1) => 0.00253522
+(1, 35) ~ (4, -1) => 0.00389469
+(1, 36) ~ (4, -1) => 0.00374353
+(1, 37) ~ (4, -1) => 0.00358886
+(1, 38) ~ (4, -1) => 0.00510991
+(1, 39) ~ (4, -1) => 0.00699538
+(1, 40) ~ (4, -1) => 0.00867957
+(1, 41) ~ (4, -1) => 0.0115793
+(1, 42) ~ (4, -1) => 0.0113542
+(1, 43) ~ (4, -1) => 0.0155427
+(1, 44) ~ (4, -1) => 0.0141918
+(1, 45) ~ (4, -1) => 0.00639582
+(1, 46) ~ (4, -1) => 0.00434816
+(1, 47) ~ (4, -1) => 0.00275648
+(1, 48) ~ (4, -1) => 0.00125778
+(1, 49) ~ (4, -1) => 0.00233644
+(1, 50) ~ (4, -1) => 0.00392306
+(1, 51) ~ (4, -1) => 0.00470459
+(1, 52) ~ (4, -1) => 0.00551981
+(1, 53) ~ (4, -1) => 0.0077188
+(1, 54) ~ (4, -1) => 0.0131648
+(1, 55) ~ (4, -1) => 0.0291715
+(1, 56) ~ (4, -1) => 0.0304282
+(1, 57) ~ (4, -1) => 0.0372456
+(1, 58) ~ (4, -1) => 0.075767
+(1, 59) ~ (4, -1) => 0.0576277
+(1, 60) ~ (4, -1) => 0.0811823
+(1, 61) ~ (4, -1) => 0.0783001
+(1, 62) ~ (4, -1) => 0.0804816
+(1, 63) ~ (4, -1) => 0.0835261
+(1, 64) ~ (4, -1) => 0.0730034
+(1, 65) ~ (4, -1) => 0.0646522
+(1, 66) ~ (4, -1) => 0.0608361
+(1, 67) ~ (4, -1) => 0.0968458
+(1, 68) ~ (4, -1) => 0.119473
+(1, 69) ~ (4, -1) => 0.0938259
+(1, 70) ~ (4, -1) => 0.128666
+(1, 71) ~ (4, -1) => 0.241706
+(1, 72) ~ (4, -1) => 0.173796
+(1, 73) ~ (4, -1) => 0.0825055
+(1, 74) ~ (4, -1) => 0.109459
+(1, 75) ~ (4, -1) => 0.149407
+(1, 76) ~ (4, -1) => 0.132171
+(1, 77) ~ (4, -1) => 0.0581304
+(1, 78) ~ (4, -1) => 0.0382406
+(1, 79) ~ (4, -1) => 0.0240311
+(1, 80) ~ (4, -1) => 0.0231795
+(1, 81) ~ (4, -1) => 0.0429596
+(1, 82) ~ (4, -1) => 0.0619419
+(1, 83) ~ (4, -1) => 0.0430918
+(1, 84) ~ (4, -1) => 0.0259712
+(1, 85) ~ (4, -1) => 0.0221565
+(1, 86) ~ (4, -1) => 0.0171378
+(1, 87) ~ (4, -1) => 0.0194864
+(1, 88) ~ (4, -1) => 0.0223163
+(1, 89) ~ (4, -1) => 0.0259754
+(1, 90) ~ (4, -1) => 0.0305189
+(1, 91) ~ (4, -1) => 0.0484836
+(1, 92) ~ (4, -1) => 0.0594014
+(1, 93) ~ (4, -1) => 0.0651627
+(1, 94) ~ (4, -1) => 0.0798298
+(1, 95) ~ (4, -1) => 0.139268
+(1, 96) ~ (4, -1) => 0.343575
+(1, 97) ~ (4, -1) => 0.406257
+(1, 98) ~ (4, -1) => 0.436375
+(1, 99) ~ (4, -1) => 0.487049
+(1, 100) ~ (4, -1) => 0.540843
+(1, 101) ~ (4, -1) => 0.484099
+(1, 102) ~ (4, -1) => 0.470674
+(1, 103) ~ (4, -1) => 0.48767
+(1, 104) ~ (4, -1) => 0.420122
+(1, 105) ~ (4, -1) => 0.311289
+(1, 106) ~ (4, -1) => 0.252177
+(1, 107) ~ (4, -1) => 0.250294
+(1, 108) ~ (4, -1) => 0.259154
+(1, 109) ~ (4, -1) => 0.226521
+(1, 110) ~ (4, -1) => 0.242506
+(1, 111) ~ (4, -1) => 0.202148
+(1, 112) ~ (4, -1) => 0.238014
+(1, 113) ~ (4, -1) => 0.208904
+(1, 114) ~ (4, -1) => 0.214967
+(1, 115) ~ (4, -1) => 0.225716
+(1, 116) ~ (4, -1) => 0.297427
+(1, 117) ~ (4, -1) => 0.404742
+(1, 118) ~ (4, -1) => 0.401949
+(1, 119) ~ (4, -1) => 0.327312
+(1, 120) ~ (4, -1) => 0.217454
+
+(1, -1) ~ (4, 0) => 0.0221156
+(1, -1) ~ (4, 1) => 0.061354
+(1, -1) ~ (4, 2) => 0.0765463
+(1, -1) ~ (4, 3) => 0.0473499
+(1, -1) ~ (4, 4) => 0.0914107
+(1, -1) ~ (4, 5) => 0.199227
+(1, -1) ~ (4, 6) => 0.0763252
+(1, -1) ~ (4, 7) => 0.0537031
+(1, -1) ~ (4, 8) => 0.0592893
+(1, -1) ~ (4, 9) => 0.0987201
+(1, -1) ~ (4, 10) => 0.0993958
+(1, -1) ~ (4, 11) => 0.106496
+(1, -1) ~ (4, 12) => 0.125902
+(1, -1) ~ (4, 13) => 0.106117
+(1, -1) ~ (4, 14) => 0.118632
+(1, -1) ~ (4, 15) => 0.166901
+(1, -1) ~ (4, 16) => 0.13401
+(1, -1) ~ (4, 17) => 0.0641384
+(1, -1) ~ (4, 18) => 0.0321292
+(1, -1) ~ (4, 19) => 0.025158
+(1, -1) ~ (4, 20) => 0.0108784
+(1, -1) ~ (4, 21) => 0.0183271
+(1, -1) ~ (4, 22) => 0.00887638
+(1, -1) ~ (4, 23) => 0.00795847
+(1, -1) ~ (4, 24) => 0.0100709
+(1, -1) ~ (4, 25) => 0.0110378
+(1, -1) ~ (4, 26) => 0.0147488
+(1, -1) ~ (4, 27) => 0.0146568
+(1, -1) ~ (4, 28) => 0.0113737
+(1, -1) ~ (4, 29) => 0.0093326
+(1, -1) ~ (4, 30) => 0.0051561
+(1, -1) ~ (4, 31) => 0.00215167
+(1, -1) ~ (4, 32) => 0.00209516
+(1, -1) ~ (4, 33) => 0.00215626
+(1, -1) ~ (4, 34) => 0.00205702
+(1, -1) ~ (4, 35) => 0.00253522
+(1, -1) ~ (4, 36) => 0.00389469
+(1, -1) ~ (4, 37) => 0.00374353
+(1, -1) ~ (4, 38) => 0.00358886
+(1, -1) ~ (4, 39) => 0.00510991
+(1, -1) ~ (4, 40) => 0.00699538
+(1, -1) ~ (4, 41) => 0.00867957
+(1, -1) ~ (4, 42) => 0.0115793
+(1, -1) ~ (4, 43) => 0.0113542
+(1, -1) ~ (4, 44) => 0.0155427
+(1, -1) ~ (4, 45) => 0.0141918
+(1, -1) ~ (4, 46) => 0.00639582
+(1, -1) ~ (4, 47) => 0.00434816
+(1, -1) ~ (4, 48) => 0.00275648
+(1, -1) ~ (4, 49) => 0.00125778
+(1, -1) ~ (4, 50) => 0.00233644
+(1, -1) ~ (4, 51) => 0.00392306
+(1, -1) ~ (4, 52) => 0.00470459
+(1, -1) ~ (4, 53) => 0.00551981
+(1, -1) ~ (4, 54) => 0.0077188
+(1, -1) ~ (4, 55) => 0.0131648
+(1, -1) ~ (4, 56) => 0.0414066
+(1, -1) ~ (4, 57) => 0.0625783
+(1, -1) ~ (4, 58) => 0.13677
+(1, -1) ~ (4, 59) => 0.208416
+(1, -1) ~ (4, 60) => 0.274527
+(1, -1) ~ (4, 61) => 0.249817
+(1, -1) ~ (4, 62) => 0.243319
+(1, -1) ~ (4, 63) => 0.227787
+(1, -1) ~ (4, 64) => 0.187623
+(1, -1) ~ (4, 65) => 0.144364
+(1, -1) ~ (4, 66) => 0.110116
+(1, -1) ~ (4, 67) => 0.0717894
+(1, -1) ~ (4, 68) => 0.0884375
+(1, -1) ~ (4, 69) => 0.0748303
+(1, -1) ~ (4, 70) => 0.0379656
+(1, -1) ~ (4, 71) => 0.0299769
+(1, -1) ~ (4, 72) => 0.0366692
+(1, -1) ~ (4, 73) => 0.0375699
+(1, -1) ~ (4, 74) => 0.036289
+(1, -1) ~ (4, 75) => 0.0283476
+(1, -1) ~ (4, 76) => 0.0173725
+(1, -1) ~ (4, 77) => 0.0153177
+(1, -1) ~ (4, 78) => 0.0107867
+(1, -1) ~ (4, 79) => 0.0114756
+(1, -1) ~ (4, 80) => 0.0110753
+(1, -1) ~ (4, 81) => 0.0103727
+(1, -1) ~ (4, 82) => 0.0129161
+(1, -1) ~ (4, 83) => 0.0108335
+(1, -1) ~ (4, 84) => 0.00888711
+(1, -1) ~ (4, 85) => 0.0112291
+(1, -1) ~ (4, 86) => 0.0133122
+(1, -1) ~ (4, 87) => 0.0129793
+(1, -1) ~ (4, 88) => 0.0160275
+(1, -1) ~ (4, 89) => 0.020042
+(1, -1) ~ (4, 90) => 0.0234923
+(1, -1) ~ (4, 91) => 0.0276008
+(1, -1) ~ (4, 92) => 0.0341268
+(1, -1) ~ (4, 93) => 0.046653
+(1, -1) ~ (4, 94) => 0.0513096
+(1, -1) ~ (4, 95) => 0.0459653
+(1, -1) ~ (4, 96) => 0.0505307
+(1, -1) ~ (4, 97) => 0.0790939
+(1, -1) ~ (4, 98) => 0.0954511
+(1, -1) ~ (4, 99) => 0.107523
+(1, -1) ~ (4, 100) => 0.0971013
+(1, -1) ~ (4, 101) => 0.0997319
+(1, -1) ~ (4, 102) => 0.0643058
+(1, -1) ~ (4, 103) => 0.0673215
+(1, -1) ~ (4, 104) => 0.0538322
+(1, -1) ~ (4, 105) => 0.060919
+(1, -1) ~ (4, 106) => 0.07562
+(1, -1) ~ (4, 107) => 0.0855923
+(1, -1) ~ (4, 108) => 0.098106
+(1, -1) ~ (4, 109) => 0.108981
+(1, -1) ~ (4, 110) => 0.114757
+(1, -1) ~ (4, 111) => 0.10531
+(1, -1) ~ (4, 112) => 0.0838537
+(1, -1) ~ (4, 113) => 0.0523201
+(1, -1) ~ (4, 114) => 0.0438755
+
+; Sparse posterior probability matrix for sequences 2 and 3
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (3, 0) => 0.912219
+(2, 1) ~ (3, 0) => 0.0718007
+(2, 1) ~ (3, 1) => 0.769694
+(2, 1) ~ (3, 2) => 0.0110463
+(2, 2) ~ (3, 0) => 0.0104892
+(2, 2) ~ (3, 1) => 0.188178
+(2, 2) ~ (3, 2) => 0.351436
+(2, 2) ~ (3, 3) => 0.0113299
+(2, 3) ~ (3, 1) => 0.0137234
+(2, 3) ~ (3, 2) => 0.591679
+(2, 3) ~ (3, 3) => 0.175511
+(2, 3) ~ (3, 4) => 0.0151036
+(2, 4) ~ (3, 2) => 0.0132808
+(2, 4) ~ (3, 3) => 0.765129
+(2, 4) ~ (3, 4) => 0.158401
+(2, 4) ~ (3, 5) => 0.013829
+(2, 5) ~ (3, 2) => 0.0148175
+(2, 5) ~ (3, 4) => 0.782908
+(2, 5) ~ (3, 5) => 0.134097
+(2, 5) ~ (3, 6) => 0.0123352
+(2, 6) ~ (3, 3) => 0.0179582
+(2, 6) ~ (3, 4) => 0.0107126
+(2, 6) ~ (3, 5) => 0.810321
+(2, 6) ~ (3, 6) => 0.109905
+(2, 6) ~ (3, 7) => 0.0124712
+(2, 7) ~ (3, 4) => 0.0164818
+(2, 7) ~ (3, 5) => 0.010239
+(2, 7) ~ (3, 6) => 0.839631
+(2, 7) ~ (3, 7) => 0.0946232
+(2, 7) ~ (3, 8) => 0.012011
+(2, 8) ~ (3, 5) => 0.0138719
+(2, 8) ~ (3, 6) => 0.010994
+(2, 8) ~ (3, 7) => 0.855491
+(2, 8) ~ (3, 8) => 0.0805815
+(2, 8) ~ (3, 9) => 0.0118083
+(2, 9) ~ (3, 6) => 0.0117331
+(2, 9) ~ (3, 8) => 0.87597
+(2, 9) ~ (3, 9) => 0.0702489
+(2, 10) ~ (3, 7) => 0.0131188
+(2, 10) ~ (3, 9) => 0.881161
+(2, 10) ~ (3, 10) => 0.0775847
+(2, 11) ~ (3, 8) => 0.0139033
+(2, 11) ~ (3, 10) => 0.882278
+(2, 11) ~ (3, 11) => 0.0769188
+(2, 12) ~ (3, 9) => 0.0159977
+(2, 12) ~ (3, 11) => 0.87372
+(2, 12) ~ (3, 12) => 0.0763642
+(2, 13) ~ (3, 10) => 0.0188449
+(2, 13) ~ (3, 12) => 0.870258
+(2, 13) ~ (3, 13) => 0.0775476
+(2, 14) ~ (3, 11) => 0.0202707
+(2, 14) ~ (3, 13) => 0.86664
+(2, 14) ~ (3, 14) => 0.0748482
+(2, 15) ~ (3, 12) => 0.0219178
+(2, 15) ~ (3, 13) => 0.010943
+(2, 15) ~ (3, 14) => 0.869692
+(2, 15) ~ (3, 15) => 0.0689487
+(2, 16) ~ (3, 13) => 0.0232454
+(2, 16) ~ (3, 15) => 0.874295
+(2, 16) ~ (3, 16) => 0.0633501
+(2, 17) ~ (3, 14) => 0.0233048
+(2, 17) ~ (3, 16) => 0.88226
+(2, 17) ~ (3, 17) => 0.0538437
+(2, 18) ~ (3, 15) => 0.0217488
+(2, 18) ~ (3, 17) => 0.855545
+(2, 18) ~ (3, 18) => 0.0793593
+(2, 18) ~ (3, 19) => 0.0157072
+(2, 19) ~ (3, 16) => 0.0175444
+(2, 19) ~ (3, 17) => 0.0160561
+(2, 19) ~ (3, 18) => 0.817885
+(2, 19) ~ (3, 19) => 0.100913
+(2, 19) ~ (3, 20) => 0.0233638
+(2, 20) ~ (3, 17) => 0.0135937
+(2, 20) ~ (3, 18) => 0.0242672
+(2, 20) ~ (3, 19) => 0.789968
+(2, 20) ~ (3, 20) => 0.123207
+(2, 20) ~ (3, 21) => 0.0213565
+(2, 21) ~ (3, 19) => 0.0261828
+(2, 21) ~ (3, 20) => 0.694714
+(2, 21) ~ (3, 21) => 0.215251
+(2, 21) ~ (3, 22) => 0.0268549
+(2, 22) ~ (3, 20) => 0.0305857
+(2, 22) ~ (3, 21) => 0.587857
+(2, 22) ~ (3, 22) => 0.311666
+(2, 22) ~ (3, 23) => 0.0283362
+(2, 23) ~ (3, 21) => 0.0326522
+(2, 23) ~ (3, 22) => 0.395926
+(2, 23) ~ (3, 23) => 0.415452
+(2, 23) ~ (3, 24) => 0.0884368
+(2, 23) ~ (3, 25) => 0.0256445
+(2, 24) ~ (3, 22) => 0.0467456
+(2, 24) ~ (3, 23) => 0.340051
+(2, 24) ~ (3, 24) => 0.420047
+(2, 24) ~ (3, 25) => 0.105561
+(2, 24) ~ (3, 26) => 0.058892
+(2, 25) ~ (3, 23) => 0.0441939
+(2, 25) ~ (3, 24) => 0.303561
+(2, 25) ~ (3, 25) => 0.440929
+(2, 25) ~ (3, 26) => 0.111829
+(2, 25) ~ (3, 27) => 0.0681721
+(2, 26) ~ (3, 24) => 0.0282852
+(2, 26) ~ (3, 25) => 0.184632
+(2, 26) ~ (3, 26) => 0.531902
+(2, 26) ~ (3, 27) => 0.160047
+(2, 26) ~ (3, 28) => 0.0681182
+(2, 27) ~ (3, 25) => 0.0210367
+(2, 27) ~ (3, 26) => 0.0955383
+(2, 27) ~ (3, 27) => 0.541095
+(2, 27) ~ (3, 28) => 0.252434
+(2, 27) ~ (3, 29) => 0.0226225
+(2, 28) ~ (3, 26) => 0.016329
+(2, 28) ~ (3, 27) => 0.0430946
+(2, 28) ~ (3, 28) => 0.390886
+(2, 28) ~ (3, 29) => 0.511642
+(2, 28) ~ (3, 30) => 0.0169631
+(2, 29) ~ (3, 28) => 0.0248496
+(2, 29) ~ (3, 29) => 0.224394
+(2, 29) ~ (3, 30) => 0.705462
+(2, 30) ~ (3, 29) => 0.0269841
+(2, 30) ~ (3, 30) => 0.19096
+(2, 30) ~ (3, 31) => 0.753588
+(2, 30) ~ (3, 32) => 0.0108379
+(2, 31) ~ (3, 30) => 0.0184418
+(2, 31) ~ (3, 31) => 0.178088
+(2, 31) ~ (3, 32) => 0.778899
+(2, 31) ~ (3, 33) => 0.0110412
+(2, 32) ~ (3, 31) => 0.0144673
+(2, 32) ~ (3, 32) => 0.162407
+(2, 32) ~ (3, 33) => 0.802215
+(2, 32) ~ (3, 34) => 0.0104707
+(2, 33) ~ (3, 33) => 0.14551
+(2, 33) ~ (3, 34) => 0.825586
+(2, 33) ~ (3, 35) => 0.0103387
+(2, 34) ~ (3, 34) => 0.106713
+(2, 34) ~ (3, 35) => 0.873839
+(2, 34) ~ (3, 36) => 0.0106047
+(2, 35) ~ (3, 35) => 0.0873912
+(2, 35) ~ (3, 36) => 0.890685
+(2, 35) ~ (3, 37) => 0.0110911
+(2, 36) ~ (3, 36) => 0.073463
+(2, 36) ~ (3, 37) => 0.905275
+(2, 37) ~ (3, 37) => 0.0566876
+(2, 37) ~ (3, 38) => 0.914633
+(2, 37) ~ (3, 39) => 0.0175098
+(2, 38) ~ (3, 38) => 0.0483487
+(2, 38) ~ (3, 39) => 0.913967
+(2, 38) ~ (3, 40) => 0.0233346
+(2, 39) ~ (3, 39) => 0.0393131
+(2, 39) ~ (3, 40) => 0.91366
+(2, 39) ~ (3, 41) => 0.0280139
+(2, 40) ~ (3, 40) => 0.0290908
+(2, 40) ~ (3, 41) => 0.910376
+(2, 40) ~ (3, 42) => 0.029927
+(2, 40) ~ (3, 43) => 0.0173682
+(2, 41) ~ (3, 41) => 0.0159556
+(2, 41) ~ (3, 42) => 0.893686
+(2, 41) ~ (3, 43) => 0.0417165
+(2, 41) ~ (3, 44) => 0.0300805
+(2, 42) ~ (3, 42) => 0.0128435
+(2, 42) ~ (3, 43) => 0.816866
+(2, 42) ~ (3, 44) => 0.0747328
+(2, 42) ~ (3, 45) => 0.0766794
+(2, 43) ~ (3, 43) => 0.0112216
+(2, 43) ~ (3, 44) => 0.744483
+(2, 43) ~ (3, 45) => 0.0722127
+(2, 43) ~ (3, 46) => 0.155164
+(2, 44) ~ (3, 45) => 0.547748
+(2, 44) ~ (3, 46) => 0.0799809
+(2, 44) ~ (3, 47) => 0.342057
+(2, 45) ~ (3, 45) => 0.0131908
+(2, 45) ~ (3, 46) => 0.358146
+(2, 45) ~ (3, 47) => 0.0648093
+(2, 45) ~ (3, 48) => 0.536005
+(2, 46) ~ (3, 46) => 0.0194527
+(2, 46) ~ (3, 47) => 0.260014
+(2, 46) ~ (3, 48) => 0.054873
+(2, 46) ~ (3, 49) => 0.63219
+(2, 47) ~ (3, 47) => 0.0211202
+(2, 47) ~ (3, 48) => 0.138658
+(2, 47) ~ (3, 49) => 0.084201
+(2, 47) ~ (3, 50) => 0.715968
+(2, 48) ~ (3, 48) => 0.019805
+(2, 48) ~ (3, 49) => 0.106673
+(2, 48) ~ (3, 50) => 0.0803427
+(2, 48) ~ (3, 51) => 0.745385
+(2, 48) ~ (3, 52) => 0.0119975
+(2, 49) ~ (3, 49) => 0.0147538
+(2, 49) ~ (3, 50) => 0.0908894
+(2, 49) ~ (3, 51) => 0.0850807
+(2, 49) ~ (3, 52) => 0.744384
+(2, 49) ~ (3, 53) => 0.0202554
+(2, 49) ~ (3, 55) => 0.0164495
+(2, 50) ~ (3, 50) => 0.0109338
+(2, 50) ~ (3, 51) => 0.078519
+(2, 50) ~ (3, 52) => 0.0704142
+(2, 50) ~ (3, 53) => 0.759322
+(2, 50) ~ (3, 54) => 0.0248888
+(2, 50) ~ (3, 56) => 0.0221958
+(2, 51) ~ (3, 52) => 0.0530084
+(2, 51) ~ (3, 53) => 0.0598729
+(2, 51) ~ (3, 54) => 0.780695
+(2, 51) ~ (3, 55) => 0.0282813
+(2, 51) ~ (3, 57) => 0.0248568
+(2, 52) ~ (3, 51) => 0.017435
+(2, 52) ~ (3, 53) => 0.0564319
+(2, 52) ~ (3, 54) => 0.0421895
+(2, 52) ~ (3, 55) => 0.784995
+(2, 52) ~ (3, 56) => 0.0311489
+(2, 52) ~ (3, 58) => 0.0274959
+(2, 53) ~ (3, 52) => 0.0217949
+(2, 53) ~ (3, 54) => 0.0601851
+(2, 53) ~ (3, 55) => 0.0197095
+(2, 53) ~ (3, 56) => 0.795482
+(2, 53) ~ (3, 57) => 0.0109175
+(2, 53) ~ (3, 58) => 0.0115474
+(2, 53) ~ (3, 59) => 0.0255435
+(2, 54) ~ (3, 53) => 0.0216466
+(2, 54) ~ (3, 55) => 0.0722559
+(2, 54) ~ (3, 57) => 0.825877
+(2, 54) ~ (3, 59) => 0.0151793
+(2, 54) ~ (3, 60) => 0.0264456
+(2, 55) ~ (3, 54) => 0.0220394
+(2, 55) ~ (3, 56) => 0.0727696
+(2, 55) ~ (3, 58) => 0.820669
+(2, 55) ~ (3, 59) => 0.0113806
+(2, 55) ~ (3, 60) => 0.0123758
+(2, 55) ~ (3, 61) => 0.0274192
+(2, 56) ~ (3, 55) => 0.0236865
+(2, 56) ~ (3, 57) => 0.0732798
+(2, 56) ~ (3, 59) => 0.812937
+(2, 56) ~ (3, 60) => 0.0178522
+(2, 56) ~ (3, 61) => 0.0110424
+(2, 56) ~ (3, 62) => 0.0260317
+(2, 57) ~ (3, 56) => 0.0231383
+(2, 57) ~ (3, 58) => 0.0651512
+(2, 57) ~ (3, 59) => 0.0202254
+(2, 57) ~ (3, 60) => 0.762579
+(2, 57) ~ (3, 61) => 0.0260054
+(2, 57) ~ (3, 62) => 0.0104877
+(2, 57) ~ (3, 63) => 0.0237027
+(2, 58) ~ (3, 57) => 0.0228056
+(2, 58) ~ (3, 59) => 0.0582755
+(2, 58) ~ (3, 60) => 0.0709923
+(2, 58) ~ (3, 61) => 0.745487
+(2, 58) ~ (3, 62) => 0.0229806
+(2, 58) ~ (3, 63) => 0.0104964
+(2, 58) ~ (3, 64) => 0.0250778
+(2, 59) ~ (3, 58) => 0.0210501
+(2, 59) ~ (3, 60) => 0.0400063
+(2, 59) ~ (3, 61) => 0.103635
+(2, 59) ~ (3, 62) => 0.743213
+(2, 59) ~ (3, 63) => 0.0120093
+(2, 59) ~ (3, 65) => 0.0269394
+(2, 60) ~ (3, 59) => 0.0205336
+(2, 60) ~ (3, 61) => 0.0311801
+(2, 60) ~ (3, 62) => 0.114275
+(2, 60) ~ (3, 63) => 0.763172
+(2, 60) ~ (3, 64) => 0.0108669
+(2, 60) ~ (3, 66) => 0.029065
+(2, 61) ~ (3, 60) => 0.019203
+(2, 61) ~ (3, 62) => 0.0250228
+(2, 61) ~ (3, 63) => 0.121338
+(2, 61) ~ (3, 64) => 0.763225
+(2, 61) ~ (3, 66) => 0.0100375
+(2, 61) ~ (3, 67) => 0.0275168
+(2, 62) ~ (3, 61) => 0.017906
+(2, 62) ~ (3, 63) => 0.0198621
+(2, 62) ~ (3, 64) => 0.114397
+(2, 62) ~ (3, 65) => 0.755672
+(2, 62) ~ (3, 66) => 0.0231649
+(2, 62) ~ (3, 68) => 0.0247336
+(2, 63) ~ (3, 62) => 0.0138077
+(2, 63) ~ (3, 64) => 0.0175315
+(2, 63) ~ (3, 65) => 0.109107
+(2, 63) ~ (3, 66) => 0.763379
+(2, 63) ~ (3, 67) => 0.0410025
+(2, 63) ~ (3, 69) => 0.020784
+(2, 64) ~ (3, 63) => 0.0102547
+(2, 64) ~ (3, 65) => 0.0138672
+(2, 64) ~ (3, 66) => 0.0731854
+(2, 64) ~ (3, 67) => 0.783173
+(2, 64) ~ (3, 68) => 0.0575795
+(2, 64) ~ (3, 70) => 0.0189942
+(2, 65) ~ (3, 66) => 0.0133074
+(2, 65) ~ (3, 67) => 0.0481256
+(2, 65) ~ (3, 68) => 0.811987
+(2, 65) ~ (3, 69) => 0.0582157
+(2, 65) ~ (3, 71) => 0.0162578
+(2, 66) ~ (3, 67) => 0.0157743
+(2, 66) ~ (3, 68) => 0.0395827
+(2, 66) ~ (3, 69) => 0.823794
+(2, 66) ~ (3, 70) => 0.0556786
+(2, 66) ~ (3, 72) => 0.0171338
+(2, 67) ~ (3, 68) => 0.0193724
+(2, 67) ~ (3, 69) => 0.0282314
+(2, 67) ~ (3, 70) => 0.834363
+(2, 67) ~ (3, 71) => 0.0464193
+(2, 67) ~ (3, 73) => 0.0174638
+(2, 68) ~ (3, 69) => 0.0260141
+(2, 68) ~ (3, 70) => 0.0165242
+(2, 68) ~ (3, 71) => 0.85728
+(2, 68) ~ (3, 72) => 0.0310383
+(2, 68) ~ (3, 74) => 0.0175118
+(2, 69) ~ (3, 70) => 0.035459
+(2, 69) ~ (3, 71) => 0.0113658
+(2, 69) ~ (3, 72) => 0.865281
+(2, 69) ~ (3, 73) => 0.0221201
+(2, 69) ~ (3, 75) => 0.0172224
+(2, 70) ~ (3, 71) => 0.0417122
+(2, 70) ~ (3, 72) => 0.0152907
+(2, 70) ~ (3, 73) => 0.860113
+(2, 70) ~ (3, 74) => 0.0226685
+(2, 70) ~ (3, 76) => 0.0159944
+(2, 71) ~ (3, 72) => 0.0421178
+(2, 71) ~ (3, 73) => 0.0216645
+(2, 71) ~ (3, 74) => 0.84704
+(2, 71) ~ (3, 75) => 0.0211169
+(2, 71) ~ (3, 77) => 0.0148277
+(2, 72) ~ (3, 73) => 0.043654
+(2, 72) ~ (3, 74) => 0.0172267
+(2, 72) ~ (3, 75) => 0.836945
+(2, 72) ~ (3, 76) => 0.0194034
+(2, 72) ~ (3, 78) => 0.0132848
+(2, 73) ~ (3, 74) => 0.0580869
+(2, 73) ~ (3, 75) => 0.0187178
+(2, 73) ~ (3, 76) => 0.810266
+(2, 73) ~ (3, 77) => 0.0276538
+(2, 73) ~ (3, 79) => 0.0104439
+(2, 74) ~ (3, 75) => 0.0717605
+(2, 74) ~ (3, 76) => 0.0191459
+(2, 74) ~ (3, 77) => 0.757251
+(2, 74) ~ (3, 78) => 0.0426763
+(2, 74) ~ (3, 79) => 0.0117989
+(2, 74) ~ (3, 80) => 0.0154628
+(2, 75) ~ (3, 76) => 0.0948856
+(2, 75) ~ (3, 77) => 0.0178498
+(2, 75) ~ (3, 78) => 0.702191
+(2, 75) ~ (3, 79) => 0.0632593
+(2, 75) ~ (3, 81) => 0.0248046
+(2, 76) ~ (3, 77) => 0.128414
+(2, 76) ~ (3, 78) => 0.0112402
+(2, 76) ~ (3, 79) => 0.672104
+(2, 76) ~ (3, 80) => 0.0661465
+(2, 76) ~ (3, 82) => 0.0333699
+(2, 77) ~ (3, 78) => 0.164143
+(2, 77) ~ (3, 80) => 0.613724
+(2, 77) ~ (3, 81) => 0.0825015
+(2, 77) ~ (3, 83) => 0.0382622
+(2, 78) ~ (3, 79) => 0.195281
+(2, 78) ~ (3, 80) => 0.0185792
+(2, 78) ~ (3, 81) => 0.555859
+(2, 78) ~ (3, 82) => 0.0961757
+(2, 78) ~ (3, 84) => 0.0421843
+(2, 79) ~ (3, 80) => 0.215348
+(2, 79) ~ (3, 81) => 0.0349873
+(2, 79) ~ (3, 82) => 0.496042
+(2, 79) ~ (3, 83) => 0.0364031
+(2, 79) ~ (3, 85) => 0.0326168
+(2, 80) ~ (3, 80) => 0.0115117
+(2, 80) ~ (3, 81) => 0.223624
+(2, 80) ~ (3, 82) => 0.079929
+(2, 80) ~ (3, 83) => 0.337106
+(2, 80) ~ (3, 84) => 0.0106316
+(2, 80) ~ (3, 86) => 0.0192009
+(2, 81) ~ (3, 81) => 0.0131745
+(2, 81) ~ (3, 82) => 0.180289
+(2, 81) ~ (3, 83) => 0.333153
+(2, 81) ~ (3, 84) => 0.188807
+(2, 82) ~ (3, 83) => 0.19264
+(2, 82) ~ (3, 84) => 0.510794
+(2, 82) ~ (3, 85) => 0.0423436
+(2, 83) ~ (3, 84) => 0.134766
+(2, 83) ~ (3, 85) => 0.748091
+(2, 83) ~ (3, 86) => 0.0340299
+(2, 84) ~ (3, 85) => 0.124034
+(2, 84) ~ (3, 86) => 0.797623
+(2, 84) ~ (3, 87) => 0.0147967
+(2, 85) ~ (3, 86) => 0.103652
+(2, 85) ~ (3, 87) => 0.842524
+(2, 85) ~ (3, 88) => 0.0208894
+(2, 86) ~ (3, 87) => 0.0997144
+(2, 86) ~ (3, 88) => 0.845196
+(2, 86) ~ (3, 89) => 0.0234072
+(2, 86) ~ (3, 90) => 0.0107157
+(2, 87) ~ (3, 88) => 0.0930518
+(2, 87) ~ (3, 89) => 0.8471
+(2, 87) ~ (3, 90) => 0.0248629
+(2, 87) ~ (3, 91) => 0.0139739
+(2, 88) ~ (3, 89) => 0.0857533
+(2, 88) ~ (3, 90) => 0.849847
+(2, 88) ~ (3, 91) => 0.0253994
+(2, 88) ~ (3, 92) => 0.0172874
+(2, 89) ~ (3, 90) => 0.0779791
+(2, 89) ~ (3, 91) => 0.853474
+(2, 89) ~ (3, 92) => 0.0248887
+(2, 89) ~ (3, 93) => 0.020537
+(2, 90) ~ (3, 91) => 0.0690332
+(2, 90) ~ (3, 92) => 0.854971
+(2, 90) ~ (3, 93) => 0.0215933
+(2, 90) ~ (3, 94) => 0.0265344
+(2, 91) ~ (3, 92) => 0.0544033
+(2, 91) ~ (3, 93) => 0.838902
+(2, 91) ~ (3, 94) => 0.0154623
+(2, 91) ~ (3, 95) => 0.04098
+(2, 92) ~ (3, 92) => 0.0132734
+(2, 92) ~ (3, 93) => 0.0640387
+(2, 92) ~ (3, 94) => 0.81029
+(2, 92) ~ (3, 95) => 0.030015
+(2, 92) ~ (3, 96) => 0.0506843
+(2, 93) ~ (3, 93) => 0.0139586
+(2, 93) ~ (3, 94) => 0.066642
+(2, 93) ~ (3, 95) => 0.793257
+(2, 93) ~ (3, 96) => 0.0371655
+(2, 93) ~ (3, 97) => 0.0576045
+(2, 94) ~ (3, 94) => 0.0134106
+(2, 94) ~ (3, 95) => 0.0708252
+(2, 94) ~ (3, 96) => 0.777998
+(2, 94) ~ (3, 97) => 0.042573
+(2, 94) ~ (3, 98) => 0.0650598
+(2, 95) ~ (3, 95) => 0.0136072
+(2, 95) ~ (3, 96) => 0.0740319
+(2, 95) ~ (3, 97) => 0.767366
+(2, 95) ~ (3, 98) => 0.0473759
+(2, 95) ~ (3, 99) => 0.0732843
+(2, 96) ~ (3, 96) => 0.0126428
+(2, 96) ~ (3, 97) => 0.0727371
+(2, 96) ~ (3, 98) => 0.746456
+(2, 96) ~ (3, 99) => 0.0447085
+(2, 96) ~ (3, 100) => 0.0872262
+(2, 97) ~ (3, 97) => 0.01097
+(2, 97) ~ (3, 98) => 0.069651
+(2, 97) ~ (3, 99) => 0.664269
+(2, 97) ~ (3, 100) => 0.0886041
+(2, 97) ~ (3, 101) => 0.136258
+(2, 98) ~ (3, 99) => 0.0633581
+(2, 98) ~ (3, 100) => 0.638794
+(2, 98) ~ (3, 101) => 0.0972055
+(2, 98) ~ (3, 102) => 0.158956
+(2, 99) ~ (3, 100) => 0.0642447
+(2, 99) ~ (3, 101) => 0.608713
+(2, 99) ~ (3, 102) => 0.101072
+(2, 99) ~ (3, 103) => 0.179987
+(2, 99) ~ (3, 104) => 0.0134226
+(2, 100) ~ (3, 101) => 0.0628381
+(2, 100) ~ (3, 102) => 0.565253
+(2, 100) ~ (3, 103) => 0.0925793
+(2, 100) ~ (3, 104) => 0.22493
+(2, 100) ~ (3, 105) => 0.0201774
+(2, 101) ~ (3, 102) => 0.0582955
+(2, 101) ~ (3, 103) => 0.488531
+(2, 101) ~ (3, 104) => 0.088342
+(2, 101) ~ (3, 105) => 0.301908
+(2, 101) ~ (3, 106) => 0.0234782
+(2, 102) ~ (3, 103) => 0.0488188
+(2, 102) ~ (3, 104) => 0.442169
+(2, 102) ~ (3, 105) => 0.0861669
+(2, 102) ~ (3, 106) => 0.339663
+(2, 102) ~ (3, 107) => 0.0319856
+(2, 102) ~ (3, 108) => 0.0102129
+(2, 103) ~ (3, 104) => 0.0451189
+(2, 103) ~ (3, 105) => 0.417869
+(2, 103) ~ (3, 106) => 0.101878
+(2, 103) ~ (3, 107) => 0.330704
+(2, 103) ~ (3, 108) => 0.0556638
+(2, 103) ~ (3, 109) => 0.0128317
+(2, 104) ~ (3, 105) => 0.0390924
+(2, 104) ~ (3, 106) => 0.358106
+(2, 104) ~ (3, 107) => 0.150172
+(2, 104) ~ (3, 108) => 0.303106
+(2, 104) ~ (3, 109) => 0.0977888
+(2, 104) ~ (3, 110) => 0.013972
+(2, 105) ~ (3, 106) => 0.0274588
+(2, 105) ~ (3, 107) => 0.340064
+(2, 105) ~ (3, 108) => 0.167527
+(2, 105) ~ (3, 109) => 0.288065
+(2, 105) ~ (3, 110) => 0.118611
+(2, 105) ~ (3, 111) => 0.0163121
+(2, 105) ~ (3, 112) => 0.0110333
+(2, 106) ~ (3, 107) => 0.0219264
+(2, 106) ~ (3, 108) => 0.298204
+(2, 106) ~ (3, 109) => 0.196487
+(2, 106) ~ (3, 110) => 0.239676
+(2, 106) ~ (3, 111) => 0.174687
+(2, 106) ~ (3, 112) => 0.0226356
+(2, 106) ~ (3, 113) => 0.01682
+(2, 107) ~ (3, 108) => 0.0112795
+(2, 107) ~ (3, 109) => 0.267841
+(2, 107) ~ (3, 110) => 0.196018
+(2, 107) ~ (3, 111) => 0.198548
+(2, 107) ~ (3, 112) => 0.249279
+(2, 107) ~ (3, 113) => 0.0255195
+(2, 107) ~ (3, 114) => 0.0218508
+(2, 108) ~ (3, 110) => 0.193457
+(2, 108) ~ (3, 111) => 0.221388
+(2, 108) ~ (3, 112) => 0.179815
+(2, 108) ~ (3, 113) => 0.318613
+(2, 108) ~ (3, 114) => 0.0269196
+(2, 108) ~ (3, 115) => 0.0301377
+(2, 109) ~ (3, 111) => 0.139579
+(2, 109) ~ (3, 112) => 0.247642
+(2, 109) ~ (3, 113) => 0.143416
+(2, 109) ~ (3, 114) => 0.363755
+(2, 109) ~ (3, 115) => 0.0293932
+(2, 109) ~ (3, 116) => 0.0436318
+(2, 109) ~ (3, 117) => 0.0103051
+(2, 110) ~ (3, 112) => 0.106042
+(2, 110) ~ (3, 113) => 0.246516
+(2, 110) ~ (3, 114) => 0.0569842
+(2, 110) ~ (3, 115) => 0.449036
+(2, 110) ~ (3, 116) => 0.0339885
+(2, 110) ~ (3, 117) => 0.0626111
+(2, 111) ~ (3, 113) => 0.0552989
+(2, 111) ~ (3, 114) => 0.224447
+(2, 111) ~ (3, 115) => 0.0445831
+(2, 111) ~ (3, 116) => 0.410877
+(2, 111) ~ (3, 117) => 0.0744035
+(2, 111) ~ (3, 118) => 0.160586
+(2, 112) ~ (3, 114) => 0.0434332
+(2, 112) ~ (3, 115) => 0.175791
+(2, 112) ~ (3, 116) => 0.0534169
+(2, 112) ~ (3, 117) => 0.355902
+(2, 112) ~ (3, 118) => 0.095059
+(2, 112) ~ (3, 119) => 0.24442
+(2, 113) ~ (3, 115) => 0.0322391
+(2, 113) ~ (3, 116) => 0.132796
+(2, 113) ~ (3, 117) => 0.0568449
+(2, 113) ~ (3, 118) => 0.30053
+(2, 113) ~ (3, 119) => 0.106687
+(2, 113) ~ (3, 120) => 0.339605
+(2, 114) ~ (3, 116) => 0.0221525
+(2, 114) ~ (3, 117) => 0.0938424
+(2, 114) ~ (3, 118) => 0.0545654
+(2, 114) ~ (3, 119) => 0.243757
+(2, 114) ~ (3, 120) => 0.109812
+(2, 114) ~ (3, 121) => 0.447637
+(2, 115) ~ (3, 117) => 0.0127634
+(2, 115) ~ (3, 118) => 0.058171
+(2, 115) ~ (3, 119) => 0.0469398
+(2, 115) ~ (3, 120) => 0.187073
+(2, 115) ~ (3, 121) => 0.103177
+(2, 115) ~ (3, 122) => 0.569744
+(2, 116) ~ (3, 119) => 0.0363324
+(2, 116) ~ (3, 120) => 0.0337418
+(2, 116) ~ (3, 121) => 0.128479
+(2, 116) ~ (3, 122) => 0.0844861
+(2, 116) ~ (3, 123) => 0.697759
+
+; gap posteriors
+(2, 0) ~ (3, -1) => 0.0877809
+(2, 1) ~ (3, -1) => 0.147459
+(2, 2) ~ (3, -1) => 0.438567
+(2, 3) ~ (3, -1) => 0.203983
+(2, 4) ~ (3, -1) => 0.0493607
+(2, 5) ~ (3, -1) => 0.0558425
+(2, 6) ~ (3, -1) => 0.0386316
+(2, 7) ~ (3, -1) => 0.0270138
+(2, 8) ~ (3, -1) => 0.0272533
+(2, 9) ~ (3, -1) => 0.0420483
+(2, 10) ~ (3, -1) => 0.0281353
+(2, 11) ~ (3, -1) => 0.0269
+(2, 12) ~ (3, -1) => 0.033918
+(2, 13) ~ (3, -1) => 0.0333499
+(2, 14) ~ (3, -1) => 0.0382407
+(2, 15) ~ (3, -1) => 0.0284983
+(2, 16) ~ (3, -1) => 0.0391094
+(2, 17) ~ (3, -1) => 0.0405911
+(2, 18) ~ (3, -1) => 0.0276393
+(2, 19) ~ (3, -1) => 0.0242372
+(2, 20) ~ (3, -1) => 0.027607
+(2, 21) ~ (3, -1) => 0.0369975
+(2, 22) ~ (3, -1) => 0.0415553
+(2, 23) ~ (3, -1) => 0.0418888
+(2, 24) ~ (3, -1) => 0.0287031
+(2, 25) ~ (3, -1) => 0.0313156
+(2, 26) ~ (3, -1) => 0.0270151
+(2, 27) ~ (3, -1) => 0.067274
+(2, 28) ~ (3, -1) => 0.0210858
+(2, 29) ~ (3, -1) => 0.0452946
+(2, 30) ~ (3, -1) => 0.01763
+(2, 31) ~ (3, -1) => 0.01353
+(2, 32) ~ (3, -1) => 0.0104404
+(2, 33) ~ (3, -1) => 0.0185649
+(2, 34) ~ (3, -1) => 0.00884382
+(2, 35) ~ (3, -1) => 0.0108326
+(2, 36) ~ (3, -1) => 0.0212617
+(2, 37) ~ (3, -1) => 0.0111692
+(2, 38) ~ (3, -1) => 0.01435
+(2, 39) ~ (3, -1) => 0.0190129
+(2, 40) ~ (3, -1) => 0.0132385
+(2, 41) ~ (3, -1) => 0.0185611
+(2, 42) ~ (3, -1) => 0.0188782
+(2, 43) ~ (3, -1) => 0.0169189
+(2, 44) ~ (3, -1) => 0.0302144
+(2, 45) ~ (3, -1) => 0.0278494
+(2, 46) ~ (3, -1) => 0.0334706
+(2, 47) ~ (3, -1) => 0.0400531
+(2, 48) ~ (3, -1) => 0.0357975
+(2, 49) ~ (3, -1) => 0.028187
+(2, 50) ~ (3, -1) => 0.033726
+(2, 51) ~ (3, -1) => 0.0532859
+(2, 52) ~ (3, -1) => 0.0403041
+(2, 53) ~ (3, -1) => 0.0548203
+(2, 54) ~ (3, -1) => 0.0385958
+(2, 55) ~ (3, -1) => 0.033346
+(2, 56) ~ (3, -1) => 0.0351706
+(2, 57) ~ (3, -1) => 0.0687101
+(2, 58) ~ (3, -1) => 0.0438844
+(2, 59) ~ (3, -1) => 0.0531467
+(2, 60) ~ (3, -1) => 0.0309074
+(2, 61) ~ (3, -1) => 0.0336566
+(2, 62) ~ (3, -1) => 0.0442651
+(2, 63) ~ (3, -1) => 0.0343893
+(2, 64) ~ (3, -1) => 0.0429456
+(2, 65) ~ (3, -1) => 0.0521062
+(2, 66) ~ (3, -1) => 0.048037
+(2, 67) ~ (3, -1) => 0.0541499
+(2, 68) ~ (3, -1) => 0.0516318
+(2, 69) ~ (3, -1) => 0.0485513
+(2, 70) ~ (3, -1) => 0.0442208
+(2, 71) ~ (3, -1) => 0.053233
+(2, 72) ~ (3, -1) => 0.0694859
+(2, 73) ~ (3, -1) => 0.0748312
+(2, 74) ~ (3, -1) => 0.0819042
+(2, 75) ~ (3, -1) => 0.0970098
+(2, 76) ~ (3, -1) => 0.0887252
+(2, 77) ~ (3, -1) => 0.10137
+(2, 78) ~ (3, -1) => 0.091921
+(2, 79) ~ (3, -1) => 0.184603
+(2, 80) ~ (3, -1) => 0.317997
+(2, 81) ~ (3, -1) => 0.284577
+(2, 82) ~ (3, -1) => 0.254223
+(2, 83) ~ (3, -1) => 0.0831129
+(2, 84) ~ (3, -1) => 0.0635464
+(2, 85) ~ (3, -1) => 0.0329345
+(2, 86) ~ (3, -1) => 0.0209663
+(2, 87) ~ (3, -1) => 0.0210114
+(2, 88) ~ (3, -1) => 0.0217129
+(2, 89) ~ (3, -1) => 0.0231215
+(2, 90) ~ (3, -1) => 0.027868
+(2, 91) ~ (3, -1) => 0.0502525
+(2, 92) ~ (3, -1) => 0.0316988
+(2, 93) ~ (3, -1) => 0.0313728
+(2, 94) ~ (3, -1) => 0.0301334
+(2, 95) ~ (3, -1) => 0.0243352
+(2, 96) ~ (3, -1) => 0.0362296
+(2, 97) ~ (3, -1) => 0.0302476
+(2, 98) ~ (3, -1) => 0.0416869
+(2, 99) ~ (3, -1) => 0.0325608
+(2, 100) ~ (3, -1) => 0.0342223
+(2, 101) ~ (3, -1) => 0.0394444
+(2, 102) ~ (3, -1) => 0.0409836
+(2, 103) ~ (3, -1) => 0.0359349
+(2, 104) ~ (3, -1) => 0.0377625
+(2, 105) ~ (3, -1) => 0.0309289
+(2, 106) ~ (3, -1) => 0.0295646
+(2, 107) ~ (3, -1) => 0.0296637
+(2, 108) ~ (3, -1) => 0.0296693
+(2, 109) ~ (3, -1) => 0.0222767
+(2, 110) ~ (3, -1) => 0.0448225
+(2, 111) ~ (3, -1) => 0.0298049
+(2, 112) ~ (3, -1) => 0.0319781
+(2, 113) ~ (3, -1) => 0.0312987
+(2, 114) ~ (3, -1) => 0.0282332
+(2, 115) ~ (3, -1) => 0.0221325
+(2, 116) ~ (3, -1) => 0.019201
+
+(2, -1) ~ (3, 0) => 0.00549098
+(2, -1) ~ (3, 1) => 0.0284047
+(2, -1) ~ (3, 2) => 0.0177408
+(2, -1) ~ (3, 3) => 0.0300718
+(2, -1) ~ (3, 4) => 0.0163935
+(2, -1) ~ (3, 5) => 0.0176419
+(2, -1) ~ (3, 6) => 0.0154013
+(2, -1) ~ (3, 7) => 0.0242956
+(2, -1) ~ (3, 8) => 0.0175344
+(2, -1) ~ (3, 9) => 0.0207839
+(2, -1) ~ (3, 10) => 0.0212925
+(2, -1) ~ (3, 11) => 0.0290905
+(2, -1) ~ (3, 12) => 0.0314603
+(2, -1) ~ (3, 13) => 0.0216237
+(2, -1) ~ (3, 14) => 0.0321548
+(2, -1) ~ (3, 15) => 0.0350075
+(2, -1) ~ (3, 16) => 0.0368452
+(2, -1) ~ (3, 17) => 0.0609611
+(2, -1) ~ (3, 18) => 0.0784882
+(2, -1) ~ (3, 19) => 0.0672284
+(2, -1) ~ (3, 20) => 0.12813
+(2, -1) ~ (3, 21) => 0.142884
+(2, -1) ~ (3, 22) => 0.218807
+(2, -1) ~ (3, 23) => 0.171967
+(2, -1) ~ (3, 24) => 0.15967
+(2, -1) ~ (3, 25) => 0.222197
+(2, -1) ~ (3, 26) => 0.18551
+(2, -1) ~ (3, 27) => 0.187592
+(2, -1) ~ (3, 28) => 0.263713
+(2, -1) ~ (3, 29) => 0.214358
+(2, -1) ~ (3, 30) => 0.0681732
+(2, -1) ~ (3, 31) => 0.0538566
+(2, -1) ~ (3, 32) => 0.0478567
+(2, -1) ~ (3, 33) => 0.0412337
+(2, -1) ~ (3, 34) => 0.0572303
+(2, -1) ~ (3, 35) => 0.0284314
+(2, -1) ~ (3, 36) => 0.0252472
+(2, -1) ~ (3, 37) => 0.026946
+(2, -1) ~ (3, 38) => 0.0370179
+(2, -1) ~ (3, 39) => 0.0292104
+(2, -1) ~ (3, 40) => 0.0339145
+(2, -1) ~ (3, 41) => 0.0456549
+(2, -1) ~ (3, 42) => 0.0635432
+(2, -1) ~ (3, 43) => 0.112828
+(2, -1) ~ (3, 44) => 0.150704
+(2, -1) ~ (3, 45) => 0.290169
+(2, -1) ~ (3, 46) => 0.387257
+(2, -1) ~ (3, 47) => 0.312
+(2, -1) ~ (3, 48) => 0.250659
+(2, -1) ~ (3, 49) => 0.162182
+(2, -1) ~ (3, 50) => 0.101866
+(2, -1) ~ (3, 51) => 0.0735808
+(2, -1) ~ (3, 52) => 0.0984006
+(2, -1) ~ (3, 53) => 0.082471
+(2, -1) ~ (3, 54) => 0.0700025
+(2, -1) ~ (3, 55) => 0.0546228
+(2, -1) ~ (3, 56) => 0.0552658
+(2, -1) ~ (3, 57) => 0.0422634
+(2, -1) ~ (3, 58) => 0.0540859
+(2, -1) ~ (3, 59) => 0.0359253
+(2, -1) ~ (3, 60) => 0.0505454
+(2, -1) ~ (3, 61) => 0.0373247
+(2, -1) ~ (3, 62) => 0.0441815
+(2, -1) ~ (3, 63) => 0.0391645
+(2, -1) ~ (3, 64) => 0.068902
+(2, -1) ~ (3, 65) => 0.0944152
+(2, -1) ~ (3, 66) => 0.0878613
+(2, -1) ~ (3, 67) => 0.0844075
+(2, -1) ~ (3, 68) => 0.0467444
+(2, -1) ~ (3, 69) => 0.0429611
+(2, -1) ~ (3, 70) => 0.0389809
+(2, -1) ~ (3, 71) => 0.0269651
+(2, -1) ~ (3, 72) => 0.0291381
+(2, -1) ~ (3, 73) => 0.0349843
+(2, -1) ~ (3, 74) => 0.0374661
+(2, -1) ~ (3, 75) => 0.0342372
+(2, -1) ~ (3, 76) => 0.0403042
+(2, -1) ~ (3, 77) => 0.0540031
+(2, -1) ~ (3, 78) => 0.066465
+(2, -1) ~ (3, 79) => 0.0471131
+(2, -1) ~ (3, 80) => 0.0592285
+(2, -1) ~ (3, 81) => 0.0650489
+(2, -1) ~ (3, 82) => 0.114195
+(2, -1) ~ (3, 83) => 0.062436
+(2, -1) ~ (3, 84) => 0.112817
+(2, -1) ~ (3, 85) => 0.0529147
+(2, -1) ~ (3, 86) => 0.0454942
+(2, -1) ~ (3, 87) => 0.042965
+(2, -1) ~ (3, 88) => 0.0408624
+(2, -1) ~ (3, 89) => 0.0437396
+(2, -1) ~ (3, 90) => 0.0365953
+(2, -1) ~ (3, 91) => 0.0381197
+(2, -1) ~ (3, 92) => 0.0351761
+(2, -1) ~ (3, 93) => 0.0409706
+(2, -1) ~ (3, 94) => 0.0676607
+(2, -1) ~ (3, 95) => 0.0513159
+(2, -1) ~ (3, 96) => 0.0474775
+(2, -1) ~ (3, 97) => 0.0487498
+(2, -1) ~ (3, 98) => 0.0714575
+(2, -1) ~ (3, 99) => 0.15438
+(2, -1) ~ (3, 100) => 0.121131
+(2, -1) ~ (3, 101) => 0.0949849
+(2, -1) ~ (3, 102) => 0.116424
+(2, -1) ~ (3, 103) => 0.190084
+(2, -1) ~ (3, 104) => 0.186017
+(2, -1) ~ (3, 105) => 0.134786
+(2, -1) ~ (3, 106) => 0.149416
+(2, -1) ~ (3, 107) => 0.125148
+(2, -1) ~ (3, 108) => 0.154007
+(2, -1) ~ (3, 109) => 0.136986
+(2, -1) ~ (3, 110) => 0.238266
+(2, -1) ~ (3, 111) => 0.249486
+(2, -1) ~ (3, 112) => 0.183553
+(2, -1) ~ (3, 113) => 0.193816
+(2, -1) ~ (3, 114) => 0.262609
+(2, -1) ~ (3, 115) => 0.23882
+(2, -1) ~ (3, 116) => 0.303138
+(2, -1) ~ (3, 117) => 0.333328
+(2, -1) ~ (3, 118) => 0.331089
+(2, -1) ~ (3, 119) => 0.321864
+(2, -1) ~ (3, 120) => 0.329769
+(2, -1) ~ (3, 121) => 0.320706
+(2, -1) ~ (3, 122) => 0.34577
+(2, -1) ~ (3, 123) => 0.302241
+
+; Sparse posterior probability matrix for sequences 2 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (4, 0) => 0.999973
+(2, 1) ~ (4, 1) => 0.999959
+(2, 2) ~ (4, 2) => 0.999958
+(2, 3) ~ (4, 3) => 0.999941
+(2, 4) ~ (4, 4) => 0.999919
+(2, 5) ~ (4, 5) => 0.999891
+(2, 6) ~ (4, 6) => 0.99981
+(2, 7) ~ (4, 7) => 0.999116
+(2, 8) ~ (4, 8) => 0.998434
+(2, 9) ~ (4, 9) => 0.995901
+(2, 10) ~ (4, 10) => 0.996327
+(2, 11) ~ (4, 11) => 0.997881
+(2, 12) ~ (4, 12) => 0.999732
+(2, 13) ~ (4, 13) => 0.999802
+(2, 14) ~ (4, 14) => 0.99983
+(2, 15) ~ (4, 15) => 0.999743
+(2, 16) ~ (4, 16) => 0.999785
+(2, 17) ~ (4, 17) => 0.999937
+(2, 18) ~ (4, 18) => 0.999951
+(2, 19) ~ (4, 19) => 0.999927
+(2, 20) ~ (4, 20) => 0.999795
+(2, 21) ~ (4, 21) => 0.999275
+(2, 22) ~ (4, 22) => 0.996451
+(2, 23) ~ (4, 23) => 0.873754
+(2, 23) ~ (4, 25) => 0.125035
+(2, 24) ~ (4, 24) => 0.829152
+(2, 24) ~ (4, 26) => 0.169029
+(2, 25) ~ (4, 25) => 0.783438
+(2, 25) ~ (4, 27) => 0.212918
+(2, 26) ~ (4, 26) => 0.737339
+(2, 26) ~ (4, 28) => 0.256707
+(2, 27) ~ (4, 27) => 0.392799
+(2, 27) ~ (4, 29) => 0.596058
+(2, 28) ~ (4, 28) => 0.0543627
+(2, 28) ~ (4, 30) => 0.941193
+(2, 29) ~ (4, 29) => 0.0102944
+(2, 29) ~ (4, 31) => 0.98758
+(2, 30) ~ (4, 32) => 0.987631
+(2, 31) ~ (4, 33) => 0.987558
+(2, 32) ~ (4, 34) => 0.987287
+(2, 33) ~ (4, 35) => 0.98688
+(2, 34) ~ (4, 36) => 0.98644
+(2, 35) ~ (4, 37) => 0.98908
+(2, 36) ~ (4, 38) => 0.991073
+(2, 37) ~ (4, 39) => 0.992566
+(2, 38) ~ (4, 40) => 0.993351
+(2, 39) ~ (4, 41) => 0.994015
+(2, 40) ~ (4, 42) => 0.994746
+(2, 41) ~ (4, 43) => 0.995839
+(2, 42) ~ (4, 44) => 0.977547
+(2, 42) ~ (4, 45) => 0.0182142
+(2, 43) ~ (4, 45) => 0.948504
+(2, 43) ~ (4, 46) => 0.0438593
+(2, 44) ~ (4, 46) => 0.80689
+(2, 44) ~ (4, 47) => 0.172119
+(2, 44) ~ (4, 48) => 0.0151122
+(2, 45) ~ (4, 47) => 0.66376
+(2, 45) ~ (4, 48) => 0.298734
+(2, 45) ~ (4, 49) => 0.0254432
+(2, 46) ~ (4, 48) => 0.535235
+(2, 46) ~ (4, 49) => 0.426938
+(2, 46) ~ (4, 50) => 0.0156811
+(2, 47) ~ (4, 49) => 0.18341
+(2, 47) ~ (4, 50) => 0.793797
+(2, 48) ~ (4, 50) => 0.0546794
+(2, 48) ~ (4, 51) => 0.937541
+(2, 49) ~ (4, 51) => 0.038142
+(2, 49) ~ (4, 52) => 0.955037
+(2, 50) ~ (4, 52) => 0.0214529
+(2, 50) ~ (4, 53) => 0.972652
+(2, 51) ~ (4, 54) => 0.990151
+(2, 52) ~ (4, 55) => 0.987688
+(2, 53) ~ (4, 56) => 0.984835
+(2, 54) ~ (4, 57) => 0.981194
+(2, 55) ~ (4, 58) => 0.98758
+(2, 56) ~ (4, 59) => 0.992328
+(2, 57) ~ (4, 60) => 0.994514
+(2, 58) ~ (4, 61) => 0.995624
+(2, 59) ~ (4, 62) => 0.995867
+(2, 60) ~ (4, 63) => 0.995137
+(2, 61) ~ (4, 64) => 0.994339
+(2, 62) ~ (4, 65) => 0.985782
+(2, 62) ~ (4, 66) => 0.0116691
+(2, 63) ~ (4, 66) => 0.974591
+(2, 63) ~ (4, 67) => 0.0177516
+(2, 64) ~ (4, 67) => 0.974288
+(2, 64) ~ (4, 68) => 0.0150426
+(2, 65) ~ (4, 68) => 0.981646
+(2, 65) ~ (4, 69) => 0.0111215
+(2, 66) ~ (4, 69) => 0.987026
+(2, 67) ~ (4, 70) => 0.991489
+(2, 68) ~ (4, 71) => 0.992768
+(2, 69) ~ (4, 72) => 0.994095
+(2, 70) ~ (4, 73) => 0.999045
+(2, 71) ~ (4, 74) => 0.999827
+(2, 72) ~ (4, 75) => 0.999803
+(2, 73) ~ (4, 76) => 0.999569
+(2, 74) ~ (4, 77) => 0.994798
+(2, 75) ~ (4, 78) => 0.988805
+(2, 76) ~ (4, 79) => 0.98439
+(2, 77) ~ (4, 80) => 0.972567
+(2, 78) ~ (4, 80) => 0.0140551
+(2, 78) ~ (4, 81) => 0.973198
+(2, 79) ~ (4, 81) => 0.0106253
+(2, 79) ~ (4, 82) => 0.984992
+(2, 80) ~ (4, 83) => 0.99094
+(2, 81) ~ (4, 84) => 0.998216
+(2, 82) ~ (4, 85) => 0.998343
+(2, 83) ~ (4, 86) => 0.995831
+(2, 84) ~ (4, 87) => 0.987651
+(2, 85) ~ (4, 88) => 0.960698
+(2, 86) ~ (4, 88) => 0.0132651
+(2, 86) ~ (4, 89) => 0.934129
+(2, 87) ~ (4, 88) => 0.0117123
+(2, 87) ~ (4, 89) => 0.0214743
+(2, 87) ~ (4, 90) => 0.90714
+(2, 87) ~ (4, 91) => 0.0102037
+(2, 88) ~ (4, 89) => 0.0203423
+(2, 88) ~ (4, 90) => 0.028983
+(2, 88) ~ (4, 91) => 0.81782
+(2, 88) ~ (4, 92) => 0.0113718
+(2, 89) ~ (4, 90) => 0.0288114
+(2, 89) ~ (4, 91) => 0.0301506
+(2, 89) ~ (4, 92) => 0.718794
+(2, 90) ~ (4, 91) => 0.031314
+(2, 90) ~ (4, 92) => 0.0267699
+(2, 90) ~ (4, 93) => 0.49835
+(2, 90) ~ (4, 96) => 0.0143709
+(2, 91) ~ (4, 90) => 0.0107846
+(2, 91) ~ (4, 92) => 0.0292316
+(2, 91) ~ (4, 94) => 0.17252
+(2, 91) ~ (4, 97) => 0.137018
+(2, 92) ~ (4, 91) => 0.0963423
+(2, 92) ~ (4, 92) => 0.0186512
+(2, 92) ~ (4, 93) => 0.165762
+(2, 92) ~ (4, 95) => 0.0926958
+(2, 92) ~ (4, 98) => 0.136725
+(2, 93) ~ (4, 92) => 0.18046
+(2, 93) ~ (4, 93) => 0.0293981
+(2, 93) ~ (4, 94) => 0.287231
+(2, 93) ~ (4, 96) => 0.0173829
+(2, 93) ~ (4, 99) => 0.135975
+(2, 94) ~ (4, 93) => 0.259966
+(2, 94) ~ (4, 94) => 0.0223073
+(2, 94) ~ (4, 95) => 0.37379
+(2, 94) ~ (4, 100) => 0.134254
+(2, 95) ~ (4, 94) => 0.313548
+(2, 95) ~ (4, 95) => 0.0147214
+(2, 95) ~ (4, 96) => 0.481227
+(2, 95) ~ (4, 101) => 0.1299
+(2, 96) ~ (4, 95) => 0.281428
+(2, 96) ~ (4, 96) => 0.0126401
+(2, 96) ~ (4, 97) => 0.489366
+(2, 96) ~ (4, 98) => 0.0191972
+(2, 96) ~ (4, 102) => 0.0159534
+(2, 97) ~ (4, 96) => 0.284253
+(2, 97) ~ (4, 97) => 0.0158498
+(2, 97) ~ (4, 98) => 0.434571
+(2, 97) ~ (4, 99) => 0.0206082
+(2, 97) ~ (4, 103) => 0.0114567
+(2, 98) ~ (4, 97) => 0.302922
+(2, 98) ~ (4, 98) => 0.0213778
+(2, 98) ~ (4, 99) => 0.380668
+(2, 98) ~ (4, 100) => 0.0200138
+(2, 99) ~ (4, 98) => 0.351583
+(2, 99) ~ (4, 99) => 0.0246088
+(2, 99) ~ (4, 100) => 0.323652
+(2, 99) ~ (4, 101) => 0.0153151
+(2, 100) ~ (4, 98) => 0.0132709
+(2, 100) ~ (4, 99) => 0.400242
+(2, 100) ~ (4, 100) => 0.0251155
+(2, 100) ~ (4, 101) => 0.192022
+(2, 100) ~ (4, 102) => 0.0236002
+(2, 101) ~ (4, 99) => 0.0189444
+(2, 101) ~ (4, 100) => 0.448056
+(2, 101) ~ (4, 101) => 0.0137732
+(2, 101) ~ (4, 102) => 0.106586
+(2, 101) ~ (4, 103) => 0.0152306
+(2, 102) ~ (4, 100) => 0.0239723
+(2, 102) ~ (4, 101) => 0.47956
+(2, 102) ~ (4, 103) => 0.0140131
+(2, 103) ~ (4, 101) => 0.136731
+(2, 103) ~ (4, 102) => 0.397817
+(2, 103) ~ (4, 104) => 0.0100579
+(2, 104) ~ (4, 102) => 0.410569
+(2, 104) ~ (4, 103) => 0.305299
+(2, 105) ~ (4, 103) => 0.610093
+(2, 105) ~ (4, 104) => 0.206547
+(2, 106) ~ (4, 104) => 0.737252
+(2, 106) ~ (4, 105) => 0.107586
+(2, 107) ~ (4, 105) => 0.863061
+(2, 108) ~ (4, 106) => 0.990022
+(2, 109) ~ (4, 107) => 0.99527
+(2, 110) ~ (4, 108) => 0.999439
+(2, 111) ~ (4, 109) => 0.999211
+(2, 112) ~ (4, 110) => 0.998805
+(2, 113) ~ (4, 111) => 0.998975
+(2, 114) ~ (4, 112) => 0.999288
+(2, 115) ~ (4, 113) => 0.999372
+(2, 116) ~ (4, 114) => 0.999479
+
+; gap posteriors
+(2, 0) ~ (4, -1) => 0.0001
+(2, 1) ~ (4, -1) => 0.0001
+(2, 2) ~ (4, -1) => 0.0001
+(2, 3) ~ (4, -1) => 0.0001
+(2, 4) ~ (4, -1) => 0.0001
+(2, 5) ~ (4, -1) => 0.000109017
+(2, 6) ~ (4, -1) => 0.000190377
+(2, 7) ~ (4, -1) => 0.000883937
+(2, 8) ~ (4, -1) => 0.00156647
+(2, 9) ~ (4, -1) => 0.00409913
+(2, 10) ~ (4, -1) => 0.00367343
+(2, 11) ~ (4, -1) => 0.00211948
+(2, 12) ~ (4, -1) => 0.000268221
+(2, 13) ~ (4, -1) => 0.000198305
+(2, 14) ~ (4, -1) => 0.000169575
+(2, 15) ~ (4, -1) => 0.000256658
+(2, 16) ~ (4, -1) => 0.000214875
+(2, 17) ~ (4, -1) => 0.0001
+(2, 18) ~ (4, -1) => 0.0001
+(2, 19) ~ (4, -1) => 0.0001
+(2, 20) ~ (4, -1) => 0.000204742
+(2, 21) ~ (4, -1) => 0.000725269
+(2, 22) ~ (4, -1) => 0.00354856
+(2, 23) ~ (4, -1) => 0.0012116
+(2, 24) ~ (4, -1) => 0.00181881
+(2, 25) ~ (4, -1) => 0.00364436
+(2, 26) ~ (4, -1) => 0.00595394
+(2, 27) ~ (4, -1) => 0.0111427
+(2, 28) ~ (4, -1) => 0.00444442
+(2, 29) ~ (4, -1) => 0.00212574
+(2, 30) ~ (4, -1) => 0.0123688
+(2, 31) ~ (4, -1) => 0.0124415
+(2, 32) ~ (4, -1) => 0.0127129
+(2, 33) ~ (4, -1) => 0.0131204
+(2, 34) ~ (4, -1) => 0.0135601
+(2, 35) ~ (4, -1) => 0.0109202
+(2, 36) ~ (4, -1) => 0.00892693
+(2, 37) ~ (4, -1) => 0.00743407
+(2, 38) ~ (4, -1) => 0.00664937
+(2, 39) ~ (4, -1) => 0.00598472
+(2, 40) ~ (4, -1) => 0.00525385
+(2, 41) ~ (4, -1) => 0.0041607
+(2, 42) ~ (4, -1) => 0.00423832
+(2, 43) ~ (4, -1) => 0.00763632
+(2, 44) ~ (4, -1) => 0.00587854
+(2, 45) ~ (4, -1) => 0.0120628
+(2, 46) ~ (4, -1) => 0.0221453
+(2, 47) ~ (4, -1) => 0.0227933
+(2, 48) ~ (4, -1) => 0.00777984
+(2, 49) ~ (4, -1) => 0.00682092
+(2, 50) ~ (4, -1) => 0.0058952
+(2, 51) ~ (4, -1) => 0.00984943
+(2, 52) ~ (4, -1) => 0.0123124
+(2, 53) ~ (4, -1) => 0.0151654
+(2, 54) ~ (4, -1) => 0.0188055
+(2, 55) ~ (4, -1) => 0.0124199
+(2, 56) ~ (4, -1) => 0.00767189
+(2, 57) ~ (4, -1) => 0.00548559
+(2, 58) ~ (4, -1) => 0.0043757
+(2, 59) ~ (4, -1) => 0.00413293
+(2, 60) ~ (4, -1) => 0.00486308
+(2, 61) ~ (4, -1) => 0.00566137
+(2, 62) ~ (4, -1) => 0.00254938
+(2, 63) ~ (4, -1) => 0.00765711
+(2, 64) ~ (4, -1) => 0.0106697
+(2, 65) ~ (4, -1) => 0.00723239
+(2, 66) ~ (4, -1) => 0.012974
+(2, 67) ~ (4, -1) => 0.00851142
+(2, 68) ~ (4, -1) => 0.00723213
+(2, 69) ~ (4, -1) => 0.00590456
+(2, 70) ~ (4, -1) => 0.000954747
+(2, 71) ~ (4, -1) => 0.000173271
+(2, 72) ~ (4, -1) => 0.000196636
+(2, 73) ~ (4, -1) => 0.000430703
+(2, 74) ~ (4, -1) => 0.00520182
+(2, 75) ~ (4, -1) => 0.0111952
+(2, 76) ~ (4, -1) => 0.0156104
+(2, 77) ~ (4, -1) => 0.027433
+(2, 78) ~ (4, -1) => 0.012747
+(2, 79) ~ (4, -1) => 0.00438237
+(2, 80) ~ (4, -1) => 0.00905997
+(2, 81) ~ (4, -1) => 0.00178385
+(2, 82) ~ (4, -1) => 0.00165653
+(2, 83) ~ (4, -1) => 0.00416887
+(2, 84) ~ (4, -1) => 0.0123487
+(2, 85) ~ (4, -1) => 0.0393024
+(2, 86) ~ (4, -1) => 0.052606
+(2, 87) ~ (4, -1) => 0.04947
+(2, 88) ~ (4, -1) => 0.121483
+(2, 89) ~ (4, -1) => 0.222244
+(2, 90) ~ (4, -1) => 0.429195
+(2, 91) ~ (4, -1) => 0.650446
+(2, 92) ~ (4, -1) => 0.489823
+(2, 93) ~ (4, -1) => 0.349553
+(2, 94) ~ (4, -1) => 0.209683
+(2, 95) ~ (4, -1) => 0.0606034
+(2, 96) ~ (4, -1) => 0.181415
+(2, 97) ~ (4, -1) => 0.233262
+(2, 98) ~ (4, -1) => 0.275018
+(2, 99) ~ (4, -1) => 0.284841
+(2, 100) ~ (4, -1) => 0.345749
+(2, 101) ~ (4, -1) => 0.39741
+(2, 102) ~ (4, -1) => 0.482455
+(2, 103) ~ (4, -1) => 0.455395
+(2, 104) ~ (4, -1) => 0.284132
+(2, 105) ~ (4, -1) => 0.18336
+(2, 106) ~ (4, -1) => 0.155162
+(2, 107) ~ (4, -1) => 0.136939
+(2, 108) ~ (4, -1) => 0.00997782
+(2, 109) ~ (4, -1) => 0.00472993
+(2, 110) ~ (4, -1) => 0.00056082
+(2, 111) ~ (4, -1) => 0.000788987
+(2, 112) ~ (4, -1) => 0.00119466
+(2, 113) ~ (4, -1) => 0.00102484
+(2, 114) ~ (4, -1) => 0.000711977
+(2, 115) ~ (4, -1) => 0.000628114
+(2, 116) ~ (4, -1) => 0.000520766
+
+(2, -1) ~ (4, 0) => 0.0001
+(2, -1) ~ (4, 1) => 0.0001
+(2, -1) ~ (4, 2) => 0.0001
+(2, -1) ~ (4, 3) => 0.0001
+(2, -1) ~ (4, 4) => 0.0001
+(2, -1) ~ (4, 5) => 0.000109017
+(2, -1) ~ (4, 6) => 0.000190377
+(2, -1) ~ (4, 7) => 0.000883937
+(2, -1) ~ (4, 8) => 0.00156647
+(2, -1) ~ (4, 9) => 0.00409913
+(2, -1) ~ (4, 10) => 0.00367343
+(2, -1) ~ (4, 11) => 0.00211948
+(2, -1) ~ (4, 12) => 0.000268221
+(2, -1) ~ (4, 13) => 0.000198305
+(2, -1) ~ (4, 14) => 0.000169575
+(2, -1) ~ (4, 15) => 0.000256658
+(2, -1) ~ (4, 16) => 0.000214875
+(2, -1) ~ (4, 17) => 0.0001
+(2, -1) ~ (4, 18) => 0.0001
+(2, -1) ~ (4, 19) => 0.0001
+(2, -1) ~ (4, 20) => 0.000204742
+(2, -1) ~ (4, 21) => 0.000725269
+(2, -1) ~ (4, 22) => 0.00354856
+(2, -1) ~ (4, 23) => 0.126246
+(2, -1) ~ (4, 24) => 0.170848
+(2, -1) ~ (4, 25) => 0.0915277
+(2, -1) ~ (4, 26) => 0.093632
+(2, -1) ~ (4, 27) => 0.394283
+(2, -1) ~ (4, 28) => 0.68893
+(2, -1) ~ (4, 29) => 0.393647
+(2, -1) ~ (4, 30) => 0.0588071
+(2, -1) ~ (4, 31) => 0.0124201
+(2, -1) ~ (4, 32) => 0.0123688
+(2, -1) ~ (4, 33) => 0.0124415
+(2, -1) ~ (4, 34) => 0.0127129
+(2, -1) ~ (4, 35) => 0.0131204
+(2, -1) ~ (4, 36) => 0.0135601
+(2, -1) ~ (4, 37) => 0.0109202
+(2, -1) ~ (4, 38) => 0.00892693
+(2, -1) ~ (4, 39) => 0.00743407
+(2, -1) ~ (4, 40) => 0.00664937
+(2, -1) ~ (4, 41) => 0.00598472
+(2, -1) ~ (4, 42) => 0.00525385
+(2, -1) ~ (4, 43) => 0.0041607
+(2, -1) ~ (4, 44) => 0.0224525
+(2, -1) ~ (4, 45) => 0.0332814
+(2, -1) ~ (4, 46) => 0.14925
+(2, -1) ~ (4, 47) => 0.164121
+(2, -1) ~ (4, 48) => 0.150918
+(2, -1) ~ (4, 49) => 0.364208
+(2, -1) ~ (4, 50) => 0.135843
+(2, -1) ~ (4, 51) => 0.0243172
+(2, -1) ~ (4, 52) => 0.02351
+(2, -1) ~ (4, 53) => 0.0273482
+(2, -1) ~ (4, 54) => 0.00984943
+(2, -1) ~ (4, 55) => 0.0123124
+(2, -1) ~ (4, 56) => 0.0151654
+(2, -1) ~ (4, 57) => 0.0188055
+(2, -1) ~ (4, 58) => 0.0124199
+(2, -1) ~ (4, 59) => 0.00767189
+(2, -1) ~ (4, 60) => 0.00548559
+(2, -1) ~ (4, 61) => 0.0043757
+(2, -1) ~ (4, 62) => 0.00413293
+(2, -1) ~ (4, 63) => 0.00486308
+(2, -1) ~ (4, 64) => 0.00566137
+(2, -1) ~ (4, 65) => 0.0142184
+(2, -1) ~ (4, 66) => 0.0137397
+(2, -1) ~ (4, 67) => 0.00796068
+(2, -1) ~ (4, 68) => 0.00331122
+(2, -1) ~ (4, 69) => 0.00185251
+(2, -1) ~ (4, 70) => 0.00851142
+(2, -1) ~ (4, 71) => 0.00723213
+(2, -1) ~ (4, 72) => 0.00590456
+(2, -1) ~ (4, 73) => 0.000954747
+(2, -1) ~ (4, 74) => 0.000173271
+(2, -1) ~ (4, 75) => 0.000196636
+(2, -1) ~ (4, 76) => 0.000430703
+(2, -1) ~ (4, 77) => 0.00520182
+(2, -1) ~ (4, 78) => 0.0111952
+(2, -1) ~ (4, 79) => 0.0156104
+(2, -1) ~ (4, 80) => 0.0133779
+(2, -1) ~ (4, 81) => 0.0161768
+(2, -1) ~ (4, 82) => 0.0150077
+(2, -1) ~ (4, 83) => 0.00905997
+(2, -1) ~ (4, 84) => 0.00178385
+(2, -1) ~ (4, 85) => 0.00165653
+(2, -1) ~ (4, 86) => 0.00416887
+(2, -1) ~ (4, 87) => 0.0123487
+(2, -1) ~ (4, 88) => 0.014325
+(2, -1) ~ (4, 89) => 0.0240546
+(2, -1) ~ (4, 90) => 0.0242813
+(2, -1) ~ (4, 91) => 0.0141692
+(2, -1) ~ (4, 92) => 0.0147225
+(2, -1) ~ (4, 93) => 0.0465231
+(2, -1) ~ (4, 94) => 0.204394
+(2, -1) ~ (4, 95) => 0.237364
+(2, -1) ~ (4, 96) => 0.190126
+(2, -1) ~ (4, 97) => 0.0548435
+(2, -1) ~ (4, 98) => 0.0232749
+(2, -1) ~ (4, 99) => 0.0189537
+(2, -1) ~ (4, 100) => 0.0249357
+(2, -1) ~ (4, 101) => 0.0326982
+(2, -1) ~ (4, 102) => 0.0454752
+(2, -1) ~ (4, 103) => 0.0439081
+(2, -1) ~ (4, 104) => 0.0461428
+(2, -1) ~ (4, 105) => 0.0293524
+(2, -1) ~ (4, 106) => 0.00997782
+(2, -1) ~ (4, 107) => 0.00472993
+(2, -1) ~ (4, 108) => 0.00056082
+(2, -1) ~ (4, 109) => 0.000788987
+(2, -1) ~ (4, 110) => 0.00119466
+(2, -1) ~ (4, 111) => 0.00102484
+(2, -1) ~ (4, 112) => 0.000711977
+(2, -1) ~ (4, 113) => 0.000628114
+(2, -1) ~ (4, 114) => 0.000520766
+
+; Sparse posterior probability matrix for sequences 3 and 4
+; Format is:
+;   (sequence_1, position_1) ~ (sequence_2, position_2) => prob
+; which means that (sequence_1, position_1) is aligned to (sequence_2, position_2) with probability prob.
+;   (sequence_1, position_1) ~ (sequence_2, -1) => prob
+; means that (sequence_1, position_1) is aligned to a gap in sequence_2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(3, 0) ~ (4, 0) => 0.945854
+(3, 0) ~ (4, 1) => 0.0426255
+(3, 1) ~ (4, 1) => 0.795816
+(3, 1) ~ (4, 2) => 0.155864
+(3, 1) ~ (4, 4) => 0.0250491
+(3, 2) ~ (4, 2) => 0.467306
+(3, 2) ~ (4, 3) => 0.455764
+(3, 2) ~ (4, 5) => 0.0474358
+(3, 3) ~ (4, 3) => 0.386836
+(3, 3) ~ (4, 4) => 0.523777
+(3, 3) ~ (4, 6) => 0.0519108
+(3, 4) ~ (4, 4) => 0.362349
+(3, 4) ~ (4, 5) => 0.544462
+(3, 4) ~ (4, 7) => 0.0504517
+(3, 5) ~ (4, 3) => 0.0139722
+(3, 5) ~ (4, 5) => 0.345338
+(3, 5) ~ (4, 6) => 0.560174
+(3, 5) ~ (4, 8) => 0.0468764
+(3, 6) ~ (4, 4) => 0.0135466
+(3, 6) ~ (4, 6) => 0.275592
+(3, 6) ~ (4, 7) => 0.630428
+(3, 6) ~ (4, 9) => 0.0439859
+(3, 7) ~ (4, 5) => 0.0140046
+(3, 7) ~ (4, 7) => 0.251357
+(3, 7) ~ (4, 8) => 0.65331
+(3, 7) ~ (4, 10) => 0.0412024
+(3, 8) ~ (4, 6) => 0.0132128
+(3, 8) ~ (4, 8) => 0.227269
+(3, 8) ~ (4, 9) => 0.678214
+(3, 8) ~ (4, 11) => 0.041237
+(3, 9) ~ (4, 7) => 0.0122744
+(3, 9) ~ (4, 8) => 0.0106347
+(3, 9) ~ (4, 9) => 0.209395
+(3, 9) ~ (4, 10) => 0.699971
+(3, 9) ~ (4, 12) => 0.0419998
+(3, 10) ~ (4, 10) => 0.192676
+(3, 10) ~ (4, 11) => 0.725324
+(3, 10) ~ (4, 13) => 0.0423334
+(3, 11) ~ (4, 11) => 0.174253
+(3, 11) ~ (4, 12) => 0.745647
+(3, 11) ~ (4, 14) => 0.0411201
+(3, 12) ~ (4, 12) => 0.161506
+(3, 12) ~ (4, 13) => 0.760658
+(3, 12) ~ (4, 15) => 0.0396721
+(3, 13) ~ (4, 13) => 0.144054
+(3, 13) ~ (4, 14) => 0.783233
+(3, 13) ~ (4, 16) => 0.0367266
+(3, 14) ~ (4, 14) => 0.131933
+(3, 14) ~ (4, 15) => 0.801345
+(3, 14) ~ (4, 17) => 0.0335606
+(3, 15) ~ (4, 15) => 0.0770446
+(3, 15) ~ (4, 16) => 0.867081
+(3, 15) ~ (4, 18) => 0.02941
+(3, 16) ~ (4, 16) => 0.0220656
+(3, 16) ~ (4, 17) => 0.932208
+(3, 16) ~ (4, 19) => 0.0244371
+(3, 17) ~ (4, 18) => 0.953203
+(3, 17) ~ (4, 20) => 0.0176096
+(3, 18) ~ (4, 19) => 0.960417
+(3, 18) ~ (4, 21) => 0.0106505
+(3, 19) ~ (4, 20) => 0.973707
+(3, 20) ~ (4, 21) => 0.982371
+(3, 21) ~ (4, 22) => 0.990437
+(3, 22) ~ (4, 23) => 0.991209
+(3, 23) ~ (4, 24) => 0.989302
+(3, 24) ~ (4, 25) => 0.98866
+(3, 25) ~ (4, 26) => 0.985898
+(3, 26) ~ (4, 27) => 0.985762
+(3, 27) ~ (4, 28) => 0.988663
+(3, 28) ~ (4, 29) => 0.990445
+(3, 29) ~ (4, 30) => 0.994917
+(3, 30) ~ (4, 31) => 0.997697
+(3, 31) ~ (4, 32) => 0.998128
+(3, 32) ~ (4, 33) => 0.998343
+(3, 33) ~ (4, 34) => 0.998602
+(3, 34) ~ (4, 35) => 0.998642
+(3, 35) ~ (4, 36) => 0.998354
+(3, 36) ~ (4, 37) => 0.998399
+(3, 37) ~ (4, 38) => 0.99846
+(3, 38) ~ (4, 39) => 0.997966
+(3, 39) ~ (4, 40) => 0.997336
+(3, 40) ~ (4, 41) => 0.996804
+(3, 41) ~ (4, 42) => 0.996123
+(3, 42) ~ (4, 43) => 0.996323
+(3, 43) ~ (4, 44) => 0.994871
+(3, 44) ~ (4, 45) => 0.995513
+(3, 45) ~ (4, 46) => 0.997885
+(3, 46) ~ (4, 47) => 0.998502
+(3, 47) ~ (4, 48) => 0.998968
+(3, 48) ~ (4, 49) => 0.999365
+(3, 49) ~ (4, 50) => 0.998898
+(3, 50) ~ (4, 51) => 0.998161
+(3, 51) ~ (4, 52) => 0.997877
+(3, 52) ~ (4, 53) => 0.99736
+(3, 53) ~ (4, 54) => 0.996798
+(3, 54) ~ (4, 55) => 0.995089
+(3, 55) ~ (4, 56) => 0.989176
+(3, 56) ~ (4, 57) => 0.980898
+(3, 57) ~ (4, 58) => 0.964716
+(3, 58) ~ (4, 57) => 0.0112644
+(3, 58) ~ (4, 59) => 0.917136
+(3, 59) ~ (4, 58) => 0.0151822
+(3, 59) ~ (4, 59) => 0.0331795
+(3, 59) ~ (4, 60) => 0.906763
+(3, 60) ~ (4, 59) => 0.0172214
+(3, 60) ~ (4, 60) => 0.0328876
+(3, 60) ~ (4, 61) => 0.907386
+(3, 61) ~ (4, 60) => 0.0158207
+(3, 61) ~ (4, 61) => 0.0332385
+(3, 61) ~ (4, 62) => 0.908808
+(3, 62) ~ (4, 61) => 0.0111186
+(3, 62) ~ (4, 62) => 0.0366779
+(3, 62) ~ (4, 63) => 0.896399
+(3, 63) ~ (4, 63) => 0.048936
+(3, 63) ~ (4, 64) => 0.891003
+(3, 64) ~ (4, 64) => 0.0514905
+(3, 64) ~ (4, 65) => 0.866675
+(3, 65) ~ (4, 65) => 0.0595006
+(3, 65) ~ (4, 66) => 0.851418
+(3, 66) ~ (4, 63) => 0.0103388
+(3, 66) ~ (4, 66) => 0.0703233
+(3, 66) ~ (4, 67) => 0.838538
+(3, 67) ~ (4, 64) => 0.0110753
+(3, 67) ~ (4, 67) => 0.0855752
+(3, 67) ~ (4, 68) => 0.827057
+(3, 68) ~ (4, 65) => 0.0131414
+(3, 68) ~ (4, 68) => 0.0919022
+(3, 68) ~ (4, 69) => 0.827332
+(3, 69) ~ (4, 66) => 0.0123491
+(3, 69) ~ (4, 69) => 0.0914567
+(3, 69) ~ (4, 70) => 0.824847
+(3, 70) ~ (4, 66) => 0.01044
+(3, 70) ~ (4, 69) => 0.0106506
+(3, 70) ~ (4, 70) => 0.0785519
+(3, 70) ~ (4, 71) => 0.839885
+(3, 71) ~ (4, 71) => 0.075831
+(3, 71) ~ (4, 72) => 0.848594
+(3, 72) ~ (4, 72) => 0.0610588
+(3, 72) ~ (4, 73) => 0.867971
+(3, 73) ~ (4, 73) => 0.0583565
+(3, 73) ~ (4, 74) => 0.881993
+(3, 74) ~ (4, 74) => 0.0589104
+(3, 74) ~ (4, 75) => 0.883948
+(3, 75) ~ (4, 75) => 0.0594331
+(3, 75) ~ (4, 76) => 0.894058
+(3, 76) ~ (4, 76) => 0.0500623
+(3, 76) ~ (4, 77) => 0.913804
+(3, 77) ~ (4, 77) => 0.0167174
+(3, 77) ~ (4, 78) => 0.958807
+(3, 78) ~ (4, 79) => 0.969092
+(3, 79) ~ (4, 80) => 0.97535
+(3, 80) ~ (4, 81) => 0.978705
+(3, 81) ~ (4, 82) => 0.978817
+(3, 82) ~ (4, 83) => 0.980909
+(3, 83) ~ (4, 84) => 0.986672
+(3, 84) ~ (4, 85) => 0.989259
+(3, 85) ~ (4, 86) => 0.99417
+(3, 86) ~ (4, 87) => 0.99593
+(3, 87) ~ (4, 88) => 0.996226
+(3, 88) ~ (4, 89) => 0.995842
+(3, 89) ~ (4, 90) => 0.995441
+(3, 90) ~ (4, 91) => 0.995144
+(3, 91) ~ (4, 92) => 0.9949
+(3, 92) ~ (4, 93) => 0.994437
+(3, 93) ~ (4, 94) => 0.993155
+(3, 94) ~ (4, 95) => 0.987908
+(3, 95) ~ (4, 96) => 0.959974
+(3, 96) ~ (4, 96) => 0.0100734
+(3, 96) ~ (4, 97) => 0.894489
+(3, 97) ~ (4, 97) => 0.0160087
+(3, 97) ~ (4, 98) => 0.83905
+(3, 97) ~ (4, 99) => 0.0104844
+(3, 98) ~ (4, 98) => 0.0209899
+(3, 98) ~ (4, 99) => 0.752437
+(3, 98) ~ (4, 100) => 0.0146597
+(3, 98) ~ (4, 101) => 0.0110792
+(3, 99) ~ (4, 99) => 0.0232331
+(3, 99) ~ (4, 100) => 0.680563
+(3, 99) ~ (4, 101) => 0.0187207
+(3, 100) ~ (4, 100) => 0.024573
+(3, 100) ~ (4, 101) => 0.637979
+(3, 100) ~ (4, 102) => 0.0229808
+(3, 101) ~ (4, 99) => 0.0151721
+(3, 101) ~ (4, 101) => 0.0202249
+(3, 101) ~ (4, 102) => 0.627795
+(3, 101) ~ (4, 103) => 0.0217507
+(3, 102) ~ (4, 99) => 0.0115034
+(3, 102) ~ (4, 100) => 0.0170404
+(3, 102) ~ (4, 102) => 0.0207155
+(3, 102) ~ (4, 103) => 0.612061
+(3, 102) ~ (4, 104) => 0.0188836
+(3, 103) ~ (4, 96) => 0.014009
+(3, 103) ~ (4, 97) => 0.0126966
+(3, 103) ~ (4, 100) => 0.0124264
+(3, 103) ~ (4, 101) => 0.0152207
+(3, 103) ~ (4, 103) => 0.0197261
+(3, 103) ~ (4, 104) => 0.582355
+(3, 103) ~ (4, 105) => 0.0175385
+(3, 104) ~ (4, 97) => 0.046542
+(3, 104) ~ (4, 98) => 0.0183285
+(3, 104) ~ (4, 99) => 0.0110259
+(3, 104) ~ (4, 101) => 0.0172575
+(3, 104) ~ (4, 102) => 0.0103727
+(3, 104) ~ (4, 104) => 0.0237605
+(3, 104) ~ (4, 105) => 0.45921
+(3, 104) ~ (4, 106) => 0.0100269
+(3, 105) ~ (4, 98) => 0.0651734
+(3, 105) ~ (4, 99) => 0.0178034
+(3, 105) ~ (4, 100) => 0.0149463
+(3, 105) ~ (4, 102) => 0.0173608
+(3, 105) ~ (4, 105) => 0.0190767
+(3, 105) ~ (4, 106) => 0.161179
+(3, 106) ~ (4, 99) => 0.112586
+(3, 106) ~ (4, 100) => 0.010777
+(3, 106) ~ (4, 101) => 0.0151981
+(3, 106) ~ (4, 102) => 0.0101708
+(3, 106) ~ (4, 103) => 0.0157665
+(3, 106) ~ (4, 106) => 0.0232581
+(3, 106) ~ (4, 107) => 0.101162
+(3, 107) ~ (4, 100) => 0.170215
+(3, 107) ~ (4, 102) => 0.0141334
+(3, 107) ~ (4, 103) => 0.0169848
+(3, 107) ~ (4, 104) => 0.0151281
+(3, 107) ~ (4, 106) => 0.0225332
+(3, 107) ~ (4, 107) => 0.0214484
+(3, 107) ~ (4, 108) => 0.0540949
+(3, 108) ~ (4, 101) => 0.205178
+(3, 108) ~ (4, 103) => 0.0114623
+(3, 108) ~ (4, 104) => 0.0216287
+(3, 108) ~ (4, 105) => 0.0167529
+(3, 108) ~ (4, 107) => 0.0432399
+(3, 108) ~ (4, 108) => 0.0275386
+(3, 108) ~ (4, 109) => 0.0188665
+(3, 109) ~ (4, 102) => 0.219284
+(3, 109) ~ (4, 104) => 0.0115448
+(3, 109) ~ (4, 105) => 0.0161419
+(3, 109) ~ (4, 108) => 0.0571243
+(3, 109) ~ (4, 109) => 0.0218307
+(3, 110) ~ (4, 101) => 0.0100538
+(3, 110) ~ (4, 103) => 0.229731
+(3, 110) ~ (4, 105) => 0.0133349
+(3, 110) ~ (4, 106) => 0.0174424
+(3, 110) ~ (4, 109) => 0.0726479
+(3, 110) ~ (4, 110) => 0.0224208
+(3, 111) ~ (4, 102) => 0.011391
+(3, 111) ~ (4, 103) => 0.0115524
+(3, 111) ~ (4, 104) => 0.247555
+(3, 111) ~ (4, 105) => 0.0118101
+(3, 111) ~ (4, 106) => 0.0431518
+(3, 111) ~ (4, 107) => 0.0162422
+(3, 111) ~ (4, 110) => 0.0749089
+(3, 111) ~ (4, 111) => 0.0192234
+(3, 112) ~ (4, 103) => 0.0130666
+(3, 112) ~ (4, 104) => 0.0173198
+(3, 112) ~ (4, 105) => 0.362588
+(3, 112) ~ (4, 106) => 0.0517833
+(3, 112) ~ (4, 107) => 0.0559057
+(3, 112) ~ (4, 108) => 0.0152714
+(3, 112) ~ (4, 111) => 0.0702002
+(3, 112) ~ (4, 112) => 0.0176271
+(3, 113) ~ (4, 104) => 0.0159644
+(3, 113) ~ (4, 105) => 0.0230932
+(3, 113) ~ (4, 106) => 0.54455
+(3, 113) ~ (4, 107) => 0.0513713
+(3, 113) ~ (4, 108) => 0.0523564
+(3, 113) ~ (4, 112) => 0.0552967
+(3, 113) ~ (4, 113) => 0.0118596
+(3, 114) ~ (4, 105) => 0.0195209
+(3, 114) ~ (4, 106) => 0.0320723
+(3, 114) ~ (4, 107) => 0.565311
+(3, 114) ~ (4, 108) => 0.0318232
+(3, 114) ~ (4, 109) => 0.0400198
+(3, 114) ~ (4, 110) => 0.0106425
+(3, 114) ~ (4, 113) => 0.0130769
+(3, 115) ~ (4, 106) => 0.0476536
+(3, 115) ~ (4, 107) => 0.0367843
+(3, 115) ~ (4, 108) => 0.59805
+(3, 115) ~ (4, 109) => 0.0249412
+(3, 115) ~ (4, 110) => 0.0241695
+(3, 116) ~ (4, 107) => 0.062439
+(3, 116) ~ (4, 108) => 0.0414171
+(3, 116) ~ (4, 109) => 0.573227
+(3, 116) ~ (4, 110) => 0.0273273
+(3, 116) ~ (4, 111) => 0.0143928
+(3, 117) ~ (4, 108) => 0.0822867
+(3, 117) ~ (4, 109) => 0.0602625
+(3, 117) ~ (4, 110) => 0.541956
+(3, 117) ~ (4, 111) => 0.0212016
+(3, 118) ~ (4, 109) => 0.14572
+(3, 118) ~ (4, 110) => 0.0712549
+(3, 118) ~ (4, 111) => 0.415964
+(3, 118) ~ (4, 112) => 0.018113
+(3, 119) ~ (4, 110) => 0.189877
+(3, 119) ~ (4, 111) => 0.0669625
+(3, 119) ~ (4, 112) => 0.326683
+(3, 119) ~ (4, 113) => 0.0163307
+(3, 120) ~ (4, 111) => 0.35028
+(3, 120) ~ (4, 112) => 0.0580825
+(3, 120) ~ (4, 113) => 0.239895
+(3, 120) ~ (4, 114) => 0.0109029
+(3, 121) ~ (4, 112) => 0.485271
+(3, 121) ~ (4, 113) => 0.0473759
+(3, 121) ~ (4, 114) => 0.15221
+(3, 122) ~ (4, 113) => 0.646363
+(3, 122) ~ (4, 114) => 0.0324235
+(3, 123) ~ (4, 114) => 0.768876
+
+; gap posteriors
+(3, 0) ~ (4, -1) => 0.011521
+(3, 1) ~ (4, -1) => 0.0232715
+(3, 2) ~ (4, -1) => 0.0294944
+(3, 3) ~ (4, -1) => 0.0374758
+(3, 4) ~ (4, -1) => 0.0427377
+(3, 5) ~ (4, -1) => 0.0336394
+(3, 6) ~ (4, -1) => 0.0364479
+(3, 7) ~ (4, -1) => 0.040126
+(3, 8) ~ (4, -1) => 0.0400677
+(3, 9) ~ (4, -1) => 0.0257251
+(3, 10) ~ (4, -1) => 0.0396668
+(3, 11) ~ (4, -1) => 0.0389797
+(3, 12) ~ (4, -1) => 0.0381644
+(3, 13) ~ (4, -1) => 0.0359863
+(3, 14) ~ (4, -1) => 0.0331617
+(3, 15) ~ (4, -1) => 0.0264647
+(3, 16) ~ (4, -1) => 0.0212889
+(3, 17) ~ (4, -1) => 0.0291869
+(3, 18) ~ (4, -1) => 0.0289326
+(3, 19) ~ (4, -1) => 0.026293
+(3, 20) ~ (4, -1) => 0.0176294
+(3, 21) ~ (4, -1) => 0.00956285
+(3, 22) ~ (4, -1) => 0.00879073
+(3, 23) ~ (4, -1) => 0.010698
+(3, 24) ~ (4, -1) => 0.0113403
+(3, 25) ~ (4, -1) => 0.0141022
+(3, 26) ~ (4, -1) => 0.0142379
+(3, 27) ~ (4, -1) => 0.0113373
+(3, 28) ~ (4, -1) => 0.00955504
+(3, 29) ~ (4, -1) => 0.00508314
+(3, 30) ~ (4, -1) => 0.00230259
+(3, 31) ~ (4, -1) => 0.00187194
+(3, 32) ~ (4, -1) => 0.00165713
+(3, 33) ~ (4, -1) => 0.00139844
+(3, 34) ~ (4, -1) => 0.00135821
+(3, 35) ~ (4, -1) => 0.00164616
+(3, 36) ~ (4, -1) => 0.00160104
+(3, 37) ~ (4, -1) => 0.00153983
+(3, 38) ~ (4, -1) => 0.00203383
+(3, 39) ~ (4, -1) => 0.00266433
+(3, 40) ~ (4, -1) => 0.00319564
+(3, 41) ~ (4, -1) => 0.00387728
+(3, 42) ~ (4, -1) => 0.00367743
+(3, 43) ~ (4, -1) => 0.00512922
+(3, 44) ~ (4, -1) => 0.00448745
+(3, 45) ~ (4, -1) => 0.00211495
+(3, 46) ~ (4, -1) => 0.00149804
+(3, 47) ~ (4, -1) => 0.00103152
+(3, 48) ~ (4, -1) => 0.000635028
+(3, 49) ~ (4, -1) => 0.00110245
+(3, 50) ~ (4, -1) => 0.00183916
+(3, 51) ~ (4, -1) => 0.00212258
+(3, 52) ~ (4, -1) => 0.00264025
+(3, 53) ~ (4, -1) => 0.00320232
+(3, 54) ~ (4, -1) => 0.00491136
+(3, 55) ~ (4, -1) => 0.0108238
+(3, 56) ~ (4, -1) => 0.0191017
+(3, 57) ~ (4, -1) => 0.0352843
+(3, 58) ~ (4, -1) => 0.0715998
+(3, 59) ~ (4, -1) => 0.0448753
+(3, 60) ~ (4, -1) => 0.042505
+(3, 61) ~ (4, -1) => 0.0421329
+(3, 62) ~ (4, -1) => 0.0558043
+(3, 63) ~ (4, -1) => 0.0600608
+(3, 64) ~ (4, -1) => 0.081835
+(3, 65) ~ (4, -1) => 0.0890811
+(3, 66) ~ (4, -1) => 0.0807998
+(3, 67) ~ (4, -1) => 0.0762923
+(3, 68) ~ (4, -1) => 0.0676247
+(3, 69) ~ (4, -1) => 0.0713468
+(3, 70) ~ (4, -1) => 0.0604725
+(3, 71) ~ (4, -1) => 0.0755754
+(3, 72) ~ (4, -1) => 0.0709699
+(3, 73) ~ (4, -1) => 0.0596501
+(3, 74) ~ (4, -1) => 0.0571417
+(3, 75) ~ (4, -1) => 0.0465088
+(3, 76) ~ (4, -1) => 0.0361339
+(3, 77) ~ (4, -1) => 0.0244761
+(3, 78) ~ (4, -1) => 0.0309075
+(3, 79) ~ (4, -1) => 0.0246496
+(3, 80) ~ (4, -1) => 0.0212947
+(3, 81) ~ (4, -1) => 0.0211834
+(3, 82) ~ (4, -1) => 0.019091
+(3, 83) ~ (4, -1) => 0.0133281
+(3, 84) ~ (4, -1) => 0.010741
+(3, 85) ~ (4, -1) => 0.00583035
+(3, 86) ~ (4, -1) => 0.0040701
+(3, 87) ~ (4, -1) => 0.00377399
+(3, 88) ~ (4, -1) => 0.0041579
+(3, 89) ~ (4, -1) => 0.00455886
+(3, 90) ~ (4, -1) => 0.00485605
+(3, 91) ~ (4, -1) => 0.00510013
+(3, 92) ~ (4, -1) => 0.0055626
+(3, 93) ~ (4, -1) => 0.00684518
+(3, 94) ~ (4, -1) => 0.0120923
+(3, 95) ~ (4, -1) => 0.0400258
+(3, 96) ~ (4, -1) => 0.095438
+(3, 97) ~ (4, -1) => 0.134457
+(3, 98) ~ (4, -1) => 0.200834
+(3, 99) ~ (4, -1) => 0.277483
+(3, 100) ~ (4, -1) => 0.314468
+(3, 101) ~ (4, -1) => 0.315057
+(3, 102) ~ (4, -1) => 0.319796
+(3, 103) ~ (4, -1) => 0.326027
+(3, 104) ~ (4, -1) => 0.403476
+(3, 105) ~ (4, -1) => 0.70446
+(3, 106) ~ (4, -1) => 0.711082
+(3, 107) ~ (4, -1) => 0.685463
+(3, 108) ~ (4, -1) => 0.655333
+(3, 109) ~ (4, -1) => 0.674074
+(3, 110) ~ (4, -1) => 0.634369
+(3, 111) ~ (4, -1) => 0.564165
+(3, 112) ~ (4, -1) => 0.396238
+(3, 113) ~ (4, -1) => 0.245508
+(3, 114) ~ (4, -1) => 0.287533
+(3, 115) ~ (4, -1) => 0.268401
+(3, 116) ~ (4, -1) => 0.281197
+(3, 117) ~ (4, -1) => 0.294293
+(3, 118) ~ (4, -1) => 0.348948
+(3, 119) ~ (4, -1) => 0.400146
+(3, 120) ~ (4, -1) => 0.34084
+(3, 121) ~ (4, -1) => 0.315143
+(3, 122) ~ (4, -1) => 0.321213
+(3, 123) ~ (4, -1) => 0.231124
+
+(3, -1) ~ (4, 0) => 0.0541465
+(3, -1) ~ (4, 1) => 0.161559
+(3, -1) ~ (4, 2) => 0.37683
+(3, -1) ~ (4, 3) => 0.143428
+(3, -1) ~ (4, 4) => 0.0752784
+(3, -1) ~ (4, 5) => 0.04876
+(3, -1) ~ (4, 6) => 0.09911
+(3, -1) ~ (4, 7) => 0.0554892
+(3, -1) ~ (4, 8) => 0.0619105
+(3, -1) ~ (4, 9) => 0.0684057
+(3, -1) ~ (4, 10) => 0.0661505
+(3, -1) ~ (4, 11) => 0.0591855
+(3, -1) ~ (4, 12) => 0.0508474
+(3, -1) ~ (4, 13) => 0.0529554
+(3, -1) ~ (4, 14) => 0.0437136
+(3, -1) ~ (4, 15) => 0.0819385
+(3, -1) ~ (4, 16) => 0.074127
+(3, -1) ~ (4, 17) => 0.0342311
+(3, -1) ~ (4, 18) => 0.0173865
+(3, -1) ~ (4, 19) => 0.015146
+(3, -1) ~ (4, 20) => 0.0086835
+(3, -1) ~ (4, 21) => 0.00697899
+(3, -1) ~ (4, 22) => 0.00956285
+(3, -1) ~ (4, 23) => 0.00879073
+(3, -1) ~ (4, 24) => 0.010698
+(3, -1) ~ (4, 25) => 0.0113403
+(3, -1) ~ (4, 26) => 0.0141022
+(3, -1) ~ (4, 27) => 0.0142379
+(3, -1) ~ (4, 28) => 0.0113373
+(3, -1) ~ (4, 29) => 0.00955504
+(3, -1) ~ (4, 30) => 0.00508314
+(3, -1) ~ (4, 31) => 0.00230259
+(3, -1) ~ (4, 32) => 0.00187194
+(3, -1) ~ (4, 33) => 0.00165713
+(3, -1) ~ (4, 34) => 0.00139844
+(3, -1) ~ (4, 35) => 0.00135821
+(3, -1) ~ (4, 36) => 0.00164616
+(3, -1) ~ (4, 37) => 0.00160104
+(3, -1) ~ (4, 38) => 0.00153983
+(3, -1) ~ (4, 39) => 0.00203383
+(3, -1) ~ (4, 40) => 0.00266433
+(3, -1) ~ (4, 41) => 0.00319564
+(3, -1) ~ (4, 42) => 0.00387728
+(3, -1) ~ (4, 43) => 0.00367743
+(3, -1) ~ (4, 44) => 0.00512922
+(3, -1) ~ (4, 45) => 0.00448745
+(3, -1) ~ (4, 46) => 0.00211495
+(3, -1) ~ (4, 47) => 0.00149804
+(3, -1) ~ (4, 48) => 0.00103152
+(3, -1) ~ (4, 49) => 0.000635028
+(3, -1) ~ (4, 50) => 0.00110245
+(3, -1) ~ (4, 51) => 0.00183916
+(3, -1) ~ (4, 52) => 0.00212258
+(3, -1) ~ (4, 53) => 0.00264025
+(3, -1) ~ (4, 54) => 0.00320232
+(3, -1) ~ (4, 55) => 0.00491136
+(3, -1) ~ (4, 56) => 0.0108238
+(3, -1) ~ (4, 57) => 0.00783731
+(3, -1) ~ (4, 58) => 0.0201021
+(3, -1) ~ (4, 59) => 0.0324633
+(3, -1) ~ (4, 60) => 0.0445287
+(3, -1) ~ (4, 61) => 0.0482569
+(3, -1) ~ (4, 62) => 0.0545141
+(3, -1) ~ (4, 63) => 0.044326
+(3, -1) ~ (4, 64) => 0.046431
+(3, -1) ~ (4, 65) => 0.0606835
+(3, -1) ~ (4, 66) => 0.0554693
+(3, -1) ~ (4, 67) => 0.0758867
+(3, -1) ~ (4, 68) => 0.0810406
+(3, -1) ~ (4, 69) => 0.0705609
+(3, -1) ~ (4, 70) => 0.0966008
+(3, -1) ~ (4, 71) => 0.0842841
+(3, -1) ~ (4, 72) => 0.0903475
+(3, -1) ~ (4, 73) => 0.0736722
+(3, -1) ~ (4, 74) => 0.0590962
+(3, -1) ~ (4, 75) => 0.056619
+(3, -1) ~ (4, 76) => 0.0558796
+(3, -1) ~ (4, 77) => 0.0694788
+(3, -1) ~ (4, 78) => 0.0411935
+(3, -1) ~ (4, 79) => 0.0309075
+(3, -1) ~ (4, 80) => 0.0246496
+(3, -1) ~ (4, 81) => 0.0212947
+(3, -1) ~ (4, 82) => 0.0211834
+(3, -1) ~ (4, 83) => 0.019091
+(3, -1) ~ (4, 84) => 0.0133281
+(3, -1) ~ (4, 85) => 0.010741
+(3, -1) ~ (4, 86) => 0.00583035
+(3, -1) ~ (4, 87) => 0.0040701
+(3, -1) ~ (4, 88) => 0.00377399
+(3, -1) ~ (4, 89) => 0.0041579
+(3, -1) ~ (4, 90) => 0.00455886
+(3, -1) ~ (4, 91) => 0.00485605
+(3, -1) ~ (4, 92) => 0.00510013
+(3, -1) ~ (4, 93) => 0.0055626
+(3, -1) ~ (4, 94) => 0.00684518
+(3, -1) ~ (4, 95) => 0.0120923
+(3, -1) ~ (4, 96) => 0.0159435
+(3, -1) ~ (4, 97) => 0.0302641
+(3, -1) ~ (4, 98) => 0.056458
+(3, -1) ~ (4, 99) => 0.0457553
+(3, -1) ~ (4, 100) => 0.0547993
+(3, -1) ~ (4, 101) => 0.0490888
+(3, -1) ~ (4, 102) => 0.0457956
+(3, -1) ~ (4, 103) => 0.0478987
+(3, -1) ~ (4, 104) => 0.0458594
+(3, -1) ~ (4, 105) => 0.0409329
+(3, -1) ~ (4, 106) => 0.0463488
+(3, -1) ~ (4, 107) => 0.0460968
+(3, -1) ~ (4, 108) => 0.0400374
+(3, -1) ~ (4, 109) => 0.0424846
+(3, -1) ~ (4, 110) => 0.0374424
+(3, -1) ~ (4, 111) => 0.0417758
+(3, -1) ~ (4, 112) => 0.0389267
+(3, -1) ~ (4, 113) => 0.0250984
+(3, -1) ~ (4, 114) => 0.0355872
+
diff --git a/examples/U5.aln1.mfa b/examples/U5.aln1.mfa
new file mode 100644
index 0000000..ff012e0
--- /dev/null
+++ b/examples/U5.aln1.mfa
@@ -0,0 +1,11 @@
+>AC005719.2-130462_130570
+U-ACUCUGGUUUCUCUUCAAUUGUCGAAUAAAUCUUUCGCCUUUUACUAAAGAUUUCCGUGGAGAGGAACA-CUCUAAUGAGUCUAAACUCAAUUUUU----------------------GUAUGACCUG---GCU
+>AC000104.1-17376_17496
+AG-CCAUGUGGUGAGCACAU--AGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCUCUCCACGCUA---AGUGGCAUACGCCUAUUUUUGGAGGG--U--UCCCACUUUAC----UGUGG-GUCCCA
+>AC009948.3-27597_27481
+AUACUCUGGAUUCUCUUCAG--AUC--AUAUAUCUUUUGCCUUUUAUUAGA-AUUUCUAGAGAGAGGAUAAAUUA---UGAGUUUGUAGCCAGUUUUUUCUUUGC-UUUU--UAUUU-UU----GGCAGG---GUU
+>AL606646.3-46909_46786
+AG-CUGCGCAGUGGGCACAA--AGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCACGCUGCAAAU---AGCAGCAUACUCUAAUUUUUUGAGGGGA-UUUCCUAUCUAAG----GACAA-ACCCCA
+>M23811.1-5_119
+AUACUCUGGUUUCUCUUCAG--AUCGUAUAAAUCUUUCCCCUUUCANCAAAGAUUUCCGUGGAGAGGAACAACUC---UGAGUCUUAAACCAAUUUUUUGAGCCUU-GU--------UCC----GGCAAG---GCU
+
diff --git a/examples/U5.aln1.reference.mfa b/examples/U5.aln1.reference.mfa
new file mode 100644
index 0000000..8a2b50c
--- /dev/null
+++ b/examples/U5.aln1.reference.mfa
@@ -0,0 +1,20 @@
+>AC005719.2-130462_130570
+-UACUCUGGUUUCUCUUCAAUUGUCGAAUAAAUCUUUCGCCUUUUACUAA
+AGAUUUCCGUGGAGAGGAACACUCUAAUGAGUCUAAACUCAAUUUUUGUA
+UGAC--------CU-----------GGCU
+>AC000104.1-17376_17496
+AGCCAU-GUGGUGAGCACA--UAGCGAACUAUUCUUUCGCCUUUUACUAA
+AGAAUACCGUGUGCUCUCCAC-GCUAA-GUGGCAUACGCCUAUUUUUGGA
+GGGUUCCCAC--UUUACUG-UGGGUCCCA
+>AC009948.3-27597_27481
+AUACUCUGGAUUCUCUUCA--GAUC--AUAUAUCUUUUGCCUUUUAUUAG
+A-AUUUCUAGAGAGAGGAUAA-AUUAU-GAGUUUGUAGCCAGUUUUUUCU
+UUGCUUUUUAU-UUUU----GGCAGGGUU
+>AL606646.3-46909_46786
+AGCUGC-GCAGUGGGCACA--AAGCGAACUAUUCUUUCGCCUUUUACUAA
+AGAAUACCGUGUGCACGCUGC-AAAUA-GCAGCAUACUCUAAUUUUUUGA
+GGGGAUUUCCUAUCUAAGGACAAACCCCA
+>M23811.1-5_119
+AUACUCUGGUUUCUCUUCA--GAUCGUAUAAAUCUUUCCCCUUUCANCAA
+AGAUUUCCGUGGAGAGGAACA-ACUCU-GAGUCUUAAACCAAUUUUUUGA
+-GCCUUGUU---CC------GGCAAGGCU
diff --git a/examples/U5.aln1.reference.stock b/examples/U5.aln1.reference.stock
new file mode 100644
index 0000000..76ba45b
--- /dev/null
+++ b/examples/U5.aln1.reference.stock
@@ -0,0 +1,13 @@
+# STOCKHOLM 1.0
+M23811.1-5_119                   AUACUCUGGUUUCUCUUCA--GAUCGUAUAAAUCUUUCCCCUUUCANCAAAGAUUUCCGUGGAGAGGAACA-ACUCU-GAGUCUUAAACCAAUUUUUUGA-GCCUUGUU---CC------GGCAAGGCU
+#=GR M23811.1-5_119 SS           --<<<<--<<<<<<<<<<<----------<<<<<<<<----------->>>>>>>>--->>>>>>>>>>>-------->>>>-----------------<-<<<<<<--------------->>>>>>>
+AC005719.2-130462_130570         -UACUCUGGUUUCUCUUCAAUUGUCGAAUAAAUCUUUCGCCUUUUACUAAAGAUUUCCGUGGAGAGGAACACUCUAAUGAGUCUAAACUCAAUUUUUGUAUGAC--------CU-----------GGCU
+#=GR AC005719.2-130462_130570 SS --<<<<--<<<<<<<<<<<----------<<<<<<<<----------->>>>>>>>--->>>>>>>>>>>-------->>>>-----------------<-<<<--------------------->>>>
+AL606646.3-46909_46786           AGCUGC-GCAGUGGGCACA--AAGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCACGCUGC-AAAUA-GCAGCAUACUCUAAUUUUUUGAGGGGAUUUCCUAUCUAAGGACAAACCCCA
+#=GR AL606646.3-46909_46786 SS   --<<<<--<<<<<<<<<<<----------<<<<<<<<----------->>>>>>>>--->>>>>>>>>>>-------->>>>-----------------<-<<<<<<--------------->>>>>>>
+AC000104.1-17376_17496           AGCCAU-GUGGUGAGCACA--UAGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCUCUCCAC-GCUAA-GUGGCAUACGCCUAUUUUUGGAGGGUUCCCAC--UUUACUG-UGGGUCCCA
+#=GR AC000104.1-17376_17496 SS   --<<<<--<<<<<<<<<<<----------<<<<<<<<----------->>>>>>>>--->>>>>>>>>>>-------->>>>-----------------<-<<<<<<--------------->>>>>>>
+AC009948.3-27597_27481           AUACUCUGGAUUCUCUUCA--GAUC--AUAUAUCUUUUGCCUUUUAUUAGA-AUUUCUAGAGAGAGGAUAA-AUUAU-GAGUUUGUAGCCAGUUUUUUCUUUGCUUUUUAU-UUUU----GGCAGGGUU
+#=GR AC009948.3-27597_27481 SS   --<<<<--<<<<<<<<<<<----------<<<<-<<<----------->>>->>>>--->>>>>>>>>>>-------->>>>-----------------<-<<<<<<--------------->>>>>>>
+#=GC SS_cons                     ..<<<<..<<<<<<<<<<<..........<<<<<<<<...........>>>>>>>>...>>>>>>>>>>>........>>>>.................<.<<<<<<...............>>>>>>>
+//
diff --git a/examples/U5.aln1.stock b/examples/U5.aln1.stock
new file mode 100644
index 0000000..a99dcdb
--- /dev/null
+++ b/examples/U5.aln1.stock
@@ -0,0 +1,9 @@
+# STOCKHOLM 1.0
+#=GF Accuracy            0.673907
+AC005719.2-130462_130570 U-ACUCUGGUUUCUCUUCAAUUGUCGAAUAAAUCUUUCGCCUUUUACUAAAGAUUUCCGUGGAGAGGAACA-CUCUAAUGAGUCUAAACUCAAUUUUU----------------------GUAUGACCUG---GCU
+AC000104.1-17376_17496   AG-CCAUGUGGUGAGCACAU--AGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCUCUCCACGCUA---AGUGGCAUACGCCUAUUUUUGGAGGG--U--UCCCACUUUAC----UGUGG-GUCCCA
+AC009948.3-27597_27481   AUACUCUGGAUUCUCUUCAG--AUC--AUAUAUCUUUUGCCUUUUAUUAGA-AUUUCUAGAGAGAGGAUAAAUUA---UGAGUUUGUAGCCAGUUUUUUCUUUGC-UUUU--UAUUU-UU----GGCAGG---GUU
+AL606646.3-46909_46786   AG-CUGCGCAGUGGGCACAA--AGCGAACUAUUCUUUCGCCUUUUACUAAAGAAUACCGUGUGCACGCUGCAAAU---AGCAGCAUACUCUAAUUUUUUGAGGGGA-UUUCCUAUCUAAG----GACAA-ACCCCA
+M23811.1-5_119           AUACUCUGGUUUCUCUUCAG--AUCGUAUAAAUCUUUCCCCUUUCANCAAAGAUUUCCGUGGAGAGGAACAACUC---UGAGUCUUAAACCAAUUUUUUGAGCCUU-GU--------UCC----GGCAAG---GCU
+#=GC Accuracy            7657777777777777777634678777777899999999999999998878777787777655555555454552325667777777777877776676665554444555666554551111555555555678
+//
diff --git a/examples/tRNA.aln1.fasta b/examples/tRNA.aln1.fasta
new file mode 100644
index 0000000..37b3984
--- /dev/null
+++ b/examples/tRNA.aln1.fasta
@@ -0,0 +1,15 @@
+>AE004843.1-4972_4900
+GCUCAUGUAGCUCAGUUGGUAGAGCACACCCUUGGUAAGGGUGAGGUCAG
+CGGUUCAAAUCCGCUCAUGAGCU
+>Z82044.1-16031_16103
+GCGGUUGUGGCGAAGUGGUUAACGCACCAGAUUGUGGCUCUGGCACUCGU
+GGGUUCGAUUCCCAUCAAUCGCC
+>M83762.1-1031_1093
+GCUUUAAAAGCUUUGCUGAAGCAACGGCCUUGUAAGUCGUAGAAAACUAU
+ACGUUUUAAAGCU
+>AB042432.1-14140_14072
+GUUUCUGUAGUUGAAUUACAACGAUGAUUUUUCAUGUCAUUGGUCGCAGU
+UGAAUGCUGUGUAGAAAUA
+>AC008670.6-83725_83795
+ACUUUUAAAGGAUAACAGCCAUCCGUUGGUCUUAGGCCCCAAAAAUUUUG
+GUGCAACUCCAAAUAAAAGUA
diff --git a/examples/tRNA.aln1.fasta.gui b/examples/tRNA.aln1.fasta.gui
new file mode 100644
index 0000000..271a87e
--- /dev/null
+++ b/examples/tRNA.aln1.fasta.gui
@@ -0,0 +1,636 @@
+; Initial DAG
+; Format is:
+;   column: (sequence, position)
+; sequence is 0-based and position is 0-based
+
+0: (0, 0)
+1: (1, 0)
+2: (2, 0)
+3: (3, 0)
+4: (4, 0)
+5: (0, 1)
+6: (1, 1)
+7: (2, 1)
+8: (3, 1)
+9: (4, 1)
+10: (0, 2)
+11: (1, 2)
+12: (2, 2)
+13: (3, 2)
+14: (4, 2)
+15: (0, 3)
+16: (1, 3)
+17: (2, 3)
+18: (3, 3)
+19: (4, 3)
+20: (0, 4)
+21: (1, 4)
+22: (2, 4)
+23: (3, 4)
+24: (4, 4)
+25: (0, 5)
+26: (1, 5)
+27: (2, 5)
+28: (3, 5)
+29: (4, 5)
+30: (0, 6)
+31: (1, 6)
+32: (2, 6)
+33: (3, 6)
+34: (4, 6)
+35: (0, 7)
+36: (1, 7)
+37: (2, 7)
+38: (3, 7)
+39: (4, 7)
+40: (0, 8)
+41: (1, 8)
+42: (2, 8)
+43: (3, 8)
+44: (4, 8)
+45: (0, 9)
+46: (1, 9)
+47: (2, 9)
+48: (3, 9)
+49: (4, 9)
+50: (0, 10)
+51: (1, 10)
+52: (2, 10)
+53: (3, 10)
+54: (4, 10)
+55: (0, 11)
+56: (1, 11)
+57: (2, 11)
+58: (3, 11)
+59: (4, 11)
+60: (0, 12)
+61: (1, 12)
+62: (2, 12)
+63: (3, 12)
+64: (4, 12)
+65: (0, 13)
+66: (1, 13)
+67: (2, 13)
+68: (3, 13)
+69: (4, 13)
+70: (0, 14)
+71: (1, 14)
+72: (2, 14)
+73: (3, 14)
+74: (4, 14)
+75: (0, 15)
+76: (1, 15)
+77: (2, 15)
+78: (3, 15)
+79: (4, 15)
+80: (0, 16)
+81: (1, 16)
+82: (2, 16)
+83: (3, 16)
+84: (4, 16)
+85: (0, 17)
+86: (1, 17)
+87: (2, 17)
+88: (3, 17)
+89: (4, 17)
+90: (0, 18)
+91: (1, 18)
+92: (2, 18)
+93: (3, 18)
+94: (4, 18)
+95: (0, 19)
+96: (1, 19)
+97: (2, 19)
+98: (3, 19)
+99: (4, 19)
+100: (0, 20)
+101: (1, 20)
+102: (2, 20)
+103: (3, 20)
+104: (4, 20)
+105: (0, 21)
+106: (1, 21)
+107: (2, 21)
+108: (3, 21)
+109: (4, 21)
+110: (0, 22)
+111: (1, 22)
+112: (2, 22)
+113: (3, 22)
+114: (4, 22)
+115: (0, 23)
+116: (1, 23)
+117: (2, 23)
+118: (3, 23)
+119: (4, 23)
+120: (0, 24)
+121: (1, 24)
+122: (2, 24)
+123: (3, 24)
+124: (4, 24)
+125: (0, 25)
+126: (1, 25)
+127: (2, 25)
+128: (3, 25)
+129: (4, 25)
+130: (0, 26)
+131: (1, 26)
+132: (2, 26)
+133: (3, 26)
+134: (4, 26)
+135: (0, 27)
+136: (1, 27)
+137: (2, 27)
+138: (3, 27)
+139: (4, 27)
+140: (0, 28)
+141: (1, 28)
+142: (2, 28)
+143: (3, 28)
+144: (4, 28)
+145: (0, 29)
+146: (1, 29)
+147: (2, 29)
+148: (3, 29)
+149: (4, 29)
+150: (0, 30)
+151: (1, 30)
+152: (2, 30)
+153: (3, 30)
+154: (4, 30)
+155: (0, 31)
+156: (1, 31)
+157: (2, 31)
+158: (3, 31)
+159: (4, 31)
+160: (0, 32)
+161: (1, 32)
+162: (2, 32)
+163: (3, 32)
+164: (4, 32)
+165: (0, 33)
+166: (1, 33)
+167: (2, 33)
+168: (3, 33)
+169: (4, 33)
+170: (0, 34)
+171: (1, 34)
+172: (2, 34)
+173: (3, 34)
+174: (4, 34)
+175: (0, 35)
+176: (1, 35)
+177: (2, 35)
+178: (3, 35)
+179: (4, 35)
+180: (0, 36)
+181: (1, 36)
+182: (2, 36)
+183: (3, 36)
+184: (4, 36)
+185: (0, 37)
+186: (1, 37)
+187: (2, 37)
+188: (3, 37)
+189: (4, 37)
+190: (0, 38)
+191: (1, 38)
+192: (2, 38)
+193: (3, 38)
+194: (4, 38)
+195: (0, 39)
+196: (1, 39)
+197: (2, 39)
+198: (3, 39)
+199: (4, 39)
+200: (0, 40)
+201: (1, 40)
+202: (2, 40)
+203: (3, 40)
+204: (4, 40)
+205: (0, 41)
+206: (1, 41)
+207: (2, 41)
+208: (3, 41)
+209: (4, 41)
+210: (0, 42)
+211: (1, 42)
+212: (2, 42)
+213: (3, 42)
+214: (4, 42)
+215: (0, 43)
+216: (1, 43)
+217: (2, 43)
+218: (3, 43)
+219: (4, 43)
+220: (0, 44)
+221: (1, 44)
+222: (2, 44)
+223: (3, 44)
+224: (4, 44)
+225: (0, 45)
+226: (1, 45)
+227: (2, 45)
+228: (3, 45)
+229: (4, 45)
+230: (0, 46)
+231: (1, 46)
+232: (2, 46)
+233: (3, 46)
+234: (4, 46)
+235: (0, 47)
+236: (1, 47)
+237: (2, 47)
+238: (3, 47)
+239: (4, 47)
+240: (0, 48)
+241: (1, 48)
+242: (2, 48)
+243: (3, 48)
+244: (4, 48)
+245: (0, 49)
+246: (1, 49)
+247: (2, 49)
+248: (3, 49)
+249: (4, 49)
+250: (0, 50)
+251: (1, 50)
+252: (2, 50)
+253: (3, 50)
+254: (4, 50)
+255: (0, 51)
+256: (1, 51)
+257: (2, 51)
+258: (3, 51)
+259: (4, 51)
+260: (0, 52)
+261: (1, 52)
+262: (2, 52)
+263: (3, 52)
+264: (4, 52)
+265: (0, 53)
+266: (1, 53)
+267: (2, 53)
+268: (3, 53)
+269: (4, 53)
+270: (0, 54)
+271: (1, 54)
+272: (2, 54)
+273: (3, 54)
+274: (4, 54)
+275: (0, 55)
+276: (1, 55)
+277: (2, 55)
+278: (3, 55)
+279: (4, 55)
+280: (0, 56)
+281: (1, 56)
+282: (2, 56)
+283: (3, 56)
+284: (4, 56)
+285: (0, 57)
+286: (1, 57)
+287: (2, 57)
+288: (3, 57)
+289: (4, 57)
+290: (0, 58)
+291: (1, 58)
+292: (2, 58)
+293: (3, 58)
+294: (4, 58)
+295: (0, 59)
+296: (1, 59)
+297: (2, 59)
+298: (3, 59)
+299: (4, 59)
+300: (0, 60)
+301: (1, 60)
+302: (2, 60)
+303: (3, 60)
+304: (4, 60)
+305: (0, 61)
+306: (1, 61)
+307: (2, 61)
+308: (3, 61)
+309: (4, 61)
+310: (0, 62)
+311: (1, 62)
+312: (2, 62)
+313: (3, 62)
+314: (4, 62)
+315: (0, 63)
+316: (1, 63)
+317: (3, 63)
+318: (4, 63)
+319: (0, 64)
+320: (1, 64)
+321: (3, 64)
+322: (4, 64)
+323: (0, 65)
+324: (1, 65)
+325: (3, 65)
+326: (4, 65)
+327: (0, 66)
+328: (1, 66)
+329: (3, 66)
+330: (4, 66)
+331: (0, 67)
+332: (1, 67)
+333: (3, 67)
+334: (4, 67)
+335: (0, 68)
+336: (1, 68)
+337: (3, 68)
+338: (4, 68)
+339: (0, 69)
+340: (1, 69)
+341: (4, 69)
+342: (0, 70)
+343: (1, 70)
+344: (4, 70)
+345: (0, 71)
+346: (1, 71)
+347: (0, 72)
+348: (1, 72)
+
+; Merges (added edges)
+; Format is:
+;   source_column -> dest_column
+; (new accuracy is source_column_accuracy + dest_column_accuracy + accuracy_change)
+; (note that all accuracies are unnormalized)
+
+1 -> 0
+51 -> 50
+271 -> 270
+276 -> 275
+6 -> 5
+301 -> 300
+66 -> 65
+56 -> 55
+46 -> 45
+71 -> 70
+266 -> 265
+61 -> 60
+41 -> 40
+306 -> 305
+296 -> 295
+281 -> 280
+36 -> 35
+76 -> 75
+261 -> 260
+286 -> 285
+31 -> 30
+291 -> 290
+11 -> 10
+81 -> 80
+311 -> 310
+96 -> 95
+86 -> 85
+320 -> 319
+26 -> 25
+91 -> 90
+316 -> 315
+256 -> 255
+101 -> 100
+16 -> 15
+116 -> 115
+21 -> 20
+121 -> 120
+324 -> 323
+106 -> 105
+111 -> 110
+251 -> 250
+126 -> 125
+156 -> 155
+246 -> 245
+131 -> 130
+241 -> 240
+151 -> 150
+236 -> 235
+161 -> 160
+136 -> 135
+146 -> 145
+141 -> 140
+328 -> 327
+231 -> 230
+348 -> 347
+343 -> 342
+166 -> 165
+346 -> 345
+340 -> 339
+336 -> 335
+332 -> 331
+226 -> 225
+171 -> 170
+221 -> 220
+216 -> 215
+211 -> 210
+176 -> 175
+181 -> 180
+186 -> 185
+206 -> 205
+191 -> 190
+201 -> 200
+196 -> 195
+3 -> 2
+344 -> 337
+341 -> 333
+338 -> 329
+334 -> 325
+330 -> 321
+313 -> 322
+326 -> 317
+123 -> 122
+318 -> 308
+4 -> 1
+128 -> 127
+8 -> 7
+118 -> 117
+314 -> 303
+113 -> 112
+108 -> 107
+309 -> 298
+133 -> 132
+103 -> 102
+304 -> 293
+83 -> 82
+78 -> 77
+13 -> 12
+98 -> 97
+299 -> 288
+88 -> 87
+53 -> 52
+268 -> 279
+294 -> 283
+48 -> 47
+273 -> 284
+93 -> 92
+289 -> 278
+274 -> 263
+238 -> 249
+18 -> 17
+73 -> 72
+243 -> 254
+58 -> 57
+218 -> 229
+43 -> 42
+224 -> 213
+244 -> 233
+248 -> 259
+223 -> 234
+219 -> 208
+239 -> 228
+68 -> 67
+9 -> 6
+38 -> 37
+63 -> 62
+214 -> 203
+269 -> 258
+4 -> 3
+23 -> 22
+33 -> 32
+209 -> 198
+264 -> 253
+28 -> 27
+138 -> 137
+204 -> 193
+143 -> 142
+199 -> 188
+9 -> 8
+14 -> 11
+348 -> 312
+194 -> 183
+19 -> 16
+346 -> 307
+148 -> 147
+189 -> 178
+24 -> 21
+39 -> 36
+34 -> 31
+44 -> 41
+14 -> 13
+29 -> 26
+184 -> 173
+346 -> 341
+49 -> 46
+153 -> 152
+343 -> 338
+179 -> 168
+19 -> 18
+348 -> 344
+54 -> 51
+59 -> 56
+24 -> 23
+158 -> 157
+163 -> 162
+29 -> 28
+340 -> 334
+64 -> 61
+343 -> 302
+306 -> 299
+332 -> 326
+328 -> 313
+304 -> 311
+34 -> 33
+324 -> 318
+39 -> 38
+301 -> 294
+309 -> 316
+79 -> 76
+74 -> 71
+69 -> 66
+296 -> 289
+291 -> 273
+84 -> 81
+44 -> 43
+336 -> 330
+320 -> 314
+89 -> 86
+286 -> 268
+49 -> 48
+281 -> 274
+340 -> 297
+54 -> 53
+151 -> 149
+161 -> 159
+276 -> 269
+156 -> 154
+94 -> 91
+166 -> 164
+99 -> 96
+336 -> 292
+171 -> 169
+271 -> 264
+146 -> 144
+59 -> 58
+332 -> 287
+266 -> 248
+176 -> 174
+136 -> 134
+141 -> 139
+104 -> 101
+114 -> 111
+261 -> 243
+328 -> 282
+131 -> 129
+64 -> 63
+79 -> 78
+324 -> 277
+256 -> 238
+126 -> 124
+74 -> 73
+109 -> 106
+197 -> 209
+204 -> 192
+69 -> 68
+121 -> 119
+199 -> 187
+84 -> 83
+320 -> 272
+202 -> 214
+194 -> 182
+251 -> 244
+236 -> 218
+309 -> 267
+246 -> 239
+189 -> 177
+304 -> 262
+207 -> 219
+89 -> 88
+184 -> 172
+241 -> 223
+306 -> 257
+179 -> 167
+231 -> 224
+94 -> 93
+116 -> 103
+181 -> 179
+301 -> 252
+186 -> 184
+199 -> 201
+123 -> 136
+204 -> 206
+191 -> 189
+143 -> 156
+148 -> 161
+212 -> 231
+196 -> 194
+99 -> 98
+108 -> 121
+151 -> 138
+146 -> 133
+197 -> 211
+221 -> 207
+176 -> 163
+153 -> 166
+216 -> 202
+141 -> 128
+131 -> 118
+296 -> 247
+126 -> 113
+171 -> 158
+217 -> 236
+291 -> 242
+222 -> 241
+286 -> 237
+227 -> 246
diff --git a/examples/tRNA.aln1.fasta.probs b/examples/tRNA.aln1.fasta.probs
new file mode 100644
index 0000000..42bc4a8
--- /dev/null
+++ b/examples/tRNA.aln1.fasta.probs
@@ -0,0 +1,3731 @@
+; Sparse posterior probability matrix for sequences 0 and 1
+; Format is:
+;   (0, position_1) ~ (1, position_2) => prob
+; which means that (0, position_1) is aligned to (1, position_2) with probability prob.
+;   (0, position_1) ~ (1, -1) => prob
+; means that (0, position_1) is aligned to a gap in 1 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (1, 0) => 0.999999
+(0, 1) ~ (1, 1) => 0.999998
+(0, 2) ~ (1, 2) => 0.999995
+(0, 3) ~ (1, 3) => 0.999994
+(0, 4) ~ (1, 4) => 0.999993
+(0, 5) ~ (1, 5) => 0.999995
+(0, 6) ~ (1, 6) => 0.999996
+(0, 7) ~ (1, 7) => 0.999997
+(0, 8) ~ (1, 8) => 0.999997
+(0, 9) ~ (1, 9) => 0.999998
+(0, 10) ~ (1, 10) => 0.999998
+(0, 11) ~ (1, 11) => 0.999998
+(0, 12) ~ (1, 12) => 0.999998
+(0, 13) ~ (1, 13) => 0.999998
+(0, 14) ~ (1, 14) => 0.999998
+(0, 15) ~ (1, 15) => 0.999997
+(0, 16) ~ (1, 16) => 0.999995
+(0, 17) ~ (1, 17) => 0.999995
+(0, 18) ~ (1, 18) => 0.999994
+(0, 19) ~ (1, 19) => 0.999995
+(0, 20) ~ (1, 20) => 0.999994
+(0, 21) ~ (1, 21) => 0.999992
+(0, 22) ~ (1, 22) => 0.999992
+(0, 23) ~ (1, 23) => 0.999993
+(0, 24) ~ (1, 24) => 0.999993
+(0, 25) ~ (1, 25) => 0.999991
+(0, 26) ~ (1, 26) => 0.999989
+(0, 27) ~ (1, 27) => 0.999986
+(0, 28) ~ (1, 28) => 0.999985
+(0, 29) ~ (1, 29) => 0.999985
+(0, 30) ~ (1, 30) => 0.999988
+(0, 31) ~ (1, 31) => 0.99999
+(0, 32) ~ (1, 32) => 0.999988
+(0, 33) ~ (1, 33) => 0.999982
+(0, 34) ~ (1, 34) => 0.999972
+(0, 35) ~ (1, 35) => 0.999963
+(0, 36) ~ (1, 36) => 0.999959
+(0, 37) ~ (1, 37) => 0.999958
+(0, 38) ~ (1, 38) => 0.999955
+(0, 39) ~ (1, 39) => 0.999953
+(0, 40) ~ (1, 40) => 0.999954
+(0, 41) ~ (1, 41) => 0.999956
+(0, 42) ~ (1, 42) => 0.999963
+(0, 43) ~ (1, 43) => 0.999967
+(0, 44) ~ (1, 44) => 0.999968
+(0, 45) ~ (1, 45) => 0.999975
+(0, 46) ~ (1, 46) => 0.999985
+(0, 47) ~ (1, 47) => 0.999988
+(0, 48) ~ (1, 48) => 0.999988
+(0, 49) ~ (1, 49) => 0.999989
+(0, 50) ~ (1, 50) => 0.999991
+(0, 51) ~ (1, 51) => 0.999994
+(0, 52) ~ (1, 52) => 0.999996
+(0, 53) ~ (1, 53) => 0.999998
+(0, 54) ~ (1, 54) => 0.999998
+(0, 55) ~ (1, 55) => 0.999998
+(0, 56) ~ (1, 56) => 0.999997
+(0, 57) ~ (1, 57) => 0.999996
+(0, 58) ~ (1, 58) => 0.999996
+(0, 59) ~ (1, 59) => 0.999997
+(0, 60) ~ (1, 60) => 0.999998
+(0, 61) ~ (1, 61) => 0.999997
+(0, 62) ~ (1, 62) => 0.999995
+(0, 63) ~ (1, 63) => 0.999994
+(0, 64) ~ (1, 64) => 0.999995
+(0, 65) ~ (1, 65) => 0.999993
+(0, 66) ~ (1, 66) => 0.999985
+(0, 67) ~ (1, 67) => 0.999977
+(0, 68) ~ (1, 68) => 0.999977
+(0, 69) ~ (1, 69) => 0.999979
+(0, 70) ~ (1, 70) => 0.999982
+(0, 71) ~ (1, 71) => 0.999981
+(0, 72) ~ (1, 72) => 0.999982
+
+; gap posteriors
+(0, 0) ~ (1, -1) => 0.0001
+(0, 1) ~ (1, -1) => 0.0001
+(0, 2) ~ (1, -1) => 0.0001
+(0, 3) ~ (1, -1) => 0.0001
+(0, 4) ~ (1, -1) => 0.0001
+(0, 5) ~ (1, -1) => 0.0001
+(0, 6) ~ (1, -1) => 0.0001
+(0, 7) ~ (1, -1) => 0.0001
+(0, 8) ~ (1, -1) => 0.0001
+(0, 9) ~ (1, -1) => 0.0001
+(0, 10) ~ (1, -1) => 0.0001
+(0, 11) ~ (1, -1) => 0.0001
+(0, 12) ~ (1, -1) => 0.0001
+(0, 13) ~ (1, -1) => 0.0001
+(0, 14) ~ (1, -1) => 0.0001
+(0, 15) ~ (1, -1) => 0.0001
+(0, 16) ~ (1, -1) => 0.0001
+(0, 17) ~ (1, -1) => 0.0001
+(0, 18) ~ (1, -1) => 0.0001
+(0, 19) ~ (1, -1) => 0.0001
+(0, 20) ~ (1, -1) => 0.0001
+(0, 21) ~ (1, -1) => 0.0001
+(0, 22) ~ (1, -1) => 0.0001
+(0, 23) ~ (1, -1) => 0.0001
+(0, 24) ~ (1, -1) => 0.0001
+(0, 25) ~ (1, -1) => 0.0001
+(0, 26) ~ (1, -1) => 0.0001
+(0, 27) ~ (1, -1) => 0.0001
+(0, 28) ~ (1, -1) => 0.0001
+(0, 29) ~ (1, -1) => 0.0001
+(0, 30) ~ (1, -1) => 0.0001
+(0, 31) ~ (1, -1) => 0.0001
+(0, 32) ~ (1, -1) => 0.0001
+(0, 33) ~ (1, -1) => 0.0001
+(0, 34) ~ (1, -1) => 0.0001
+(0, 35) ~ (1, -1) => 0.0001
+(0, 36) ~ (1, -1) => 0.0001
+(0, 37) ~ (1, -1) => 0.0001
+(0, 38) ~ (1, -1) => 0.0001
+(0, 39) ~ (1, -1) => 0.0001
+(0, 40) ~ (1, -1) => 0.0001
+(0, 41) ~ (1, -1) => 0.0001
+(0, 42) ~ (1, -1) => 0.0001
+(0, 43) ~ (1, -1) => 0.0001
+(0, 44) ~ (1, -1) => 0.0001
+(0, 45) ~ (1, -1) => 0.0001
+(0, 46) ~ (1, -1) => 0.0001
+(0, 47) ~ (1, -1) => 0.0001
+(0, 48) ~ (1, -1) => 0.0001
+(0, 49) ~ (1, -1) => 0.0001
+(0, 50) ~ (1, -1) => 0.0001
+(0, 51) ~ (1, -1) => 0.0001
+(0, 52) ~ (1, -1) => 0.0001
+(0, 53) ~ (1, -1) => 0.0001
+(0, 54) ~ (1, -1) => 0.0001
+(0, 55) ~ (1, -1) => 0.0001
+(0, 56) ~ (1, -1) => 0.0001
+(0, 57) ~ (1, -1) => 0.0001
+(0, 58) ~ (1, -1) => 0.0001
+(0, 59) ~ (1, -1) => 0.0001
+(0, 60) ~ (1, -1) => 0.0001
+(0, 61) ~ (1, -1) => 0.0001
+(0, 62) ~ (1, -1) => 0.0001
+(0, 63) ~ (1, -1) => 0.0001
+(0, 64) ~ (1, -1) => 0.0001
+(0, 65) ~ (1, -1) => 0.0001
+(0, 66) ~ (1, -1) => 0.0001
+(0, 67) ~ (1, -1) => 0.0001
+(0, 68) ~ (1, -1) => 0.0001
+(0, 69) ~ (1, -1) => 0.0001
+(0, 70) ~ (1, -1) => 0.0001
+(0, 71) ~ (1, -1) => 0.0001
+(0, 72) ~ (1, -1) => 0.0001
+
+(0, -1) ~ (1, 0) => 0.0001
+(0, -1) ~ (1, 1) => 0.0001
+(0, -1) ~ (1, 2) => 0.0001
+(0, -1) ~ (1, 3) => 0.0001
+(0, -1) ~ (1, 4) => 0.0001
+(0, -1) ~ (1, 5) => 0.0001
+(0, -1) ~ (1, 6) => 0.0001
+(0, -1) ~ (1, 7) => 0.0001
+(0, -1) ~ (1, 8) => 0.0001
+(0, -1) ~ (1, 9) => 0.0001
+(0, -1) ~ (1, 10) => 0.0001
+(0, -1) ~ (1, 11) => 0.0001
+(0, -1) ~ (1, 12) => 0.0001
+(0, -1) ~ (1, 13) => 0.0001
+(0, -1) ~ (1, 14) => 0.0001
+(0, -1) ~ (1, 15) => 0.0001
+(0, -1) ~ (1, 16) => 0.0001
+(0, -1) ~ (1, 17) => 0.0001
+(0, -1) ~ (1, 18) => 0.0001
+(0, -1) ~ (1, 19) => 0.0001
+(0, -1) ~ (1, 20) => 0.0001
+(0, -1) ~ (1, 21) => 0.0001
+(0, -1) ~ (1, 22) => 0.0001
+(0, -1) ~ (1, 23) => 0.0001
+(0, -1) ~ (1, 24) => 0.0001
+(0, -1) ~ (1, 25) => 0.0001
+(0, -1) ~ (1, 26) => 0.0001
+(0, -1) ~ (1, 27) => 0.0001
+(0, -1) ~ (1, 28) => 0.0001
+(0, -1) ~ (1, 29) => 0.0001
+(0, -1) ~ (1, 30) => 0.0001
+(0, -1) ~ (1, 31) => 0.0001
+(0, -1) ~ (1, 32) => 0.0001
+(0, -1) ~ (1, 33) => 0.0001
+(0, -1) ~ (1, 34) => 0.0001
+(0, -1) ~ (1, 35) => 0.0001
+(0, -1) ~ (1, 36) => 0.0001
+(0, -1) ~ (1, 37) => 0.0001
+(0, -1) ~ (1, 38) => 0.0001
+(0, -1) ~ (1, 39) => 0.0001
+(0, -1) ~ (1, 40) => 0.0001
+(0, -1) ~ (1, 41) => 0.0001
+(0, -1) ~ (1, 42) => 0.0001
+(0, -1) ~ (1, 43) => 0.0001
+(0, -1) ~ (1, 44) => 0.0001
+(0, -1) ~ (1, 45) => 0.0001
+(0, -1) ~ (1, 46) => 0.0001
+(0, -1) ~ (1, 47) => 0.0001
+(0, -1) ~ (1, 48) => 0.0001
+(0, -1) ~ (1, 49) => 0.0001
+(0, -1) ~ (1, 50) => 0.0001
+(0, -1) ~ (1, 51) => 0.0001
+(0, -1) ~ (1, 52) => 0.0001
+(0, -1) ~ (1, 53) => 0.0001
+(0, -1) ~ (1, 54) => 0.0001
+(0, -1) ~ (1, 55) => 0.0001
+(0, -1) ~ (1, 56) => 0.0001
+(0, -1) ~ (1, 57) => 0.0001
+(0, -1) ~ (1, 58) => 0.0001
+(0, -1) ~ (1, 59) => 0.0001
+(0, -1) ~ (1, 60) => 0.0001
+(0, -1) ~ (1, 61) => 0.0001
+(0, -1) ~ (1, 62) => 0.0001
+(0, -1) ~ (1, 63) => 0.0001
+(0, -1) ~ (1, 64) => 0.0001
+(0, -1) ~ (1, 65) => 0.0001
+(0, -1) ~ (1, 66) => 0.0001
+(0, -1) ~ (1, 67) => 0.0001
+(0, -1) ~ (1, 68) => 0.0001
+(0, -1) ~ (1, 69) => 0.0001
+(0, -1) ~ (1, 70) => 0.0001
+(0, -1) ~ (1, 71) => 0.0001
+(0, -1) ~ (1, 72) => 0.0001
+
+; Sparse posterior probability matrix for sequences 0 and 2
+; Format is:
+;   (0, position_1) ~ (2, position_2) => prob
+; which means that (0, position_1) is aligned to (2, position_2) with probability prob.
+;   (0, position_1) ~ (2, -1) => prob
+; means that (0, position_1) is aligned to a gap in 2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (2, 0) => 0.999724
+(0, 1) ~ (2, 1) => 0.998259
+(0, 2) ~ (2, 2) => 0.994262
+(0, 3) ~ (2, 3) => 0.989699
+(0, 4) ~ (2, 4) => 0.984788
+(0, 5) ~ (2, 5) => 0.98371
+(0, 6) ~ (2, 6) => 0.984832
+(0, 7) ~ (2, 7) => 0.986823
+(0, 8) ~ (2, 8) => 0.990154
+(0, 9) ~ (2, 9) => 0.993648
+(0, 10) ~ (2, 10) => 0.992968
+(0, 11) ~ (2, 11) => 0.97876
+(0, 12) ~ (2, 12) => 0.921718
+(0, 13) ~ (2, 13) => 0.887071
+(0, 14) ~ (2, 14) => 0.871222
+(0, 15) ~ (2, 12) => 0.0582702
+(0, 15) ~ (2, 15) => 0.849592
+(0, 15) ~ (2, 18) => 0.0100661
+(0, 16) ~ (2, 13) => 0.0887852
+(0, 16) ~ (2, 16) => 0.823034
+(0, 17) ~ (2, 14) => 0.101264
+(0, 17) ~ (2, 17) => 0.772626
+(0, 17) ~ (2, 20) => 0.0101951
+(0, 18) ~ (2, 15) => 0.111043
+(0, 18) ~ (2, 17) => 0.0266189
+(0, 18) ~ (2, 18) => 0.634374
+(0, 18) ~ (2, 20) => 0.0130161
+(0, 19) ~ (2, 15) => 0.0101311
+(0, 19) ~ (2, 16) => 0.130759
+(0, 19) ~ (2, 18) => 0.0390973
+(0, 19) ~ (2, 19) => 0.511963
+(0, 19) ~ (2, 21) => 0.014438
+(0, 19) ~ (2, 22) => 0.0108856
+(0, 20) ~ (2, 16) => 0.0118631
+(0, 20) ~ (2, 17) => 0.146939
+(0, 20) ~ (2, 18) => 0.0396141
+(0, 20) ~ (2, 19) => 0.0482135
+(0, 20) ~ (2, 20) => 0.410275
+(0, 20) ~ (2, 22) => 0.0168449
+(0, 20) ~ (2, 23) => 0.0104926
+(0, 21) ~ (2, 17) => 0.0164278
+(0, 21) ~ (2, 18) => 0.217703
+(0, 21) ~ (2, 19) => 0.0659514
+(0, 21) ~ (2, 20) => 0.0485805
+(0, 21) ~ (2, 21) => 0.360963
+(0, 21) ~ (2, 23) => 0.0107928
+(0, 22) ~ (2, 18) => 0.0175471
+(0, 22) ~ (2, 19) => 0.292626
+(0, 22) ~ (2, 20) => 0.090073
+(0, 22) ~ (2, 21) => 0.0254846
+(0, 22) ~ (2, 22) => 0.338077
+(0, 23) ~ (2, 19) => 0.0151479
+(0, 23) ~ (2, 20) => 0.351957
+(0, 23) ~ (2, 21) => 0.127763
+(0, 23) ~ (2, 22) => 0.0214119
+(0, 23) ~ (2, 23) => 0.278308
+(0, 24) ~ (2, 21) => 0.35012
+(0, 24) ~ (2, 22) => 0.184091
+(0, 24) ~ (2, 23) => 0.0102155
+(0, 24) ~ (2, 24) => 0.230821
+(0, 25) ~ (2, 20) => 0.0163298
+(0, 25) ~ (2, 22) => 0.223097
+(0, 25) ~ (2, 23) => 0.381562
+(0, 25) ~ (2, 25) => 0.159674
+(0, 26) ~ (2, 21) => 0.0275944
+(0, 26) ~ (2, 22) => 0.0131233
+(0, 26) ~ (2, 23) => 0.0808135
+(0, 26) ~ (2, 24) => 0.560693
+(0, 26) ~ (2, 25) => 0.0229938
+(0, 26) ~ (2, 26) => 0.0856582
+(0, 26) ~ (2, 27) => 0.0132148
+(0, 27) ~ (2, 22) => 0.0282464
+(0, 27) ~ (2, 23) => 0.0326558
+(0, 27) ~ (2, 24) => 0.0448551
+(0, 27) ~ (2, 25) => 0.621584
+(0, 27) ~ (2, 26) => 0.0519631
+(0, 27) ~ (2, 27) => 0.0247191
+(0, 28) ~ (2, 23) => 0.024229
+(0, 28) ~ (2, 24) => 0.0391592
+(0, 28) ~ (2, 25) => 0.0415402
+(0, 28) ~ (2, 26) => 0.674947
+(0, 28) ~ (2, 27) => 0.0693055
+(0, 28) ~ (2, 28) => 0.0241231
+(0, 29) ~ (2, 24) => 0.0185494
+(0, 29) ~ (2, 26) => 0.0432005
+(0, 29) ~ (2, 27) => 0.773768
+(0, 29) ~ (2, 28) => 0.0661617
+(0, 29) ~ (2, 29) => 0.0184992
+(0, 30) ~ (2, 27) => 0.0597814
+(0, 30) ~ (2, 28) => 0.79759
+(0, 30) ~ (2, 29) => 0.0537858
+(0, 30) ~ (2, 30) => 0.0134248
+(0, 31) ~ (2, 28) => 0.062305
+(0, 31) ~ (2, 29) => 0.788477
+(0, 31) ~ (2, 30) => 0.0418489
+(0, 31) ~ (2, 32) => 0.0152908
+(0, 32) ~ (2, 29) => 0.0799714
+(0, 32) ~ (2, 30) => 0.756954
+(0, 32) ~ (2, 33) => 0.017271
+(0, 33) ~ (2, 30) => 0.0917165
+(0, 33) ~ (2, 31) => 0.634551
+(0, 33) ~ (2, 34) => 0.0191927
+(0, 34) ~ (2, 31) => 0.175789
+(0, 34) ~ (2, 32) => 0.400881
+(0, 34) ~ (2, 33) => 0.0207365
+(0, 34) ~ (2, 35) => 0.0223507
+(0, 35) ~ (2, 30) => 0.0147897
+(0, 35) ~ (2, 32) => 0.229849
+(0, 35) ~ (2, 33) => 0.313607
+(0, 35) ~ (2, 34) => 0.0222486
+(0, 35) ~ (2, 36) => 0.020426
+(0, 36) ~ (2, 31) => 0.0205284
+(0, 36) ~ (2, 32) => 0.071508
+(0, 36) ~ (2, 33) => 0.204588
+(0, 36) ~ (2, 34) => 0.245642
+(0, 36) ~ (2, 35) => 0.023337
+(0, 36) ~ (2, 37) => 0.0109347
+(0, 37) ~ (2, 30) => 0.0116018
+(0, 37) ~ (2, 32) => 0.0423532
+(0, 37) ~ (2, 33) => 0.110317
+(0, 37) ~ (2, 34) => 0.172453
+(0, 37) ~ (2, 35) => 0.161916
+(0, 37) ~ (2, 36) => 0.0341586
+(0, 38) ~ (2, 31) => 0.0235705
+(0, 38) ~ (2, 33) => 0.051835
+(0, 38) ~ (2, 34) => 0.140796
+(0, 38) ~ (2, 35) => 0.128513
+(0, 38) ~ (2, 36) => 0.138184
+(0, 38) ~ (2, 37) => 0.0419751
+(0, 39) ~ (2, 32) => 0.0284375
+(0, 39) ~ (2, 34) => 0.0605162
+(0, 39) ~ (2, 35) => 0.177165
+(0, 39) ~ (2, 36) => 0.056401
+(0, 39) ~ (2, 37) => 0.133565
+(0, 39) ~ (2, 38) => 0.0645766
+(0, 39) ~ (2, 40) => 0.0138348
+(0, 40) ~ (2, 31) => 0.0398725
+(0, 40) ~ (2, 33) => 0.0382519
+(0, 40) ~ (2, 35) => 0.0703581
+(0, 40) ~ (2, 36) => 0.188482
+(0, 40) ~ (2, 37) => 0.0221293
+(0, 40) ~ (2, 38) => 0.140343
+(0, 40) ~ (2, 39) => 0.0662712
+(0, 40) ~ (2, 41) => 0.0153682
+(0, 41) ~ (2, 32) => 0.0639644
+(0, 41) ~ (2, 34) => 0.0479564
+(0, 41) ~ (2, 36) => 0.0646349
+(0, 41) ~ (2, 37) => 0.215527
+(0, 41) ~ (2, 39) => 0.128938
+(0, 41) ~ (2, 40) => 0.076872
+(0, 41) ~ (2, 42) => 0.0144392
+(0, 42) ~ (2, 32) => 0.0304373
+(0, 42) ~ (2, 33) => 0.059531
+(0, 42) ~ (2, 35) => 0.0595085
+(0, 42) ~ (2, 37) => 0.0261667
+(0, 42) ~ (2, 38) => 0.250169
+(0, 42) ~ (2, 40) => 0.0911969
+(0, 42) ~ (2, 41) => 0.0914186
+(0, 42) ~ (2, 43) => 0.0136913
+(0, 43) ~ (2, 33) => 0.0837669
+(0, 43) ~ (2, 34) => 0.0562082
+(0, 43) ~ (2, 36) => 0.0614359
+(0, 43) ~ (2, 38) => 0.012928
+(0, 43) ~ (2, 39) => 0.253133
+(0, 43) ~ (2, 40) => 0.0173352
+(0, 43) ~ (2, 41) => 0.0589634
+(0, 43) ~ (2, 42) => 0.0964243
+(0, 43) ~ (2, 44) => 0.0126652
+(0, 44) ~ (2, 34) => 0.132966
+(0, 44) ~ (2, 35) => 0.0482587
+(0, 44) ~ (2, 37) => 0.0630964
+(0, 44) ~ (2, 40) => 0.26258
+(0, 44) ~ (2, 41) => 0.0226665
+(0, 44) ~ (2, 42) => 0.0471306
+(0, 44) ~ (2, 43) => 0.0955452
+(0, 44) ~ (2, 45) => 0.0107377
+(0, 45) ~ (2, 31) => 0.017201
+(0, 45) ~ (2, 35) => 0.196908
+(0, 45) ~ (2, 36) => 0.0319099
+(0, 45) ~ (2, 38) => 0.07081
+(0, 45) ~ (2, 41) => 0.271162
+(0, 45) ~ (2, 42) => 0.0205864
+(0, 45) ~ (2, 43) => 0.0353805
+(0, 45) ~ (2, 44) => 0.0941144
+(0, 46) ~ (2, 32) => 0.0253401
+(0, 46) ~ (2, 36) => 0.241181
+(0, 46) ~ (2, 37) => 0.031351
+(0, 46) ~ (2, 39) => 0.0664009
+(0, 46) ~ (2, 42) => 0.260711
+(0, 46) ~ (2, 43) => 0.0179568
+(0, 46) ~ (2, 44) => 0.0215948
+(0, 46) ~ (2, 45) => 0.0931938
+(0, 47) ~ (2, 33) => 0.0275964
+(0, 47) ~ (2, 37) => 0.246739
+(0, 47) ~ (2, 38) => 0.029932
+(0, 47) ~ (2, 39) => 0.0204301
+(0, 47) ~ (2, 40) => 0.0498507
+(0, 47) ~ (2, 43) => 0.251047
+(0, 47) ~ (2, 44) => 0.0135477
+(0, 47) ~ (2, 46) => 0.0926613
+(0, 48) ~ (2, 34) => 0.0334336
+(0, 48) ~ (2, 37) => 0.0116868
+(0, 48) ~ (2, 38) => 0.193955
+(0, 48) ~ (2, 39) => 0.0456215
+(0, 48) ~ (2, 40) => 0.0421049
+(0, 48) ~ (2, 41) => 0.0410816
+(0, 48) ~ (2, 42) => 0.0123284
+(0, 48) ~ (2, 44) => 0.254717
+(0, 48) ~ (2, 45) => 0.0123801
+(0, 48) ~ (2, 47) => 0.0667051
+(0, 49) ~ (2, 35) => 0.0389983
+(0, 49) ~ (2, 38) => 0.0422504
+(0, 49) ~ (2, 39) => 0.177682
+(0, 49) ~ (2, 40) => 0.0594786
+(0, 49) ~ (2, 41) => 0.0511579
+(0, 49) ~ (2, 42) => 0.0388787
+(0, 49) ~ (2, 43) => 0.0135967
+(0, 49) ~ (2, 45) => 0.252676
+(0, 49) ~ (2, 48) => 0.0456863
+(0, 50) ~ (2, 36) => 0.0415821
+(0, 50) ~ (2, 39) => 0.050177
+(0, 50) ~ (2, 40) => 0.181601
+(0, 50) ~ (2, 41) => 0.0671565
+(0, 50) ~ (2, 42) => 0.0472804
+(0, 50) ~ (2, 43) => 0.0351595
+(0, 50) ~ (2, 44) => 0.0129426
+(0, 50) ~ (2, 46) => 0.248721
+(0, 50) ~ (2, 49) => 0.0291422
+(0, 51) ~ (2, 37) => 0.0420335
+(0, 51) ~ (2, 40) => 0.0512515
+(0, 51) ~ (2, 41) => 0.192155
+(0, 51) ~ (2, 42) => 0.0946379
+(0, 51) ~ (2, 43) => 0.0492776
+(0, 51) ~ (2, 44) => 0.0356747
+(0, 51) ~ (2, 45) => 0.0148672
+(0, 51) ~ (2, 47) => 0.174671
+(0, 51) ~ (2, 50) => 0.0178835
+(0, 52) ~ (2, 38) => 0.0515219
+(0, 52) ~ (2, 41) => 0.0516903
+(0, 52) ~ (2, 42) => 0.189746
+(0, 52) ~ (2, 43) => 0.124305
+(0, 52) ~ (2, 44) => 0.0495705
+(0, 52) ~ (2, 45) => 0.0354658
+(0, 52) ~ (2, 46) => 0.0152973
+(0, 52) ~ (2, 48) => 0.151707
+(0, 53) ~ (2, 39) => 0.0545825
+(0, 53) ~ (2, 42) => 0.0452449
+(0, 53) ~ (2, 43) => 0.187371
+(0, 53) ~ (2, 44) => 0.15197
+(0, 53) ~ (2, 45) => 0.0487567
+(0, 53) ~ (2, 46) => 0.0329965
+(0, 53) ~ (2, 47) => 0.0290346
+(0, 53) ~ (2, 49) => 0.133888
+(0, 54) ~ (2, 40) => 0.0535747
+(0, 54) ~ (2, 43) => 0.0385975
+(0, 54) ~ (2, 44) => 0.184618
+(0, 54) ~ (2, 45) => 0.18189
+(0, 54) ~ (2, 46) => 0.0464012
+(0, 54) ~ (2, 47) => 0.0365166
+(0, 54) ~ (2, 48) => 0.023408
+(0, 54) ~ (2, 50) => 0.1125
+(0, 55) ~ (2, 41) => 0.0520236
+(0, 55) ~ (2, 44) => 0.0314222
+(0, 55) ~ (2, 45) => 0.182111
+(0, 55) ~ (2, 46) => 0.211635
+(0, 55) ~ (2, 47) => 0.0502179
+(0, 55) ~ (2, 48) => 0.0192955
+(0, 55) ~ (2, 49) => 0.0183962
+(0, 55) ~ (2, 51) => 0.0807924
+(0, 56) ~ (2, 42) => 0.054673
+(0, 56) ~ (2, 45) => 0.0300687
+(0, 56) ~ (2, 46) => 0.192478
+(0, 56) ~ (2, 47) => 0.178491
+(0, 56) ~ (2, 48) => 0.0411804
+(0, 56) ~ (2, 49) => 0.0126608
+(0, 56) ~ (2, 50) => 0.014626
+(0, 56) ~ (2, 52) => 0.0444692
+(0, 57) ~ (2, 43) => 0.0546273
+(0, 57) ~ (2, 46) => 0.0107941
+(0, 57) ~ (2, 47) => 0.330134
+(0, 57) ~ (2, 48) => 0.143113
+(0, 57) ~ (2, 49) => 0.0270833
+(0, 57) ~ (2, 50) => 0.0108142
+(0, 57) ~ (2, 53) => 0.0317131
+(0, 58) ~ (2, 44) => 0.0521404
+(0, 58) ~ (2, 48) => 0.462548
+(0, 58) ~ (2, 49) => 0.102628
+(0, 58) ~ (2, 50) => 0.0228717
+(0, 58) ~ (2, 54) => 0.0236598
+(0, 59) ~ (2, 45) => 0.0486479
+(0, 59) ~ (2, 49) => 0.579688
+(0, 59) ~ (2, 50) => 0.0901317
+(0, 59) ~ (2, 55) => 0.0201023
+(0, 60) ~ (2, 46) => 0.0474697
+(0, 60) ~ (2, 50) => 0.645043
+(0, 60) ~ (2, 51) => 0.0615694
+(0, 60) ~ (2, 56) => 0.0147287
+(0, 61) ~ (2, 47) => 0.0335597
+(0, 61) ~ (2, 51) => 0.789701
+(0, 61) ~ (2, 52) => 0.0265989
+(0, 62) ~ (2, 48) => 0.0279606
+(0, 62) ~ (2, 52) => 0.869536
+(0, 62) ~ (2, 53) => 0.0204472
+(0, 63) ~ (2, 49) => 0.0240568
+(0, 63) ~ (2, 53) => 0.887267
+(0, 63) ~ (2, 54) => 0.0216905
+(0, 64) ~ (2, 50) => 0.0199529
+(0, 64) ~ (2, 54) => 0.900811
+(0, 64) ~ (2, 55) => 0.0230221
+(0, 65) ~ (2, 51) => 0.0177709
+(0, 65) ~ (2, 55) => 0.90596
+(0, 65) ~ (2, 56) => 0.0223452
+(0, 66) ~ (2, 52) => 0.0115729
+(0, 66) ~ (2, 56) => 0.91626
+(0, 66) ~ (2, 57) => 0.0194429
+(0, 67) ~ (2, 56) => 0.010609
+(0, 67) ~ (2, 57) => 0.932905
+(0, 67) ~ (2, 58) => 0.0135614
+(0, 68) ~ (2, 58) => 0.954925
+(0, 69) ~ (2, 59) => 0.974332
+(0, 70) ~ (2, 60) => 0.990845
+(0, 71) ~ (2, 61) => 0.997531
+(0, 72) ~ (2, 62) => 0.998506
+
+; gap posteriors
+(0, 0) ~ (2, -1) => 0.000275612
+(0, 1) ~ (2, -1) => 0.00174129
+(0, 2) ~ (2, -1) => 0.00573754
+(0, 3) ~ (2, -1) => 0.010301
+(0, 4) ~ (2, -1) => 0.0152116
+(0, 5) ~ (2, -1) => 0.0162897
+(0, 6) ~ (2, -1) => 0.015168
+(0, 7) ~ (2, -1) => 0.0131771
+(0, 8) ~ (2, -1) => 0.00984573
+(0, 9) ~ (2, -1) => 0.00635201
+(0, 10) ~ (2, -1) => 0.0070315
+(0, 11) ~ (2, -1) => 0.0212397
+(0, 12) ~ (2, -1) => 0.078282
+(0, 13) ~ (2, -1) => 0.112929
+(0, 14) ~ (2, -1) => 0.128778
+(0, 15) ~ (2, -1) => 0.082072
+(0, 16) ~ (2, -1) => 0.0881804
+(0, 17) ~ (2, -1) => 0.115915
+(0, 18) ~ (2, -1) => 0.214949
+(0, 19) ~ (2, -1) => 0.282726
+(0, 20) ~ (2, -1) => 0.315758
+(0, 21) ~ (2, -1) => 0.279582
+(0, 22) ~ (2, -1) => 0.236192
+(0, 23) ~ (2, -1) => 0.205413
+(0, 24) ~ (2, -1) => 0.224752
+(0, 25) ~ (2, -1) => 0.219337
+(0, 26) ~ (2, -1) => 0.195909
+(0, 27) ~ (2, -1) => 0.195977
+(0, 28) ~ (2, -1) => 0.126696
+(0, 29) ~ (2, -1) => 0.0798208
+(0, 30) ~ (2, -1) => 0.0754177
+(0, 31) ~ (2, -1) => 0.0920783
+(0, 32) ~ (2, -1) => 0.145803
+(0, 33) ~ (2, -1) => 0.254539
+(0, 34) ~ (2, -1) => 0.380242
+(0, 35) ~ (2, -1) => 0.39908
+(0, 36) ~ (2, -1) => 0.423462
+(0, 37) ~ (2, -1) => 0.4672
+(0, 38) ~ (2, -1) => 0.475126
+(0, 39) ~ (2, -1) => 0.465504
+(0, 40) ~ (2, -1) => 0.418923
+(0, 41) ~ (2, -1) => 0.387668
+(0, 42) ~ (2, -1) => 0.377881
+(0, 43) ~ (2, -1) => 0.34714
+(0, 44) ~ (2, -1) => 0.317019
+(0, 45) ~ (2, -1) => 0.261928
+(0, 46) ~ (2, -1) => 0.242271
+(0, 47) ~ (2, -1) => 0.268196
+(0, 48) ~ (2, -1) => 0.285986
+(0, 49) ~ (2, -1) => 0.279595
+(0, 50) ~ (2, -1) => 0.286238
+(0, 51) ~ (2, -1) => 0.327548
+(0, 52) ~ (2, -1) => 0.330696
+(0, 53) ~ (2, -1) => 0.316156
+(0, 54) ~ (2, -1) => 0.322494
+(0, 55) ~ (2, -1) => 0.354106
+(0, 56) ~ (2, -1) => 0.431354
+(0, 57) ~ (2, -1) => 0.391721
+(0, 58) ~ (2, -1) => 0.336152
+(0, 59) ~ (2, -1) => 0.26143
+(0, 60) ~ (2, -1) => 0.231189
+(0, 61) ~ (2, -1) => 0.150141
+(0, 62) ~ (2, -1) => 0.0820566
+(0, 63) ~ (2, -1) => 0.066986
+(0, 64) ~ (2, -1) => 0.0562138
+(0, 65) ~ (2, -1) => 0.0539238
+(0, 66) ~ (2, -1) => 0.0527242
+(0, 67) ~ (2, -1) => 0.0429246
+(0, 68) ~ (2, -1) => 0.0450748
+(0, 69) ~ (2, -1) => 0.0256681
+(0, 70) ~ (2, -1) => 0.00915456
+(0, 71) ~ (2, -1) => 0.002469
+(0, 72) ~ (2, -1) => 0.00149399
+
+(0, -1) ~ (2, 0) => 0.000275612
+(0, -1) ~ (2, 1) => 0.00174129
+(0, -1) ~ (2, 2) => 0.00573754
+(0, -1) ~ (2, 3) => 0.010301
+(0, -1) ~ (2, 4) => 0.0152116
+(0, -1) ~ (2, 5) => 0.0162897
+(0, -1) ~ (2, 6) => 0.015168
+(0, -1) ~ (2, 7) => 0.0131771
+(0, -1) ~ (2, 8) => 0.00984573
+(0, -1) ~ (2, 9) => 0.00635201
+(0, -1) ~ (2, 10) => 0.0070315
+(0, -1) ~ (2, 11) => 0.0212397
+(0, -1) ~ (2, 12) => 0.0200118
+(0, -1) ~ (2, 13) => 0.0241438
+(0, -1) ~ (2, 14) => 0.0275133
+(0, -1) ~ (2, 15) => 0.0292348
+(0, -1) ~ (2, 16) => 0.0343431
+(0, -1) ~ (2, 17) => 0.0373887
+(0, -1) ~ (2, 18) => 0.0415987
+(0, -1) ~ (2, 19) => 0.0660981
+(0, -1) ~ (2, 20) => 0.0595737
+(0, -1) ~ (2, 21) => 0.0936376
+(0, -1) ~ (2, 22) => 0.164222
+(0, -1) ~ (2, 23) => 0.170931
+(0, -1) ~ (2, 24) => 0.105922
+(0, -1) ~ (2, 25) => 0.154209
+(0, -1) ~ (2, 26) => 0.144231
+(0, -1) ~ (2, 27) => 0.0592109
+(0, -1) ~ (2, 28) => 0.0498198
+(0, -1) ~ (2, 29) => 0.0592668
+(0, -1) ~ (2, 30) => 0.0696642
+(0, -1) ~ (2, 31) => 0.0884868
+(0, -1) ~ (2, 32) => 0.0919386
+(0, -1) ~ (2, 33) => 0.0724985
+(0, -1) ~ (2, 34) => 0.0685876
+(0, -1) ~ (2, 35) => 0.0726866
+(0, -1) ~ (2, 36) => 0.121605
+(0, -1) ~ (2, 37) => 0.154795
+(0, -1) ~ (2, 38) => 0.143514
+(0, -1) ~ (2, 39) => 0.136763
+(0, -1) ~ (2, 40) => 0.10032
+(0, -1) ~ (2, 41) => 0.0851562
+(0, -1) ~ (2, 42) => 0.0779182
+(0, -1) ~ (2, 43) => 0.0834449
+(0, -1) ~ (2, 44) => 0.0850222
+(0, -1) ~ (2, 45) => 0.089206
+(0, -1) ~ (2, 46) => 0.101546
+(0, -1) ~ (2, 47) => 0.100671
+(0, -1) ~ (2, 48) => 0.0851012
+(0, -1) ~ (2, 49) => 0.0724566
+(0, -1) ~ (2, 50) => 0.066177
+(0, -1) ~ (2, 51) => 0.0501667
+(0, -1) ~ (2, 52) => 0.0478234
+(0, -1) ~ (2, 53) => 0.060573
+(0, -1) ~ (2, 54) => 0.0538386
+(0, -1) ~ (2, 55) => 0.0509156
+(0, -1) ~ (2, 56) => 0.036057
+(0, -1) ~ (2, 57) => 0.0476521
+(0, -1) ~ (2, 58) => 0.0315134
+(0, -1) ~ (2, 59) => 0.0256681
+(0, -1) ~ (2, 60) => 0.00915456
+(0, -1) ~ (2, 61) => 0.002469
+(0, -1) ~ (2, 62) => 0.00149399
+
+; Sparse posterior probability matrix for sequences 0 and 3
+; Format is:
+;   (0, position_1) ~ (3, position_2) => prob
+; which means that (0, position_1) is aligned to (3, position_2) with probability prob.
+;   (0, position_1) ~ (3, -1) => prob
+; means that (0, position_1) is aligned to a gap in 3 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (3, 0) => 0.999868
+(0, 1) ~ (3, 1) => 0.999554
+(0, 2) ~ (3, 2) => 0.999334
+(0, 3) ~ (3, 3) => 0.999235
+(0, 4) ~ (3, 4) => 0.999279
+(0, 5) ~ (3, 5) => 0.999524
+(0, 6) ~ (3, 6) => 0.999585
+(0, 7) ~ (3, 7) => 0.999572
+(0, 8) ~ (3, 8) => 0.999311
+(0, 9) ~ (3, 9) => 0.998955
+(0, 10) ~ (3, 10) => 0.99825
+(0, 11) ~ (3, 11) => 0.997211
+(0, 12) ~ (3, 12) => 0.996337
+(0, 13) ~ (3, 13) => 0.99552
+(0, 14) ~ (3, 14) => 0.993473
+(0, 15) ~ (3, 15) => 0.988359
+(0, 16) ~ (3, 16) => 0.976493
+(0, 17) ~ (3, 17) => 0.928737
+(0, 18) ~ (3, 17) => 0.0325857
+(0, 18) ~ (3, 18) => 0.855379
+(0, 18) ~ (3, 19) => 0.0148667
+(0, 19) ~ (3, 17) => 0.0110468
+(0, 19) ~ (3, 18) => 0.0543214
+(0, 19) ~ (3, 19) => 0.721971
+(0, 19) ~ (3, 20) => 0.0169913
+(0, 20) ~ (3, 17) => 0.0143884
+(0, 20) ~ (3, 18) => 0.047874
+(0, 20) ~ (3, 19) => 0.13454
+(0, 20) ~ (3, 20) => 0.690495
+(0, 20) ~ (3, 21) => 0.0206943
+(0, 21) ~ (3, 18) => 0.0172511
+(0, 21) ~ (3, 19) => 0.0933079
+(0, 21) ~ (3, 20) => 0.148898
+(0, 21) ~ (3, 21) => 0.646272
+(0, 21) ~ (3, 22) => 0.030991
+(0, 22) ~ (3, 19) => 0.0201563
+(0, 22) ~ (3, 20) => 0.107175
+(0, 22) ~ (3, 21) => 0.167541
+(0, 22) ~ (3, 22) => 0.604437
+(0, 22) ~ (3, 23) => 0.0351532
+(0, 23) ~ (3, 20) => 0.0189054
+(0, 23) ~ (3, 21) => 0.118466
+(0, 23) ~ (3, 22) => 0.192156
+(0, 23) ~ (3, 23) => 0.594313
+(0, 23) ~ (3, 24) => 0.027865
+(0, 24) ~ (3, 21) => 0.0168377
+(0, 24) ~ (3, 22) => 0.131108
+(0, 24) ~ (3, 23) => 0.195914
+(0, 24) ~ (3, 24) => 0.540339
+(0, 24) ~ (3, 25) => 0.0282492
+(0, 25) ~ (3, 23) => 0.137636
+(0, 25) ~ (3, 24) => 0.264318
+(0, 25) ~ (3, 25) => 0.209762
+(0, 25) ~ (3, 26) => 0.0367611
+(0, 26) ~ (3, 24) => 0.122203
+(0, 26) ~ (3, 25) => 0.610714
+(0, 26) ~ (3, 26) => 0.0458083
+(0, 26) ~ (3, 27) => 0.0310703
+(0, 27) ~ (3, 25) => 0.0343706
+(0, 27) ~ (3, 26) => 0.868687
+(0, 27) ~ (3, 27) => 0.0307455
+(0, 27) ~ (3, 28) => 0.0212694
+(0, 28) ~ (3, 26) => 0.0153008
+(0, 28) ~ (3, 27) => 0.911727
+(0, 28) ~ (3, 28) => 0.0305757
+(0, 28) ~ (3, 29) => 0.0197958
+(0, 29) ~ (3, 27) => 0.0154065
+(0, 29) ~ (3, 28) => 0.923867
+(0, 29) ~ (3, 29) => 0.0282678
+(0, 29) ~ (3, 30) => 0.0180916
+(0, 30) ~ (3, 28) => 0.0148131
+(0, 30) ~ (3, 29) => 0.928523
+(0, 30) ~ (3, 30) => 0.025473
+(0, 30) ~ (3, 31) => 0.0151869
+(0, 31) ~ (3, 29) => 0.0138116
+(0, 31) ~ (3, 30) => 0.931348
+(0, 31) ~ (3, 31) => 0.0204346
+(0, 32) ~ (3, 30) => 0.0119587
+(0, 32) ~ (3, 31) => 0.930356
+(0, 32) ~ (3, 32) => 0.0112762
+(0, 33) ~ (3, 32) => 0.913441
+(0, 34) ~ (3, 33) => 0.886764
+(0, 34) ~ (3, 35) => 0.0140674
+(0, 35) ~ (3, 31) => 0.0101124
+(0, 35) ~ (3, 34) => 0.860442
+(0, 35) ~ (3, 36) => 0.0174668
+(0, 36) ~ (3, 32) => 0.0147431
+(0, 36) ~ (3, 35) => 0.757718
+(0, 36) ~ (3, 37) => 0.017365
+(0, 37) ~ (3, 32) => 0.0104763
+(0, 37) ~ (3, 33) => 0.0191068
+(0, 37) ~ (3, 35) => 0.0137239
+(0, 37) ~ (3, 36) => 0.724875
+(0, 37) ~ (3, 37) => 0.0101107
+(0, 37) ~ (3, 38) => 0.0150061
+(0, 38) ~ (3, 33) => 0.0167235
+(0, 38) ~ (3, 34) => 0.0206122
+(0, 38) ~ (3, 35) => 0.0170961
+(0, 38) ~ (3, 36) => 0.0213794
+(0, 38) ~ (3, 37) => 0.693712
+(0, 39) ~ (3, 32) => 0.0187956
+(0, 39) ~ (3, 34) => 0.022139
+(0, 39) ~ (3, 35) => 0.0437584
+(0, 39) ~ (3, 36) => 0.0153575
+(0, 39) ~ (3, 37) => 0.0362792
+(0, 39) ~ (3, 38) => 0.640753
+(0, 40) ~ (3, 33) => 0.032433
+(0, 40) ~ (3, 35) => 0.0639345
+(0, 40) ~ (3, 36) => 0.0480517
+(0, 40) ~ (3, 37) => 0.0171286
+(0, 40) ~ (3, 38) => 0.0482781
+(0, 40) ~ (3, 39) => 0.583542
+(0, 41) ~ (3, 34) => 0.0464326
+(0, 41) ~ (3, 36) => 0.0763925
+(0, 41) ~ (3, 37) => 0.059493
+(0, 41) ~ (3, 38) => 0.0148169
+(0, 41) ~ (3, 39) => 0.0572248
+(0, 41) ~ (3, 40) => 0.556763
+(0, 42) ~ (3, 35) => 0.0563854
+(0, 42) ~ (3, 37) => 0.0673534
+(0, 42) ~ (3, 38) => 0.110734
+(0, 42) ~ (3, 39) => 0.0229042
+(0, 42) ~ (3, 40) => 0.0357203
+(0, 42) ~ (3, 41) => 0.360305
+(0, 43) ~ (3, 36) => 0.0588889
+(0, 43) ~ (3, 38) => 0.0604748
+(0, 43) ~ (3, 39) => 0.157368
+(0, 43) ~ (3, 40) => 0.0370634
+(0, 43) ~ (3, 41) => 0.0199648
+(0, 43) ~ (3, 42) => 0.161219
+(0, 44) ~ (3, 37) => 0.0629392
+(0, 44) ~ (3, 39) => 0.0344668
+(0, 44) ~ (3, 40) => 0.217001
+(0, 44) ~ (3, 41) => 0.0728361
+(0, 44) ~ (3, 42) => 0.0230368
+(0, 44) ~ (3, 43) => 0.0615437
+(0, 45) ~ (3, 38) => 0.065582
+(0, 45) ~ (3, 40) => 0.0132727
+(0, 45) ~ (3, 41) => 0.424589
+(0, 45) ~ (3, 42) => 0.0956251
+(0, 45) ~ (3, 44) => 0.0521909
+(0, 46) ~ (3, 39) => 0.0683149
+(0, 46) ~ (3, 41) => 0.0103489
+(0, 46) ~ (3, 42) => 0.607405
+(0, 46) ~ (3, 43) => 0.0793701
+(0, 46) ~ (3, 45) => 0.0409314
+(0, 47) ~ (3, 40) => 0.0592941
+(0, 47) ~ (3, 43) => 0.768465
+(0, 47) ~ (3, 44) => 0.059465
+(0, 47) ~ (3, 46) => 0.0361746
+(0, 48) ~ (3, 41) => 0.048867
+(0, 48) ~ (3, 44) => 0.813133
+(0, 48) ~ (3, 45) => 0.0197414
+(0, 48) ~ (3, 47) => 0.0310433
+(0, 49) ~ (3, 42) => 0.0437046
+(0, 49) ~ (3, 45) => 0.874886
+(0, 49) ~ (3, 48) => 0.0237211
+(0, 50) ~ (3, 43) => 0.0375795
+(0, 50) ~ (3, 46) => 0.900147
+(0, 50) ~ (3, 49) => 0.0160224
+(0, 51) ~ (3, 44) => 0.0216162
+(0, 51) ~ (3, 47) => 0.9279
+(0, 52) ~ (3, 45) => 0.0116906
+(0, 52) ~ (3, 47) => 0.0112825
+(0, 52) ~ (3, 48) => 0.946085
+(0, 53) ~ (3, 48) => 0.0128174
+(0, 53) ~ (3, 49) => 0.963231
+(0, 54) ~ (3, 49) => 0.015348
+(0, 54) ~ (3, 50) => 0.972575
+(0, 55) ~ (3, 50) => 0.0172364
+(0, 55) ~ (3, 51) => 0.973723
+(0, 56) ~ (3, 51) => 0.0160667
+(0, 56) ~ (3, 52) => 0.97698
+(0, 57) ~ (3, 52) => 0.0177774
+(0, 57) ~ (3, 53) => 0.976109
+(0, 58) ~ (3, 53) => 0.0190756
+(0, 58) ~ (3, 54) => 0.97426
+(0, 59) ~ (3, 54) => 0.0182465
+(0, 59) ~ (3, 55) => 0.977275
+(0, 60) ~ (3, 56) => 0.98739
+(0, 61) ~ (3, 57) => 0.993847
+(0, 62) ~ (3, 58) => 0.996528
+(0, 63) ~ (3, 59) => 0.997048
+(0, 64) ~ (3, 60) => 0.997148
+(0, 65) ~ (3, 61) => 0.998164
+(0, 66) ~ (3, 62) => 0.998541
+(0, 67) ~ (3, 63) => 0.997815
+(0, 68) ~ (3, 64) => 0.997719
+(0, 69) ~ (3, 65) => 0.998095
+(0, 70) ~ (3, 66) => 0.998485
+(0, 71) ~ (3, 67) => 0.998721
+(0, 72) ~ (3, 68) => 0.998798
+
+; gap posteriors
+(0, 0) ~ (3, -1) => 0.000132024
+(0, 1) ~ (3, -1) => 0.000445604
+(0, 2) ~ (3, -1) => 0.00066638
+(0, 3) ~ (3, -1) => 0.000764966
+(0, 4) ~ (3, -1) => 0.000720799
+(0, 5) ~ (3, -1) => 0.000475764
+(0, 6) ~ (3, -1) => 0.000415146
+(0, 7) ~ (3, -1) => 0.000428081
+(0, 8) ~ (3, -1) => 0.00068903
+(0, 9) ~ (3, -1) => 0.00104487
+(0, 10) ~ (3, -1) => 0.00174987
+(0, 11) ~ (3, -1) => 0.0027886
+(0, 12) ~ (3, -1) => 0.0036633
+(0, 13) ~ (3, -1) => 0.00448018
+(0, 14) ~ (3, -1) => 0.00652683
+(0, 15) ~ (3, -1) => 0.0116414
+(0, 16) ~ (3, -1) => 0.0235071
+(0, 17) ~ (3, -1) => 0.0712631
+(0, 18) ~ (3, -1) => 0.0971687
+(0, 19) ~ (3, -1) => 0.19567
+(0, 20) ~ (3, -1) => 0.092008
+(0, 21) ~ (3, -1) => 0.0632803
+(0, 22) ~ (3, -1) => 0.0655384
+(0, 23) ~ (3, -1) => 0.0482949
+(0, 24) ~ (3, -1) => 0.0875526
+(0, 25) ~ (3, -1) => 0.351522
+(0, 26) ~ (3, -1) => 0.190204
+(0, 27) ~ (3, -1) => 0.0449275
+(0, 28) ~ (3, -1) => 0.0226006
+(0, 29) ~ (3, -1) => 0.0143671
+(0, 30) ~ (3, -1) => 0.0160044
+(0, 31) ~ (3, -1) => 0.0344054
+(0, 32) ~ (3, -1) => 0.0464087
+(0, 33) ~ (3, -1) => 0.0865594
+(0, 34) ~ (3, -1) => 0.0991687
+(0, 35) ~ (3, -1) => 0.111979
+(0, 36) ~ (3, -1) => 0.210174
+(0, 37) ~ (3, -1) => 0.206701
+(0, 38) ~ (3, -1) => 0.230477
+(0, 39) ~ (3, -1) => 0.222917
+(0, 40) ~ (3, -1) => 0.206632
+(0, 41) ~ (3, -1) => 0.188877
+(0, 42) ~ (3, -1) => 0.346598
+(0, 43) ~ (3, -1) => 0.505021
+(0, 44) ~ (3, -1) => 0.528176
+(0, 45) ~ (3, -1) => 0.34874
+(0, 46) ~ (3, -1) => 0.19363
+(0, 47) ~ (3, -1) => 0.0766014
+(0, 48) ~ (3, -1) => 0.0872151
+(0, 49) ~ (3, -1) => 0.0576887
+(0, 50) ~ (3, -1) => 0.0462513
+(0, 51) ~ (3, -1) => 0.0504838
+(0, 52) ~ (3, -1) => 0.0309421
+(0, 53) ~ (3, -1) => 0.0239515
+(0, 54) ~ (3, -1) => 0.0120769
+(0, 55) ~ (3, -1) => 0.00904036
+(0, 56) ~ (3, -1) => 0.00695324
+(0, 57) ~ (3, -1) => 0.00611335
+(0, 58) ~ (3, -1) => 0.00666398
+(0, 59) ~ (3, -1) => 0.00447881
+(0, 60) ~ (3, -1) => 0.01261
+(0, 61) ~ (3, -1) => 0.00615257
+(0, 62) ~ (3, -1) => 0.00347233
+(0, 63) ~ (3, -1) => 0.0029515
+(0, 64) ~ (3, -1) => 0.00285226
+(0, 65) ~ (3, -1) => 0.00183558
+(0, 66) ~ (3, -1) => 0.00145894
+(0, 67) ~ (3, -1) => 0.00218451
+(0, 68) ~ (3, -1) => 0.00228107
+(0, 69) ~ (3, -1) => 0.0019049
+(0, 70) ~ (3, -1) => 0.00151461
+(0, 71) ~ (3, -1) => 0.00127912
+(0, 72) ~ (3, -1) => 0.00120163
+
+(0, -1) ~ (3, 0) => 0.000132024
+(0, -1) ~ (3, 1) => 0.000445604
+(0, -1) ~ (3, 2) => 0.00066638
+(0, -1) ~ (3, 3) => 0.000764966
+(0, -1) ~ (3, 4) => 0.000720799
+(0, -1) ~ (3, 5) => 0.000475764
+(0, -1) ~ (3, 6) => 0.000415146
+(0, -1) ~ (3, 7) => 0.000428081
+(0, -1) ~ (3, 8) => 0.00068903
+(0, -1) ~ (3, 9) => 0.00104487
+(0, -1) ~ (3, 10) => 0.00174987
+(0, -1) ~ (3, 11) => 0.0027886
+(0, -1) ~ (3, 12) => 0.0036633
+(0, -1) ~ (3, 13) => 0.00448018
+(0, -1) ~ (3, 14) => 0.00652683
+(0, -1) ~ (3, 15) => 0.0116414
+(0, -1) ~ (3, 16) => 0.0235071
+(0, -1) ~ (3, 17) => 0.0132422
+(0, -1) ~ (3, 18) => 0.0251746
+(0, -1) ~ (3, 19) => 0.0151578
+(0, -1) ~ (3, 20) => 0.0175357
+(0, -1) ~ (3, 21) => 0.0301902
+(0, -1) ~ (3, 22) => 0.0413084
+(0, -1) ~ (3, 23) => 0.0369834
+(0, -1) ~ (3, 24) => 0.0452749
+(0, -1) ~ (3, 25) => 0.116903
+(0, -1) ~ (3, 26) => 0.0334428
+(0, -1) ~ (3, 27) => 0.0110505
+(0, -1) ~ (3, 28) => 0.00947493
+(0, -1) ~ (3, 29) => 0.00960221
+(0, -1) ~ (3, 30) => 0.0131282
+(0, -1) ~ (3, 31) => 0.0239097
+(0, -1) ~ (3, 32) => 0.0312681
+(0, -1) ~ (3, 33) => 0.0449728
+(0, -1) ~ (3, 34) => 0.050374
+(0, -1) ~ (3, 35) => 0.0333168
+(0, -1) ~ (3, 36) => 0.0375886
+(0, -1) ~ (3, 37) => 0.0356192
+(0, -1) ~ (3, 38) => 0.0443555
+(0, -1) ~ (3, 39) => 0.0761793
+(0, -1) ~ (3, 40) => 0.0808852
+(0, -1) ~ (3, 41) => 0.0630895
+(0, -1) ~ (3, 42) => 0.0690095
+(0, -1) ~ (3, 43) => 0.0530418
+(0, -1) ~ (3, 44) => 0.0535947
+(0, -1) ~ (3, 45) => 0.0527511
+(0, -1) ~ (3, 46) => 0.0636786
+(0, -1) ~ (3, 47) => 0.0297743
+(0, -1) ~ (3, 48) => 0.0173768
+(0, -1) ~ (3, 49) => 0.00539852
+(0, -1) ~ (3, 50) => 0.0101885
+(0, -1) ~ (3, 51) => 0.0102101
+(0, -1) ~ (3, 52) => 0.00524251
+(0, -1) ~ (3, 53) => 0.00481516
+(0, -1) ~ (3, 54) => 0.00749309
+(0, -1) ~ (3, 55) => 0.0227253
+(0, -1) ~ (3, 56) => 0.01261
+(0, -1) ~ (3, 57) => 0.00615257
+(0, -1) ~ (3, 58) => 0.00347233
+(0, -1) ~ (3, 59) => 0.0029515
+(0, -1) ~ (3, 60) => 0.00285226
+(0, -1) ~ (3, 61) => 0.00183558
+(0, -1) ~ (3, 62) => 0.00145894
+(0, -1) ~ (3, 63) => 0.00218451
+(0, -1) ~ (3, 64) => 0.00228107
+(0, -1) ~ (3, 65) => 0.0019049
+(0, -1) ~ (3, 66) => 0.00151461
+(0, -1) ~ (3, 67) => 0.00127912
+(0, -1) ~ (3, 68) => 0.00120163
+
+; Sparse posterior probability matrix for sequences 0 and 4
+; Format is:
+;   (0, position_1) ~ (4, position_2) => prob
+; which means that (0, position_1) is aligned to (4, position_2) with probability prob.
+;   (0, position_1) ~ (4, -1) => prob
+; means that (0, position_1) is aligned to a gap in 4 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(0, 0) ~ (4, 0) => 0.999514
+(0, 1) ~ (4, 1) => 0.998516
+(0, 2) ~ (4, 2) => 0.997281
+(0, 3) ~ (4, 3) => 0.995841
+(0, 4) ~ (4, 4) => 0.994201
+(0, 5) ~ (4, 5) => 0.993769
+(0, 6) ~ (4, 6) => 0.993297
+(0, 7) ~ (4, 7) => 0.992672
+(0, 8) ~ (4, 8) => 0.992009
+(0, 9) ~ (4, 9) => 0.990084
+(0, 10) ~ (4, 10) => 0.985447
+(0, 11) ~ (4, 11) => 0.98106
+(0, 12) ~ (4, 12) => 0.975757
+(0, 13) ~ (4, 13) => 0.958052
+(0, 14) ~ (4, 14) => 0.93861
+(0, 14) ~ (4, 15) => 0.0147639
+(0, 15) ~ (4, 14) => 0.0126409
+(0, 15) ~ (4, 15) => 0.912625
+(0, 15) ~ (4, 16) => 0.0257896
+(0, 16) ~ (4, 15) => 0.0185846
+(0, 16) ~ (4, 16) => 0.894391
+(0, 16) ~ (4, 17) => 0.0308256
+(0, 17) ~ (4, 16) => 0.0242979
+(0, 17) ~ (4, 17) => 0.857031
+(0, 17) ~ (4, 18) => 0.0570543
+(0, 18) ~ (4, 17) => 0.0281106
+(0, 18) ~ (4, 18) => 0.791574
+(0, 18) ~ (4, 19) => 0.100693
+(0, 19) ~ (4, 18) => 0.0298682
+(0, 19) ~ (4, 19) => 0.728809
+(0, 19) ~ (4, 20) => 0.145172
+(0, 19) ~ (4, 21) => 0.0101754
+(0, 20) ~ (4, 17) => 0.0109799
+(0, 20) ~ (4, 19) => 0.0332834
+(0, 20) ~ (4, 20) => 0.696943
+(0, 20) ~ (4, 21) => 0.166937
+(0, 21) ~ (4, 18) => 0.0174621
+(0, 21) ~ (4, 20) => 0.0345769
+(0, 21) ~ (4, 21) => 0.618242
+(0, 21) ~ (4, 22) => 0.235162
+(0, 22) ~ (4, 19) => 0.0239593
+(0, 22) ~ (4, 20) => 0.0101096
+(0, 22) ~ (4, 21) => 0.0329467
+(0, 22) ~ (4, 22) => 0.588253
+(0, 22) ~ (4, 23) => 0.26687
+(0, 23) ~ (4, 18) => 0.0128343
+(0, 23) ~ (4, 20) => 0.0289404
+(0, 23) ~ (4, 22) => 0.0314561
+(0, 23) ~ (4, 23) => 0.559074
+(0, 23) ~ (4, 24) => 0.298491
+(0, 24) ~ (4, 19) => 0.0182627
+(0, 24) ~ (4, 21) => 0.0336418
+(0, 24) ~ (4, 22) => 0.0110812
+(0, 24) ~ (4, 23) => 0.03092
+(0, 24) ~ (4, 24) => 0.541415
+(0, 24) ~ (4, 25) => 0.315487
+(0, 25) ~ (4, 20) => 0.0202519
+(0, 25) ~ (4, 22) => 0.0331185
+(0, 25) ~ (4, 23) => 0.0107767
+(0, 25) ~ (4, 24) => 0.0274971
+(0, 25) ~ (4, 25) => 0.53752
+(0, 25) ~ (4, 26) => 0.318873
+(0, 26) ~ (4, 21) => 0.0213842
+(0, 26) ~ (4, 23) => 0.0324301
+(0, 26) ~ (4, 25) => 0.0268448
+(0, 26) ~ (4, 26) => 0.536632
+(0, 26) ~ (4, 27) => 0.324565
+(0, 27) ~ (4, 21) => 0.0104048
+(0, 27) ~ (4, 22) => 0.0203407
+(0, 27) ~ (4, 24) => 0.0295516
+(0, 27) ~ (4, 26) => 0.0226638
+(0, 27) ~ (4, 27) => 0.520972
+(0, 27) ~ (4, 28) => 0.343537
+(0, 27) ~ (4, 29) => 0.0114994
+(0, 28) ~ (4, 22) => 0.0129635
+(0, 28) ~ (4, 23) => 0.0188873
+(0, 28) ~ (4, 25) => 0.0278172
+(0, 28) ~ (4, 27) => 0.01552
+(0, 28) ~ (4, 28) => 0.509783
+(0, 28) ~ (4, 29) => 0.368894
+(0, 28) ~ (4, 30) => 0.013488
+(0, 29) ~ (4, 23) => 0.0142972
+(0, 29) ~ (4, 24) => 0.0162591
+(0, 29) ~ (4, 26) => 0.0239518
+(0, 29) ~ (4, 28) => 0.0119455
+(0, 29) ~ (4, 29) => 0.512726
+(0, 29) ~ (4, 30) => 0.379499
+(0, 29) ~ (4, 31) => 0.0141546
+(0, 30) ~ (4, 24) => 0.0152735
+(0, 30) ~ (4, 25) => 0.0153808
+(0, 30) ~ (4, 27) => 0.0193743
+(0, 30) ~ (4, 29) => 0.0113134
+(0, 30) ~ (4, 30) => 0.512265
+(0, 30) ~ (4, 31) => 0.386834
+(0, 30) ~ (4, 32) => 0.0144186
+(0, 31) ~ (4, 25) => 0.0173578
+(0, 31) ~ (4, 26) => 0.0140679
+(0, 31) ~ (4, 28) => 0.0179109
+(0, 31) ~ (4, 31) => 0.508472
+(0, 31) ~ (4, 32) => 0.391715
+(0, 31) ~ (4, 33) => 0.0138223
+(0, 32) ~ (4, 26) => 0.0184863
+(0, 32) ~ (4, 27) => 0.0120909
+(0, 32) ~ (4, 29) => 0.0183136
+(0, 32) ~ (4, 32) => 0.502458
+(0, 32) ~ (4, 33) => 0.394539
+(0, 32) ~ (4, 34) => 0.0129449
+(0, 33) ~ (4, 27) => 0.0195599
+(0, 33) ~ (4, 28) => 0.0118155
+(0, 33) ~ (4, 30) => 0.0179152
+(0, 33) ~ (4, 33) => 0.490753
+(0, 33) ~ (4, 34) => 0.395656
+(0, 33) ~ (4, 35) => 0.0148373
+(0, 34) ~ (4, 28) => 0.0190948
+(0, 34) ~ (4, 29) => 0.0103769
+(0, 34) ~ (4, 31) => 0.0176846
+(0, 34) ~ (4, 34) => 0.476603
+(0, 34) ~ (4, 35) => 0.391058
+(0, 34) ~ (4, 36) => 0.0153786
+(0, 35) ~ (4, 29) => 0.017431
+(0, 35) ~ (4, 30) => 0.0101261
+(0, 35) ~ (4, 31) => 0.010376
+(0, 35) ~ (4, 32) => 0.0197472
+(0, 35) ~ (4, 33) => 0.0131514
+(0, 35) ~ (4, 34) => 0.0105301
+(0, 35) ~ (4, 35) => 0.438519
+(0, 35) ~ (4, 36) => 0.358745
+(0, 35) ~ (4, 37) => 0.0167357
+(0, 36) ~ (4, 30) => 0.0152305
+(0, 36) ~ (4, 31) => 0.010468
+(0, 36) ~ (4, 32) => 0.0126431
+(0, 36) ~ (4, 33) => 0.0209446
+(0, 36) ~ (4, 34) => 0.0195897
+(0, 36) ~ (4, 35) => 0.017062
+(0, 36) ~ (4, 36) => 0.417176
+(0, 36) ~ (4, 37) => 0.332704
+(0, 36) ~ (4, 38) => 0.0170539
+(0, 37) ~ (4, 31) => 0.0117718
+(0, 37) ~ (4, 32) => 0.0112397
+(0, 37) ~ (4, 33) => 0.0166754
+(0, 37) ~ (4, 34) => 0.0198598
+(0, 37) ~ (4, 35) => 0.0477904
+(0, 37) ~ (4, 36) => 0.0281445
+(0, 37) ~ (4, 37) => 0.393131
+(0, 37) ~ (4, 38) => 0.305903
+(0, 37) ~ (4, 39) => 0.0168858
+(0, 38) ~ (4, 33) => 0.0124444
+(0, 38) ~ (4, 34) => 0.0182892
+(0, 38) ~ (4, 35) => 0.023384
+(0, 38) ~ (4, 36) => 0.0950097
+(0, 38) ~ (4, 37) => 0.0361916
+(0, 38) ~ (4, 38) => 0.367469
+(0, 38) ~ (4, 39) => 0.278029
+(0, 38) ~ (4, 40) => 0.0157316
+(0, 39) ~ (4, 34) => 0.0124835
+(0, 39) ~ (4, 35) => 0.01799
+(0, 39) ~ (4, 36) => 0.0214553
+(0, 39) ~ (4, 37) => 0.141615
+(0, 39) ~ (4, 38) => 0.0441001
+(0, 39) ~ (4, 39) => 0.342546
+(0, 39) ~ (4, 40) => 0.245489
+(0, 39) ~ (4, 41) => 0.0134022
+(0, 40) ~ (4, 35) => 0.0115237
+(0, 40) ~ (4, 36) => 0.0147978
+(0, 40) ~ (4, 37) => 0.0191242
+(0, 40) ~ (4, 38) => 0.194733
+(0, 40) ~ (4, 39) => 0.0516583
+(0, 40) ~ (4, 40) => 0.312011
+(0, 40) ~ (4, 41) => 0.211869
+(0, 40) ~ (4, 42) => 0.0108932
+(0, 41) ~ (4, 37) => 0.0114752
+(0, 41) ~ (4, 38) => 0.0164653
+(0, 41) ~ (4, 39) => 0.252944
+(0, 41) ~ (4, 40) => 0.0575781
+(0, 41) ~ (4, 41) => 0.280072
+(0, 41) ~ (4, 42) => 0.180025
+(0, 42) ~ (4, 39) => 0.0135825
+(0, 42) ~ (4, 40) => 0.325667
+(0, 42) ~ (4, 41) => 0.0643341
+(0, 42) ~ (4, 42) => 0.256768
+(0, 42) ~ (4, 43) => 0.154878
+(0, 43) ~ (4, 40) => 0.0123884
+(0, 43) ~ (4, 41) => 0.394095
+(0, 43) ~ (4, 42) => 0.0690658
+(0, 43) ~ (4, 43) => 0.232745
+(0, 43) ~ (4, 44) => 0.130116
+(0, 44) ~ (4, 41) => 0.0106287
+(0, 44) ~ (4, 42) => 0.452426
+(0, 44) ~ (4, 43) => 0.0709358
+(0, 44) ~ (4, 44) => 0.206051
+(0, 44) ~ (4, 45) => 0.0984956
+(0, 45) ~ (4, 43) => 0.507375
+(0, 45) ~ (4, 44) => 0.0718677
+(0, 45) ~ (4, 45) => 0.172093
+(0, 45) ~ (4, 46) => 0.0927931
+(0, 46) ~ (4, 44) => 0.564698
+(0, 46) ~ (4, 45) => 0.0694848
+(0, 46) ~ (4, 46) => 0.166909
+(0, 46) ~ (4, 47) => 0.0913847
+(0, 47) ~ (4, 45) => 0.637546
+(0, 47) ~ (4, 46) => 0.0648203
+(0, 47) ~ (4, 47) => 0.153889
+(0, 47) ~ (4, 48) => 0.0820016
+(0, 48) ~ (4, 46) => 0.654355
+(0, 48) ~ (4, 47) => 0.0454965
+(0, 48) ~ (4, 48) => 0.0825864
+(0, 48) ~ (4, 49) => 0.0714093
+(0, 49) ~ (4, 47) => 0.689994
+(0, 49) ~ (4, 48) => 0.0132113
+(0, 49) ~ (4, 49) => 0.0595504
+(0, 49) ~ (4, 50) => 0.0713961
+(0, 50) ~ (4, 48) => 0.806874
+(0, 50) ~ (4, 50) => 0.0355284
+(0, 50) ~ (4, 51) => 0.0704155
+(0, 51) ~ (4, 49) => 0.849007
+(0, 51) ~ (4, 51) => 0.0251387
+(0, 51) ~ (4, 52) => 0.0660731
+(0, 52) ~ (4, 50) => 0.876333
+(0, 52) ~ (4, 52) => 0.0229833
+(0, 52) ~ (4, 53) => 0.0447138
+(0, 53) ~ (4, 51) => 0.89111
+(0, 53) ~ (4, 54) => 0.0355685
+(0, 54) ~ (4, 52) => 0.898423
+(0, 54) ~ (4, 55) => 0.0284183
+(0, 55) ~ (4, 53) => 0.934729
+(0, 55) ~ (4, 56) => 0.0228447
+(0, 56) ~ (4, 54) => 0.949109
+(0, 56) ~ (4, 57) => 0.0111105
+(0, 57) ~ (4, 55) => 0.959562
+(0, 58) ~ (4, 56) => 0.965689
+(0, 59) ~ (4, 57) => 0.978606
+(0, 60) ~ (4, 58) => 0.985098
+(0, 61) ~ (4, 59) => 0.988442
+(0, 62) ~ (4, 60) => 0.990037
+(0, 63) ~ (4, 61) => 0.990973
+(0, 64) ~ (4, 62) => 0.994206
+(0, 65) ~ (4, 63) => 0.996555
+(0, 66) ~ (4, 64) => 0.997557
+(0, 67) ~ (4, 65) => 0.997882
+(0, 68) ~ (4, 66) => 0.99823
+(0, 69) ~ (4, 67) => 0.998604
+(0, 70) ~ (4, 68) => 0.999028
+(0, 71) ~ (4, 69) => 0.999454
+(0, 72) ~ (4, 70) => 0.999603
+
+; gap posteriors
+(0, 0) ~ (4, -1) => 0.000485778
+(0, 1) ~ (4, -1) => 0.00148392
+(0, 2) ~ (4, -1) => 0.00271869
+(0, 3) ~ (4, -1) => 0.00415862
+(0, 4) ~ (4, -1) => 0.0057987
+(0, 5) ~ (4, -1) => 0.00623131
+(0, 6) ~ (4, -1) => 0.00670302
+(0, 7) ~ (4, -1) => 0.00732833
+(0, 8) ~ (4, -1) => 0.00799137
+(0, 9) ~ (4, -1) => 0.00991583
+(0, 10) ~ (4, -1) => 0.0145533
+(0, 11) ~ (4, -1) => 0.0189404
+(0, 12) ~ (4, -1) => 0.0242434
+(0, 13) ~ (4, -1) => 0.0419483
+(0, 14) ~ (4, -1) => 0.0466256
+(0, 15) ~ (4, -1) => 0.0489447
+(0, 16) ~ (4, -1) => 0.0561989
+(0, 17) ~ (4, -1) => 0.0616167
+(0, 18) ~ (4, -1) => 0.0796226
+(0, 19) ~ (4, -1) => 0.0859755
+(0, 20) ~ (4, -1) => 0.0918564
+(0, 21) ~ (4, -1) => 0.0945573
+(0, 22) ~ (4, -1) => 0.0778609
+(0, 23) ~ (4, -1) => 0.0692046
+(0, 24) ~ (4, -1) => 0.0491916
+(0, 25) ~ (4, -1) => 0.0519622
+(0, 26) ~ (4, -1) => 0.0581443
+(0, 27) ~ (4, -1) => 0.0410307
+(0, 28) ~ (4, -1) => 0.0326463
+(0, 29) ~ (4, -1) => 0.0271674
+(0, 30) ~ (4, -1) => 0.0251403
+(0, 31) ~ (4, -1) => 0.0366544
+(0, 32) ~ (4, -1) => 0.0411676
+(0, 33) ~ (4, -1) => 0.0494631
+(0, 34) ~ (4, -1) => 0.0698045
+(0, 35) ~ (4, -1) => 0.104638
+(0, 36) ~ (4, -1) => 0.137128
+(0, 37) ~ (4, -1) => 0.148598
+(0, 38) ~ (4, -1) => 0.153452
+(0, 39) ~ (4, -1) => 0.160919
+(0, 40) ~ (4, -1) => 0.173389
+(0, 41) ~ (4, -1) => 0.20144
+(0, 42) ~ (4, -1) => 0.18477
+(0, 43) ~ (4, -1) => 0.161589
+(0, 44) ~ (4, -1) => 0.161462
+(0, 45) ~ (4, -1) => 0.155872
+(0, 46) ~ (4, -1) => 0.107523
+(0, 47) ~ (4, -1) => 0.0617432
+(0, 48) ~ (4, -1) => 0.146152
+(0, 49) ~ (4, -1) => 0.165848
+(0, 50) ~ (4, -1) => 0.0871824
+(0, 51) ~ (4, -1) => 0.0597811
+(0, 52) ~ (4, -1) => 0.0559696
+(0, 53) ~ (4, -1) => 0.0733211
+(0, 54) ~ (4, -1) => 0.0731589
+(0, 55) ~ (4, -1) => 0.0424263
+(0, 56) ~ (4, -1) => 0.03978
+(0, 57) ~ (4, -1) => 0.0404378
+(0, 58) ~ (4, -1) => 0.0343113
+(0, 59) ~ (4, -1) => 0.0213943
+(0, 60) ~ (4, -1) => 0.0149022
+(0, 61) ~ (4, -1) => 0.011558
+(0, 62) ~ (4, -1) => 0.00996262
+(0, 63) ~ (4, -1) => 0.00902694
+(0, 64) ~ (4, -1) => 0.00579423
+(0, 65) ~ (4, -1) => 0.00344515
+(0, 66) ~ (4, -1) => 0.00244266
+(0, 67) ~ (4, -1) => 0.00211805
+(0, 68) ~ (4, -1) => 0.00176966
+(0, 69) ~ (4, -1) => 0.00139618
+(0, 70) ~ (4, -1) => 0.00097239
+(0, 71) ~ (4, -1) => 0.000545561
+(0, 72) ~ (4, -1) => 0.000396788
+
+(0, -1) ~ (4, 0) => 0.000485778
+(0, -1) ~ (4, 1) => 0.00148392
+(0, -1) ~ (4, 2) => 0.00271869
+(0, -1) ~ (4, 3) => 0.00415862
+(0, -1) ~ (4, 4) => 0.0057987
+(0, -1) ~ (4, 5) => 0.00623131
+(0, -1) ~ (4, 6) => 0.00670302
+(0, -1) ~ (4, 7) => 0.00732833
+(0, -1) ~ (4, 8) => 0.00799137
+(0, -1) ~ (4, 9) => 0.00991583
+(0, -1) ~ (4, 10) => 0.0145533
+(0, -1) ~ (4, 11) => 0.0189404
+(0, -1) ~ (4, 12) => 0.0242434
+(0, -1) ~ (4, 13) => 0.0419483
+(0, -1) ~ (4, 14) => 0.0487487
+(0, -1) ~ (4, 15) => 0.0540268
+(0, -1) ~ (4, 16) => 0.0555215
+(0, -1) ~ (4, 17) => 0.0730528
+(0, -1) ~ (4, 18) => 0.0912071
+(0, -1) ~ (4, 19) => 0.0949929
+(0, -1) ~ (4, 20) => 0.0640061
+(0, -1) ~ (4, 21) => 0.106268
+(0, -1) ~ (4, 22) => 0.0676255
+(0, -1) ~ (4, 23) => 0.0667446
+(0, -1) ~ (4, 24) => 0.0715125
+(0, -1) ~ (4, 25) => 0.0595916
+(0, -1) ~ (4, 26) => 0.0653252
+(0, -1) ~ (4, 27) => 0.087918
+(0, -1) ~ (4, 28) => 0.085913
+(0, -1) ~ (4, 29) => 0.0494456
+(0, -1) ~ (4, 30) => 0.0514761
+(0, -1) ~ (4, 31) => 0.040239
+(0, -1) ~ (4, 32) => 0.0477791
+(0, -1) ~ (4, 33) => 0.0376703
+(0, -1) ~ (4, 34) => 0.0340439
+(0, -1) ~ (4, 35) => 0.0378354
+(0, -1) ~ (4, 36) => 0.0492928
+(0, -1) ~ (4, 37) => 0.0490222
+(0, -1) ~ (4, 38) => 0.0542755
+(0, -1) ~ (4, 39) => 0.0443546
+(0, -1) ~ (4, 40) => 0.0311347
+(0, -1) ~ (4, 41) => 0.0255986
+(0, -1) ~ (4, 42) => 0.0308209
+(0, -1) ~ (4, 43) => 0.0340663
+(0, -1) ~ (4, 44) => 0.0272668
+(0, -1) ~ (4, 45) => 0.0223807
+(0, -1) ~ (4, 46) => 0.021122
+(0, -1) ~ (4, 47) => 0.0192357
+(0, -1) ~ (4, 48) => 0.015327
+(0, -1) ~ (4, 49) => 0.0200332
+(0, -1) ~ (4, 50) => 0.0167421
+(0, -1) ~ (4, 51) => 0.0133354
+(0, -1) ~ (4, 52) => 0.0125208
+(0, -1) ~ (4, 53) => 0.0205573
+(0, -1) ~ (4, 54) => 0.015322
+(0, -1) ~ (4, 55) => 0.0120195
+(0, -1) ~ (4, 56) => 0.0114666
+(0, -1) ~ (4, 57) => 0.0102838
+(0, -1) ~ (4, 58) => 0.0149022
+(0, -1) ~ (4, 59) => 0.011558
+(0, -1) ~ (4, 60) => 0.00996262
+(0, -1) ~ (4, 61) => 0.00902694
+(0, -1) ~ (4, 62) => 0.00579423
+(0, -1) ~ (4, 63) => 0.00344515
+(0, -1) ~ (4, 64) => 0.00244266
+(0, -1) ~ (4, 65) => 0.00211805
+(0, -1) ~ (4, 66) => 0.00176966
+(0, -1) ~ (4, 67) => 0.00139618
+(0, -1) ~ (4, 68) => 0.00097239
+(0, -1) ~ (4, 69) => 0.000545561
+(0, -1) ~ (4, 70) => 0.000396788
+
+; Sparse posterior probability matrix for sequences 1 and 2
+; Format is:
+;   (1, position_1) ~ (2, position_2) => prob
+; which means that (1, position_1) is aligned to (2, position_2) with probability prob.
+;   (1, position_1) ~ (2, -1) => prob
+; means that (1, position_1) is aligned to a gap in 2 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (2, 0) => 0.999094
+(1, 1) ~ (2, 1) => 0.997448
+(1, 2) ~ (2, 2) => 0.986767
+(1, 3) ~ (2, 3) => 0.978374
+(1, 4) ~ (2, 4) => 0.972173
+(1, 5) ~ (2, 5) => 0.964819
+(1, 6) ~ (2, 6) => 0.95891
+(1, 7) ~ (2, 7) => 0.955012
+(1, 8) ~ (2, 8) => 0.95247
+(1, 9) ~ (2, 9) => 0.951644
+(1, 10) ~ (2, 10) => 0.943464
+(1, 11) ~ (2, 11) => 0.782914
+(1, 12) ~ (2, 12) => 0.623542
+(1, 13) ~ (2, 10) => 0.0112665
+(1, 13) ~ (2, 13) => 0.565875
+(1, 14) ~ (2, 11) => 0.139013
+(1, 14) ~ (2, 12) => 0.0175483
+(1, 14) ~ (2, 14) => 0.54091
+(1, 15) ~ (2, 12) => 0.268444
+(1, 15) ~ (2, 13) => 0.0187597
+(1, 15) ~ (2, 15) => 0.502274
+(1, 16) ~ (2, 13) => 0.314698
+(1, 16) ~ (2, 14) => 0.0140877
+(1, 16) ~ (2, 16) => 0.460893
+(1, 16) ~ (2, 17) => 0.0108112
+(1, 17) ~ (2, 14) => 0.343784
+(1, 17) ~ (2, 17) => 0.430631
+(1, 18) ~ (2, 15) => 0.366036
+(1, 18) ~ (2, 18) => 0.29449
+(1, 19) ~ (2, 16) => 0.381954
+(1, 19) ~ (2, 19) => 0.163511
+(1, 20) ~ (2, 17) => 0.38833
+(1, 20) ~ (2, 19) => 0.0138335
+(1, 20) ~ (2, 20) => 0.0530408
+(1, 21) ~ (2, 12) => 0.0134113
+(1, 21) ~ (2, 14) => 0.0102321
+(1, 21) ~ (2, 18) => 0.480316
+(1, 21) ~ (2, 20) => 0.0148497
+(1, 21) ~ (2, 21) => 0.0205532
+(1, 22) ~ (2, 13) => 0.0258397
+(1, 22) ~ (2, 15) => 0.0174053
+(1, 22) ~ (2, 16) => 0.0245665
+(1, 22) ~ (2, 19) => 0.57662
+(1, 22) ~ (2, 21) => 0.0182654
+(1, 22) ~ (2, 22) => 0.0182623
+(1, 23) ~ (2, 14) => 0.0349297
+(1, 23) ~ (2, 16) => 0.0145924
+(1, 23) ~ (2, 17) => 0.0414316
+(1, 23) ~ (2, 20) => 0.661132
+(1, 23) ~ (2, 22) => 0.012064
+(1, 23) ~ (2, 23) => 0.0160862
+(1, 24) ~ (2, 15) => 0.0390256
+(1, 24) ~ (2, 17) => 0.0127681
+(1, 24) ~ (2, 18) => 0.050498
+(1, 24) ~ (2, 19) => 0.0149119
+(1, 24) ~ (2, 21) => 0.657612
+(1, 24) ~ (2, 24) => 0.0143432
+(1, 25) ~ (2, 16) => 0.0340814
+(1, 25) ~ (2, 18) => 0.0123949
+(1, 25) ~ (2, 19) => 0.058215
+(1, 25) ~ (2, 20) => 0.0186699
+(1, 25) ~ (2, 22) => 0.58866
+(1, 25) ~ (2, 23) => 0.0109872
+(1, 26) ~ (2, 16) => 0.0135688
+(1, 26) ~ (2, 17) => 0.0333154
+(1, 26) ~ (2, 19) => 0.0111839
+(1, 26) ~ (2, 20) => 0.0655114
+(1, 26) ~ (2, 21) => 0.0272406
+(1, 26) ~ (2, 23) => 0.527228
+(1, 26) ~ (2, 24) => 0.0138852
+(1, 27) ~ (2, 15) => 0.0109047
+(1, 27) ~ (2, 17) => 0.0219079
+(1, 27) ~ (2, 18) => 0.0345236
+(1, 27) ~ (2, 21) => 0.0698108
+(1, 27) ~ (2, 22) => 0.022402
+(1, 27) ~ (2, 24) => 0.459169
+(1, 28) ~ (2, 16) => 0.010307
+(1, 28) ~ (2, 18) => 0.0369566
+(1, 28) ~ (2, 19) => 0.0349588
+(1, 28) ~ (2, 22) => 0.048518
+(1, 28) ~ (2, 23) => 0.0140514
+(1, 28) ~ (2, 25) => 0.11556
+(1, 29) ~ (2, 17) => 0.0110613
+(1, 29) ~ (2, 19) => 0.0530166
+(1, 29) ~ (2, 20) => 0.0350594
+(1, 29) ~ (2, 23) => 0.0263944
+(1, 29) ~ (2, 25) => 0.0119736
+(1, 29) ~ (2, 26) => 0.0670001
+(1, 30) ~ (2, 20) => 0.0739915
+(1, 30) ~ (2, 21) => 0.011643
+(1, 30) ~ (2, 27) => 0.0129328
+(1, 31) ~ (2, 21) => 0.135111
+(1, 31) ~ (2, 22) => 0.0115332
+(1, 31) ~ (2, 23) => 0.011898
+(1, 32) ~ (2, 22) => 0.22652
+(1, 32) ~ (2, 24) => 0.0121469
+(1, 33) ~ (2, 23) => 0.3225
+(1, 33) ~ (2, 25) => 0.0126822
+(1, 34) ~ (2, 24) => 0.449264
+(1, 35) ~ (2, 25) => 0.81488
+(1, 36) ~ (2, 25) => 0.0113769
+(1, 36) ~ (2, 26) => 0.888401
+(1, 37) ~ (2, 26) => 0.0113593
+(1, 37) ~ (2, 27) => 0.939763
+(1, 38) ~ (2, 27) => 0.0152703
+(1, 38) ~ (2, 28) => 0.938306
+(1, 39) ~ (2, 28) => 0.0202989
+(1, 39) ~ (2, 29) => 0.941099
+(1, 40) ~ (2, 29) => 0.0186615
+(1, 40) ~ (2, 30) => 0.947784
+(1, 41) ~ (2, 30) => 0.0164206
+(1, 41) ~ (2, 31) => 0.952835
+(1, 42) ~ (2, 31) => 0.015842
+(1, 42) ~ (2, 32) => 0.952413
+(1, 43) ~ (2, 32) => 0.0129773
+(1, 43) ~ (2, 33) => 0.954789
+(1, 44) ~ (2, 33) => 0.0101037
+(1, 44) ~ (2, 34) => 0.958371
+(1, 45) ~ (2, 35) => 0.959456
+(1, 46) ~ (2, 36) => 0.965329
+(1, 46) ~ (2, 37) => 0.0111856
+(1, 47) ~ (2, 37) => 0.964527
+(1, 47) ~ (2, 38) => 0.015778
+(1, 48) ~ (2, 38) => 0.944404
+(1, 48) ~ (2, 39) => 0.0345369
+(1, 49) ~ (2, 39) => 0.897005
+(1, 49) ~ (2, 40) => 0.0749715
+(1, 50) ~ (2, 40) => 0.831309
+(1, 50) ~ (2, 41) => 0.130936
+(1, 51) ~ (2, 41) => 0.798738
+(1, 51) ~ (2, 42) => 0.154102
+(1, 52) ~ (2, 41) => 0.0132142
+(1, 52) ~ (2, 42) => 0.725309
+(1, 52) ~ (2, 43) => 0.209116
+(1, 53) ~ (2, 42) => 0.0150667
+(1, 53) ~ (2, 43) => 0.655637
+(1, 53) ~ (2, 44) => 0.265498
+(1, 54) ~ (2, 43) => 0.015162
+(1, 54) ~ (2, 44) => 0.589069
+(1, 54) ~ (2, 45) => 0.322512
+(1, 55) ~ (2, 44) => 0.0140719
+(1, 55) ~ (2, 45) => 0.524877
+(1, 55) ~ (2, 46) => 0.380721
+(1, 55) ~ (2, 51) => 0.0100137
+(1, 56) ~ (2, 45) => 0.0137075
+(1, 56) ~ (2, 46) => 0.500871
+(1, 56) ~ (2, 47) => 0.384918
+(1, 56) ~ (2, 52) => 0.0103494
+(1, 57) ~ (2, 45) => 0.0100424
+(1, 57) ~ (2, 46) => 0.0112021
+(1, 57) ~ (2, 47) => 0.509806
+(1, 57) ~ (2, 48) => 0.366433
+(1, 58) ~ (2, 44) => 0.0105319
+(1, 58) ~ (2, 47) => 0.015009
+(1, 58) ~ (2, 48) => 0.536204
+(1, 58) ~ (2, 49) => 0.346334
+(1, 59) ~ (2, 45) => 0.0123206
+(1, 59) ~ (2, 48) => 0.0156557
+(1, 59) ~ (2, 49) => 0.565172
+(1, 59) ~ (2, 50) => 0.324536
+(1, 60) ~ (2, 46) => 0.0144696
+(1, 60) ~ (2, 49) => 0.0164832
+(1, 60) ~ (2, 50) => 0.591594
+(1, 60) ~ (2, 51) => 0.306718
+(1, 61) ~ (2, 47) => 0.0122717
+(1, 61) ~ (2, 50) => 0.0177466
+(1, 61) ~ (2, 51) => 0.616943
+(1, 61) ~ (2, 52) => 0.282094
+(1, 62) ~ (2, 48) => 0.0114546
+(1, 62) ~ (2, 51) => 0.0197631
+(1, 62) ~ (2, 52) => 0.63336
+(1, 62) ~ (2, 53) => 0.260882
+(1, 62) ~ (2, 54) => 0.0103619
+(1, 63) ~ (2, 49) => 0.0104938
+(1, 63) ~ (2, 52) => 0.0170966
+(1, 63) ~ (2, 53) => 0.654907
+(1, 63) ~ (2, 54) => 0.215816
+(1, 63) ~ (2, 55) => 0.0109924
+(1, 64) ~ (2, 50) => 0.0100197
+(1, 64) ~ (2, 53) => 0.0170993
+(1, 64) ~ (2, 54) => 0.703137
+(1, 64) ~ (2, 55) => 0.201086
+(1, 64) ~ (2, 56) => 0.0125242
+(1, 65) ~ (2, 54) => 0.0149272
+(1, 65) ~ (2, 55) => 0.723008
+(1, 65) ~ (2, 56) => 0.181918
+(1, 65) ~ (2, 57) => 0.01143
+(1, 66) ~ (2, 55) => 0.0117348
+(1, 66) ~ (2, 56) => 0.74943
+(1, 66) ~ (2, 57) => 0.137998
+(1, 67) ~ (2, 57) => 0.805113
+(1, 67) ~ (2, 58) => 0.0939498
+(1, 68) ~ (2, 58) => 0.860193
+(1, 68) ~ (2, 59) => 0.0510018
+(1, 69) ~ (2, 59) => 0.918843
+(1, 69) ~ (2, 60) => 0.0142735
+(1, 70) ~ (2, 60) => 0.971603
+(1, 71) ~ (2, 61) => 0.987802
+(1, 72) ~ (2, 62) => 0.989852
+
+; gap posteriors
+(1, 0) ~ (2, -1) => 0.000905573
+(1, 1) ~ (2, -1) => 0.00255185
+(1, 2) ~ (2, -1) => 0.0132332
+(1, 3) ~ (2, -1) => 0.0216258
+(1, 4) ~ (2, -1) => 0.0278274
+(1, 5) ~ (2, -1) => 0.0351809
+(1, 6) ~ (2, -1) => 0.0410896
+(1, 7) ~ (2, -1) => 0.0449879
+(1, 8) ~ (2, -1) => 0.0475303
+(1, 9) ~ (2, -1) => 0.0483561
+(1, 10) ~ (2, -1) => 0.0565364
+(1, 11) ~ (2, -1) => 0.217086
+(1, 12) ~ (2, -1) => 0.376458
+(1, 13) ~ (2, -1) => 0.422859
+(1, 14) ~ (2, -1) => 0.302529
+(1, 15) ~ (2, -1) => 0.210523
+(1, 16) ~ (2, -1) => 0.19951
+(1, 17) ~ (2, -1) => 0.225584
+(1, 18) ~ (2, -1) => 0.339474
+(1, 19) ~ (2, -1) => 0.454535
+(1, 20) ~ (2, -1) => 0.544796
+(1, 21) ~ (2, -1) => 0.460637
+(1, 22) ~ (2, -1) => 0.319041
+(1, 23) ~ (2, -1) => 0.219764
+(1, 24) ~ (2, -1) => 0.210841
+(1, 25) ~ (2, -1) => 0.276991
+(1, 26) ~ (2, -1) => 0.308066
+(1, 27) ~ (2, -1) => 0.381282
+(1, 28) ~ (2, -1) => 0.739648
+(1, 29) ~ (2, -1) => 0.795495
+(1, 30) ~ (2, -1) => 0.901433
+(1, 31) ~ (2, -1) => 0.841457
+(1, 32) ~ (2, -1) => 0.761333
+(1, 33) ~ (2, -1) => 0.664818
+(1, 34) ~ (2, -1) => 0.550736
+(1, 35) ~ (2, -1) => 0.18512
+(1, 36) ~ (2, -1) => 0.100222
+(1, 37) ~ (2, -1) => 0.0488778
+(1, 38) ~ (2, -1) => 0.0464234
+(1, 39) ~ (2, -1) => 0.0386017
+(1, 40) ~ (2, -1) => 0.0335548
+(1, 41) ~ (2, -1) => 0.0307443
+(1, 42) ~ (2, -1) => 0.0317452
+(1, 43) ~ (2, -1) => 0.0322342
+(1, 44) ~ (2, -1) => 0.0315252
+(1, 45) ~ (2, -1) => 0.0405439
+(1, 46) ~ (2, -1) => 0.0234852
+(1, 47) ~ (2, -1) => 0.0196954
+(1, 48) ~ (2, -1) => 0.0210589
+(1, 49) ~ (2, -1) => 0.0280236
+(1, 50) ~ (2, -1) => 0.0377551
+(1, 51) ~ (2, -1) => 0.0471599
+(1, 52) ~ (2, -1) => 0.052361
+(1, 53) ~ (2, -1) => 0.0637985
+(1, 54) ~ (2, -1) => 0.073257
+(1, 55) ~ (2, -1) => 0.0703172
+(1, 56) ~ (2, -1) => 0.0901538
+(1, 57) ~ (2, -1) => 0.102516
+(1, 58) ~ (2, -1) => 0.0919218
+(1, 59) ~ (2, -1) => 0.0823148
+(1, 60) ~ (2, -1) => 0.0707349
+(1, 61) ~ (2, -1) => 0.0709448
+(1, 62) ~ (2, -1) => 0.0641783
+(1, 63) ~ (2, -1) => 0.0906945
+(1, 64) ~ (2, -1) => 0.0561339
+(1, 65) ~ (2, -1) => 0.0687169
+(1, 66) ~ (2, -1) => 0.100837
+(1, 67) ~ (2, -1) => 0.100937
+(1, 68) ~ (2, -1) => 0.0888056
+(1, 69) ~ (2, -1) => 0.0668831
+(1, 70) ~ (2, -1) => 0.0283966
+(1, 71) ~ (2, -1) => 0.0121977
+(1, 72) ~ (2, -1) => 0.0101479
+
+(1, -1) ~ (2, 0) => 0.000905573
+(1, -1) ~ (2, 1) => 0.00255185
+(1, -1) ~ (2, 2) => 0.0132332
+(1, -1) ~ (2, 3) => 0.0216258
+(1, -1) ~ (2, 4) => 0.0278274
+(1, -1) ~ (2, 5) => 0.0351809
+(1, -1) ~ (2, 6) => 0.0410896
+(1, -1) ~ (2, 7) => 0.0449879
+(1, -1) ~ (2, 8) => 0.0475303
+(1, -1) ~ (2, 9) => 0.0483561
+(1, -1) ~ (2, 10) => 0.0452699
+(1, -1) ~ (2, 11) => 0.0780733
+(1, -1) ~ (2, 12) => 0.0770544
+(1, -1) ~ (2, 13) => 0.0748279
+(1, -1) ~ (2, 14) => 0.0560563
+(1, -1) ~ (2, 15) => 0.0643543
+(1, -1) ~ (2, 16) => 0.0600374
+(1, -1) ~ (2, 17) => 0.0497433
+(1, -1) ~ (2, 18) => 0.0908208
+(1, -1) ~ (2, 19) => 0.0737488
+(1, -1) ~ (2, 20) => 0.0777454
+(1, -1) ~ (2, 21) => 0.0597632
+(1, -1) ~ (2, 22) => 0.0720404
+(1, -1) ~ (2, 23) => 0.0708541
+(1, -1) ~ (2, 24) => 0.0511919
+(1, -1) ~ (2, 25) => 0.0335279
+(1, -1) ~ (2, 26) => 0.0332396
+(1, -1) ~ (2, 27) => 0.032034
+(1, -1) ~ (2, 28) => 0.0413947
+(1, -1) ~ (2, 29) => 0.0402391
+(1, -1) ~ (2, 30) => 0.0357957
+(1, -1) ~ (2, 31) => 0.0313229
+(1, -1) ~ (2, 32) => 0.0346099
+(1, -1) ~ (2, 33) => 0.0351078
+(1, -1) ~ (2, 34) => 0.0416289
+(1, -1) ~ (2, 35) => 0.0405439
+(1, -1) ~ (2, 36) => 0.0346707
+(1, -1) ~ (2, 37) => 0.0242878
+(1, -1) ~ (2, 38) => 0.0398179
+(1, -1) ~ (2, 39) => 0.0684582
+(1, -1) ~ (2, 40) => 0.0937197
+(1, -1) ~ (2, 41) => 0.0571113
+(1, -1) ~ (2, 42) => 0.105523
+(1, -1) ~ (2, 43) => 0.120085
+(1, -1) ~ (2, 44) => 0.12083
+(1, -1) ~ (2, 45) => 0.116541
+(1, -1) ~ (2, 46) => 0.0927367
+(1, -1) ~ (2, 47) => 0.077995
+(1, -1) ~ (2, 48) => 0.0702529
+(1, -1) ~ (2, 49) => 0.0615169
+(1, -1) ~ (2, 50) => 0.0561027
+(1, -1) ~ (2, 51) => 0.0465621
+(1, -1) ~ (2, 52) => 0.0571002
+(1, -1) ~ (2, 53) => 0.0671119
+(1, -1) ~ (2, 54) => 0.0557581
+(1, -1) ~ (2, 55) => 0.0531792
+(1, -1) ~ (2, 56) => 0.0561283
+(1, -1) ~ (2, 57) => 0.0454589
+(1, -1) ~ (2, 58) => 0.0458576
+(1, -1) ~ (2, 59) => 0.0301548
+(1, -1) ~ (2, 60) => 0.0141231
+(1, -1) ~ (2, 61) => 0.0121977
+(1, -1) ~ (2, 62) => 0.0101479
+
+; Sparse posterior probability matrix for sequences 1 and 3
+; Format is:
+;   (1, position_1) ~ (3, position_2) => prob
+; which means that (1, position_1) is aligned to (3, position_2) with probability prob.
+;   (1, position_1) ~ (3, -1) => prob
+; means that (1, position_1) is aligned to a gap in 3 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (3, 0) => 0.995396
+(1, 1) ~ (3, 1) => 0.990391
+(1, 2) ~ (3, 2) => 0.985028
+(1, 3) ~ (3, 3) => 0.981486
+(1, 4) ~ (3, 4) => 0.978827
+(1, 5) ~ (3, 5) => 0.97648
+(1, 6) ~ (3, 6) => 0.972703
+(1, 7) ~ (3, 4) => 0.0115628
+(1, 7) ~ (3, 7) => 0.967717
+(1, 8) ~ (3, 5) => 0.0135615
+(1, 8) ~ (3, 8) => 0.959045
+(1, 9) ~ (3, 6) => 0.0163987
+(1, 9) ~ (3, 9) => 0.949696
+(1, 10) ~ (3, 7) => 0.0190044
+(1, 10) ~ (3, 10) => 0.937617
+(1, 10) ~ (3, 11) => 0.0129853
+(1, 11) ~ (3, 8) => 0.0211865
+(1, 11) ~ (3, 11) => 0.910826
+(1, 11) ~ (3, 12) => 0.0157986
+(1, 12) ~ (3, 9) => 0.023134
+(1, 12) ~ (3, 12) => 0.881964
+(1, 12) ~ (3, 13) => 0.0158382
+(1, 13) ~ (3, 10) => 0.0266981
+(1, 13) ~ (3, 12) => 0.0105404
+(1, 13) ~ (3, 13) => 0.844069
+(1, 13) ~ (3, 14) => 0.0148972
+(1, 14) ~ (3, 11) => 0.0439572
+(1, 14) ~ (3, 13) => 0.0126215
+(1, 14) ~ (3, 14) => 0.815765
+(1, 14) ~ (3, 15) => 0.0138622
+(1, 15) ~ (3, 11) => 0.0104431
+(1, 15) ~ (3, 12) => 0.0608694
+(1, 15) ~ (3, 14) => 0.0112314
+(1, 15) ~ (3, 15) => 0.78086
+(1, 15) ~ (3, 16) => 0.0134008
+(1, 16) ~ (3, 12) => 0.0109899
+(1, 16) ~ (3, 13) => 0.0983563
+(1, 16) ~ (3, 15) => 0.0179452
+(1, 16) ~ (3, 16) => 0.739521
+(1, 16) ~ (3, 17) => 0.0113865
+(1, 17) ~ (3, 13) => 0.0104095
+(1, 17) ~ (3, 14) => 0.125531
+(1, 17) ~ (3, 16) => 0.026547
+(1, 17) ~ (3, 17) => 0.703378
+(1, 18) ~ (3, 15) => 0.151156
+(1, 18) ~ (3, 16) => 0.0111796
+(1, 18) ~ (3, 17) => 0.034269
+(1, 18) ~ (3, 18) => 0.629933
+(1, 19) ~ (3, 15) => 0.0108788
+(1, 19) ~ (3, 16) => 0.174132
+(1, 19) ~ (3, 18) => 0.0721763
+(1, 19) ~ (3, 19) => 0.477315
+(1, 19) ~ (3, 21) => 0.0153414
+(1, 20) ~ (3, 16) => 0.01192
+(1, 20) ~ (3, 17) => 0.189344
+(1, 20) ~ (3, 18) => 0.0114817
+(1, 20) ~ (3, 19) => 0.0996167
+(1, 20) ~ (3, 20) => 0.420865
+(1, 20) ~ (3, 22) => 0.0172597
+(1, 21) ~ (3, 17) => 0.0189469
+(1, 21) ~ (3, 18) => 0.20813
+(1, 21) ~ (3, 19) => 0.0268727
+(1, 21) ~ (3, 20) => 0.100019
+(1, 21) ~ (3, 21) => 0.371805
+(1, 21) ~ (3, 22) => 0.0109161
+(1, 21) ~ (3, 23) => 0.0192062
+(1, 22) ~ (3, 18) => 0.0247649
+(1, 22) ~ (3, 19) => 0.301992
+(1, 22) ~ (3, 20) => 0.0263423
+(1, 22) ~ (3, 21) => 0.0976981
+(1, 22) ~ (3, 22) => 0.363576
+(1, 22) ~ (3, 23) => 0.0116817
+(1, 22) ~ (3, 24) => 0.0184189
+(1, 23) ~ (3, 19) => 0.0252746
+(1, 23) ~ (3, 20) => 0.35478
+(1, 23) ~ (3, 21) => 0.0269343
+(1, 23) ~ (3, 22) => 0.0801417
+(1, 23) ~ (3, 23) => 0.359805
+(1, 23) ~ (3, 24) => 0.0124989
+(1, 23) ~ (3, 25) => 0.0163924
+(1, 24) ~ (3, 18) => 0.011919
+(1, 24) ~ (3, 20) => 0.0199273
+(1, 24) ~ (3, 21) => 0.390984
+(1, 24) ~ (3, 22) => 0.038907
+(1, 24) ~ (3, 23) => 0.0517075
+(1, 24) ~ (3, 24) => 0.348992
+(1, 24) ~ (3, 25) => 0.0137934
+(1, 24) ~ (3, 26) => 0.0130414
+(1, 25) ~ (3, 19) => 0.0129538
+(1, 25) ~ (3, 21) => 0.0148458
+(1, 25) ~ (3, 22) => 0.403158
+(1, 25) ~ (3, 23) => 0.0561948
+(1, 25) ~ (3, 24) => 0.0273747
+(1, 25) ~ (3, 25) => 0.329881
+(1, 25) ~ (3, 26) => 0.0169664
+(1, 25) ~ (3, 27) => 0.0105858
+(1, 26) ~ (3, 20) => 0.01294
+(1, 26) ~ (3, 21) => 0.0118539
+(1, 26) ~ (3, 22) => 0.0161972
+(1, 26) ~ (3, 23) => 0.418513
+(1, 26) ~ (3, 24) => 0.0706186
+(1, 26) ~ (3, 25) => 0.0222531
+(1, 26) ~ (3, 26) => 0.311964
+(1, 26) ~ (3, 27) => 0.0183467
+(1, 26) ~ (3, 28) => 0.0103098
+(1, 27) ~ (3, 21) => 0.0131638
+(1, 27) ~ (3, 22) => 0.0118709
+(1, 27) ~ (3, 23) => 0.0183417
+(1, 27) ~ (3, 24) => 0.44009
+(1, 27) ~ (3, 25) => 0.0747324
+(1, 27) ~ (3, 26) => 0.0175087
+(1, 27) ~ (3, 27) => 0.300328
+(1, 27) ~ (3, 28) => 0.0161952
+(1, 28) ~ (3, 22) => 0.0121037
+(1, 28) ~ (3, 23) => 0.0126842
+(1, 28) ~ (3, 24) => 0.0212302
+(1, 28) ~ (3, 25) => 0.445472
+(1, 28) ~ (3, 26) => 0.0814102
+(1, 28) ~ (3, 27) => 0.0138388
+(1, 28) ~ (3, 28) => 0.267678
+(1, 29) ~ (3, 23) => 0.0111073
+(1, 29) ~ (3, 24) => 0.012566
+(1, 29) ~ (3, 25) => 0.0339763
+(1, 29) ~ (3, 26) => 0.453241
+(1, 29) ~ (3, 27) => 0.085766
+(1, 29) ~ (3, 28) => 0.0147963
+(1, 29) ~ (3, 29) => 0.25958
+(1, 30) ~ (3, 25) => 0.0125012
+(1, 30) ~ (3, 26) => 0.041281
+(1, 30) ~ (3, 27) => 0.450709
+(1, 30) ~ (3, 28) => 0.0867804
+(1, 30) ~ (3, 29) => 0.0116203
+(1, 30) ~ (3, 30) => 0.252879
+(1, 31) ~ (3, 26) => 0.0113047
+(1, 31) ~ (3, 27) => 0.0465356
+(1, 31) ~ (3, 28) => 0.47938
+(1, 31) ~ (3, 29) => 0.0979211
+(1, 31) ~ (3, 30) => 0.0128137
+(1, 31) ~ (3, 31) => 0.256682
+(1, 32) ~ (3, 26) => 0.0108535
+(1, 32) ~ (3, 27) => 0.0139025
+(1, 32) ~ (3, 28) => 0.0458842
+(1, 32) ~ (3, 29) => 0.486734
+(1, 32) ~ (3, 30) => 0.103579
+(1, 32) ~ (3, 31) => 0.0112588
+(1, 32) ~ (3, 32) => 0.257243
+(1, 33) ~ (3, 27) => 0.0166269
+(1, 33) ~ (3, 28) => 0.0141723
+(1, 33) ~ (3, 29) => 0.04278
+(1, 33) ~ (3, 30) => 0.489511
+(1, 33) ~ (3, 31) => 0.103811
+(1, 33) ~ (3, 33) => 0.254368
+(1, 34) ~ (3, 28) => 0.0219532
+(1, 34) ~ (3, 29) => 0.0143756
+(1, 34) ~ (3, 30) => 0.03998
+(1, 34) ~ (3, 31) => 0.492067
+(1, 34) ~ (3, 32) => 0.105331
+(1, 34) ~ (3, 34) => 0.246016
+(1, 35) ~ (3, 29) => 0.0255324
+(1, 35) ~ (3, 30) => 0.0135853
+(1, 35) ~ (3, 31) => 0.0350078
+(1, 35) ~ (3, 32) => 0.4903
+(1, 35) ~ (3, 33) => 0.0987823
+(1, 35) ~ (3, 34) => 0.0161749
+(1, 35) ~ (3, 35) => 0.235413
+(1, 36) ~ (3, 30) => 0.0296384
+(1, 36) ~ (3, 31) => 0.010736
+(1, 36) ~ (3, 32) => 0.0177727
+(1, 36) ~ (3, 33) => 0.52432
+(1, 36) ~ (3, 34) => 0.0860192
+(1, 36) ~ (3, 35) => 0.0234103
+(1, 36) ~ (3, 36) => 0.212867
+(1, 37) ~ (3, 31) => 0.034319
+(1, 37) ~ (3, 33) => 0.0167545
+(1, 37) ~ (3, 34) => 0.543198
+(1, 37) ~ (3, 35) => 0.0778639
+(1, 37) ~ (3, 36) => 0.0273952
+(1, 37) ~ (3, 37) => 0.196289
+(1, 38) ~ (3, 32) => 0.0377224
+(1, 38) ~ (3, 34) => 0.0174039
+(1, 38) ~ (3, 35) => 0.555875
+(1, 38) ~ (3, 36) => 0.0659105
+(1, 38) ~ (3, 37) => 0.0275898
+(1, 38) ~ (3, 38) => 0.177806
+(1, 38) ~ (3, 39) => 0.0101026
+(1, 39) ~ (3, 33) => 0.0394619
+(1, 39) ~ (3, 35) => 0.0129644
+(1, 39) ~ (3, 36) => 0.594134
+(1, 39) ~ (3, 37) => 0.0510767
+(1, 39) ~ (3, 38) => 0.0271276
+(1, 39) ~ (3, 39) => 0.175218
+(1, 39) ~ (3, 40) => 0.0109782
+(1, 40) ~ (3, 34) => 0.0419389
+(1, 40) ~ (3, 36) => 0.0112319
+(1, 40) ~ (3, 37) => 0.62399
+(1, 40) ~ (3, 38) => 0.0328705
+(1, 40) ~ (3, 39) => 0.0265368
+(1, 40) ~ (3, 40) => 0.169942
+(1, 40) ~ (3, 41) => 0.0114618
+(1, 41) ~ (3, 35) => 0.0430015
+(1, 41) ~ (3, 38) => 0.660358
+(1, 41) ~ (3, 39) => 0.0296371
+(1, 41) ~ (3, 40) => 0.0233448
+(1, 41) ~ (3, 41) => 0.161792
+(1, 41) ~ (3, 42) => 0.0149258
+(1, 42) ~ (3, 36) => 0.0428936
+(1, 42) ~ (3, 39) => 0.669817
+(1, 42) ~ (3, 40) => 0.0264389
+(1, 42) ~ (3, 41) => 0.0214453
+(1, 42) ~ (3, 42) => 0.149187
+(1, 42) ~ (3, 43) => 0.0175046
+(1, 43) ~ (3, 37) => 0.0431126
+(1, 43) ~ (3, 40) => 0.682826
+(1, 43) ~ (3, 41) => 0.0247335
+(1, 43) ~ (3, 42) => 0.0168342
+(1, 43) ~ (3, 43) => 0.12862
+(1, 43) ~ (3, 44) => 0.0206483
+(1, 44) ~ (3, 38) => 0.0433083
+(1, 44) ~ (3, 41) => 0.691843
+(1, 44) ~ (3, 42) => 0.0244189
+(1, 44) ~ (3, 43) => 0.0125934
+(1, 44) ~ (3, 44) => 0.101424
+(1, 44) ~ (3, 45) => 0.02514
+(1, 45) ~ (3, 39) => 0.0423174
+(1, 45) ~ (3, 42) => 0.704015
+(1, 45) ~ (3, 43) => 0.0230706
+(1, 45) ~ (3, 44) => 0.0153593
+(1, 45) ~ (3, 45) => 0.096491
+(1, 45) ~ (3, 46) => 0.0253639
+(1, 46) ~ (3, 40) => 0.040037
+(1, 46) ~ (3, 43) => 0.725074
+(1, 46) ~ (3, 44) => 0.0185435
+(1, 46) ~ (3, 45) => 0.0139109
+(1, 46) ~ (3, 46) => 0.0932612
+(1, 46) ~ (3, 47) => 0.0240035
+(1, 47) ~ (3, 41) => 0.0358536
+(1, 47) ~ (3, 44) => 0.742786
+(1, 47) ~ (3, 45) => 0.01195
+(1, 47) ~ (3, 46) => 0.0152377
+(1, 47) ~ (3, 47) => 0.0851979
+(1, 47) ~ (3, 48) => 0.0262604
+(1, 48) ~ (3, 42) => 0.0328576
+(1, 48) ~ (3, 43) => 0.0135657
+(1, 48) ~ (3, 45) => 0.746086
+(1, 48) ~ (3, 47) => 0.0133431
+(1, 48) ~ (3, 48) => 0.0797635
+(1, 48) ~ (3, 49) => 0.0294528
+(1, 49) ~ (3, 43) => 0.0280398
+(1, 49) ~ (3, 44) => 0.019162
+(1, 49) ~ (3, 45) => 0.0162065
+(1, 49) ~ (3, 46) => 0.734722
+(1, 49) ~ (3, 49) => 0.0725957
+(1, 49) ~ (3, 50) => 0.0333288
+(1, 50) ~ (3, 44) => 0.0163408
+(1, 50) ~ (3, 45) => 0.0248054
+(1, 50) ~ (3, 46) => 0.0400117
+(1, 50) ~ (3, 47) => 0.669056
+(1, 50) ~ (3, 50) => 0.0639796
+(1, 50) ~ (3, 51) => 0.0362032
+(1, 51) ~ (3, 45) => 0.0105474
+(1, 51) ~ (3, 46) => 0.0199165
+(1, 51) ~ (3, 47) => 0.127149
+(1, 51) ~ (3, 48) => 0.600043
+(1, 51) ~ (3, 51) => 0.0578059
+(1, 51) ~ (3, 52) => 0.0382132
+(1, 52) ~ (3, 47) => 0.0288882
+(1, 52) ~ (3, 48) => 0.20295
+(1, 52) ~ (3, 49) => 0.518334
+(1, 52) ~ (3, 52) => 0.048736
+(1, 52) ~ (3, 53) => 0.0391005
+(1, 53) ~ (3, 48) => 0.0341356
+(1, 53) ~ (3, 49) => 0.271832
+(1, 53) ~ (3, 50) => 0.462479
+(1, 53) ~ (3, 53) => 0.0339093
+(1, 53) ~ (3, 54) => 0.038158
+(1, 54) ~ (3, 49) => 0.0551342
+(1, 54) ~ (3, 50) => 0.318716
+(1, 54) ~ (3, 51) => 0.403304
+(1, 54) ~ (3, 52) => 0.0130531
+(1, 54) ~ (3, 53) => 0.0116799
+(1, 54) ~ (3, 54) => 0.0279478
+(1, 54) ~ (3, 55) => 0.0343756
+(1, 55) ~ (3, 50) => 0.0696785
+(1, 55) ~ (3, 51) => 0.362204
+(1, 55) ~ (3, 52) => 0.37353
+(1, 55) ~ (3, 53) => 0.0220372
+(1, 55) ~ (3, 54) => 0.0161689
+(1, 55) ~ (3, 55) => 0.0183638
+(1, 55) ~ (3, 56) => 0.0334753
+(1, 56) ~ (3, 51) => 0.0805352
+(1, 56) ~ (3, 52) => 0.391937
+(1, 56) ~ (3, 53) => 0.356031
+(1, 56) ~ (3, 54) => 0.0284829
+(1, 56) ~ (3, 55) => 0.0183179
+(1, 56) ~ (3, 57) => 0.0311126
+(1, 57) ~ (3, 52) => 0.082601
+(1, 57) ~ (3, 53) => 0.409511
+(1, 57) ~ (3, 54) => 0.320715
+(1, 57) ~ (3, 55) => 0.0370158
+(1, 57) ~ (3, 56) => 0.0157029
+(1, 57) ~ (3, 58) => 0.0290831
+(1, 58) ~ (3, 53) => 0.0836298
+(1, 58) ~ (3, 54) => 0.424384
+(1, 58) ~ (3, 55) => 0.318713
+(1, 58) ~ (3, 56) => 0.0398674
+(1, 58) ~ (3, 57) => 0.0186446
+(1, 58) ~ (3, 59) => 0.0258257
+(1, 59) ~ (3, 54) => 0.0994068
+(1, 59) ~ (3, 55) => 0.41132
+(1, 59) ~ (3, 56) => 0.334235
+(1, 59) ~ (3, 57) => 0.0396993
+(1, 59) ~ (3, 58) => 0.019212
+(1, 59) ~ (3, 60) => 0.0210773
+(1, 60) ~ (3, 55) => 0.103516
+(1, 60) ~ (3, 56) => 0.414033
+(1, 60) ~ (3, 57) => 0.341186
+(1, 60) ~ (3, 58) => 0.0363834
+(1, 60) ~ (3, 59) => 0.0226094
+(1, 60) ~ (3, 61) => 0.0183042
+(1, 61) ~ (3, 56) => 0.106281
+(1, 61) ~ (3, 57) => 0.415867
+(1, 61) ~ (3, 58) => 0.342795
+(1, 61) ~ (3, 59) => 0.0342202
+(1, 61) ~ (3, 60) => 0.0236904
+(1, 61) ~ (3, 62) => 0.0151772
+(1, 62) ~ (3, 57) => 0.108796
+(1, 62) ~ (3, 58) => 0.410822
+(1, 62) ~ (3, 59) => 0.350547
+(1, 62) ~ (3, 60) => 0.026028
+(1, 62) ~ (3, 61) => 0.0242796
+(1, 62) ~ (3, 63) => 0.012299
+(1, 63) ~ (3, 58) => 0.108405
+(1, 63) ~ (3, 59) => 0.413771
+(1, 63) ~ (3, 60) => 0.337751
+(1, 63) ~ (3, 61) => 0.0138994
+(1, 63) ~ (3, 62) => 0.0230785
+(1, 64) ~ (3, 59) => 0.102746
+(1, 64) ~ (3, 60) => 0.448018
+(1, 64) ~ (3, 61) => 0.303239
+(1, 64) ~ (3, 62) => 0.0123941
+(1, 64) ~ (3, 63) => 0.0203131
+(1, 65) ~ (3, 60) => 0.0698707
+(1, 65) ~ (3, 61) => 0.533674
+(1, 65) ~ (3, 62) => 0.262921
+(1, 65) ~ (3, 63) => 0.016051
+(1, 65) ~ (3, 64) => 0.0206803
+(1, 66) ~ (3, 61) => 0.0550442
+(1, 66) ~ (3, 62) => 0.590582
+(1, 66) ~ (3, 63) => 0.228459
+(1, 66) ~ (3, 64) => 0.0193094
+(1, 66) ~ (3, 65) => 0.018637
+(1, 67) ~ (3, 62) => 0.0533169
+(1, 67) ~ (3, 63) => 0.631199
+(1, 67) ~ (3, 64) => 0.194184
+(1, 67) ~ (3, 65) => 0.0169158
+(1, 67) ~ (3, 66) => 0.0145392
+(1, 68) ~ (3, 63) => 0.0484263
+(1, 68) ~ (3, 64) => 0.673038
+(1, 68) ~ (3, 65) => 0.103311
+(1, 68) ~ (3, 66) => 0.0109832
+(1, 68) ~ (3, 67) => 0.0111111
+(1, 69) ~ (3, 64) => 0.0443406
+(1, 69) ~ (3, 65) => 0.785169
+(1, 69) ~ (3, 66) => 0.0659399
+(1, 69) ~ (3, 67) => 0.0105862
+(1, 70) ~ (3, 65) => 0.0381781
+(1, 70) ~ (3, 66) => 0.850399
+(1, 70) ~ (3, 67) => 0.0439482
+(1, 71) ~ (3, 66) => 0.0283484
+(1, 71) ~ (3, 67) => 0.894354
+(1, 71) ~ (3, 68) => 0.0300751
+(1, 72) ~ (3, 67) => 0.0237847
+(1, 72) ~ (3, 68) => 0.923415
+
+; gap posteriors
+(1, 0) ~ (3, -1) => 0.00460368
+(1, 1) ~ (3, -1) => 0.00960892
+(1, 2) ~ (3, -1) => 0.0149716
+(1, 3) ~ (3, -1) => 0.0185144
+(1, 4) ~ (3, -1) => 0.0211734
+(1, 5) ~ (3, -1) => 0.0235199
+(1, 6) ~ (3, -1) => 0.0272967
+(1, 7) ~ (3, -1) => 0.0207204
+(1, 8) ~ (3, -1) => 0.0273939
+(1, 9) ~ (3, -1) => 0.0339053
+(1, 10) ~ (3, -1) => 0.0303934
+(1, 11) ~ (3, -1) => 0.052189
+(1, 12) ~ (3, -1) => 0.0790636
+(1, 13) ~ (3, -1) => 0.103795
+(1, 14) ~ (3, -1) => 0.113794
+(1, 15) ~ (3, -1) => 0.123195
+(1, 16) ~ (3, -1) => 0.121801
+(1, 17) ~ (3, -1) => 0.134134
+(1, 18) ~ (3, -1) => 0.173462
+(1, 19) ~ (3, -1) => 0.250156
+(1, 20) ~ (3, -1) => 0.249512
+(1, 21) ~ (3, -1) => 0.244104
+(1, 22) ~ (3, -1) => 0.155526
+(1, 23) ~ (3, -1) => 0.124173
+(1, 24) ~ (3, -1) => 0.110728
+(1, 25) ~ (3, -1) => 0.12804
+(1, 26) ~ (3, -1) => 0.107004
+(1, 27) ~ (3, -1) => 0.10777
+(1, 28) ~ (3, -1) => 0.145583
+(1, 29) ~ (3, -1) => 0.128967
+(1, 30) ~ (3, -1) => 0.14423
+(1, 31) ~ (3, -1) => 0.0953625
+(1, 32) ~ (3, -1) => 0.0705453
+(1, 33) ~ (3, -1) => 0.0787321
+(1, 34) ~ (3, -1) => 0.0802766
+(1, 35) ~ (3, -1) => 0.0852045
+(1, 36) ~ (3, -1) => 0.0952369
+(1, 37) ~ (3, -1) => 0.10418
+(1, 38) ~ (3, -1) => 0.10759
+(1, 39) ~ (3, -1) => 0.0890398
+(1, 40) ~ (3, -1) => 0.0820279
+(1, 41) ~ (3, -1) => 0.0669413
+(1, 42) ~ (3, -1) => 0.072714
+(1, 43) ~ (3, -1) => 0.0832253
+(1, 44) ~ (3, -1) => 0.101272
+(1, 45) ~ (3, -1) => 0.0933826
+(1, 46) ~ (3, -1) => 0.0851695
+(1, 47) ~ (3, -1) => 0.0827143
+(1, 48) ~ (3, -1) => 0.0849315
+(1, 49) ~ (3, -1) => 0.0959448
+(1, 50) ~ (3, -1) => 0.149604
+(1, 51) ~ (3, -1) => 0.146325
+(1, 52) ~ (3, -1) => 0.161991
+(1, 53) ~ (3, -1) => 0.159486
+(1, 54) ~ (3, -1) => 0.13579
+(1, 55) ~ (3, -1) => 0.104543
+(1, 56) ~ (3, -1) => 0.0935837
+(1, 57) ~ (3, -1) => 0.105371
+(1, 58) ~ (3, -1) => 0.0889355
+(1, 59) ~ (3, -1) => 0.0750498
+(1, 60) ~ (3, -1) => 0.0639688
+(1, 61) ~ (3, -1) => 0.0619684
+(1, 62) ~ (3, -1) => 0.0672282
+(1, 63) ~ (3, -1) => 0.103096
+(1, 64) ~ (3, -1) => 0.113289
+(1, 65) ~ (3, -1) => 0.0968023
+(1, 66) ~ (3, -1) => 0.0879686
+(1, 67) ~ (3, -1) => 0.0898454
+(1, 68) ~ (3, -1) => 0.15313
+(1, 69) ~ (3, -1) => 0.0939643
+(1, 70) ~ (3, -1) => 0.0674745
+(1, 71) ~ (3, -1) => 0.047223
+(1, 72) ~ (3, -1) => 0.0528007
+
+(1, -1) ~ (3, 0) => 0.00460368
+(1, -1) ~ (3, 1) => 0.00960892
+(1, -1) ~ (3, 2) => 0.0149716
+(1, -1) ~ (3, 3) => 0.0185144
+(1, -1) ~ (3, 4) => 0.00961064
+(1, -1) ~ (3, 5) => 0.0099584
+(1, -1) ~ (3, 6) => 0.0108979
+(1, -1) ~ (3, 7) => 0.0132788
+(1, -1) ~ (3, 8) => 0.0197689
+(1, -1) ~ (3, 9) => 0.0271701
+(1, -1) ~ (3, 10) => 0.0356849
+(1, -1) ~ (3, 11) => 0.0217885
+(1, -1) ~ (3, 12) => 0.0198375
+(1, -1) ~ (3, 13) => 0.0187054
+(1, -1) ~ (3, 14) => 0.0325754
+(1, -1) ~ (3, 15) => 0.0252975
+(1, -1) ~ (3, 16) => 0.0232991
+(1, -1) ~ (3, 17) => 0.0426747
+(1, -1) ~ (3, 18) => 0.0415947
+(1, -1) ~ (3, 19) => 0.0559758
+(1, -1) ~ (3, 20) => 0.0651271
+(1, -1) ~ (3, 21) => 0.0573729
+(1, -1) ~ (3, 22) => 0.0458691
+(1, -1) ~ (3, 23) => 0.0407588
+(1, -1) ~ (3, 24) => 0.0482111
+(1, -1) ~ (3, 25) => 0.050998
+(1, -1) ~ (3, 26) => 0.0424293
+(1, -1) ~ (3, 27) => 0.043361
+(1, -1) ~ (3, 28) => 0.0428509
+(1, -1) ~ (3, 29) => 0.0614567
+(1, -1) ~ (3, 30) => 0.058014
+(1, -1) ~ (3, 31) => 0.0561184
+(1, -1) ~ (3, 32) => 0.0916308
+(1, -1) ~ (3, 33) => 0.0663138
+(1, -1) ~ (3, 34) => 0.0492484
+(1, -1) ~ (3, 35) => 0.0514725
+(1, -1) ~ (3, 36) => 0.0455687
+(1, -1) ~ (3, 37) => 0.057942
+(1, -1) ~ (3, 38) => 0.0585302
+(1, -1) ~ (3, 39) => 0.0463716
+(1, -1) ~ (3, 40) => 0.0464333
+(1, -1) ~ (3, 41) => 0.0528705
+(1, -1) ~ (3, 42) => 0.0577614
+(1, -1) ~ (3, 43) => 0.0515314
+(1, -1) ~ (3, 44) => 0.0657357
+(1, -1) ~ (3, 45) => 0.054863
+(1, -1) ~ (3, 46) => 0.0714867
+(1, -1) ~ (3, 47) => 0.0523624
+(1, -1) ~ (3, 48) => 0.0568473
+(1, -1) ~ (3, 49) => 0.052651
+(1, -1) ~ (3, 50) => 0.051819
+(1, -1) ~ (3, 51) => 0.0599482
+(1, -1) ~ (3, 52) => 0.0519298
+(1, -1) ~ (3, 53) => 0.0441015
+(1, -1) ~ (3, 54) => 0.0447369
+(1, -1) ~ (3, 55) => 0.0583776
+(1, -1) ~ (3, 56) => 0.056406
+(1, -1) ~ (3, 57) => 0.0446942
+(1, -1) ~ (3, 58) => 0.0532994
+(1, -1) ~ (3, 59) => 0.050281
+(1, -1) ~ (3, 60) => 0.0735643
+(1, -1) ~ (3, 61) => 0.0515588
+(1, -1) ~ (3, 62) => 0.04253
+(1, -1) ~ (3, 63) => 0.043253
+(1, -1) ~ (3, 64) => 0.0484475
+(1, -1) ~ (3, 65) => 0.0377892
+(1, -1) ~ (3, 66) => 0.0297902
+(1, -1) ~ (3, 67) => 0.0162162
+(1, -1) ~ (3, 68) => 0.0465104
+
+; Sparse posterior probability matrix for sequences 1 and 4
+; Format is:
+;   (1, position_1) ~ (4, position_2) => prob
+; which means that (1, position_1) is aligned to (4, position_2) with probability prob.
+;   (1, position_1) ~ (4, -1) => prob
+; means that (1, position_1) is aligned to a gap in 4 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(1, 0) ~ (4, 0) => 0.9997
+(1, 1) ~ (4, 1) => 0.998453
+(1, 2) ~ (4, 2) => 0.994036
+(1, 3) ~ (4, 3) => 0.990408
+(1, 4) ~ (4, 4) => 0.988165
+(1, 5) ~ (4, 5) => 0.986209
+(1, 6) ~ (4, 6) => 0.982967
+(1, 6) ~ (4, 7) => 0.0100327
+(1, 7) ~ (4, 7) => 0.978678
+(1, 7) ~ (4, 8) => 0.0119843
+(1, 8) ~ (4, 8) => 0.976071
+(1, 8) ~ (4, 9) => 0.0141077
+(1, 9) ~ (4, 9) => 0.973414
+(1, 9) ~ (4, 10) => 0.0162018
+(1, 10) ~ (4, 10) => 0.969108
+(1, 10) ~ (4, 11) => 0.0152438
+(1, 11) ~ (4, 11) => 0.972431
+(1, 11) ~ (4, 12) => 0.012889
+(1, 12) ~ (4, 12) => 0.976003
+(1, 13) ~ (4, 13) => 0.984501
+(1, 14) ~ (4, 14) => 0.990905
+(1, 15) ~ (4, 15) => 0.997242
+(1, 16) ~ (4, 16) => 0.997814
+(1, 17) ~ (4, 17) => 0.997782
+(1, 18) ~ (4, 18) => 0.995086
+(1, 19) ~ (4, 19) => 0.991604
+(1, 20) ~ (4, 20) => 0.911543
+(1, 21) ~ (4, 20) => 0.081885
+(1, 21) ~ (4, 21) => 0.830548
+(1, 22) ~ (4, 21) => 0.157179
+(1, 22) ~ (4, 22) => 0.785469
+(1, 22) ~ (4, 23) => 0.0137291
+(1, 23) ~ (4, 22) => 0.18888
+(1, 23) ~ (4, 23) => 0.0844835
+(1, 23) ~ (4, 24) => 0.0231893
+(1, 24) ~ (4, 23) => 0.879762
+(1, 24) ~ (4, 24) => 0.0510101
+(1, 24) ~ (4, 25) => 0.0155857
+(1, 25) ~ (4, 24) => 0.914978
+(1, 25) ~ (4, 25) => 0.0301128
+(1, 26) ~ (4, 25) => 0.941345
+(1, 26) ~ (4, 26) => 0.0216416
+(1, 27) ~ (4, 26) => 0.956951
+(1, 27) ~ (4, 27) => 0.0115729
+(1, 28) ~ (4, 26) => 0.0109663
+(1, 28) ~ (4, 27) => 0.966065
+(1, 29) ~ (4, 27) => 0.0159347
+(1, 29) ~ (4, 28) => 0.974505
+(1, 30) ~ (4, 28) => 0.0161725
+(1, 30) ~ (4, 29) => 0.97449
+(1, 31) ~ (4, 29) => 0.0190305
+(1, 31) ~ (4, 30) => 0.977209
+(1, 32) ~ (4, 30) => 0.0194295
+(1, 32) ~ (4, 31) => 0.976426
+(1, 33) ~ (4, 31) => 0.0191771
+(1, 33) ~ (4, 32) => 0.975558
+(1, 34) ~ (4, 32) => 0.0195985
+(1, 34) ~ (4, 33) => 0.976658
+(1, 35) ~ (4, 33) => 0.0175109
+(1, 35) ~ (4, 34) => 0.98082
+(1, 36) ~ (4, 34) => 0.01437
+(1, 36) ~ (4, 35) => 0.984299
+(1, 37) ~ (4, 35) => 0.0109015
+(1, 37) ~ (4, 36) => 0.985344
+(1, 38) ~ (4, 36) => 0.0119291
+(1, 38) ~ (4, 37) => 0.982136
+(1, 39) ~ (4, 37) => 0.0136494
+(1, 39) ~ (4, 38) => 0.979989
+(1, 40) ~ (4, 38) => 0.0144306
+(1, 40) ~ (4, 39) => 0.977198
+(1, 41) ~ (4, 39) => 0.01581
+(1, 41) ~ (4, 40) => 0.947786
+(1, 42) ~ (4, 40) => 0.0428728
+(1, 42) ~ (4, 41) => 0.917917
+(1, 43) ~ (4, 41) => 0.0696512
+(1, 43) ~ (4, 42) => 0.880536
+(1, 43) ~ (4, 43) => 0.0110859
+(1, 44) ~ (4, 42) => 0.104454
+(1, 44) ~ (4, 43) => 0.851407
+(1, 44) ~ (4, 44) => 0.0123777
+(1, 45) ~ (4, 43) => 0.131508
+(1, 45) ~ (4, 44) => 0.814437
+(1, 45) ~ (4, 45) => 0.0125995
+(1, 46) ~ (4, 44) => 0.166203
+(1, 46) ~ (4, 45) => 0.755124
+(1, 46) ~ (4, 46) => 0.0124186
+(1, 47) ~ (4, 45) => 0.224856
+(1, 47) ~ (4, 46) => 0.69205
+(1, 47) ~ (4, 47) => 0.0106718
+(1, 48) ~ (4, 46) => 0.287558
+(1, 48) ~ (4, 47) => 0.591345
+(1, 49) ~ (4, 47) => 0.390257
+(1, 49) ~ (4, 48) => 0.534056
+(1, 50) ~ (4, 48) => 0.451092
+(1, 50) ~ (4, 49) => 0.43122
+(1, 51) ~ (4, 49) => 0.555362
+(1, 51) ~ (4, 50) => 0.328075
+(1, 51) ~ (4, 51) => 0.010077
+(1, 52) ~ (4, 50) => 0.65686
+(1, 52) ~ (4, 51) => 0.22068
+(1, 52) ~ (4, 52) => 0.0147259
+(1, 53) ~ (4, 51) => 0.758032
+(1, 53) ~ (4, 52) => 0.161636
+(1, 54) ~ (4, 52) => 0.815324
+(1, 54) ~ (4, 53) => 0.10525
+(1, 55) ~ (4, 53) => 0.883556
+(1, 55) ~ (4, 54) => 0.0684677
+(1, 56) ~ (4, 54) => 0.92492
+(1, 56) ~ (4, 55) => 0.0400275
+(1, 57) ~ (4, 55) => 0.955228
+(1, 57) ~ (4, 56) => 0.0105455
+(1, 58) ~ (4, 56) => 0.984308
+(1, 58) ~ (4, 57) => 0.0105717
+(1, 59) ~ (4, 57) => 0.983824
+(1, 59) ~ (4, 58) => 0.010638
+(1, 60) ~ (4, 58) => 0.983863
+(1, 60) ~ (4, 59) => 0.0107324
+(1, 61) ~ (4, 59) => 0.983473
+(1, 61) ~ (4, 60) => 0.0107019
+(1, 62) ~ (4, 60) => 0.982547
+(1, 62) ~ (4, 61) => 0.0113025
+(1, 63) ~ (4, 61) => 0.982421
+(1, 63) ~ (4, 62) => 0.0119239
+(1, 64) ~ (4, 62) => 0.982245
+(1, 64) ~ (4, 63) => 0.0113742
+(1, 65) ~ (4, 63) => 0.984131
+(1, 66) ~ (4, 64) => 0.986408
+(1, 67) ~ (4, 65) => 0.98779
+(1, 68) ~ (4, 66) => 0.989351
+(1, 69) ~ (4, 67) => 0.993642
+(1, 70) ~ (4, 68) => 0.996821
+(1, 71) ~ (4, 69) => 0.99803
+(1, 72) ~ (4, 70) => 0.998733
+
+; gap posteriors
+(1, 0) ~ (4, -1) => 0.000300169
+(1, 1) ~ (4, -1) => 0.00154728
+(1, 2) ~ (4, -1) => 0.00596356
+(1, 3) ~ (4, -1) => 0.00959235
+(1, 4) ~ (4, -1) => 0.0118346
+(1, 5) ~ (4, -1) => 0.0137908
+(1, 6) ~ (4, -1) => 0.00700056
+(1, 7) ~ (4, -1) => 0.00933819
+(1, 8) ~ (4, -1) => 0.00982151
+(1, 9) ~ (4, -1) => 0.0103839
+(1, 10) ~ (4, -1) => 0.0156481
+(1, 11) ~ (4, -1) => 0.0146795
+(1, 12) ~ (4, -1) => 0.0239967
+(1, 13) ~ (4, -1) => 0.0154991
+(1, 14) ~ (4, -1) => 0.00909489
+(1, 15) ~ (4, -1) => 0.00275785
+(1, 16) ~ (4, -1) => 0.00218636
+(1, 17) ~ (4, -1) => 0.00221789
+(1, 18) ~ (4, -1) => 0.00491434
+(1, 19) ~ (4, -1) => 0.00839573
+(1, 20) ~ (4, -1) => 0.0884575
+(1, 21) ~ (4, -1) => 0.0875668
+(1, 22) ~ (4, -1) => 0.0436231
+(1, 23) ~ (4, -1) => 0.703447
+(1, 24) ~ (4, -1) => 0.053642
+(1, 25) ~ (4, -1) => 0.0549091
+(1, 26) ~ (4, -1) => 0.0370133
+(1, 27) ~ (4, -1) => 0.0314757
+(1, 28) ~ (4, -1) => 0.0229687
+(1, 29) ~ (4, -1) => 0.00956059
+(1, 30) ~ (4, -1) => 0.00933713
+(1, 31) ~ (4, -1) => 0.00376034
+(1, 32) ~ (4, -1) => 0.00414461
+(1, 33) ~ (4, -1) => 0.00526446
+(1, 34) ~ (4, -1) => 0.00374305
+(1, 35) ~ (4, -1) => 0.00166941
+(1, 36) ~ (4, -1) => 0.00133061
+(1, 37) ~ (4, -1) => 0.00375503
+(1, 38) ~ (4, -1) => 0.00593489
+(1, 39) ~ (4, -1) => 0.00636154
+(1, 40) ~ (4, -1) => 0.00837189
+(1, 41) ~ (4, -1) => 0.0364044
+(1, 42) ~ (4, -1) => 0.0392098
+(1, 43) ~ (4, -1) => 0.0387269
+(1, 44) ~ (4, -1) => 0.0317611
+(1, 45) ~ (4, -1) => 0.0414552
+(1, 46) ~ (4, -1) => 0.0662551
+(1, 47) ~ (4, -1) => 0.0724223
+(1, 48) ~ (4, -1) => 0.121097
+(1, 49) ~ (4, -1) => 0.0756867
+(1, 50) ~ (4, -1) => 0.117688
+(1, 51) ~ (4, -1) => 0.106486
+(1, 52) ~ (4, -1) => 0.107734
+(1, 53) ~ (4, -1) => 0.0803325
+(1, 54) ~ (4, -1) => 0.0794263
+(1, 55) ~ (4, -1) => 0.0479762
+(1, 56) ~ (4, -1) => 0.035052
+(1, 57) ~ (4, -1) => 0.0342262
+(1, 58) ~ (4, -1) => 0.00512001
+(1, 59) ~ (4, -1) => 0.005538
+(1, 60) ~ (4, -1) => 0.00540488
+(1, 61) ~ (4, -1) => 0.00582494
+(1, 62) ~ (4, -1) => 0.00615006
+(1, 63) ~ (4, -1) => 0.00565557
+(1, 64) ~ (4, -1) => 0.00638068
+(1, 65) ~ (4, -1) => 0.015869
+(1, 66) ~ (4, -1) => 0.0135918
+(1, 67) ~ (4, -1) => 0.0122096
+(1, 68) ~ (4, -1) => 0.0106486
+(1, 69) ~ (4, -1) => 0.00635767
+(1, 70) ~ (4, -1) => 0.00317913
+(1, 71) ~ (4, -1) => 0.00197041
+(1, 72) ~ (4, -1) => 0.00126714
+
+(1, -1) ~ (4, 0) => 0.000300169
+(1, -1) ~ (4, 1) => 0.00154728
+(1, -1) ~ (4, 2) => 0.00596356
+(1, -1) ~ (4, 3) => 0.00959235
+(1, -1) ~ (4, 4) => 0.0118346
+(1, -1) ~ (4, 5) => 0.0137908
+(1, -1) ~ (4, 6) => 0.0170333
+(1, -1) ~ (4, 7) => 0.0112898
+(1, -1) ~ (4, 8) => 0.0119449
+(1, -1) ~ (4, 9) => 0.0124781
+(1, -1) ~ (4, 10) => 0.01469
+(1, -1) ~ (4, 11) => 0.0123247
+(1, -1) ~ (4, 12) => 0.0111076
+(1, -1) ~ (4, 13) => 0.0154991
+(1, -1) ~ (4, 14) => 0.00909489
+(1, -1) ~ (4, 15) => 0.00275785
+(1, -1) ~ (4, 16) => 0.00218636
+(1, -1) ~ (4, 17) => 0.00221789
+(1, -1) ~ (4, 18) => 0.00491434
+(1, -1) ~ (4, 19) => 0.00839573
+(1, -1) ~ (4, 20) => 0.00657246
+(1, -1) ~ (4, 21) => 0.0122733
+(1, -1) ~ (4, 22) => 0.0256506
+(1, -1) ~ (4, 23) => 0.0220253
+(1, -1) ~ (4, 24) => 0.0108224
+(1, -1) ~ (4, 25) => 0.0129564
+(1, -1) ~ (4, 26) => 0.0104407
+(1, -1) ~ (4, 27) => 0.00642735
+(1, -1) ~ (4, 28) => 0.00932278
+(1, -1) ~ (4, 29) => 0.00647917
+(1, -1) ~ (4, 30) => 0.00336128
+(1, -1) ~ (4, 31) => 0.00439699
+(1, -1) ~ (4, 32) => 0.00484306
+(1, -1) ~ (4, 33) => 0.00583074
+(1, -1) ~ (4, 34) => 0.00481027
+(1, -1) ~ (4, 35) => 0.00479911
+(1, -1) ~ (4, 36) => 0.00272742
+(1, -1) ~ (4, 37) => 0.00421452
+(1, -1) ~ (4, 38) => 0.00558037
+(1, -1) ~ (4, 39) => 0.00699246
+(1, -1) ~ (4, 40) => 0.00934161
+(1, -1) ~ (4, 41) => 0.0124315
+(1, -1) ~ (4, 42) => 0.0150102
+(1, -1) ~ (4, 43) => 0.00599855
+(1, -1) ~ (4, 44) => 0.0069824
+(1, -1) ~ (4, 45) => 0.00742133
+(1, -1) ~ (4, 46) => 0.00797325
+(1, -1) ~ (4, 47) => 0.00772557
+(1, -1) ~ (4, 48) => 0.0148522
+(1, -1) ~ (4, 49) => 0.0134176
+(1, -1) ~ (4, 50) => 0.0150655
+(1, -1) ~ (4, 51) => 0.0112107
+(1, -1) ~ (4, 52) => 0.00831461
+(1, -1) ~ (4, 53) => 0.011194
+(1, -1) ~ (4, 54) => 0.00661182
+(1, -1) ~ (4, 55) => 0.00474423
+(1, -1) ~ (4, 56) => 0.00514627
+(1, -1) ~ (4, 57) => 0.00560421
+(1, -1) ~ (4, 58) => 0.0054993
+(1, -1) ~ (4, 59) => 0.00579447
+(1, -1) ~ (4, 60) => 0.00675058
+(1, -1) ~ (4, 61) => 0.00627697
+(1, -1) ~ (4, 62) => 0.005831
+(1, -1) ~ (4, 63) => 0.00449479
+(1, -1) ~ (4, 64) => 0.0135918
+(1, -1) ~ (4, 65) => 0.0122096
+(1, -1) ~ (4, 66) => 0.0106486
+(1, -1) ~ (4, 67) => 0.00635767
+(1, -1) ~ (4, 68) => 0.00317913
+(1, -1) ~ (4, 69) => 0.00197041
+(1, -1) ~ (4, 70) => 0.00126714
+
+; Sparse posterior probability matrix for sequences 2 and 3
+; Format is:
+;   (2, position_1) ~ (3, position_2) => prob
+; which means that (2, position_1) is aligned to (3, position_2) with probability prob.
+;   (2, position_1) ~ (3, -1) => prob
+; means that (2, position_1) is aligned to a gap in 3 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (3, 0) => 0.999947
+(2, 1) ~ (3, 1) => 0.999575
+(2, 2) ~ (3, 2) => 0.999214
+(2, 3) ~ (3, 3) => 0.99887
+(2, 4) ~ (3, 4) => 0.99831
+(2, 5) ~ (3, 5) => 0.998182
+(2, 6) ~ (3, 6) => 0.99829
+(2, 7) ~ (3, 7) => 0.998429
+(2, 8) ~ (3, 8) => 0.998767
+(2, 9) ~ (3, 9) => 0.999066
+(2, 10) ~ (3, 10) => 0.999117
+(2, 11) ~ (3, 11) => 0.998802
+(2, 12) ~ (3, 12) => 0.998399
+(2, 13) ~ (3, 13) => 0.998518
+(2, 14) ~ (3, 14) => 0.998869
+(2, 15) ~ (3, 15) => 0.999238
+(2, 16) ~ (3, 16) => 0.999264
+(2, 17) ~ (3, 17) => 0.999154
+(2, 18) ~ (3, 18) => 0.999025
+(2, 19) ~ (3, 19) => 0.99917
+(2, 20) ~ (3, 20) => 0.999306
+(2, 21) ~ (3, 21) => 0.999472
+(2, 22) ~ (3, 22) => 0.999481
+(2, 23) ~ (3, 23) => 0.999569
+(2, 24) ~ (3, 24) => 0.999641
+(2, 25) ~ (3, 25) => 0.999579
+(2, 26) ~ (3, 26) => 0.999351
+(2, 27) ~ (3, 27) => 0.998136
+(2, 28) ~ (3, 28) => 0.996861
+(2, 29) ~ (3, 29) => 0.992417
+(2, 30) ~ (3, 30) => 0.987346
+(2, 31) ~ (3, 31) => 0.975394
+(2, 31) ~ (3, 38) => 0.015923
+(2, 32) ~ (3, 32) => 0.973891
+(2, 32) ~ (3, 39) => 0.0176899
+(2, 33) ~ (3, 33) => 0.973302
+(2, 33) ~ (3, 40) => 0.0185581
+(2, 34) ~ (3, 34) => 0.971226
+(2, 34) ~ (3, 41) => 0.0198995
+(2, 35) ~ (3, 35) => 0.969745
+(2, 35) ~ (3, 42) => 0.0210121
+(2, 36) ~ (3, 36) => 0.967632
+(2, 36) ~ (3, 43) => 0.0217485
+(2, 37) ~ (3, 37) => 0.964778
+(2, 37) ~ (3, 44) => 0.0223772
+(2, 38) ~ (3, 38) => 0.953399
+(2, 38) ~ (3, 45) => 0.0214184
+(2, 39) ~ (3, 39) => 0.93942
+(2, 39) ~ (3, 46) => 0.0200209
+(2, 39) ~ (3, 49) => 0.0161367
+(2, 40) ~ (3, 40) => 0.918972
+(2, 40) ~ (3, 47) => 0.0203095
+(2, 40) ~ (3, 50) => 0.0222161
+(2, 41) ~ (3, 41) => 0.899034
+(2, 41) ~ (3, 44) => 0.0102455
+(2, 41) ~ (3, 45) => 0.0119202
+(2, 41) ~ (3, 48) => 0.019201
+(2, 41) ~ (3, 51) => 0.0290967
+(2, 42) ~ (3, 42) => 0.803096
+(2, 42) ~ (3, 45) => 0.0837254
+(2, 42) ~ (3, 46) => 0.0143956
+(2, 42) ~ (3, 49) => 0.0166466
+(2, 42) ~ (3, 50) => 0.0127695
+(2, 42) ~ (3, 52) => 0.035725
+(2, 43) ~ (3, 43) => 0.703701
+(2, 43) ~ (3, 46) => 0.157502
+(2, 43) ~ (3, 47) => 0.020418
+(2, 43) ~ (3, 50) => 0.0149749
+(2, 43) ~ (3, 51) => 0.0245522
+(2, 43) ~ (3, 53) => 0.0401055
+(2, 44) ~ (3, 44) => 0.57052
+(2, 44) ~ (3, 47) => 0.279577
+(2, 44) ~ (3, 48) => 0.0221508
+(2, 44) ~ (3, 51) => 0.0140063
+(2, 44) ~ (3, 52) => 0.0338077
+(2, 44) ~ (3, 54) => 0.042243
+(2, 45) ~ (3, 45) => 0.527121
+(2, 45) ~ (3, 48) => 0.321751
+(2, 45) ~ (3, 49) => 0.0217577
+(2, 45) ~ (3, 52) => 0.0125016
+(2, 45) ~ (3, 53) => 0.0372461
+(2, 45) ~ (3, 55) => 0.0441308
+(2, 46) ~ (3, 46) => 0.483585
+(2, 46) ~ (3, 49) => 0.363802
+(2, 46) ~ (3, 50) => 0.0227212
+(2, 46) ~ (3, 54) => 0.0389651
+(2, 46) ~ (3, 56) => 0.0453491
+(2, 47) ~ (3, 47) => 0.429915
+(2, 47) ~ (3, 50) => 0.384198
+(2, 47) ~ (3, 51) => 0.0191817
+(2, 47) ~ (3, 53) => 0.0319531
+(2, 47) ~ (3, 55) => 0.0377027
+(2, 47) ~ (3, 57) => 0.0444744
+(2, 48) ~ (3, 48) => 0.393476
+(2, 48) ~ (3, 51) => 0.385334
+(2, 48) ~ (3, 52) => 0.0188001
+(2, 48) ~ (3, 53) => 0.019089
+(2, 48) ~ (3, 54) => 0.0562167
+(2, 48) ~ (3, 56) => 0.0380848
+(2, 48) ~ (3, 58) => 0.0425972
+(2, 49) ~ (3, 49) => 0.351502
+(2, 49) ~ (3, 52) => 0.384086
+(2, 49) ~ (3, 53) => 0.0152873
+(2, 49) ~ (3, 54) => 0.0242159
+(2, 49) ~ (3, 55) => 0.091456
+(2, 49) ~ (3, 57) => 0.0412649
+(2, 49) ~ (3, 59) => 0.0407586
+(2, 50) ~ (3, 50) => 0.211871
+(2, 50) ~ (3, 53) => 0.392184
+(2, 50) ~ (3, 54) => 0.010663
+(2, 50) ~ (3, 55) => 0.0236556
+(2, 50) ~ (3, 56) => 0.227295
+(2, 50) ~ (3, 58) => 0.0429079
+(2, 50) ~ (3, 60) => 0.03873
+(2, 51) ~ (3, 51) => 0.0266461
+(2, 51) ~ (3, 54) => 0.359766
+(2, 51) ~ (3, 56) => 0.0140821
+(2, 51) ~ (3, 57) => 0.48286
+(2, 51) ~ (3, 59) => 0.0437669
+(2, 51) ~ (3, 61) => 0.0315115
+(2, 52) ~ (3, 52) => 0.0222039
+(2, 52) ~ (3, 55) => 0.316429
+(2, 52) ~ (3, 58) => 0.547264
+(2, 52) ~ (3, 60) => 0.0418991
+(2, 52) ~ (3, 62) => 0.023413
+(2, 53) ~ (3, 53) => 0.0176828
+(2, 53) ~ (3, 56) => 0.26957
+(2, 53) ~ (3, 59) => 0.601712
+(2, 53) ~ (3, 61) => 0.0324992
+(2, 54) ~ (3, 54) => 0.0158207
+(2, 54) ~ (3, 57) => 0.25143
+(2, 54) ~ (3, 60) => 0.624199
+(2, 54) ~ (3, 62) => 0.0226157
+(2, 55) ~ (3, 58) => 0.172852
+(2, 55) ~ (3, 61) => 0.727637
+(2, 55) ~ (3, 63) => 0.0129581
+(2, 56) ~ (3, 59) => 0.156297
+(2, 56) ~ (3, 61) => 0.0112923
+(2, 56) ~ (3, 62) => 0.765054
+(2, 56) ~ (3, 64) => 0.0101235
+(2, 57) ~ (3, 60) => 0.112502
+(2, 57) ~ (3, 62) => 0.0111839
+(2, 57) ~ (3, 63) => 0.836895
+(2, 58) ~ (3, 61) => 0.0697027
+(2, 58) ~ (3, 64) => 0.892758
+(2, 59) ~ (3, 62) => 0.0478014
+(2, 59) ~ (3, 65) => 0.923074
+(2, 60) ~ (3, 63) => 0.026092
+(2, 60) ~ (3, 66) => 0.951758
+(2, 61) ~ (3, 67) => 0.982544
+(2, 62) ~ (3, 68) => 0.98509
+
+; gap posteriors
+(2, 0) ~ (3, -1) => 0.0001
+(2, 1) ~ (3, -1) => 0.000425398
+(2, 2) ~ (3, -1) => 0.000786066
+(2, 3) ~ (3, -1) => 0.00112969
+(2, 4) ~ (3, -1) => 0.00168991
+(2, 5) ~ (3, -1) => 0.00181818
+(2, 6) ~ (3, -1) => 0.00170982
+(2, 7) ~ (3, -1) => 0.00157106
+(2, 8) ~ (3, -1) => 0.0012331
+(2, 9) ~ (3, -1) => 0.000933766
+(2, 10) ~ (3, -1) => 0.000883043
+(2, 11) ~ (3, -1) => 0.00119829
+(2, 12) ~ (3, -1) => 0.0016014
+(2, 13) ~ (3, -1) => 0.00148249
+(2, 14) ~ (3, -1) => 0.00113052
+(2, 15) ~ (3, -1) => 0.000762403
+(2, 16) ~ (3, -1) => 0.000735939
+(2, 17) ~ (3, -1) => 0.000846386
+(2, 18) ~ (3, -1) => 0.000974774
+(2, 19) ~ (3, -1) => 0.000830472
+(2, 20) ~ (3, -1) => 0.000693679
+(2, 21) ~ (3, -1) => 0.000527978
+(2, 22) ~ (3, -1) => 0.00051868
+(2, 23) ~ (3, -1) => 0.000430584
+(2, 24) ~ (3, -1) => 0.000358582
+(2, 25) ~ (3, -1) => 0.000420928
+(2, 26) ~ (3, -1) => 0.000649154
+(2, 27) ~ (3, -1) => 0.00186402
+(2, 28) ~ (3, -1) => 0.0031389
+(2, 29) ~ (3, -1) => 0.00758296
+(2, 30) ~ (3, -1) => 0.0126536
+(2, 31) ~ (3, -1) => 0.00868261
+(2, 32) ~ (3, -1) => 0.00841863
+(2, 33) ~ (3, -1) => 0.00813985
+(2, 34) ~ (3, -1) => 0.00887471
+(2, 35) ~ (3, -1) => 0.00924337
+(2, 36) ~ (3, -1) => 0.0106191
+(2, 37) ~ (3, -1) => 0.0128444
+(2, 38) ~ (3, -1) => 0.0251826
+(2, 39) ~ (3, -1) => 0.0244229
+(2, 40) ~ (3, -1) => 0.0385019
+(2, 41) ~ (3, -1) => 0.0305023
+(2, 42) ~ (3, -1) => 0.0336419
+(2, 43) ~ (3, -1) => 0.0387467
+(2, 44) ~ (3, -1) => 0.0376953
+(2, 45) ~ (3, -1) => 0.035491
+(2, 46) ~ (3, -1) => 0.0455778
+(2, 47) ~ (3, -1) => 0.0525756
+(2, 48) ~ (3, -1) => 0.0464022
+(2, 49) ~ (3, -1) => 0.0514287
+(2, 50) ~ (3, -1) => 0.0526932
+(2, 51) ~ (3, -1) => 0.041367
+(2, 52) ~ (3, -1) => 0.0487913
+(2, 53) ~ (3, -1) => 0.0785365
+(2, 54) ~ (3, -1) => 0.0859343
+(2, 55) ~ (3, -1) => 0.0865522
+(2, 56) ~ (3, -1) => 0.0572338
+(2, 57) ~ (3, -1) => 0.0394192
+(2, 58) ~ (3, -1) => 0.037539
+(2, 59) ~ (3, -1) => 0.0291246
+(2, 60) ~ (3, -1) => 0.0221495
+(2, 61) ~ (3, -1) => 0.0174562
+(2, 62) ~ (3, -1) => 0.0149099
+
+(2, -1) ~ (3, 0) => 0.0001
+(2, -1) ~ (3, 1) => 0.000425398
+(2, -1) ~ (3, 2) => 0.000786066
+(2, -1) ~ (3, 3) => 0.00112969
+(2, -1) ~ (3, 4) => 0.00168991
+(2, -1) ~ (3, 5) => 0.00181818
+(2, -1) ~ (3, 6) => 0.00170982
+(2, -1) ~ (3, 7) => 0.00157106
+(2, -1) ~ (3, 8) => 0.0012331
+(2, -1) ~ (3, 9) => 0.000933766
+(2, -1) ~ (3, 10) => 0.000883043
+(2, -1) ~ (3, 11) => 0.00119829
+(2, -1) ~ (3, 12) => 0.0016014
+(2, -1) ~ (3, 13) => 0.00148249
+(2, -1) ~ (3, 14) => 0.00113052
+(2, -1) ~ (3, 15) => 0.000762403
+(2, -1) ~ (3, 16) => 0.000735939
+(2, -1) ~ (3, 17) => 0.000846386
+(2, -1) ~ (3, 18) => 0.000974774
+(2, -1) ~ (3, 19) => 0.000830472
+(2, -1) ~ (3, 20) => 0.000693679
+(2, -1) ~ (3, 21) => 0.000527978
+(2, -1) ~ (3, 22) => 0.00051868
+(2, -1) ~ (3, 23) => 0.000430584
+(2, -1) ~ (3, 24) => 0.000358582
+(2, -1) ~ (3, 25) => 0.000420928
+(2, -1) ~ (3, 26) => 0.000649154
+(2, -1) ~ (3, 27) => 0.00186402
+(2, -1) ~ (3, 28) => 0.0031389
+(2, -1) ~ (3, 29) => 0.00758296
+(2, -1) ~ (3, 30) => 0.0126536
+(2, -1) ~ (3, 31) => 0.0246056
+(2, -1) ~ (3, 32) => 0.0261086
+(2, -1) ~ (3, 33) => 0.026698
+(2, -1) ~ (3, 34) => 0.0287742
+(2, -1) ~ (3, 35) => 0.0302554
+(2, -1) ~ (3, 36) => 0.0323676
+(2, -1) ~ (3, 37) => 0.0352216
+(2, -1) ~ (3, 38) => 0.030678
+(2, -1) ~ (3, 39) => 0.0428905
+(2, -1) ~ (3, 40) => 0.0624694
+(2, -1) ~ (3, 41) => 0.0810661
+(2, -1) ~ (3, 42) => 0.175892
+(2, -1) ~ (3, 43) => 0.274551
+(2, -1) ~ (3, 44) => 0.396857
+(2, -1) ~ (3, 45) => 0.355815
+(2, -1) ~ (3, 46) => 0.324496
+(2, -1) ~ (3, 47) => 0.249781
+(2, -1) ~ (3, 48) => 0.243421
+(2, -1) ~ (3, 49) => 0.230155
+(2, -1) ~ (3, 50) => 0.33125
+(2, -1) ~ (3, 51) => 0.501183
+(2, -1) ~ (3, 52) => 0.492875
+(2, -1) ~ (3, 53) => 0.446452
+(2, -1) ~ (3, 54) => 0.452109
+(2, -1) ~ (3, 55) => 0.486626
+(2, -1) ~ (3, 56) => 0.405619
+(2, -1) ~ (3, 57) => 0.17997
+(2, -1) ~ (3, 58) => 0.194379
+(2, -1) ~ (3, 59) => 0.157466
+(2, -1) ~ (3, 60) => 0.18267
+(2, -1) ~ (3, 61) => 0.127357
+(2, -1) ~ (3, 62) => 0.129932
+(2, -1) ~ (3, 63) => 0.124055
+(2, -1) ~ (3, 64) => 0.0971181
+(2, -1) ~ (3, 65) => 0.076926
+(2, -1) ~ (3, 66) => 0.0482416
+(2, -1) ~ (3, 67) => 0.0174562
+(2, -1) ~ (3, 68) => 0.0149099
+
+; Sparse posterior probability matrix for sequences 2 and 4
+; Format is:
+;   (2, position_1) ~ (4, position_2) => prob
+; which means that (2, position_1) is aligned to (4, position_2) with probability prob.
+;   (2, position_1) ~ (4, -1) => prob
+; means that (2, position_1) is aligned to a gap in 4 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(2, 0) ~ (4, 0) => 0.998542
+(2, 1) ~ (4, 1) => 0.995426
+(2, 2) ~ (4, 2) => 0.988666
+(2, 3) ~ (4, 3) => 0.9822
+(2, 4) ~ (4, 4) => 0.976237
+(2, 4) ~ (4, 5) => 0.011716
+(2, 5) ~ (4, 5) => 0.970037
+(2, 5) ~ (4, 6) => 0.0135695
+(2, 6) ~ (4, 6) => 0.969056
+(2, 6) ~ (4, 7) => 0.0128288
+(2, 7) ~ (4, 7) => 0.967063
+(2, 7) ~ (4, 8) => 0.0117285
+(2, 8) ~ (4, 8) => 0.961482
+(2, 8) ~ (4, 10) => 0.0113458
+(2, 9) ~ (4, 9) => 0.945805
+(2, 9) ~ (4, 11) => 0.0200771
+(2, 10) ~ (4, 10) => 0.917843
+(2, 10) ~ (4, 12) => 0.0322421
+(2, 11) ~ (4, 11) => 0.898282
+(2, 11) ~ (4, 13) => 0.0360191
+(2, 12) ~ (4, 12) => 0.875037
+(2, 12) ~ (4, 14) => 0.03943
+(2, 13) ~ (4, 13) => 0.839135
+(2, 13) ~ (4, 15) => 0.0426612
+(2, 13) ~ (4, 16) => 0.0126761
+(2, 14) ~ (4, 14) => 0.791557
+(2, 14) ~ (4, 16) => 0.0512953
+(2, 14) ~ (4, 17) => 0.0182511
+(2, 15) ~ (4, 15) => 0.752944
+(2, 15) ~ (4, 17) => 0.0601359
+(2, 15) ~ (4, 18) => 0.0200182
+(2, 16) ~ (4, 13) => 0.0143305
+(2, 16) ~ (4, 14) => 0.0207263
+(2, 16) ~ (4, 16) => 0.626354
+(2, 16) ~ (4, 18) => 0.107548
+(2, 16) ~ (4, 19) => 0.0164787
+(2, 16) ~ (4, 26) => 0.0135834
+(2, 17) ~ (4, 14) => 0.0194406
+(2, 17) ~ (4, 15) => 0.034932
+(2, 17) ~ (4, 17) => 0.488906
+(2, 17) ~ (4, 19) => 0.201939
+(2, 17) ~ (4, 20) => 0.0127226
+(2, 17) ~ (4, 27) => 0.0163895
+(2, 18) ~ (4, 15) => 0.0234762
+(2, 18) ~ (4, 16) => 0.0780552
+(2, 18) ~ (4, 18) => 0.194741
+(2, 18) ~ (4, 20) => 0.428106
+(2, 18) ~ (4, 21) => 0.0118382
+(2, 18) ~ (4, 28) => 0.0185021
+(2, 19) ~ (4, 10) => 0.0133417
+(2, 19) ~ (4, 13) => 0.0139654
+(2, 19) ~ (4, 16) => 0.0487628
+(2, 19) ~ (4, 17) => 0.0960511
+(2, 19) ~ (4, 19) => 0.118091
+(2, 19) ~ (4, 20) => 0.0149224
+(2, 19) ~ (4, 21) => 0.464154
+(2, 19) ~ (4, 29) => 0.0207406
+(2, 20) ~ (4, 11) => 0.0194049
+(2, 20) ~ (4, 14) => 0.016594
+(2, 20) ~ (4, 17) => 0.0584456
+(2, 20) ~ (4, 18) => 0.139877
+(2, 20) ~ (4, 20) => 0.0892666
+(2, 20) ~ (4, 22) => 0.490776
+(2, 20) ~ (4, 30) => 0.0225482
+(2, 21) ~ (4, 12) => 0.0283802
+(2, 21) ~ (4, 15) => 0.0199346
+(2, 21) ~ (4, 18) => 0.0615525
+(2, 21) ~ (4, 19) => 0.173024
+(2, 21) ~ (4, 21) => 0.0478844
+(2, 21) ~ (4, 23) => 0.528753
+(2, 21) ~ (4, 31) => 0.0254757
+(2, 22) ~ (4, 13) => 0.0395842
+(2, 22) ~ (4, 16) => 0.0218912
+(2, 22) ~ (4, 19) => 0.0538685
+(2, 22) ~ (4, 20) => 0.180307
+(2, 22) ~ (4, 22) => 0.0236441
+(2, 22) ~ (4, 24) => 0.545339
+(2, 22) ~ (4, 32) => 0.0289556
+(2, 23) ~ (4, 14) => 0.0456339
+(2, 23) ~ (4, 17) => 0.0208566
+(2, 23) ~ (4, 20) => 0.0535287
+(2, 23) ~ (4, 21) => 0.168727
+(2, 23) ~ (4, 23) => 0.010217
+(2, 23) ~ (4, 25) => 0.565428
+(2, 23) ~ (4, 31) => 0.0102546
+(2, 23) ~ (4, 33) => 0.0325792
+(2, 24) ~ (4, 15) => 0.0482736
+(2, 24) ~ (4, 18) => 0.0218967
+(2, 24) ~ (4, 21) => 0.0416151
+(2, 24) ~ (4, 22) => 0.157218
+(2, 24) ~ (4, 23) => 0.0106472
+(2, 24) ~ (4, 26) => 0.588907
+(2, 24) ~ (4, 32) => 0.0122367
+(2, 24) ~ (4, 34) => 0.0283261
+(2, 25) ~ (4, 16) => 0.0499502
+(2, 25) ~ (4, 19) => 0.0197446
+(2, 25) ~ (4, 22) => 0.0277653
+(2, 25) ~ (4, 23) => 0.118998
+(2, 25) ~ (4, 27) => 0.62122
+(2, 25) ~ (4, 33) => 0.0131312
+(2, 25) ~ (4, 34) => 0.0316962
+(2, 25) ~ (4, 35) => 0.0298539
+(2, 26) ~ (4, 17) => 0.0527431
+(2, 26) ~ (4, 20) => 0.0187036
+(2, 26) ~ (4, 23) => 0.0206173
+(2, 26) ~ (4, 24) => 0.10183
+(2, 26) ~ (4, 28) => 0.629162
+(2, 26) ~ (4, 34) => 0.0134891
+(2, 26) ~ (4, 35) => 0.0435539
+(2, 26) ~ (4, 36) => 0.0292252
+(2, 27) ~ (4, 18) => 0.0545301
+(2, 27) ~ (4, 21) => 0.0165803
+(2, 27) ~ (4, 23) => 0.0149166
+(2, 27) ~ (4, 24) => 0.0168673
+(2, 27) ~ (4, 25) => 0.0685298
+(2, 27) ~ (4, 29) => 0.611743
+(2, 27) ~ (4, 30) => 0.0193867
+(2, 27) ~ (4, 35) => 0.0121248
+(2, 27) ~ (4, 36) => 0.0525759
+(2, 27) ~ (4, 37) => 0.0312284
+(2, 28) ~ (4, 19) => 0.0536277
+(2, 28) ~ (4, 22) => 0.0149467
+(2, 28) ~ (4, 24) => 0.0165919
+(2, 28) ~ (4, 25) => 0.0180463
+(2, 28) ~ (4, 26) => 0.0384618
+(2, 28) ~ (4, 28) => 0.0159832
+(2, 28) ~ (4, 29) => 0.013103
+(2, 28) ~ (4, 30) => 0.60593
+(2, 28) ~ (4, 31) => 0.0227669
+(2, 28) ~ (4, 36) => 0.0144775
+(2, 28) ~ (4, 37) => 0.0556122
+(2, 28) ~ (4, 38) => 0.0311845
+(2, 28) ~ (4, 39) => 0.0107012
+(2, 29) ~ (4, 20) => 0.048755
+(2, 29) ~ (4, 25) => 0.0264382
+(2, 29) ~ (4, 26) => 0.0184859
+(2, 29) ~ (4, 28) => 0.0110817
+(2, 29) ~ (4, 29) => 0.0453943
+(2, 29) ~ (4, 30) => 0.0174069
+(2, 29) ~ (4, 31) => 0.572724
+(2, 29) ~ (4, 32) => 0.0257223
+(2, 29) ~ (4, 37) => 0.015401
+(2, 29) ~ (4, 38) => 0.0567127
+(2, 29) ~ (4, 39) => 0.0286675
+(2, 29) ~ (4, 40) => 0.0111553
+(2, 30) ~ (4, 21) => 0.0412323
+(2, 30) ~ (4, 23) => 0.0151097
+(2, 30) ~ (4, 26) => 0.0289787
+(2, 30) ~ (4, 27) => 0.0123347
+(2, 30) ~ (4, 29) => 0.0321478
+(2, 30) ~ (4, 30) => 0.0536235
+(2, 30) ~ (4, 31) => 0.0235189
+(2, 30) ~ (4, 32) => 0.40967
+(2, 30) ~ (4, 33) => 0.0225321
+(2, 30) ~ (4, 38) => 0.0181489
+(2, 30) ~ (4, 39) => 0.061002
+(2, 30) ~ (4, 40) => 0.0271024
+(2, 30) ~ (4, 41) => 0.0108536
+(2, 31) ~ (4, 22) => 0.028064
+(2, 31) ~ (4, 24) => 0.0264322
+(2, 31) ~ (4, 27) => 0.0269888
+(2, 31) ~ (4, 28) => 0.0158611
+(2, 31) ~ (4, 30) => 0.0415634
+(2, 31) ~ (4, 31) => 0.069801
+(2, 31) ~ (4, 32) => 0.0137445
+(2, 31) ~ (4, 33) => 0.200735
+(2, 31) ~ (4, 34) => 0.0193556
+(2, 31) ~ (4, 39) => 0.0241224
+(2, 31) ~ (4, 40) => 0.0699924
+(2, 31) ~ (4, 41) => 0.0249167
+(2, 31) ~ (4, 42) => 0.0105018
+(2, 32) ~ (4, 23) => 0.0136887
+(2, 32) ~ (4, 25) => 0.0282818
+(2, 32) ~ (4, 29) => 0.0114172
+(2, 32) ~ (4, 31) => 0.0589819
+(2, 32) ~ (4, 32) => 0.258287
+(2, 32) ~ (4, 33) => 0.0422695
+(2, 32) ~ (4, 34) => 0.0996642
+(2, 32) ~ (4, 40) => 0.0349906
+(2, 32) ~ (4, 41) => 0.0800872
+(2, 32) ~ (4, 42) => 0.0236234
+(2, 32) ~ (4, 43) => 0.0105396
+(2, 33) ~ (4, 26) => 0.0272326
+(2, 33) ~ (4, 32) => 0.0678857
+(2, 33) ~ (4, 33) => 0.419549
+(2, 33) ~ (4, 34) => 0.0618204
+(2, 33) ~ (4, 35) => 0.0860165
+(2, 33) ~ (4, 41) => 0.0373187
+(2, 33) ~ (4, 42) => 0.0834393
+(2, 33) ~ (4, 43) => 0.0225148
+(2, 33) ~ (4, 44) => 0.0104026
+(2, 34) ~ (4, 27) => 0.0278057
+(2, 34) ~ (4, 33) => 0.088788
+(2, 34) ~ (4, 34) => 0.477058
+(2, 34) ~ (4, 35) => 0.0675444
+(2, 34) ~ (4, 36) => 0.0774371
+(2, 34) ~ (4, 42) => 0.0371009
+(2, 34) ~ (4, 43) => 0.0842122
+(2, 34) ~ (4, 44) => 0.0201752
+(2, 35) ~ (4, 28) => 0.0286754
+(2, 35) ~ (4, 34) => 0.0837725
+(2, 35) ~ (4, 35) => 0.506085
+(2, 35) ~ (4, 36) => 0.0747323
+(2, 35) ~ (4, 37) => 0.0764505
+(2, 35) ~ (4, 43) => 0.0355005
+(2, 35) ~ (4, 44) => 0.0828104
+(2, 35) ~ (4, 45) => 0.0136008
+(2, 36) ~ (4, 29) => 0.027168
+(2, 36) ~ (4, 35) => 0.0643335
+(2, 36) ~ (4, 36) => 0.510644
+(2, 36) ~ (4, 37) => 0.0893118
+(2, 36) ~ (4, 38) => 0.0813454
+(2, 36) ~ (4, 44) => 0.0324763
+(2, 36) ~ (4, 45) => 0.0769031
+(2, 36) ~ (4, 46) => 0.0122441
+(2, 36) ~ (4, 47) => 0.0117149
+(2, 36) ~ (4, 48) => 0.017039
+(2, 37) ~ (4, 30) => 0.0229957
+(2, 37) ~ (4, 36) => 0.0706496
+(2, 37) ~ (4, 37) => 0.510045
+(2, 37) ~ (4, 38) => 0.100204
+(2, 37) ~ (4, 39) => 0.0855251
+(2, 37) ~ (4, 45) => 0.029787
+(2, 37) ~ (4, 46) => 0.0661604
+(2, 37) ~ (4, 48) => 0.0135499
+(2, 37) ~ (4, 49) => 0.0269367
+(2, 38) ~ (4, 31) => 0.0175032
+(2, 38) ~ (4, 37) => 0.0700266
+(2, 38) ~ (4, 38) => 0.500383
+(2, 38) ~ (4, 39) => 0.105014
+(2, 38) ~ (4, 40) => 0.0818513
+(2, 38) ~ (4, 46) => 0.0234666
+(2, 38) ~ (4, 47) => 0.045906
+(2, 38) ~ (4, 49) => 0.0131891
+(2, 38) ~ (4, 50) => 0.0505568
+(2, 39) ~ (4, 32) => 0.0174012
+(2, 39) ~ (4, 38) => 0.0729988
+(2, 39) ~ (4, 39) => 0.495093
+(2, 39) ~ (4, 40) => 0.111376
+(2, 39) ~ (4, 41) => 0.0786771
+(2, 39) ~ (4, 47) => 0.0283747
+(2, 39) ~ (4, 48) => 0.0460581
+(2, 39) ~ (4, 51) => 0.0545152
+(2, 40) ~ (4, 33) => 0.0162995
+(2, 40) ~ (4, 39) => 0.076679
+(2, 40) ~ (4, 40) => 0.493329
+(2, 40) ~ (4, 41) => 0.114089
+(2, 40) ~ (4, 42) => 0.0766321
+(2, 40) ~ (4, 48) => 0.0278742
+(2, 40) ~ (4, 49) => 0.0420016
+(2, 40) ~ (4, 51) => 0.0110042
+(2, 40) ~ (4, 52) => 0.0547848
+(2, 41) ~ (4, 34) => 0.0116131
+(2, 41) ~ (4, 40) => 0.0914023
+(2, 41) ~ (4, 41) => 0.473634
+(2, 41) ~ (4, 42) => 0.111796
+(2, 41) ~ (4, 43) => 0.0713917
+(2, 41) ~ (4, 49) => 0.0269032
+(2, 41) ~ (4, 50) => 0.0395052
+(2, 41) ~ (4, 52) => 0.0132486
+(2, 41) ~ (4, 53) => 0.0566103
+(2, 42) ~ (4, 40) => 0.010478
+(2, 42) ~ (4, 41) => 0.119968
+(2, 42) ~ (4, 42) => 0.468146
+(2, 42) ~ (4, 43) => 0.114051
+(2, 42) ~ (4, 44) => 0.0674412
+(2, 42) ~ (4, 49) => 0.0116669
+(2, 42) ~ (4, 50) => 0.0207721
+(2, 42) ~ (4, 51) => 0.0295392
+(2, 42) ~ (4, 53) => 0.012907
+(2, 42) ~ (4, 54) => 0.0614878
+(2, 43) ~ (4, 41) => 0.0117239
+(2, 43) ~ (4, 42) => 0.131597
+(2, 43) ~ (4, 43) => 0.455075
+(2, 43) ~ (4, 44) => 0.110172
+(2, 43) ~ (4, 45) => 0.0534491
+(2, 43) ~ (4, 50) => 0.0282732
+(2, 43) ~ (4, 51) => 0.0164233
+(2, 43) ~ (4, 52) => 0.0210911
+(2, 43) ~ (4, 53) => 0.0203271
+(2, 43) ~ (4, 54) => 0.0161768
+(2, 43) ~ (4, 55) => 0.0610701
+(2, 44) ~ (4, 42) => 0.0112944
+(2, 44) ~ (4, 43) => 0.139226
+(2, 44) ~ (4, 44) => 0.421492
+(2, 44) ~ (4, 45) => 0.0887165
+(2, 44) ~ (4, 46) => 0.040336
+(2, 44) ~ (4, 51) => 0.0649874
+(2, 44) ~ (4, 52) => 0.0112763
+(2, 44) ~ (4, 53) => 0.0119737
+(2, 44) ~ (4, 54) => 0.053519
+(2, 44) ~ (4, 55) => 0.0155204
+(2, 44) ~ (4, 56) => 0.0574473
+(2, 45) ~ (4, 44) => 0.142093
+(2, 45) ~ (4, 45) => 0.338973
+(2, 45) ~ (4, 46) => 0.077569
+(2, 45) ~ (4, 47) => 0.0328013
+(2, 45) ~ (4, 49) => 0.0101379
+(2, 45) ~ (4, 51) => 0.0124482
+(2, 45) ~ (4, 52) => 0.136998
+(2, 45) ~ (4, 54) => 0.0126651
+(2, 45) ~ (4, 55) => 0.0692334
+(2, 45) ~ (4, 56) => 0.0110808
+(2, 45) ~ (4, 57) => 0.0585642
+(2, 46) ~ (4, 45) => 0.128081
+(2, 46) ~ (4, 46) => 0.266793
+(2, 46) ~ (4, 47) => 0.066356
+(2, 46) ~ (4, 48) => 0.0234567
+(2, 46) ~ (4, 50) => 0.012666
+(2, 46) ~ (4, 52) => 0.0160433
+(2, 46) ~ (4, 53) => 0.241252
+(2, 46) ~ (4, 54) => 0.0103079
+(2, 46) ~ (4, 56) => 0.0726072
+(2, 46) ~ (4, 58) => 0.0620953
+(2, 47) ~ (4, 46) => 0.11423
+(2, 47) ~ (4, 47) => 0.204916
+(2, 47) ~ (4, 48) => 0.054265
+(2, 47) ~ (4, 49) => 0.0122485
+(2, 47) ~ (4, 51) => 0.0217386
+(2, 47) ~ (4, 53) => 0.0281462
+(2, 47) ~ (4, 54) => 0.278594
+(2, 47) ~ (4, 55) => 0.0621101
+(2, 47) ~ (4, 57) => 0.0578478
+(2, 47) ~ (4, 59) => 0.0566805
+(2, 48) ~ (4, 47) => 0.0887885
+(2, 48) ~ (4, 48) => 0.113481
+(2, 48) ~ (4, 49) => 0.0294213
+(2, 48) ~ (4, 50) => 0.0277509
+(2, 48) ~ (4, 52) => 0.0240366
+(2, 48) ~ (4, 53) => 0.0183568
+(2, 48) ~ (4, 54) => 0.0513192
+(2, 48) ~ (4, 55) => 0.316657
+(2, 48) ~ (4, 56) => 0.113577
+(2, 48) ~ (4, 58) => 0.039584
+(2, 48) ~ (4, 60) => 0.0580738
+(2, 49) ~ (4, 47) => 0.010221
+(2, 49) ~ (4, 48) => 0.0671802
+(2, 49) ~ (4, 49) => 0.031381
+(2, 49) ~ (4, 51) => 0.0425332
+(2, 49) ~ (4, 53) => 0.0248722
+(2, 49) ~ (4, 54) => 0.0435647
+(2, 49) ~ (4, 55) => 0.0433843
+(2, 49) ~ (4, 56) => 0.288596
+(2, 49) ~ (4, 57) => 0.256565
+(2, 49) ~ (4, 59) => 0.0262983
+(2, 49) ~ (4, 61) => 0.050732
+(2, 50) ~ (4, 49) => 0.0370334
+(2, 50) ~ (4, 50) => 0.0265945
+(2, 50) ~ (4, 52) => 0.0411731
+(2, 50) ~ (4, 54) => 0.0251351
+(2, 50) ~ (4, 55) => 0.0520817
+(2, 50) ~ (4, 56) => 0.0309156
+(2, 50) ~ (4, 57) => 0.281636
+(2, 50) ~ (4, 58) => 0.329423
+(2, 50) ~ (4, 60) => 0.0218362
+(2, 50) ~ (4, 62) => 0.0427575
+(2, 51) ~ (4, 51) => 0.0206836
+(2, 51) ~ (4, 53) => 0.0389724
+(2, 51) ~ (4, 56) => 0.0332808
+(2, 51) ~ (4, 57) => 0.0210553
+(2, 51) ~ (4, 58) => 0.261659
+(2, 51) ~ (4, 59) => 0.481388
+(2, 51) ~ (4, 63) => 0.0250212
+(2, 52) ~ (4, 52) => 0.017403
+(2, 52) ~ (4, 54) => 0.0313144
+(2, 52) ~ (4, 58) => 0.0163025
+(2, 52) ~ (4, 59) => 0.226902
+(2, 52) ~ (4, 60) => 0.569504
+(2, 52) ~ (4, 64) => 0.0147197
+(2, 53) ~ (4, 53) => 0.0109879
+(2, 53) ~ (4, 55) => 0.0228179
+(2, 53) ~ (4, 59) => 0.0133433
+(2, 53) ~ (4, 60) => 0.208012
+(2, 53) ~ (4, 61) => 0.63705
+(2, 54) ~ (4, 56) => 0.0137268
+(2, 54) ~ (4, 60) => 0.0124162
+(2, 54) ~ (4, 61) => 0.188405
+(2, 54) ~ (4, 62) => 0.690922
+(2, 55) ~ (4, 61) => 0.010233
+(2, 55) ~ (4, 62) => 0.16719
+(2, 55) ~ (4, 63) => 0.746819
+(2, 56) ~ (4, 63) => 0.148808
+(2, 56) ~ (4, 64) => 0.792702
+(2, 57) ~ (4, 64) => 0.126001
+(2, 57) ~ (4, 65) => 0.839467
+(2, 58) ~ (4, 65) => 0.101762
+(2, 58) ~ (4, 66) => 0.875193
+(2, 59) ~ (4, 66) => 0.0770482
+(2, 59) ~ (4, 67) => 0.907624
+(2, 60) ~ (4, 67) => 0.0518415
+(2, 60) ~ (4, 68) => 0.938915
+(2, 61) ~ (4, 68) => 0.0344177
+(2, 61) ~ (4, 69) => 0.959284
+(2, 62) ~ (4, 69) => 0.0276166
+(2, 62) ~ (4, 70) => 0.96798
+
+; gap posteriors
+(2, 0) ~ (4, -1) => 0.00145835
+(2, 1) ~ (4, -1) => 0.00457394
+(2, 2) ~ (4, -1) => 0.0113339
+(2, 3) ~ (4, -1) => 0.0178
+(2, 4) ~ (4, -1) => 0.0120469
+(2, 5) ~ (4, -1) => 0.0163938
+(2, 6) ~ (4, -1) => 0.0181152
+(2, 7) ~ (4, -1) => 0.0212082
+(2, 8) ~ (4, -1) => 0.0271727
+(2, 9) ~ (4, -1) => 0.034118
+(2, 10) ~ (4, -1) => 0.0499147
+(2, 11) ~ (4, -1) => 0.0656988
+(2, 12) ~ (4, -1) => 0.0855329
+(2, 13) ~ (4, -1) => 0.105528
+(2, 14) ~ (4, -1) => 0.138896
+(2, 15) ~ (4, -1) => 0.166902
+(2, 16) ~ (4, -1) => 0.200979
+(2, 17) ~ (4, -1) => 0.22567
+(2, 18) ~ (4, -1) => 0.245282
+(2, 19) ~ (4, -1) => 0.209971
+(2, 20) ~ (4, -1) => 0.163088
+(2, 21) ~ (4, -1) => 0.114996
+(2, 22) ~ (4, -1) => 0.106411
+(2, 23) ~ (4, -1) => 0.0927752
+(2, 24) ~ (4, -1) => 0.0908801
+(2, 25) ~ (4, -1) => 0.08764
+(2, 26) ~ (4, -1) => 0.090675
+(2, 27) ~ (4, -1) => 0.101518
+(2, 28) ~ (4, -1) => 0.0885668
+(2, 29) ~ (4, -1) => 0.122055
+(2, 30) ~ (4, -1) => 0.243746
+(2, 31) ~ (4, -1) => 0.427921
+(2, 32) ~ (4, -1) => 0.338169
+(2, 33) ~ (4, -1) => 0.183821
+(2, 34) ~ (4, -1) => 0.119878
+(2, 35) ~ (4, -1) => 0.0983728
+(2, 36) ~ (4, -1) => 0.0768198
+(2, 37) ~ (4, -1) => 0.0741467
+(2, 38) ~ (4, -1) => 0.0921037
+(2, 39) ~ (4, -1) => 0.0955057
+(2, 40) ~ (4, -1) => 0.0873058
+(2, 41) ~ (4, -1) => 0.103895
+(2, 42) ~ (4, -1) => 0.0835427
+(2, 43) ~ (4, -1) => 0.0746221
+(2, 44) ~ (4, -1) => 0.0842112
+(2, 45) ~ (4, -1) => 0.0974357
+(2, 46) ~ (4, -1) => 0.100342
+(2, 47) ~ (4, -1) => 0.109223
+(2, 48) ~ (4, -1) => 0.118954
+(2, 49) ~ (4, -1) => 0.114672
+(2, 50) ~ (4, -1) => 0.111414
+(2, 51) ~ (4, -1) => 0.117939
+(2, 52) ~ (4, -1) => 0.123854
+(2, 53) ~ (4, -1) => 0.10779
+(2, 54) ~ (4, -1) => 0.0945296
+(2, 55) ~ (4, -1) => 0.0757575
+(2, 56) ~ (4, -1) => 0.0584903
+(2, 57) ~ (4, -1) => 0.0345322
+(2, 58) ~ (4, -1) => 0.0230455
+(2, 59) ~ (4, -1) => 0.0153277
+(2, 60) ~ (4, -1) => 0.00924337
+(2, 61) ~ (4, -1) => 0.00629866
+(2, 62) ~ (4, -1) => 0.00440294
+
+(2, -1) ~ (4, 0) => 0.00145835
+(2, -1) ~ (4, 1) => 0.00457394
+(2, -1) ~ (4, 2) => 0.0113339
+(2, -1) ~ (4, 3) => 0.0178
+(2, -1) ~ (4, 4) => 0.0237629
+(2, -1) ~ (4, 5) => 0.0182473
+(2, -1) ~ (4, 6) => 0.0173745
+(2, -1) ~ (4, 7) => 0.0201079
+(2, -1) ~ (4, 8) => 0.02679
+(2, -1) ~ (4, 9) => 0.054195
+(2, -1) ~ (4, 10) => 0.0574693
+(2, -1) ~ (4, 11) => 0.0622358
+(2, -1) ~ (4, 12) => 0.0643405
+(2, -1) ~ (4, 13) => 0.0569663
+(2, -1) ~ (4, 14) => 0.0666182
+(2, -1) ~ (4, 15) => 0.0777789
+(2, -1) ~ (4, 16) => 0.111015
+(2, -1) ~ (4, 17) => 0.204611
+(2, -1) ~ (4, 18) => 0.399836
+(2, -1) ~ (4, 19) => 0.363226
+(2, -1) ~ (4, 20) => 0.153688
+(2, -1) ~ (4, 21) => 0.207969
+(2, -1) ~ (4, 22) => 0.257586
+(2, -1) ~ (4, 23) => 0.267052
+(2, -1) ~ (4, 24) => 0.29294
+(2, -1) ~ (4, 25) => 0.293276
+(2, -1) ~ (4, 26) => 0.284351
+(2, -1) ~ (4, 27) => 0.295261
+(2, -1) ~ (4, 28) => 0.280734
+(2, -1) ~ (4, 29) => 0.238287
+(2, -1) ~ (4, 30) => 0.216545
+(2, -1) ~ (4, 31) => 0.198974
+(2, -1) ~ (4, 32) => 0.166097
+(2, -1) ~ (4, 33) => 0.164116
+(2, -1) ~ (4, 34) => 0.173205
+(2, -1) ~ (4, 35) => 0.190488
+(2, -1) ~ (4, 36) => 0.170258
+(2, -1) ~ (4, 37) => 0.151924
+(2, -1) ~ (4, 38) => 0.139023
+(2, -1) ~ (4, 39) => 0.113196
+(2, -1) ~ (4, 40) => 0.0683219
+(2, -1) ~ (4, 41) => 0.0487309
+(2, -1) ~ (4, 42) => 0.0458689
+(2, -1) ~ (4, 43) => 0.0674903
+(2, -1) ~ (4, 44) => 0.112937
+(2, -1) ~ (4, 45) => 0.27049
+(2, -1) ~ (4, 46) => 0.399201
+(2, -1) ~ (4, 47) => 0.510922
+(2, -1) ~ (4, 48) => 0.637096
+(2, -1) ~ (4, 49) => 0.75908
+(2, -1) ~ (4, 50) => 0.793881
+(2, -1) ~ (4, 51) => 0.726127
+(2, -1) ~ (4, 52) => 0.663945
+(2, -1) ~ (4, 53) => 0.535594
+(2, -1) ~ (4, 54) => 0.415915
+(2, -1) ~ (4, 55) => 0.357125
+(2, -1) ~ (4, 56) => 0.378768
+(2, -1) ~ (4, 57) => 0.324332
+(2, -1) ~ (4, 58) => 0.290936
+(2, -1) ~ (4, 59) => 0.195387
+(2, -1) ~ (4, 60) => 0.130158
+(2, -1) ~ (4, 61) => 0.11358
+(2, -1) ~ (4, 62) => 0.0991303
+(2, -1) ~ (4, 63) => 0.0793515
+(2, -1) ~ (4, 64) => 0.0665778
+(2, -1) ~ (4, 65) => 0.0587713
+(2, -1) ~ (4, 66) => 0.0477591
+(2, -1) ~ (4, 67) => 0.0405344
+(2, -1) ~ (4, 68) => 0.0266672
+(2, -1) ~ (4, 69) => 0.0130997
+(2, -1) ~ (4, 70) => 0.0320196
+
+; Sparse posterior probability matrix for sequences 3 and 4
+; Format is:
+;   (3, position_1) ~ (4, position_2) => prob
+; which means that (3, position_1) is aligned to (4, position_2) with probability prob.
+;   (3, position_1) ~ (4, -1) => prob
+; means that (3, position_1) is aligned to a gap in 4 with probability prob.
+; sequence is 0-based and position is 0-based
+
+; match posteriors
+(3, 0) ~ (4, 0) => 0.997285
+(3, 1) ~ (4, 1) => 0.992992
+(3, 2) ~ (4, 2) => 0.988812
+(3, 3) ~ (4, 3) => 0.983294
+(3, 4) ~ (4, 4) => 0.971159
+(3, 5) ~ (4, 5) => 0.964403
+(3, 6) ~ (4, 6) => 0.932676
+(3, 7) ~ (4, 4) => 0.0138149
+(3, 7) ~ (4, 7) => 0.901384
+(3, 8) ~ (4, 5) => 0.0165789
+(3, 8) ~ (4, 8) => 0.871325
+(3, 9) ~ (4, 6) => 0.0441118
+(3, 9) ~ (4, 9) => 0.80773
+(3, 10) ~ (4, 7) => 0.0721722
+(3, 10) ~ (4, 10) => 0.742859
+(3, 10) ~ (4, 11) => 0.0103132
+(3, 11) ~ (4, 8) => 0.101789
+(3, 11) ~ (4, 11) => 0.722337
+(3, 11) ~ (4, 12) => 0.0104381
+(3, 12) ~ (4, 9) => 0.164341
+(3, 12) ~ (4, 12) => 0.712839
+(3, 13) ~ (4, 10) => 0.225053
+(3, 13) ~ (4, 13) => 0.709947
+(3, 14) ~ (4, 11) => 0.245643
+(3, 14) ~ (4, 14) => 0.703531
+(3, 15) ~ (4, 12) => 0.25589
+(3, 15) ~ (4, 15) => 0.695015
+(3, 16) ~ (4, 13) => 0.258876
+(3, 16) ~ (4, 16) => 0.685029
+(3, 17) ~ (4, 14) => 0.265331
+(3, 17) ~ (4, 17) => 0.676414
+(3, 17) ~ (4, 18) => 0.0128501
+(3, 18) ~ (4, 12) => 0.0104514
+(3, 18) ~ (4, 15) => 0.271436
+(3, 18) ~ (4, 18) => 0.655436
+(3, 18) ~ (4, 19) => 0.0279704
+(3, 19) ~ (4, 13) => 0.0112605
+(3, 19) ~ (4, 16) => 0.277563
+(3, 19) ~ (4, 19) => 0.620308
+(3, 19) ~ (4, 20) => 0.0424477
+(3, 19) ~ (4, 21) => 0.0149749
+(3, 20) ~ (4, 14) => 0.0118974
+(3, 20) ~ (4, 17) => 0.277555
+(3, 20) ~ (4, 20) => 0.596722
+(3, 20) ~ (4, 21) => 0.0403282
+(3, 20) ~ (4, 22) => 0.0436599
+(3, 21) ~ (4, 15) => 0.0122614
+(3, 21) ~ (4, 18) => 0.268807
+(3, 21) ~ (4, 21) => 0.373359
+(3, 21) ~ (4, 22) => 0.0585173
+(3, 21) ~ (4, 23) => 0.259138
+(3, 22) ~ (4, 16) => 0.0126356
+(3, 22) ~ (4, 19) => 0.259571
+(3, 22) ~ (4, 22) => 0.233008
+(3, 22) ~ (4, 23) => 0.066998
+(3, 22) ~ (4, 24) => 0.397471
+(3, 23) ~ (4, 17) => 0.0128529
+(3, 23) ~ (4, 20) => 0.25384
+(3, 23) ~ (4, 23) => 0.149743
+(3, 23) ~ (4, 24) => 0.0764351
+(3, 23) ~ (4, 25) => 0.476947
+(3, 24) ~ (4, 18) => 0.0117948
+(3, 24) ~ (4, 21) => 0.164833
+(3, 24) ~ (4, 24) => 0.0405693
+(3, 24) ~ (4, 25) => 0.0595401
+(3, 24) ~ (4, 26) => 0.697766
+(3, 25) ~ (4, 19) => 0.0109566
+(3, 25) ~ (4, 22) => 0.0747387
+(3, 25) ~ (4, 25) => 0.0173782
+(3, 25) ~ (4, 26) => 0.0392685
+(3, 25) ~ (4, 27) => 0.834523
+(3, 26) ~ (4, 20) => 0.010506
+(3, 26) ~ (4, 23) => 0.0238937
+(3, 26) ~ (4, 27) => 0.029038
+(3, 26) ~ (4, 28) => 0.913101
+(3, 27) ~ (4, 24) => 0.0125322
+(3, 27) ~ (4, 28) => 0.0173845
+(3, 27) ~ (4, 29) => 0.942428
+(3, 28) ~ (4, 25) => 0.0100139
+(3, 28) ~ (4, 29) => 0.0150017
+(3, 28) ~ (4, 30) => 0.952637
+(3, 29) ~ (4, 30) => 0.011663
+(3, 29) ~ (4, 31) => 0.963971
+(3, 30) ~ (4, 32) => 0.971813
+(3, 31) ~ (4, 33) => 0.975934
+(3, 32) ~ (4, 34) => 0.981038
+(3, 33) ~ (4, 35) => 0.985724
+(3, 34) ~ (4, 36) => 0.989666
+(3, 35) ~ (4, 37) => 0.991388
+(3, 36) ~ (4, 38) => 0.99414
+(3, 37) ~ (4, 39) => 0.996371
+(3, 38) ~ (4, 40) => 0.998076
+(3, 39) ~ (4, 41) => 0.998239
+(3, 40) ~ (4, 42) => 0.998395
+(3, 41) ~ (4, 43) => 0.998593
+(3, 42) ~ (4, 44) => 0.998744
+(3, 43) ~ (4, 45) => 0.998774
+(3, 44) ~ (4, 46) => 0.998657
+(3, 45) ~ (4, 47) => 0.99856
+(3, 46) ~ (4, 48) => 0.998716
+(3, 47) ~ (4, 49) => 0.998885
+(3, 48) ~ (4, 50) => 0.998833
+(3, 49) ~ (4, 51) => 0.998673
+(3, 50) ~ (4, 52) => 0.998235
+(3, 51) ~ (4, 53) => 0.998379
+(3, 52) ~ (4, 54) => 0.998923
+(3, 53) ~ (4, 55) => 0.999092
+(3, 54) ~ (4, 56) => 0.999044
+(3, 55) ~ (4, 57) => 0.998946
+(3, 56) ~ (4, 58) => 0.999078
+(3, 57) ~ (4, 59) => 0.999169
+(3, 58) ~ (4, 60) => 0.999287
+(3, 59) ~ (4, 61) => 0.999352
+(3, 60) ~ (4, 62) => 0.999499
+(3, 61) ~ (4, 63) => 0.999638
+(3, 62) ~ (4, 64) => 0.999671
+(3, 63) ~ (4, 65) => 0.999653
+(3, 64) ~ (4, 66) => 0.999679
+(3, 65) ~ (4, 67) => 0.999716
+(3, 66) ~ (4, 68) => 0.999772
+(3, 67) ~ (4, 69) => 0.999893
+(3, 68) ~ (4, 70) => 0.999934
+
+; gap posteriors
+(3, 0) ~ (4, -1) => 0.00271541
+(3, 1) ~ (4, -1) => 0.00700843
+(3, 2) ~ (4, -1) => 0.0111883
+(3, 3) ~ (4, -1) => 0.0167065
+(3, 4) ~ (4, -1) => 0.0288411
+(3, 5) ~ (4, -1) => 0.0355971
+(3, 6) ~ (4, -1) => 0.0673243
+(3, 7) ~ (4, -1) => 0.084801
+(3, 8) ~ (4, -1) => 0.112096
+(3, 9) ~ (4, -1) => 0.148158
+(3, 10) ~ (4, -1) => 0.174656
+(3, 11) ~ (4, -1) => 0.165435
+(3, 12) ~ (4, -1) => 0.12282
+(3, 13) ~ (4, -1) => 0.0650001
+(3, 14) ~ (4, -1) => 0.0508256
+(3, 15) ~ (4, -1) => 0.0490953
+(3, 16) ~ (4, -1) => 0.0560949
+(3, 17) ~ (4, -1) => 0.0454046
+(3, 18) ~ (4, -1) => 0.034706
+(3, 19) ~ (4, -1) => 0.0334462
+(3, 20) ~ (4, -1) => 0.0298373
+(3, 21) ~ (4, -1) => 0.0279173
+(3, 22) ~ (4, -1) => 0.0303174
+(3, 23) ~ (4, -1) => 0.0301821
+(3, 24) ~ (4, -1) => 0.0254968
+(3, 25) ~ (4, -1) => 0.0231351
+(3, 26) ~ (4, -1) => 0.0234612
+(3, 27) ~ (4, -1) => 0.0276558
+(3, 28) ~ (4, -1) => 0.0223477
+(3, 29) ~ (4, -1) => 0.0243657
+(3, 30) ~ (4, -1) => 0.0281865
+(3, 31) ~ (4, -1) => 0.0240664
+(3, 32) ~ (4, -1) => 0.0189616
+(3, 33) ~ (4, -1) => 0.0142764
+(3, 34) ~ (4, -1) => 0.0103343
+(3, 35) ~ (4, -1) => 0.0086115
+(3, 36) ~ (4, -1) => 0.00586039
+(3, 37) ~ (4, -1) => 0.00362867
+(3, 38) ~ (4, -1) => 0.00192404
+(3, 39) ~ (4, -1) => 0.00176054
+(3, 40) ~ (4, -1) => 0.0016048
+(3, 41) ~ (4, -1) => 0.00140727
+(3, 42) ~ (4, -1) => 0.00125629
+(3, 43) ~ (4, -1) => 0.00122613
+(3, 44) ~ (4, -1) => 0.00134307
+(3, 45) ~ (4, -1) => 0.00144017
+(3, 46) ~ (4, -1) => 0.0012843
+(3, 47) ~ (4, -1) => 0.0011152
+(3, 48) ~ (4, -1) => 0.00116652
+(3, 49) ~ (4, -1) => 0.00132734
+(3, 50) ~ (4, -1) => 0.0017646
+(3, 51) ~ (4, -1) => 0.00162137
+(3, 52) ~ (4, -1) => 0.00107741
+(3, 53) ~ (4, -1) => 0.000908136
+(3, 54) ~ (4, -1) => 0.000956237
+(3, 55) ~ (4, -1) => 0.00105375
+(3, 56) ~ (4, -1) => 0.000921726
+(3, 57) ~ (4, -1) => 0.00083077
+(3, 58) ~ (4, -1) => 0.000712752
+(3, 59) ~ (4, -1) => 0.000647902
+(3, 60) ~ (4, -1) => 0.000500739
+(3, 61) ~ (4, -1) => 0.000361562
+(3, 62) ~ (4, -1) => 0.000329196
+(3, 63) ~ (4, -1) => 0.000346661
+(3, 64) ~ (4, -1) => 0.000320613
+(3, 65) ~ (4, -1) => 0.000283718
+(3, 66) ~ (4, -1) => 0.000228167
+(3, 67) ~ (4, -1) => 0.000107467
+(3, 68) ~ (4, -1) => 0.0001
+
+(3, -1) ~ (4, 0) => 0.00271541
+(3, -1) ~ (4, 1) => 0.00700843
+(3, -1) ~ (4, 2) => 0.0111883
+(3, -1) ~ (4, 3) => 0.0167065
+(3, -1) ~ (4, 4) => 0.0150261
+(3, -1) ~ (4, 5) => 0.0190183
+(3, -1) ~ (4, 6) => 0.0232125
+(3, -1) ~ (4, 7) => 0.0264437
+(3, -1) ~ (4, 8) => 0.0268854
+(3, -1) ~ (4, 9) => 0.0279289
+(3, -1) ~ (4, 10) => 0.032088
+(3, -1) ~ (4, 11) => 0.0217061
+(3, -1) ~ (4, 12) => 0.010382
+(3, -1) ~ (4, 13) => 0.0199166
+(3, -1) ~ (4, 14) => 0.0192406
+(3, -1) ~ (4, 15) => 0.0212876
+(3, -1) ~ (4, 16) => 0.0247724
+(3, -1) ~ (4, 17) => 0.0331775
+(3, -1) ~ (4, 18) => 0.0511122
+(3, -1) ~ (4, 19) => 0.0811947
+(3, -1) ~ (4, 20) => 0.096484
+(3, -1) ~ (4, 21) => 0.406505
+(3, -1) ~ (4, 22) => 0.590076
+(3, -1) ~ (4, 23) => 0.500228
+(3, -1) ~ (4, 24) => 0.472993
+(3, -1) ~ (4, 25) => 0.436121
+(3, -1) ~ (4, 26) => 0.262965
+(3, -1) ~ (4, 27) => 0.136439
+(3, -1) ~ (4, 28) => 0.0695145
+(3, -1) ~ (4, 29) => 0.0425707
+(3, -1) ~ (4, 30) => 0.0357003
+(3, -1) ~ (4, 31) => 0.0360287
+(3, -1) ~ (4, 32) => 0.0281865
+(3, -1) ~ (4, 33) => 0.0240664
+(3, -1) ~ (4, 34) => 0.0189616
+(3, -1) ~ (4, 35) => 0.0142764
+(3, -1) ~ (4, 36) => 0.0103343
+(3, -1) ~ (4, 37) => 0.0086115
+(3, -1) ~ (4, 38) => 0.00586039
+(3, -1) ~ (4, 39) => 0.00362867
+(3, -1) ~ (4, 40) => 0.00192404
+(3, -1) ~ (4, 41) => 0.00176054
+(3, -1) ~ (4, 42) => 0.0016048
+(3, -1) ~ (4, 43) => 0.00140727
+(3, -1) ~ (4, 44) => 0.00125629
+(3, -1) ~ (4, 45) => 0.00122613
+(3, -1) ~ (4, 46) => 0.00134307
+(3, -1) ~ (4, 47) => 0.00144017
+(3, -1) ~ (4, 48) => 0.0012843
+(3, -1) ~ (4, 49) => 0.0011152
+(3, -1) ~ (4, 50) => 0.00116652
+(3, -1) ~ (4, 51) => 0.00132734
+(3, -1) ~ (4, 52) => 0.0017646
+(3, -1) ~ (4, 53) => 0.00162137
+(3, -1) ~ (4, 54) => 0.00107741
+(3, -1) ~ (4, 55) => 0.000908136
+(3, -1) ~ (4, 56) => 0.000956237
+(3, -1) ~ (4, 57) => 0.00105375
+(3, -1) ~ (4, 58) => 0.000921726
+(3, -1) ~ (4, 59) => 0.00083077
+(3, -1) ~ (4, 60) => 0.000712752
+(3, -1) ~ (4, 61) => 0.000647902
+(3, -1) ~ (4, 62) => 0.000500739
+(3, -1) ~ (4, 63) => 0.000361562
+(3, -1) ~ (4, 64) => 0.000329196
+(3, -1) ~ (4, 65) => 0.000346661
+(3, -1) ~ (4, 66) => 0.000320613
+(3, -1) ~ (4, 67) => 0.000283718
+(3, -1) ~ (4, 68) => 0.000228167
+(3, -1) ~ (4, 69) => 0.000107467
+(3, -1) ~ (4, 70) => 0.0001
+
diff --git a/examples/tRNA.aln1.mfa b/examples/tRNA.aln1.mfa
new file mode 100644
index 0000000..ce0e381
--- /dev/null
+++ b/examples/tRNA.aln1.mfa
@@ -0,0 +1,11 @@
+>AE004843.1-4972_4900
+GCUCAUGUAGCUCAGUUGGUAGAGCACACCCUUGGUAAGGGUGAGGUCAG-CGGUUCAAAUCCGCUCAUGAGCU
+>Z82044.1-16031_16103
+GCGGUUGUGGCGAAGUGGUUAACGCACCAGAUUGUGGCUCUGGCACUCGU-GGGUUCGAUUCCCAUCAAUCGCC
+>M83762.1-1031_1093
+GCUUUAAAAGCUUUGCUGAA---GCAACGGCCUUGUAAGUCGUAG-AAAAC-------UAUACGUUUUAAAGCU
+>AB042432.1-14140_14072
+GUUUCUGUAGUUGAAUUACA---ACGAUGAUUUUUCAUGUCAUUG-GUCG-CAGUUGAAUGCUGUGUAGAAAUA
+>AC008670.6-83725_83795
+ACUUUUAAAGGAUAACAGCCAUC-CGUUGGUCUUAGGCCCCAAAA-AUUU-UGGUGCAACUCCAAAUAAAAGUA
+
diff --git a/examples/tRNA.aln1.reference.mfa b/examples/tRNA.aln1.reference.mfa
new file mode 100644
index 0000000..0bde3f9
--- /dev/null
+++ b/examples/tRNA.aln1.reference.mfa
@@ -0,0 +1,15 @@
+>AE004843.1-4972_4900
+GCUCAUGUAGCUCAGUUGGU-AGAGCACACCCUUGGUAAGGGUGAGGUCA
+GCGGUUCAAAUCCGCUCAUGAGCU
+>Z82044.1-16031_16103
+GCGGUUGUGGCGAAGU-GGUUAACGCACCAGAUUGUGGCUCUGGCACUCG
+UGGGUUCGAUUCCCAUCAAUCGCC
+>M83762.1-1031_1093
+GCUUUAAAAGCUUUG--CU--GAAGCAACGGCCUUGUAAGUCGUAGA-AA
+AC---UAUAC---GUUUUAAAGCU
+>AB042432.1-14140_14072
+GUUUCUGUAGUUGAA--UU--ACAACGAUGAUUUUUCAUGUCAUUGG-UC
+GCAGUUGAAUGCUGUGUAGAAAUA
+>AC008670.6-83725_83795
+ACUUUUAAAGGAUAAC-AGC-CAUCCGUUGGUCUUAGGCCCCAAAAA-UU
+UUGGUGCAACUCCAAAUAAAAGUA
diff --git a/examples/tRNA.aln1.reference.stock b/examples/tRNA.aln1.reference.stock
new file mode 100644
index 0000000..5c5c87d
--- /dev/null
+++ b/examples/tRNA.aln1.reference.stock
@@ -0,0 +1,13 @@
+# STOCKHOLM 1.0
+AB042432.1-14140_14072         GUUUCUGUAGUUGAA--UU--ACAACGAUGAUUUUUCAUGUCAUUGG-UCGCAGUUGAAUGCUGUGUAGAAAUA
+#=GR AB042432.1-14140_14072 SS <<<<<<<--<<<<--------->>>>-<<<<<------->>>>>-----<<<<<------->>>>>>>>>>>>-
+Z82044.1-16031_16103           GCGGUUGUGGCGAAGU-GGUUAACGCACCAGAUUGUGGCUCUGGCACUCGUGGGUUCGAUUCCCAUCAAUCGCC
+#=GR Z82044.1-16031_16103 SS   <<<<<<<--<<<<--------->>>>-<<<<<------->>>>>-----<<<<<------->>>>>>>>>>>>-
+AC008670.6-83725_83795         ACUUUUAAAGGAUAAC-AGC-CAUCCGUUGGUCUUAGGCCCCAAAAA-UUUUGGUGCAACUCCAAAUAAAAGUA
+#=GR AC008670.6-83725_83795 SS <<<<<<<--<<<<--------->>>>-<<<<<------->>>>>-----<<<<<------->>>>>>>>>>>>-
+AE004843.1-4972_4900           GCUCAUGUAGCUCAGUUGGU-AGAGCACACCCUUGGUAAGGGUGAGGUCAGCGGUUCAAAUCCGCUCAUGAGCU
+#=GR AE004843.1-4972_4900 SS   <<<<<<<--<<<<--------->>>>-<<<<<------->>>>>-----<<<<<------->>>>>>>>>>>>-
+M83762.1-1031_1093             GCUUUAAAAGCUUUG--CU--GAAGCAACGGCCUUGUAAGUCGUAGA-AAAC---UAUAC---GUUUUAAAGCU
+#=GR M83762.1-1031_1093 SS     <<<<<<<--<<<<--------->>>>-<<<<<------->>>>>-----<<<----------->>>>>>>>>>-
+#=GC SS_cons                   <<<<<<<..<<<<.........>>>>.<<<<<.......>>>>>.....<<<<<.......>>>>>>>>>>>>.
+//
diff --git a/examples/tRNA.aln1.stock b/examples/tRNA.aln1.stock
new file mode 100644
index 0000000..9b18270
--- /dev/null
+++ b/examples/tRNA.aln1.stock
@@ -0,0 +1,9 @@
+# STOCKHOLM 1.0
+#=GF Accuracy          0.702093
+AE004843.1-4972_4900   GCUCAUGUAGCUCAGUUGGUAGAGCACACCCUUGGUAAGGGUGAGGUCAG-CGGUUCAAAUCCGCUCAUGAGCU
+Z82044.1-16031_16103   GCGGUUGUGGCGAAGUGGUUAACGCACCAGAUUGUGGCUCUGGCACUCGU-GGGUUCGAUUCCCAUCAAUCGCC
+M83762.1-1031_1093     GCUUUAAAAGCUUUGCUGAA---GCAACGGCCUUGUAAGUCGUAG-AAAAC-------UAUACGUUUUAAAGCU
+AB042432.1-14140_14072 GUUUCUGUAGUUGAAUUACA---ACGAUGAUUUUUCAUGUCAUUG-GUCG-CAGUUGAAUGCUGUGUAGAAAUA
+AC008670.6-83725_83795 ACUUUUAAAGGAUAACAGCCAUC-CGUUGGUCUUAGGCCCCAAAA-AUUU-UGGUGCAACUCCAAAUAAAAGUA
+#=GC Accuracy          99999999999988888776555455555555544444444444434444066667776667778888999999
+//
diff --git a/html/FAQ.html b/html/FAQ.html
new file mode 100644
index 0000000..8eff1a4
--- /dev/null
+++ b/html/FAQ.html
@@ -0,0 +1,532 @@
+
+<HTML>
+  <HEAD>
+
+    <link rel = "stylesheet" href = "pretty.css" type = "text/css"> 
+
+    <TITLE>FSA Frequently Asked Questions</TITLE>
+    <META NAME="version" content="0.9" />
+    <META NAME="keywords" CONTENT="FSA, fast statistical alignment, multiple sequence alignment, statistical alignment, bioinformatics, sequence annealing">
+    <META NAME="description" CONTENT="FSA Frequently Asked Questions">
+    <META NAME="ROBOTS" CONTENT="ALL">
+    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+    <!-- ImageReady Preload Script (faq.tif) -->
+  </HEAD>
+
+
+  <BODY BGCOLOR=#FFFFFF ONLOAD="preloadImages();">
+
+    <h1><a href="http://fsa.sourceforge.net/index.html">FSA</a> Frequently Asked Questions</h1>
+
+    <h2>Introduction</h2>
+    <ul>
+      <li><a href = "#intro">What is FSA?</a></li>
+      <li><a href = "#acronym">What does FSA stand for?</a></li>
+      <li><a href = "#install"> How do I download and install FSA?</a></li>
+      <li><a href = "#runfsa">How do I run FSA?</a></li>
+      <li><a href = "#server">Is there a webserver for FSA?</a></li>
+      <li><a href = "#help"> How do I get a help message to explain the options?</a></li>
+    </ul>
+
+    <h2>Alignments</h2>
+    <ul>
+      <li><a href = "#manyseqs"> How do I align many sequences?</a></li>
+      <li><a href = "#longseqs"> How do I align long sequences?</a></li>
+      <li><a href = "#genomes"> How do I align genomes?</a></li>
+      <li><a href = "#manygaps">Why are there so many gaps in my alignment?</a></li>
+      <li><a href = "#gapfactor">How do I control the sensitivity/specificity tradeoff of my alignment?</a></li>
+    </ul>
+
+    <h2>Visualization</h2>
+    <ul>
+      <li><a href="#gui">How do I visualize the alignments produced by FSA?</a></li>
+      <li><a href = "#reliable">How do I see what parts of my alignment are the most reliable?</a></li>
+    </ul>
+
+    <h2>Output formats and tools</h2>
+    <ul>
+      <li><a href = "#stockholm"> How do I parse Stockholm alignments?</a></li>
+      <li><a href = "#comparealign"> How do I compare alignments?</a></li>
+    </ul>
+
+    <h2>Troubleshooting</h2>
+    <ul>
+      <li> <a href = "#logging"> My alignment is taking a long time.  How do I see what FSA is doing?</a>
+      <li> <a href = "#gui_memory">I'm getting memory errors when using the GUI.</a>
+      <li> <a href = "#malloc">I get out-of-memory (bad alloc) errors when I try to align long sequences.</a>
+    </ul>
+
+    <h2>More information</h2>
+    <ul>
+      <li><a href = "#contact"> How do I contact you?</a></li>
+      <li><a href = "#citation"> How do I cite FSA?</a></li>
+      <li><a href = "#license"> Under what license is FSA distributed?</a></li>
+      <li><a href = "#git"> How do I become an FSA developer?</a></li>
+      <li><a href = "#influences"> What other programs influenced the development of FSA?</a></li>
+    </ul>
+
+
+    <!-- Introduction -->
+    <hr>
+    <h2>Introduction</h2>
+
+    <h4><a name = "intro">What is FSA?</a></h4>
+
+    FSA is a probabilistic multiple sequence alignment algorithm which uses
+    a "distance-based" approach to aligning homologous protein, RNA or DNA
+    sequences.  Much as distance-based phylogenetic reconstruction methods
+    like Neighbor-Joining build a phylogeny using only pairwise divergence
+    estimates, FSA builds a multiple alignment using only pairwise
+    estimations of homology.  This is made possible by the sequence
+    annealing technique for constructing a multiple alignment from pairwise
+    comparisons, developed by Ariel Schwartz in
+    <a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2007/EECS-2007-39.html">
+    "Posterior Decoding Methods for Optimization and Control of Multiple
+    Alignments</a>."
+
+    <p>
+      FSA brings the high accuracies previously available only for small-scale analyses of proteins or RNAs
+      to large-scale problems such as aligning thousands of sequences or megabase-long sequences.
+      FSA introduces several novel methods for constructing better alignments:
+      <ul>
+	<li type=square>
+	  FSA uses machine-learning techniques to estimate gap and
+	  substitution parameters on the fly for each set of input sequences.
+	  This "query-specific learning" alignment method makes FSA very robust: it
+	  can produce superior alignments of sets of homologous sequences
+	  which are subject to very different evolutionary constraints.
+	<li type=square>
+	  FSA is capable of aligning hundreds or even thousands of sequences
+	  using a randomized inference algorithm to reduce the computational
+	  cost of multiple alignment.  This randomized inference can be over
+	  ten times faster than a direct approach with little loss of
+	  accuracy.
+	<li type=square>
+	  FSA can quickly align very long sequences using the "anchor
+	  annealing" technique for resolving anchors and projecting them with
+	  transitive anchoring.  It then stitches together the alignment
+	  between the anchors using the methods described above.
+	<li type=square>
+	  The included GUI, MAD (Multiple Alignment Display), can display
+	  the intermediate alignments produced by FSA, where each character
+	  is colored according to the probability that it is correctly
+	  aligned.
+      </ul>
+
+
+
+      <h4><a name = "acronym">What does FSA stand for?</a></h4>
+      Fast statistical alignment: We use machine-learning techniques to quickly
+      re-estimate parameters for each alignment problem.
+    <p>
+      Fast sequence annealing: We build a multiple alignment from pairwise comparisons
+      with the sequence annealing technique.
+    <p>
+      Functional statistical alignment: We implicitly use functional information when
+      constructing alignments.
+    <p>
+      <a href="http://www.fullspeedahead.com/">Full Speed Ahead</a><p>
+    <p>
+      ...and more...
+
+
+
+      <h4><a name = "install">How do I download and install FSA?</a></h4>
+      FSA is hosted by <a href="http://sourceforge.net">SourceForge</a>.
+      You can download the latest version from the <a href="http://sourceforge.net/projects/fsa/">SourceForge project page</a>.
+    <p>
+
+      FSA is built and installed by running the following commands: <br>
+    <p><kbd>
+       tar xvzf fsa-X.X.X.tar.gz <br>
+       cd fsa-X.X.X <br>
+       ./configure <br>
+       make <br>
+       make install <br>
+      </kbd>
+
+    <p>
+      (Substitute <var>fsa-X.X.X.tar.gz</var> with the name of the file
+      that you downloaded.)
+
+    <p>
+      The FSA executables can then be found in your system's standard
+      binary directory (e.g., /usr/local/bin).  Alternatively, you may
+      just run FSA from the src/main subdirectory in which it is built
+      (which does not require running the <kbd>make install</kbd> step).
+      If you wish to install the FSA binaries in a location other than
+      your system's standard directories (which usually requires root
+      permissions), specify the top-level installation directory with
+      the <kbd>--prefix</kbd> option to configure.  For example,
+    <p><kbd>./configure --prefix=$HOME</kbd>
+    <p>
+      specifies that binaries should be installed in <var>$HOME/bin</var>, libraries in
+      <var>$HOME/lib</var>, etc. <br>
+    <p>
+      If you wish to align long sequences, then you must download and install <a href="http://mummer.sourceforge.net/">MUMmer</a>,
+      which FSA calls to get candidate anchors between sequences.
+      When running <kbd>./configure</kbd>, either have the MUMmer executable in your path
+      or specify the executable with the <kbd>--with-mummer</kbd> option to <kbd>./configure</kbd>.
+
+    <p>
+      FSA can also call <a href="http://www.ebi.ac.uk/~guy/exonerate/">exonerate</a>
+      to obtain anchors.  If you wish to use exonerate, then as with MUMmer,
+      when running <kbd>./configure</kbd>, you must either have the exonerate executable in your path
+      or specify the executable with the <kbd>--with-exonerate</kbd> option to <kbd>./configure</kbd>.
+
+    <p>
+      See the <var>README</var> file and <a href = "#longseqs">How do I align long sequences?</a>
+      for more information.
+    <p>
+      Please contact us if you have any build problems.
+
+
+
+      <h4><a name = "runfsa"> How do I run FSA?</a></h4>
+      FSA accepts FASTA-format input files and outputs multi-FASTA
+      alignments by default.  The most basic usage is:
+    <p><kbd>fsa <mysequences.fa> >myalignedsequences.mfa</kbd>
+    <p>
+      or
+    <p><kbd>fsa --stockholm <mysequences.fa> >myalignedsequences.stk</kbd>
+    <p>
+
+
+      <h4><a name = "server"> Is there a webserver for FSA?</a></h4>
+      There is a webserver hosted <a href="http://orangutan.math.berkeley.edu/fsa/">here</a>
+      which you can submit alignment jobs to.
+      You will be emailed when the alignment is completed.
+
+
+
+      <h4><a name = "help"> How do I get a help message to explain the options?</a></h4>
+      Run
+    <p><kbd>fsa --help</kbd>
+
+
+
+      <h4><a name = "example_files"> Are there example sequence files and alignments?</a></h4>
+      Yes.  Please see the <var>examples/</var> directory.
+
+
+
+      <!-- Alignments -->
+      <hr>
+      <h2>Alignments</h2>
+
+      <h4><a name = "manyseqs"> How do I align many sequences?</a></h4>
+      FSA can align thousands or tens of thousands of sequences.
+      Try running FSA with the <kbd>--fast</kbd> option.  You can get finer-grained control with
+      the <kbd>--alignment-number <int></kbd> option, which controls the total number of pairwise
+      comparisons which FSA uses to build a multiple alignment.  If you want to align
+      N sequences, then you can set <kbd>--alignment-number</kbd> to as low as (N - 1) or as
+      high as (N choose 2) == (N * (N - 1) / 2).
+
+
+
+
+      <h4><a name = "longseqs"> How do I align long sequences?</a></h4>
+      FSA can align long sequences (megabases or tens of megabases) with the
+      "anchor annealing" technique.  It uses the program MUMmer to find maximal
+      unique matches between pairs of sequences to be aligned, resolves 
+      inconsistencies with anchor annealing, and then pieces together the alignment
+      between anchored regions using its standard inference method.
+
+    <p>
+      FSA can also use the program exonerate to detect remote homology.
+
+    <p>
+      Please use the <kbd>--with-mummer</kbd> and <kbd>--with-exonerate</kbd> options to <kbd>./configure</kbd>
+      before compilation as explained in <a href="#runfsa">How do I run FSA?</a>.
+
+    <p>
+      You can read about the MUMmer and exonerate programs in:
+    <p>
+      S. Kurtz, A. Phillippy, A.L. Delcher, M. Smoot, M. Shumway, C. Antonescu, and S.L. Salzberg.
+      <a href="http://genomebiology.com/2004/5/2/R12">Versatile and open software for comparing large genomes</a>. Genome Biology. 2004, 5:R12.
+    <p>
+      G. S. Slater and E. Birney.
+      <a href="http://www.biomedcentral.com/1471-2105/6/31">Automated generation of heuristics for biological sequence comparison</a>. BMC Bioinformatics. 2005, 6:31.
+
+
+
+      <h4><a name = "genomes"> How do I align genomes?</a></h4>
+      If the genomes which you want to align have few rearrangements, then
+      you can run FSA directly on them.  If they have rearrangments, then 
+      you must first use a program such as Colin Dewey's <a href="http://www.biostat.wisc.edu/~cdewey/mercator/">Mercator</a>
+      to construct a homology map for the genomes and then run FSA on the
+      homologous segments.  FSA can directly use the constraint information
+      produced by Mercator to inform its multiple alignment
+      (use the <kbd>--mercator</kbd> option to specify the Mercator constraint file).
+
+    <p>
+      You can read about Mercator in:
+
+    <p>
+      C. Dewey. <a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-104.html">Whole-genome alignments and polytopes for comparative genomics</a>.
+      Ph.D. thesis, University of California, Berkeley. 2006.
+
+
+      <h4><a name = "logging"> My alignment is taking a long time.  How do I see what FSA is doing?</a></h4>
+
+      FSA has an extensive logging system.  Try running with the <kbd>--log 7</kbd> option
+      to see progress of the DP algorithm, and <kbd>--log 6</kbd> to see progress of anchoring
+      (when aligning long sequences).
+      Log levels from 0 to 10 are permitted,
+      where lower numbers are more verbose.
+
+
+      <h4><a name = "manygaps">Why are there so many gaps in my alignment?</a></h4>
+
+      Most alignment programs attempt to maximize sensitivity, even at
+      the expense of specificity, leading to over-alignment (alignment of
+      non-homologous sequence).  FSA, in contrast, maximizes the expected
+      accuracy of the alignment with a measure which rewards sensitivity
+      but penalizes over-alignment.  If FSA cannot reliably detect homology,
+      then it will leave characters unaligned (gapped).
+
+
+      <h4><a name = "gapfactor">How do I control the sensitivity/specificity tradeoff of my alignment?</a></h4>
+
+      By default FSA stops aligning characters when the probability that
+      a character is aligned is equal to the probability that it is gapped.
+      Use the <kbd>--maxsn</kbd> option for maximum sensitivity.
+
+    <p>
+      You can get finer-grained control with the <kbd>--gapfactor <int></kbd> option.
+      By default FSA runs at <kbd>--gapfactor 1</kbd>.
+      Use <kbd>--gapfactor 0</kbd> for highest sensitivity (this is equivalent to <kbd>--maxsn</kbd>)
+      and gap factors > 1 for higher specificity.
+
+
+
+      <!-- Visualization -->
+      <hr>
+      <h2>Visualization</h2>
+
+      <h4><a name = "gui"> How do I visualize the alignments produced by FSA?</a></h4>
+      Run FSA with the command-line option <kbd>--gui</kbd>.  If the input alignment file
+      is <var>myseqs.fasta</var>, then FSA will write the files <var>myseqs.fasta.gui</var> and
+      'myseqs.fasta.probs'.  Invoke the MAD (Multiple Alignment Display) GUI
+      as
+    <p><kbd>java -jar display/mad.jar myseqs.fasta</kbd>
+    <p>
+      Please be patient if it takes a while to load.
+    <p>
+      Characters in the multiple alignment are colored according to the 
+      probability that they are correctly aligned.
+
+    <p>
+      You can see what a typical FSA alignment looks like by running
+      on one of the provided example alignments, such as
+    <p><kbd>java -jar display/mad.jar examples/tRNA.aln1.fasta</kbd>
+
+    <p>
+      You can also use the GUI to compare a FSA alignment with another alignment,
+      such as one which you have edited by hand.  Invoke the GUI as
+    <p><kbd>java -jar display/mad.jar examples/tRNA.aln1.fasta myalignment.fa</kbd>
+      The alternate alignment <kbd>myalignment.mfa</kbd> must be in multi-FASTA format.
+
+
+
+      <h4><a name = "reliable">How do I see what parts of my alignment are the most reliable?</a></h4>
+      The accuracy estimates produced by FSA and the GUI are useful for
+      downstream analyses, for example allowing biologists to restrict
+      their analyses to the most reliable portions of the alignment
+      or edit unreliable parts of the alignment by hand.
+
+      The accuracy measures also allow you to visualize how FSA works.
+      If you switch to the "Specificity" coloring and watch the animation from the beginning,
+      you will see FSA first aligns characters whose homology it is most sure of (red),
+      and only later aligns characters of unclear homology (blue).
+      Similarly, you can visualize the sensitivity/specificity tradeoff: Near the beginning
+      of the alignment the specificity is very high, but the sensitivity is low.
+      The specificity decreases and the sensitivity increases as the alignment progresses.
+
+      The GUI displays five different accuracy measures for each position in the multiple alignment.
+      These are:
+      <ul>
+
+	<li type=square><u>Accuracy</u>: What characters or gaps of the multiple alignment are the most accurate?
+	  <blockquote>
+	    Accuracy is the per-character estimated Alignment Metric Accuracy,
+	    which measures the fidelity of both aligned characters and unaligned characters (gaps).
+	    It can be thought of as a single measure encompassing the sensitivity/specificity tradeoff.
+	  </blockquote>
+
+	<li type=square><u>Sensitivity</u>: What characters are aligned with the greatest sensitivity?
+	  <blockquote>
+	    Sensitivity is the estimated number of correctly-aligned character pairs divided by the
+	    true number of aligned character pairs.
+	    <br>
+	    Sensitivity is defined as the expectation of (True positives) / (True positives + False negatives).
+	    This definition is equivalent to <a href="http://en.wikipedia.org/wiki/Precision_and_recall">recall</a> as used in classification problems.
+	  </blockquote>
+
+	<li type=square><u>Specificity</u>: What characters are aligned with the greatest specificity?
+	  <blockquote>
+	    Specificity is the estimated fraction of character pairs which are aligned correctly.
+	    <br>
+	    Specificity is defined as the expectation of (True positives) / (True positives + False positives).
+	    This definition is equivalent to <a href="http://en.wikipedia.org/wiki/Precision_and_recall">precision</a> as used in classification problems.
+	    It is also frequently called <a href="http://en.wikipedia.org/wiki/Positive_predictive_value">Positive Predictive Value</a> in the literature.
+	  </blockquote>
+
+	<li type=square><u>Certainty</u>: Was there a better place to align this character?
+	  <blockquote>
+	    Certainty measures whether a character or gap is aligned correctly.
+	  </blockquote>
+	  
+	<li type=square><u>Consistency</u>: What parts of the multiple alignment are optimal on a pairwise level?
+	  <blockquote>
+	    Consistency measures the extent to which the posterior probabilities from pairwise comparisons
+	    are optimized by the multiple alignment.  If a multiple alignment is perfectly consistent,
+	    then each pairwise alignment implied by the multiple alignment corresponds perfectly to the pairwise alignment
+	    which you would obtain by aligning only those two sequences.
+	  </blockquote>
+
+      </ul>
+
+      <p>
+	Please see the manuscript for precise definitions of these reliability measures.
+
+      <p>
+	Notice that the accuracy scores tend to
+	decrease near gaps, reflecting the difficulty of precisely 
+	resolving gap boundaries.
+
+
+
+      <!-- Output formats and tools -->
+      <hr>
+      <h2>Output formats and tools</h2>
+
+      <h4><a name = "stockholm"> How do I parse Stockholm alignments?</a></h4>
+      Use the <kbd>--stockholm</kbd> output option to tell FSA 
+      to produce a Stockholm-format alignment.  The alignment is marked up with
+      a per-column accuracy annotation which is identical to the values
+      reported by the <a href="#gui">GUI</a>.
+
+      FSA includes tools for working with Stockholm alignments, such as
+      <kbd>prettify.pl</kbd> for making Stockholm-format alignments human-
+      readable, in the <var>perl/</var> directory.
+
+
+      <h4><a name = "comparealign"> How do I compare alignments?</a></h4>
+      The included script <kbd>cmpalign.pl</kbd> will compare two alignments
+      and report accuracies measures including Accuracy (AMA), Sensitivity and Specificity.
+      It can parse Stockholm, multi-FASTA, MSF and CLUSTAL format alignments.
+
+
+
+
+      <!-- Troubleshooting -->
+      <hr>
+      <h2>Troubleshooting</h2>
+
+      <h4><a name = "gui_memory"> I'm getting memory errors when using the GUI.</a></h4>
+      If you're getting errors which say something like
+    <p><kbd>Exception in thread ... java.lang.OutOfMemoryError: Java heap space</kbd>
+    <p>
+      then try increasing the memory allowed with with <kbd>-Xmx</kbd> option, ie
+    <p><kbd>java -Xmx256m jar display/mad.jar examples/tRNA.aln1.fasta</kbd>
+    <p>
+      You can increase it up to the maximum allowed by your machine.
+
+
+      <h4><a name = "malloc"> I get out-of-memory (bad alloc) errors when I try to align long sequences.</a></h4>
+      This occurs when FSA is unable to find good anchors between your sequences
+      to restrict the complexity of inference.  This can occur if you use the option
+      <kbd>--noanchored</kbd> to prevent anchoring, if your sequences are very diverged,
+      or if they have many simple repeats.  Use the <kbd>--maxram</kbd> option to
+      prevent FSA from attempting to perform exhaustive inference when it can't
+      find good anchors.  It will leave sequence for which it can't find 
+      sufficiently-good anchors unaligned.
+
+
+
+
+
+
+      <!-- More information -->
+      <hr>
+      <h2>More information</h2>
+
+      <h4><a name = "contact"> How do I contact you?</a></h4>
+      You can reach the FSA team at <a href="mailto:fsa at math.berkeley.edu">fsa at math.berkeley.edu</a> with any questions, feedback, etc.
+
+
+      <h4><a name = "citation"> How do I cite FSA?</a></h4>
+      Bradley RK, Roberts A, Smoot M, Juvekar S, Do J, Dewey C, Holmes I, Pachter L (2009) <a href="http://www.ploscompbiol.org/article/info%3Adoi%2F10.1371%2Fjournal.pcbi.1000392">Fast Statistical Alignment</a>. PLoS Computational Biology. 5:e1000392.
+      <p>The FSA manuscript can also be found in the <var>doc/</var>
+      directory of the FSA source code distribution.
+      
+
+      <h4><a name = "license">Under what license is FSA distributed?</a></h4>
+      FSA is licensed under version 3 of the <a href="http://www.gnu.org/licenses/gpl.html">GNU General Public License</a>.
+      Please see the files <var>LICENSE</var> and <var>COPYING</var> for further information.
+
+
+      <h4><a name = "git"> How do I become an FSA developer?</a></h4>
+      FSA is designed to be modular and there are many aspects of the program that can be improved;
+      we welcome your help! The code is under <a href="http://git.or.cz/">Git</a> version control.
+      Please contact us at <a href="mailto:fsa at math.berkeley.edu">fsa at math.berkeley.edu</a> for information.
+      The source code is set up for use with <a href="http://www.doxygen.org/">Doxygen</a>,
+      a system for automated building of documentation.
+
+      <h4><a name = "influences"> What other programs influenced the development of FSA?</a></h4>
+      Source code in <var>seq/</var> and <var>util/</var> is from Ian Holmes's DART library [1],
+      which is used for input and output routines.
+
+    <p>
+      FSA's DP code was generated by HMMoC by Gerton Lunter [2]. The
+      aligner example distributed with HMMoC, which implements a 
+      learning procedure for gap parameters, was an inspiration for FSA's
+      learning strategies. FSA's banding code is taken directly from the
+      aligner example.
+
+    <p>
+      The sequence annealing technique for constructing a multiple
+      alignment from pairwise comparisons was developed by Ariel Schwartz.
+      The implementation of sequence annealing in FSA is a modified version
+      of the original implementation in AMAP by Ariel Schwartz and Lior Pachter [3,4].
+
+    <p>
+      The anchor annealing approach used in FSA is modeled after the recursive
+      anchoring strategy used in MAVID by Nicolas Bray and Lior Pachter [5].
+
+    <p>
+      The MAD GUI interface to FSA was written by Adam Roberts based on a preliminary
+      version developed by Michael Smoot.
+
+    <p>
+      Please see:
+
+    <p>[1] I. Holmes and R. Durbin. <a href="http://www.ncbi.nlm.nih.gov/entrez/query.fcgi?cmd=Retrieve&db=pubmed&dopt=Abstract&list_uids=9773345">Dynamic Programming Alignment 	Accuracy</a>. Journal of Computational Biology. 1998, 5 (3):493-504.
+
+    <p>[2] G.A. Lunter. <a href="http://bioinformatics.oxfordjournals.org/cgi/content/abstract/23/18/2485">HMMoC - a Compiler for Hidden Markov Models</a>. Bioinformatics. 2007, 23       (18):2485-2487.
+
+    <p>[3] A.S. Schwartz. <a href="http://www.eecs.berkeley.edu/Pubs/TechRpts/2007/EECS-2007-39.html">Posterior Decoding Methods for Optimization and Control of Multiple 	Alignments</a>. Ph.D. Thesis, UC Berkeley. 2007.
+
+    <p>[4] A.S. Schwartz and L. Pachter. <a href="http://bioinformatics.oxfordjournals.org/cgi/content/abstract/23/2/e24?etoc">Multiple Alignment by Sequence Annealing</a>.       Bioinformatics. 2007, 23 (2):e24-e29.
+
+    <p>[5] N. Bray and L. Pachter. <a href="http://www.genome.org/cgi/content/abstract/14/4/693">MAVID: Constrained Ancestral Alignment of Multiple Sequences</a>. Genome Research. 2004, 14:693-699.
+
+      <hr>
+      <a href="http://sourceforge.net/projects/fsa"><img src="http://sflogo.sourceforge.net/sflogo.php?group_id=234783&type=15" width="150" height="40" border="0" alt="Get FSA at SourceForge.net. Fast, secure and Free Open Source software downloads" /></a>
+
+      <!-- Piwik -->
+      <script type="text/javascript">
+	var pkBaseURL = (("https:" == document.location.protocol) ? "https://apps.sourceforge.net/piwik/fsa/" : "http://apps.sourceforge.net/piwik/fsa/");
+	document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));
+      </script><script type="text/javascript">
+	piwik_action_name = '';
+	piwik_idsite = 1;
+	piwik_url = pkBaseURL + "piwik.php";
+	piwik_log(piwik_action_name, piwik_idsite, piwik_url);
+      </script>
+      <object><noscript><p><img src="http://apps.sourceforge.net/piwik/fsa/piwik.php?idsite=1" alt="piwik"/></p></noscript></object>
+      <!-- End Piwik Tag -->
+
+  </BODY>
+</HTML>
diff --git a/html/Makefile.am b/html/Makefile.am
new file mode 100644
index 0000000..7ace2a7
--- /dev/null
+++ b/html/Makefile.am
@@ -0,0 +1,3 @@
+EXTRA_DIST = \
+	FAQ.html \
+	pretty.css
diff --git a/html/Makefile.in b/html/Makefile.in
new file mode 100644
index 0000000..35ebe8a
--- /dev/null
+++ b/html/Makefile.in
@@ -0,0 +1,411 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = html
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+	FAQ.html \
+	pretty.css
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign html/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign html/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+	ctags-am distclean distclean-generic distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/html/pretty.css b/html/pretty.css
new file mode 100644
index 0000000..e9a8eef
--- /dev/null
+++ b/html/pretty.css
@@ -0,0 +1,12 @@
+body{margin:10px 10px 10px 10px;font-family:times;background-color:#FFFFF9;}
+
+a{text-decoration:none;}
+
+a:link{font-weight:bold; color:#000066;}
+
+a:visited{color:#000099; font-weight:bold;}
+
+a:hover{text-decoration:underline;}
+
+a:active{text-decoration:underline;}
+
diff --git a/perl/FSA/Model.pm b/perl/FSA/Model.pm
new file mode 100644
index 0000000..449f768
--- /dev/null
+++ b/perl/FSA/Model.pm
@@ -0,0 +1,493 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+FSA::Model.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating FSA's statistical model.
+
+Written by Robert Bradley.
+
+=head1 METHODS
+
+=cut
+
+package FSA::Model;
+
+use strict;
+use Carp;
+
+use FSA::SparseMatrices;
+use Stockholm;
+
+use vars '@ISA';
+
+sub new {
+  my ($class) = @_;
+
+  my $self = {
+	      'sparse_matrices' => "", # SparseMatrices object
+	      'seqname_map' => {},     # map sequence names to their SparseMatrices indices
+	      'acc' => '',             # Acc (total accuracy)
+	      'sn' => '',              # Sn (total sensivity)
+	      'ppv' => '',             # PPV (total positive predictive value)
+	      'cert' => '',            # Certainty (total certainty)
+	      'cons' => '',            # Consistency (total consistency)
+	      'acc_annot' => "",       # Acc per-column annotation
+	      'sn_annot' => "",        # Sn per-column annotation
+	      'ppv_annot' => "",       # PPV per-column annotation
+	      'cert_annot' => "",      # Certainty per-column annotation
+	      'cons_annot' => "",      # Consistency per-column annotation
+	      'model_cert' => "",      # Model certainty (approximate average slope of probability distributions)
+	      'exp_correct' => 0,      # expected number of correctly-aligned characters
+	      'exp_incorrect' => 0,    # expected number of correctly-aligned characters
+	      'total_chars' => 0       # total number of characters
+	     };
+
+  bless $self, ref ($class) || $class;
+
+  return $self;
+}
+
+# Catch methods.
+sub AUTOLOAD {
+  my ($self, @args) = @_;
+  my $sub = our $AUTOLOAD; # $AUTOLOAD contains the fully qualified name of the original subroutine
+  $sub =~ s/.*:://;
+
+  # check for DESTROY
+  return if $sub eq 'DESTROY';
+
+  # check for directives accessor, e.g. $self->directives_debug or $self->directives_('debug')
+  if ($sub =~ /^directives_(\S*)$/i) {
+    my $flag = lc ($1);
+    $flag = shift @args unless (length $flag); # this catches the argument 'debug' in the second example usage given above
+    if (!defined $self->{'directives'}->{$flag}) {
+      $self->{'directives'}->{$flag} = "";     # if no such flag exists, create one with the value ""
+    }                                          # we therefore have to test 'if ($self->directives_debug)' rather than 'if (defined $self->directives_debug)'
+    return $self->{'directives'}->{$flag};     # the second will always be true because AUTOLOAD will create an empty flag for us
+  }
+
+  # check for ordinary accessors
+  # This has the effect of automatically implementing getter and setter methods.
+  # If there's an instance variable $name, then the getter method is $self->name
+  # and the setter method is $self->name('newName')
+  if (exists $self->{$sub}) {
+    if (@args > 1) { croak "Usage: $sub() or $sub(newValue)"; }
+    return
+      @args                      # if @args > 0
+      ? $self->{$sub} = $args[0] # { $self->{$sub} = $args[0]; return $args[0]; }
+      : $self->{$sub};            # else { return $self->{$sub}; }
+  }
+
+  croak "Unsupported method: $sub\n";
+}
+
+# Initialization routines.
+sub _initialize {
+  my ($class, $seqfile) = @_;
+
+  if (!defined $seqfile) { croak "You must define a sequence file!\n"; }
+
+  my $self = $class->new;
+
+  # create map from sequence names to indices
+  unless (Stockholm->detect_FASTA ($seqfile)) {
+    croak "'$seqfile' isn't a valid FASTA file.\n";
+  }
+  my $fasta = Stockholm->from_file ($seqfile);
+  for (my $seq = 0; $seq < @{$fasta->seqname}; ++$seq) {
+    $self->seqname_map->{@{$fasta->seqname}[$seq]} = $seq;
+  }
+
+  return $self;
+}
+
+# Load model from a FSA .probs file.
+sub from_probsfile {
+  my ($class, $seqfile, $probsfile) = @_;
+
+  my $self = $class->_initialize ($seqfile);
+
+  # initialize sparse matrices
+  $self->sparse_matrices (FSA::SparseMatrices->from_probsfile ($probsfile));
+
+  return $self;
+}
+
+# Initialize 0-1 posterior probabilities using the passed reference alignment.
+sub from_alignment {
+  my ($class, $seqfile, $alignfile) = @_;
+
+  my $self = $class->_initialize ($seqfile);
+  $self->sparse_matrices (FSA::SparseMatrices->new);
+
+  # initialize sparse matrices from the passed alignment
+  my $stock = Stockholm->from_file ($alignfile);
+  # sanity checks
+  $stock->assert_flush();
+  $stock->drop_allgaps_columns();
+  for (my $col = 0; $col < $stock->columns; ++$col) {
+
+    foreach my $seq1 (@{$stock->seqname}) {
+      # convert to index
+      my $i = $self->seqname_map->{$seq1};
+      my $ii = ($stock->is_gap ($seq1, $col)) ? -1 : ($stock->map_align_to_seq_coords ($col, $col, $seq1, 0))[0];
+      
+      foreach my $seq2 (@{$stock->seqname}) {
+	my $j = $self->seqname_map->{$seq2};
+	my $jj = ($stock->is_gap ($seq2, $col)) ? -1 : ($stock->map_align_to_seq_coords ($col, $col, $seq2, 0))[0];
+
+	# skip gap-gap entries
+	if (($ii < 0) && ($jj < 0)) { next; }
+
+	# store with unit probability
+	$self->sparse_matrices->store_entry ($i, $j, $ii, $jj, 1.0);
+      
+      }
+    }
+
+  }
+
+  return $self;
+}
+
+
+# Calculate alignment accuracy information.
+# Use either a "soft" logarithmic transform
+# or a hard threshold for the certainty calculation.
+sub calc_accuracies {
+  my ($self, $stock, $acc_threshold, $cert_threshold, $use_log) = @_;
+
+  if (!defined $acc_threshold) { $acc_threshold = 0.9; }
+  if (!defined $cert_threshold) { $cert_threshold = 5.0; }
+  if (!defined $use_log) { $use_log = 1; }
+
+  # initialize temporary variables to 0
+  # (these will be used to populate the alignment-specific variables in $self)
+
+  # accuracy (Acc)
+  my $acc_num = 0;
+  my $acc_denom = 0;
+  my $acc_annot = "";
+
+  # positive predictive value (PPV)
+  my $ppv_num = 0;
+  my $ppv_denom = 0;
+  my $ppv_annot = "";  
+
+  # sensitivity (Sn)
+  my $sn_num = 0;
+  my $sn_denom = 0;
+  my $sn_annot = "";
+
+  # certainty
+  my $cert_num = 0;
+  my $cert_denom = 0;
+  my $cert_annot = "";
+
+  # consistency
+  my $cons_num = 0;
+  my $cons_denom = 0;
+  my $cons_annot = "";
+
+  # expected numbers of correctly and incorrectly-aligned characters
+  # (meeting our $acc_threshold)
+  my $exp_correct = 0;
+  my $exp_incorrect = 0;
+  my $total_chars = 0;
+
+  # first calculate Acc and PPV
+  # loop over columns
+  for (my $col = 0; $col < $stock->columns; ++$col) {
+
+    # per-column values
+    my $col_acc_num = 0;
+    my $col_acc_denom = 0;
+    
+    my $col_ppv_num = 0;
+    my $col_ppv_denom = 0;
+
+    my $col_sn_num = 0;
+    my $col_sn_denom = 0;
+    
+    my $col_cert_num = 0;
+    my $col_cert_denom = 0;
+
+    my $col_cons_num = 0;
+    my $col_cons_denom = 0;
+
+    # loop over seqs in column
+    foreach my $seq1 (@{$stock->seqname}) {
+
+      # convert to index
+      my $i = $self->seqname_map->{$seq1};
+
+      # estimate whether it's correctly-aligned
+      my $char_acc_num = 0;
+      my $char_acc_denom = 0;
+
+      # loop over all seqs
+      foreach my $seq2 (@{$stock->seqname}) {
+
+	my $j = $self->seqname_map->{$seq2};
+
+	# skip the diagonal
+	next if ($i == $j);
+
+	# check that matrix is available
+	if (!$self->sparse_matrices->exists_matrix ($i, $j)) { next; }
+	
+	# skip gap-gap entries
+	if ($stock->is_gap ($seq1, $col) && $stock->is_gap ($seq2, $col)) { next; }
+
+	# if seq1 is gapped
+	if ($stock->is_gap ($seq1, $col)) {
+
+	  # get position in seq j
+	  my $jj = ($stock->map_align_to_seq_coords ($col, $col, $seq2, 0))[0]; # final argument to map_align_to_seq_coords
+                                                                                # specifies 0-based coordinates         
+	  my $p = $self->sparse_matrices->get_gap_prob ($j, $i, $jj);
+
+	  $col_acc_num += $p;
+	  $col_acc_denom += 1;
+
+	}
+
+	# if seq2 is gapped
+	elsif ($stock->is_gap ($seq2, $col)) {
+
+	  # get position in seq i
+	  my $ii = ($stock->map_align_to_seq_coords ($col, $col, $seq1, 0))[0];
+
+	  my $p = $self->sparse_matrices->get_gap_prob ($i, $j, $ii);
+
+	  $col_acc_num += $p;
+	  $col_acc_denom += 1;
+
+	  $char_acc_num +=  $p;
+	  $char_acc_denom += 1;
+	  
+	  # numerator for sn doesn't increase
+	  # but denominator does
+	  $col_sn_denom += $self->sparse_matrices->get_sum_prob ($i, $j, $ii);
+
+	  # both numerator and denominator for consistency increase
+	  $col_cons_num += $p;
+	  $col_cons_denom += $self->sparse_matrices->get_max_prob ($i, $j, $ii);
+
+	  if ($use_log) {
+	    $col_cert_num += $p;
+	    $col_cert_denom += $self->sparse_matrices->get_altmax_prob ($i, $j, $ii, -1);
+	  } else {
+	    $col_cert_num += ($p / $self->sparse_matrices->get_altmax_prob ($i, $j, $ii, -1) >= $cert_threshold) ? 1 : 0;
+	    $col_cert_denom += 1;
+	  }
+
+	}
+
+	# if match
+	else {
+
+	  # get position in seqs i and j
+	  my $ii = ($stock->map_align_to_seq_coords ($col, $col, $seq1, 0))[0];
+	  my $jj = ($stock->map_align_to_seq_coords ($col, $col, $seq2, 0))[0];
+	    
+	  my $p = $self->sparse_matrices->get_match_prob ($i, $j, $ii, $jj);
+
+	  $col_acc_num += 2 * $p;
+	  $col_acc_denom += 2;
+
+	  $char_acc_num += 2 * $p;
+	  $char_acc_denom += 2;
+
+	  $col_ppv_num += 2 * $p;
+	  $col_ppv_denom += 2;
+	  
+	  # both numerator and denominator for sn increase
+	  $col_sn_num += $p;
+	  $col_sn_denom += $self->sparse_matrices->get_sum_prob ($i, $j, $ii);
+
+	  # both numerator and denominator for consistency increase
+	  $col_cons_num += $p;
+	  $col_cons_denom += $self->sparse_matrices->get_max_prob ($i, $j, $ii);
+
+	  if ($use_log) {
+	    $col_cert_num += 2 * $p;
+	    $col_cert_denom += 2 * $self->sparse_matrices->get_altmax_prob ($i, $j, $ii, $jj);
+	  } else {
+	    $col_cert_num += 2 * (($p / $self->sparse_matrices->get_altmax_prob ($i, $j, $ii, $jj) >= $cert_threshold) ? 1 : 0);
+	    $col_cert_denom += 2 * 1;
+	  }
+
+	}
+
+      }
+
+      # is it correctly aligned according to our threshold?
+      if (!$stock->is_gap ($seq1, $col)) {
+	++$total_chars;
+	if ($char_acc_num / $char_acc_denom > $acc_threshold) { ++$exp_correct; }
+	elsif ($char_acc_num / $char_acc_denom < 1.0 - $acc_threshold) { ++$exp_incorrect; }
+      }
+
+    }
+
+    # increment alignment counters
+    $acc_num += $col_acc_num;
+    $acc_denom += $col_acc_denom;
+
+    $ppv_num += $col_ppv_num;
+    $ppv_denom += $col_ppv_denom;
+
+    $sn_num += $col_sn_num;
+    $sn_denom += $col_sn_denom;
+
+    $cons_num += $col_cons_num;
+    $cons_denom += $col_cons_denom;
+
+    $cert_num += $col_cert_num;
+    $cert_denom += $col_cert_denom;
+
+    # sanity checks
+    if (($col_acc_num / $col_acc_denom < 0) || ($col_acc_num / $col_acc_denom > 1)) {
+      warn "Dangerous-looking Acc for column $col: $col_acc_num / $col_acc_denom.\n";
+    }
+    if (($col_ppv_denom > 0) and
+	($col_ppv_num / $col_ppv_denom < 0) || ($col_ppv_num / $col_ppv_denom > 1)) {
+      warn "Dangerous-looking PPV for column $col: $col_ppv_num / $col_ppv_denom.\n";
+    }
+
+    # modify per-column annotation as appropriate
+    substr ($acc_annot, $col, 1) = get_markup_char ($col_acc_num / $col_acc_denom);
+    substr ($ppv_annot, $col, 1) = ($col_ppv_denom > 0) ? get_markup_char ($col_ppv_num /$col_ppv_denom) : "-";
+    substr ($sn_annot, $col, 1) = get_markup_char ($col_sn_num / $col_sn_denom);
+    substr ($cons_annot, $col, 1) = get_markup_char ($col_cons_num / $col_cons_denom);
+    if ($use_log) {
+      substr ($cert_annot, $col, 1) = get_markup_char ($self->normalize_certainty ($col_cert_num / $col_cert_denom, $cert_threshold));
+    } else {
+      substr ($cert_annot, $col, 1) = get_markup_char ($col_cert_num / $col_cert_denom);
+    }
+
+  }
+
+  # store total values
+  $self->acc ($acc_num / $acc_denom);
+  $self->sn ($sn_num / $sn_denom);
+  $self->ppv ($ppv_num / $ppv_denom);
+  $self->cons ($cons_num / $cons_denom);
+  if ($use_log) {
+    $self->cert ($self->normalize_certainty ($cert_num / $cert_denom, $cert_threshold));
+  } else {
+    $self->cert ($cert_num / $cert_denom);
+  }
+  $self->model_cert ($self->sparse_matrices->get_model_certainty());
+
+  $self->exp_correct ($exp_correct);
+  $self->exp_incorrect ($exp_incorrect);
+  $self->total_chars ($total_chars);
+
+  # store per-column annotation lines
+  $self->acc_annot ($acc_annot);
+  $self->sn_annot ($sn_annot);
+  $self->ppv_annot ($ppv_annot);
+  $self->cons_annot ($cons_annot);
+  $self->cert_annot ($cert_annot);
+
+}
+
+# Normalize certainty to [0,1] with a logarithmic transform.
+# Use the logarithm transform on values below $cert_threshold.
+sub normalize_certainty {
+  my ($class, $c, $cert_threshold) = @_;
+
+  if (!defined $cert_threshold) { $cert_threshold = 5.0; }
+
+  # if there was a better alternative, then return 0
+  if ($c < 1.0) {
+    return 0;
+  }
+
+  # if it was $cert_threshold times better than the best alternative, then return 1
+  elsif ($c >= $cert_threshold) {
+    return 1;
+  }
+
+  # else perform a logarithmic transform
+  else {
+    return (log ($c) / log ($cert_threshold));
+  }
+
+}
+
+# Show alignment accuracy information.
+sub show_accuracies {
+  my ($self, $precision, $terse) = @_;
+
+  if (!defined $precision) { $precision = 3; }
+  if (!defined $terse) { $terse = 0; }
+
+  # summary of accuracy metrics
+  my $acc_summary = sprintf "%.${precision}f %.${precision}f %.${precision}f %.${precision}f %.${precision}f", $self->acc, $self->sn, $self->ppv, $self->cert, $self->cons;
+  # model certainty
+  my $model_cert = sprintf "%.${precision}f", $self->model_cert;
+  # estimated number of definitely correct and incorrect characters`
+  my $correctness = sprintf "%d %d %d", $self->exp_correct, $self->exp_incorrect, $self->total_chars;
+
+  if (!$terse) {
+    printf "Acc %.${precision}f\n", $self->acc;
+    printf "Sn  %.${precision}f\n", $self->sn;
+    printf "PPV %.${precision}f\n", $self->ppv;
+    printf "Certainty %.${precision}f\n", $self->cert;
+    printf "Consistency %.${precision}f\n", $self->cons;
+    printf "Model certainty (slope) %.${precision}f\n", $self->model_cert;
+    printf "Definitely correct characters %d / %d\n", $self->exp_correct, $self->total_chars;
+    printf "Definitely incorrect characters %d / %d\n", $self->exp_incorrect, $self->total_chars;
+    printf "%-10s %s %s %s\n", "Summary:", $acc_summary, $model_cert, $correctness;
+  }
+  else {
+    print "$acc_summary $model_cert $correctness\n";
+  }
+
+
+}
+
+
+# Annotate Stockholm alignment.
+sub annotate_alignment {
+  my ($self, $stock, $precision) = @_;
+  
+  # #=GF annotations
+  $stock->add_gf ("Acc", sprintf "%.${precision}f", $self->acc);
+  $stock->add_gf ("Sn", sprintf "%.${precision}f", $self->sn);
+  $stock->add_gf ("PPV", sprintf "%.${precision}f", $self->ppv);
+  $stock->add_gf ("Consistency", sprintf "%.${precision}f", $self->cons);
+
+  # #=GC annotations
+  $stock->gc->{"Acc"} = $self->acc_annot;
+  $stock->gc->{"Sn"} = $self->sn_annot;
+  $stock->gc->{"PPV"} = $self->ppv_annot;
+  $stock->gc->{"Consistency"} = $self->cons_annot;
+
+  if (!$stock->is_flush()) {
+    croak "Alignment not flush.\n";
+  }
+
+}
+
+
+# Convert a number in the interval [0-1] to an integer [0-9].
+sub get_markup_char {
+  my ($norm) = @_;
+
+  my $safe = int (10 * $norm);
+  $safe = ($safe > 9) ? 9 : $safe;
+  my $char = substr ("0123456789", $safe, 1);
+
+  return $char;
+}
+
+
+1
diff --git a/perl/FSA/SparseMatrices.pm b/perl/FSA/SparseMatrices.pm
new file mode 100644
index 0000000..e9216e3
--- /dev/null
+++ b/perl/FSA/SparseMatrices.pm
@@ -0,0 +1,490 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+FSA::SparseMatrices.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating sparse alignment posterior probability matrices.
+
+Written by Robert Bradley.
+
+=head1 METHODS
+
+=cut
+
+package FSA::SparseMatrices;
+
+use strict;
+use Carp;
+
+use vars '@ISA';
+
+sub new {
+  my ($class) = @_;
+
+  my $self = {
+	      'seq_keys' => {},    # sequence keys (names)
+	      'seq_len' => {},     # sequence lengths
+	      'match_probs' => {}, # seq1->seq2->pos1->pos2; transpose stored also
+	      'gap_probs' => {},   # seq1->seq2->pos1
+	      'sum_probs' => {},   # seq1->seq2->pos1
+	      'max_probs' => {}    # seq1->seq2->pos1 is a 2-element hash (element 0 is max, 1 is altmax)
+	     };
+
+  bless $self, ref ($class) || $class;
+
+  return $self;
+}
+
+# catch methods
+sub AUTOLOAD {
+  my ($self, @args) = @_;
+  my $sub = our $AUTOLOAD; # $AUTOLOAD contains the fully qualified name of the original subroutine
+  $sub =~ s/.*:://;
+
+  # check for DESTROY
+  return if $sub eq 'DESTROY';
+
+  # check for directives accessor, e.g. $self->directives_debug or $self->directives_('debug')
+  if ($sub =~ /^directives_(\S*)$/i) {
+    my $flag = lc ($1);
+    $flag = shift @args unless (length $flag); # this catches the argument 'debug' in the second example usage given above
+    if (!defined $self->{'directives'}->{$flag}) {
+      $self->{'directives'}->{$flag} = "";     # if no such flag exists, create one with the value ""
+    }                                          # we therefore have to test 'if ($self->directives_debug)' rather than 'if (defined $self->directives_debug)'
+    return $self->{'directives'}->{$flag};     # the second will always be true because AUTOLOAD will create an empty flag for us
+  }
+
+  # check for ordinary accessors
+  # This has the effect of automatically implementing getter and setter methods.
+  # If there's an instance variable $name, then the getter method is $self->name
+  # and the setter method is $self->name('newName')
+  if (exists $self->{$sub}) {
+    if (@args > 1) { croak "Usage: $sub() or $sub(newValue)"; }
+    return
+      @args                      # if @args > 0
+      ? $self->{$sub} = $args[0] # { $self->{$sub} = $args[0]; return $args[0]; }
+      : $self->{$sub};           # else { return $self->{$sub}; }
+  }
+
+  croak "Unsupported method: $sub\n";
+}
+
+# Load from a FSA .probs file.
+sub from_probsfile {
+  my ($class, $probsfile) = @_;
+
+  my $self = $class->new;
+
+  # parse post probs
+  open PROBS,"<$probsfile" or croak "Couldn't open '$probsfile' for reading.\n";
+
+  warn "Loading posterior alignment probabilities from '$probsfile'.\n";
+
+  while (<PROBS>) {
+
+    chomp;
+    next if $_ eq '';
+
+    # comment
+    if (/^;/) { next; }
+
+    # probability entry
+    # (0, 4022) ~ (1, -1) => 0.773072
+    # handle case of scientific notation
+    elsif (/\((\d+),\s(-?\d+)\)\s~\s\((\d+),\s(-?\d+)\)\s=>\s(\d?\.?\d+)\*?[eE]?(-\d+)?/) {
+
+      my ($seq1, $pos1) = ($1, $2);
+      my ($seq2, $pos2) = ($3, $4);
+      my $prob = $5;
+      my $exponent = $6;
+
+      if (defined $exponent) {
+	$prob *= 10 ** $exponent;
+      }
+
+      # store
+      $self->store_entry ($seq1, $seq2, $pos1, $pos2, $prob);
+
+    }
+
+    else {
+      warn "Skipping input line '$_'.\n";
+    }
+    
+  }
+
+  close PROBS;
+
+  return $self;
+}
+
+# Store a match or gap probability.
+# Update all information about the sparse matrices accordingly.
+sub store_entry {
+  my ($self, $seq1, $seq2, $pos1, $pos2, $prob) = @_;
+
+  # sequence keys
+  $self->seq_keys->{$seq1} = 1;
+  $self->seq_keys->{$seq2} = 1;
+
+  # sequence lengths
+  # remember 0-based indexing!
+  if (!defined $self->seq_len->{$seq1}) { $self->seq_len->{$seq1} = $pos1; }
+  else { $self->seq_len->{$seq1} = ($self->seq_len->{$seq1} < $pos1 + 1) ? $pos1 + 1 : $self->seq_len->{$seq1}; }
+  if (!defined $self->seq_len->{$seq2}) { $self->seq_len->{$seq2} = $pos2; }
+  else { $self->seq_len->{$seq2} = ($self->seq_len->{$seq2} < $pos2 + 1) ? $pos2 + 1 : $self->seq_len->{$seq2}; }
+
+  # match probs
+  # store transpose
+  if (($pos1 >= 0) && ($pos2 >= 0)) {
+
+    # match_probs
+    $self->match_probs->{$seq1}->{$seq2}->{$pos1}->{$pos2} = $prob;
+    $self->match_probs->{$seq2}->{$seq1}->{$pos2}->{$pos1} = $prob;
+
+    # max_probs: seq1
+
+    # if max_prob is undefined, then store new value
+    if (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0]) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1} = [];
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] = $prob;
+    }
+    # if new max, then store new value and update alternate max
+    elsif ($self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] < $prob) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0];
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] = $prob;
+    }
+    # if new alternate max because alternate max is undefined
+    elsif (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1]) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $prob;
+    }
+    # if new alternate max
+    elsif ($self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] < $prob) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $prob;
+    }
+
+    # max_probs: seq2
+
+    # if max_prob is undefined, then store new value
+    if (!defined $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0]) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2} = [];
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] = $prob;
+    }
+    # if new max, then store new value and update alternate max
+    elsif ($self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] < $prob) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0];
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] = $prob;
+    }
+    # if new alternate max because alternate max is undefined
+    elsif (!defined $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1]) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $prob;
+    }
+    # if new alternate max
+    elsif ($self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] < $prob) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $prob;
+    }
+
+    # sum prob: seq1
+    if (!defined $self->sum_probs->{$seq1}->{$seq2}->{$pos1}) {
+      $self->sum_probs->{$seq1}->{$seq2}->{$pos1} = $prob;
+    } else {
+      $self->sum_probs->{$seq1}->{$seq2}->{$pos1} += $prob;
+    }
+
+    # sum prob: seq2
+    if (!defined $self->sum_probs->{$seq2}->{$seq1}->{$pos2}) {
+      $self->sum_probs->{$seq2}->{$seq1}->{$pos2} = $prob;
+    } else {
+      $self->sum_probs->{$seq2}->{$seq1}->{$pos2} += $prob;
+    }
+
+  }
+
+  # seq1 ~ -
+  elsif (($pos1 >= 0) && ($pos2 == -1)) {
+
+    # gap_probs
+    $self->gap_probs->{$seq1}->{$seq2}->{$pos1} = $prob;
+
+    # max_prob: seq1
+
+    # if max_prob is undefined, then store new value
+    if (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0]) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1} = [];
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] = $prob;
+    }
+    # if new max, then store new value and update alternate max
+    elsif ($self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] < $prob) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0];
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] = $prob;
+    }
+    # if new alternate max because alternate max is undefined
+    elsif (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1]) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $prob;
+    }
+    # if new alternate max
+    elsif ($self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] < $prob) {
+      $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1] = $prob;
+    }
+
+  }
+
+  # - ~ seq2
+  elsif (($pos1 == -1) && ($pos2 >= 0)) {
+
+    # gap_probs
+    $self->gap_probs->{$seq2}->{$seq1}->{$pos2} = $prob;
+
+    # max_prob: seq2
+
+    # if max_prob is undefined, then store new value
+    if (!defined $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0]) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2} = [];
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] = $prob;
+    }
+    # if new max, then store new value and update alternate max
+    elsif ($self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] < $prob) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0];
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[0] = $prob;
+    }
+    # if new alternate max because alternate max is undefined
+    elsif (!defined $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1]) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $prob;
+    }
+    # if new alternate max
+    elsif ($self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] < $prob) {
+      $self->max_probs->{$seq2}->{$seq1}->{$pos2}->[1] = $prob;
+    }
+
+  } else {
+    croak "Unreachable on input line:\n$_";
+  }
+
+}
+
+# Write formatted .probs file to a string.
+# In the format produced by FSA.
+sub to_string {
+  my ($self) = @_;
+
+  my $s;
+  my @seqs = sort { $a <=> $b } keys %{$self->seq_keys};
+  for (my $i = 0; $i < @seqs; ++$i) {
+    my $seq1 = $seqs[$i];
+
+    for (my $j = $i + 1; $j < @seqs; ++$j) {
+      my $seq2 = $seqs[$j];
+
+      if (!$self->exists_matrix ($seq1, $seq2)) { next; }
+
+      $s .= "
+; Sparse posterior probability matrix for sequences $seq1 and $seq2
+; Format is:
+;   ($seq1, position_1) ~ ($seq2, position_2) => prob
+; which means that ($seq1, position_1) is aligned to ($seq2, position_2) with probability prob.
+;   ($seq1, position_1) ~ ($seq2, -1) => prob
+; means that ($seq1, position_1) is aligned to a gap in $seq2 with probability prob.
+; sequence is 0-based and position is 0-based
+";
+
+      $s .= "; match posteriors\n";
+      foreach my $pos1 (sort { $a <=> $b } keys %{$self->match_probs->{$seq1}->{$seq2}}) {
+	foreach my $pos2 (sort { $a <=> $b } keys %{$self->match_probs->{$seq1}->{$seq2}->{$pos1}}) {
+	  $s .= "($seq1, $pos1) ~ ($seq2, $pos2) => " . $self->match_probs->{$seq1}->{$seq2}->{$pos1}->{$pos2} . "\n";
+	}
+      }
+      $s .= "\n";
+
+      $s .= "; gap posteriors\n";
+      foreach my $pos1 (sort { $a <=> $b } keys %{$self->gap_probs->{$seq1}->{$seq2}}) {
+	$s .= "($seq1, $pos1) ~ ($seq2, -1) => " . $self->gap_probs->{$seq1}->{$seq2}->{$pos1} . "\n";
+      }
+      $s .= "\n";
+      foreach my $pos2 (sort { $a <=> $b } keys %{$self->gap_probs->{$seq2}->{$seq1}}) {
+	$s .= "($seq1, -1) ~ ($seq2, $pos2) => " . $self->gap_probs->{$seq2}->{$seq1}->{$pos2} . "\n";
+      }
+      $s .= "\n";
+
+    }
+  }
+
+  return $s;
+}
+
+# Do we have information for a particular sequence pair?
+sub exists_matrix {
+  my ($self, $seq1, $seq2) = @_;
+
+  if (defined $self->match_probs->{$seq1} and
+      defined $self->match_probs->{$seq1}->{$seq2}) {
+    return 1;
+  }
+
+  return 0;
+}
+
+# Get match probability.
+sub get_match_prob {
+  my ($self, $seq1, $seq2, $pos1, $pos2) = @_;
+
+  if (!$self->exists_matrix ($seq1, $seq2)) {
+    croak "No probability matrix for sequences '$seq1' and '$seq2'.";
+  }
+
+  # if no entry, return 0
+  if (!defined $self->match_probs->{$seq1}->{$seq2}->{$pos1} or
+      !defined $self->match_probs->{$seq1}->{$seq2}->{$pos1}->{$pos2}) {
+    return 0;
+  }
+
+  return assert_valid_prob ($self->match_probs->{$seq1}->{$seq2}->{$pos1}->{$pos2});
+}
+
+sub assert_valid_prob {
+  my ($prob) = shift;
+
+  if ($prob > 1.0001) { die "Probability of ", $prob, " exceeds bounds.\n"; }
+  
+  return ($prob > 1.0) ? 1.0 : $prob;
+}
+
+# Get gap probability.
+sub get_gap_prob {
+  my ($self, $seq1, $seq2, $pos1) = @_;
+
+  if (!$self->exists_matrix ($seq1, $seq2)) {
+    croak "No matrix for sequences '$seq1' and '$seq2';"
+  }
+
+  # there must exist an entry (FSA always outputs one)
+  if (!defined $self->gap_probs->{$seq1}->{$seq2}->{$pos1}) {
+    croak "No gap probability ($seq1, $pos1) ~ ($seq2, -1); I'm quitting.";
+  }
+
+  return $self->gap_probs->{$seq1}->{$seq2}->{$pos1};
+}
+
+# Get sum_pos2 P((seq1, pos1) ~ (seq2, pos2)).
+# Cover the case of no entry for a match probability > 0.01.
+# This coarse-graining of probabilities is important,
+# since sum_prob is used as a denominator.
+sub get_sum_prob {
+  my ($self, $seq1, $seq2, $pos1) = @_;
+
+  my $p = (defined $self->sum_probs->{$seq1}->{$seq2}->{$pos1}) ? $self->sum_probs->{$seq1}->{$seq2}->{$pos1} : 0.01;
+  return assert_valid_prob ($p);
+}
+
+# Get max_pos2 P((seq1, pos1) ~ (seq2, pos2)),
+# where pos2 can be a gap as well.
+sub get_max_prob {
+  my ($self, $seq1, $seq2, $pos1) = @_;
+
+  # assert that max prob is defined
+  # (because pos2 can be a gap, a max prob is always defined)
+  if (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0]) {
+    croak "A max prob is undefined; this should never happen!\n";
+  }
+
+  return assert_valid_prob ($self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0]);
+}
+
+# Get altmax_pos2 P((seq1, pos1) ~ (seq2, pos2)),
+# where pos2 can be a gap as well.
+# Note that we need to know $pos2 here (in contrast to get_max_prob),
+# in order to determine whether the probability corresponding to
+# the alignment ($seq1, $pos1) ~ ($seq2, $pos2)
+# is the max, altmax or otherwise.
+sub get_altmax_prob {
+  my ($self, $seq1, $seq2, $pos1, $pos2) = @_;
+
+  # assert that max prob is defined
+  if (!defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0]) {
+    croak "A max prob is undefined; this should never happen!\n";
+  }
+  # note that an altmax might not be defined,
+  # ie if there is no match probability entry and so the max prob is
+  # the gap prob
+
+  my $p;
+  if ($pos1 >= 0 && $pos2 >= 0) {
+    $p = $self->get_match_prob ($seq1, $seq2, $pos1, $pos2);
+  }
+  elsif ($pos1 >= 0 && $pos2 == -1) {
+    $p = $self->get_gap_prob ($seq1, $seq2, $pos1);
+  }
+  else {
+    croak "No good; tried to get the altmax for a gap!\n";
+  }
+
+  # if $p is the max, then return the second-best alternative
+  if (abs ($p - $self->get_max_prob ($seq1, $seq2, $pos1)) < 0.0001) {
+    if (defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1]) {
+      return $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1];
+    } else {
+      return 0.01;
+    }
+  }
+  # else return the max
+  else {
+    return $self->get_max_prob ($seq1, $seq2, $pos1);
+  }
+
+}
+
+# Compute the average certainty of the model.
+# This corresponds to:
+#  for each sequence seq1
+#     for each sequence seq2
+#        for each position pos1 in seq1
+#           += P(pos1 ~ best)
+#           += P(pos1 ~ next-best)
+# Note that this calculation is only a measure of the width of the 
+# probability distribution in the DP matrix, and as such is alignment-independent.
+sub get_model_certainty {
+  my ($self) = @_;
+
+  my $max = 0;
+  my $altmax = 0;
+
+  foreach my $seq1 (keys %{$self->max_probs}) {
+    for (my $pos1 = 0; $pos1 < $self->seq_len->{$seq1}; ++$pos1) {
+      foreach my $seq2 (keys %{$self->max_probs->{$seq1}}) {
+	# remember that altmax automatically gets initialized to minimum value
+	# when max is initialized
+	$max += $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0];
+	if (defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1]) {
+	  $altmax += $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1];
+	} else {
+	  $altmax += 0.01;
+	}
+      }
+    }
+  }
+
+  return ($max / $altmax);
+}
+
+# As above, but show the entire distribution of slopes (for all characters).
+sub show_model_certainty_slopes {
+  my ($self, $precision) = @_;
+
+  foreach my $seq1 (keys %{$self->max_probs}) {
+    for (my $pos1 = 0; $pos1 < $self->seq_len->{$seq1}; ++$pos1) {
+      foreach my $seq2 (keys %{$self->max_probs->{$seq1}}) {
+	if (defined $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1]) {
+	  printf "%.${precision}f\n", $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] / $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[1];
+	} else {
+	  printf "%.${precision}f\n", $self->max_probs->{$seq1}->{$seq2}->{$pos1}->[0] / 0.01;
+	}
+      }
+    }
+  }
+
+}
+
+
+1
diff --git a/perl/GFF.pm b/perl/GFF.pm
new file mode 100644
index 0000000..34bd2cc
--- /dev/null
+++ b/perl/GFF.pm
@@ -0,0 +1,271 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+GFF.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating a single GFF entry.
+Note that the GFF format, which specifies that coordinates
+are 1-based and fully-closed, is enforced by this module.
+
+The original GFF module was written by Ian Holmes.
+This version has been extended by Robert Bradley.
+
+=head1 METHODS
+
+=cut
+
+package GFF;
+
+use strict;
+use Carp;
+
+=head2 new
+
+    my $gff = GFF->new()
+
+Creates an empty GFF object.
+
+=cut
+sub new {
+  my $class = shift;
+
+  my $self = {
+	      'seqid' => '.',
+	      'source' => '.',
+	      'type' => '.',
+	      'start' => '.',
+	      'end' => '.',
+	      'score' => '.',
+	      'strand' => '.',
+	      'phase' => '.',
+	      'attributes' => '.',
+              'attributes_hash' => undef,
+	      @_
+              };
+
+  bless $self, ref($class) || $class;
+
+  return $self;
+}
+
+=head2 seqid
+
+    my $seqid = $gff->seqid
+
+Returns the seqid field.
+
+    $gff->seqid ($newseqid)
+
+Sets the seqid field.
+
+Similarly implemented for all GFF fields.
+
+Catches all methods by default.
+
+=cut
+sub AUTOLOAD {
+  my ($self, @args) = @_;
+  my $sub = our $AUTOLOAD; # $AUTOLOAD contains the fully qualified name of the original subroutine
+  $sub =~ s/.*:://;
+
+  # check for DESTROY
+  return if $sub eq 'DESTROY';
+
+  # check for ordinary accessors
+  # This has the effect of automatically implementing getter and setter methods.
+  # If there's an instance variable $name, then the getter method is $self->name
+  # and the setter method is $self->name('newName')
+  if (exists $self->{$sub}) {
+    if (@args > 1) { croak "Usage: $sub() or $sub(newValue)"; }
+    return
+      @args                      # if @args > 0
+      ? $self->{$sub} = $args[0] # { $self->{$sub} = $args[0]; return $args[0]; }
+      : $self->{$sub};            # else { return $self->{$sub}; }
+  }
+
+  croak "Unsupported method: $sub\n";
+}
+
+=head2 from_string
+
+    my $gff = GFF->from_string ($str)
+
+Reads values from a string in GFF format.
+
+=cut 
+sub from_string {
+  my $class = shift;
+
+  my $self = $class;
+  if (!ref ($class)) { $self = $class->new(); }
+
+  my $str = shift if (@_);
+  if (!defined $str) { return undef; }
+
+  chomp ($str);
+
+  # check for:
+  # empty lines
+  # comment and sequence header lines
+  # sequence lines
+  if ($str eq ""
+      || $str =~ /^\s*(#|>)/
+      || $str =~ /^\s*\S+\s*$/)
+    { return undef; }
+
+  my @gff = split /\t/, $str;
+  $self->{"seqid"} = $gff[0];
+  $self->{"source"} = $gff[1];
+  $self->{"type"} = $gff[2];
+  $self->set_start ($gff[3]);
+  $self->{"end"} = $gff[4];
+  $self->{"score"} = $gff[5];
+  $self->{"strand"} = $gff[6];
+  $self->{"phase"} = $gff[7];
+  $self->{"attributes"} = $gff[8];
+
+  return $self;
+}
+
+=head2 to_string
+
+    print $gff->to_string()
+
+Output to a string in GFF format.
+
+=cut 
+sub to_string {
+  my $self = shift;
+  return join ("\t", $self->seqid, $self->source, $self->type, 
+	       $self->start, $self->end, $self->score,
+	       $self->strand, $self->phase, (defined $self->attributes ? $self->attributes : '') . "\n");
+}
+
+=head2 to_file
+
+    $gff->to_file ($myfile)
+
+Output to a file in GFF format.
+
+    $gff->to_file ($myfile, 1)
+
+Append mode.
+
+=cut
+sub to_file {
+  my ($self, $pFile, $pMode) = @_;
+
+  my $modeOp = ">";
+  if ($pMode) {$modeOp = ">>";}
+  open(FILE, $modeOp . $pFile) or die "Could not open $pFile.\n";
+  print FILE $self->to_string();
+}
+
+=head2 set_start
+
+   $gff->set_start ($start)
+
+Set the start coordinate.
+Enforces start coordinate >= 1.
+
+=cut
+sub set_start {
+  my ($self, $s) = @_;
+  if ($s < 1) { warn "Setting start coordinate '$s' to 1.\n"; $s = 1; }
+  $self->start ($s);
+}
+
+=head2 add_value
+
+   $gff->add_value()
+
+Add single entry (key and value) to attributes field.
+
+=cut 
+sub add_value {
+  my ($self, $key, $value) = @_;
+
+  # add value to string for attributes field
+  if (($self->attributes eq ".") || !length ($self->attributes)) {
+    $self->attributes ("$key=$value");
+  } elsif ($self->attributes =~ /;$/) {
+    $self->{attributes} .= "$key=$value";
+  } else {
+    $self->{attributes} .= ";$key=$value";
+  }
+
+  # store in attributes hash if appropriate
+  if ($self->{attributes_hash}) { ${$self->{attributes_hash}}{$key} = $value; }
+}
+
+=head2 get_attributes_hash 
+
+   $gff->get_attributes_hash()
+
+Get attributes field as a hash from keys to values.
+Creates it if it doesn't already exist.
+
+=cut 
+sub get_attributes_hash {
+  my $self = shift;
+
+  my $hashRef = $self->{attributes_hash};
+  my %hash;
+  if (!$hashRef) {
+    my @pairs = split (/;/, $self->{attributes});
+    foreach my $pair (@pairs) {
+      my @keyVal = split (/=/, $pair);
+      $hash{$keyVal[0]} = $keyVal[1];
+    }
+    $hashRef = \%hash;
+    # set attributes_hash
+    $self->{attributes_hash} = $hashRef;
+  }
+
+  return $hashRef;
+
+}
+
+=head2 get_value
+
+   $gff->get_value ($key)
+
+Get value in attributes field.
+
+=cut 
+sub get_value {
+  my ($self, $key) = @_;
+
+  return ${$self->get_attributes_hash()}{$key};
+
+}
+
+=head2 set_value
+
+   $gff->set_value ($key)
+
+Set value in attributes field.
+
+=cut 
+sub set_value {
+  my ($self, $key, $value) = @_;
+
+  my $hashref = $self->get_attributes_hash();
+  # add the value if it's new
+  if (!defined $hashref->{$key}) {
+    $self->add_value ($key, $value);
+  }
+  # else parse out and replace the old value
+  # (yes, this is very slow, but I can't be bothered to fix it now)
+  else {
+    my $oldstr = "$key=" . $hashref->{$key};
+    my $newstr = "$key=" . $value;
+    $self->{attributes} =~ s/$oldstr/$newstr/;
+  }
+
+}
+
+1
diff --git a/perl/GFF/Database.pm b/perl/GFF/Database.pm
new file mode 100644
index 0000000..e259877
--- /dev/null
+++ b/perl/GFF/Database.pm
@@ -0,0 +1,201 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+GFF::Database.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating a GFF file ("database").
+
+The original GFF::Database module was written by Ian Holmes.
+This version has been extended by Robert Bradley.
+
+=cut
+
+package GFF::Database;
+
+use strict;
+use Carp;
+
+use GFF;
+
+=head2 new
+
+    my $gffdb = GFF::Database->new()
+
+Creates an empty GFF::Database object.
+
+=cut
+sub new {
+  my ($class) = @_;
+
+  my $self = {
+	      'db' => []
+	     };
+
+  bless $self, ref ($class) || $class;
+
+  return $self;
+}
+
+=head2 db
+
+    my $records = $gffdb->db
+
+Returns the list of GFF records contained.
+
+Catches all methods by default.
+
+=cut
+sub AUTOLOAD {
+  my ($self, @args) = @_;
+  my $sub = our $AUTOLOAD; # $AUTOLOAD contains the fully qualified name of the original subroutine
+  $sub =~ s/.*:://;
+
+  # check for DESTROY
+  return if $sub eq 'DESTROY';
+
+  # check for ordinary accessors
+  # This has the effect of automatically implementing getter and setter methods.
+  # If there's an instance variable $name, then the getter method is $self->name
+  # and the setter method is $self->name('newName')
+  if (exists $self->{$sub}) {
+    if (@args > 1) { croak "Usage: $sub() or $sub(newValue)"; }
+    return
+      @args                      # if @args > 0
+      ? $self->{$sub} = $args[0] # { $self->{$sub} = $args[0]; return $args[0]; }
+      : $self->{$sub};            # else { return $self->{$sub}; }
+  }
+
+  croak "Unsupported method: $sub\n";
+}
+
+=head2 from_file
+
+    my $gffdb = GFF::Database->from_file ($filename)
+
+Reads GFF file.
+
+=cut 
+sub from_file {
+  my ($class, $filename) = @_;
+
+  my $self = $class->new;
+
+  $self->append_from_file ($filename);
+
+  return $self;
+}
+
+=head2 append_from_file
+
+    my $gffdb->append_from_file ($filename)
+
+Appends from GFF file.
+
+=cut 
+sub append_from_file {
+  my ($self, $filename) = @_;
+
+  my $gff;
+  local *FILE;
+  local $_;
+  open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+  while (<FILE>) {
+
+    # skip empty lines
+    chomp;
+    if ($_ eq "") { next; }
+
+    # skip comment and sequence header lines
+    if (/^\s*(#|>)/) { next; }
+
+    # skip sequence lines
+    if (/^\s*\S+\s*$/) { next; }
+      
+    $gff = GFF->new unless defined $gff;
+    if ($gff->from_string ($_)) {
+      $self->add ($gff);
+      $gff = undef;
+    }
+
+  }
+  close FILE;
+
+  # catch end case
+  $self->add ($gff) if defined $gff;
+
+}
+
+=head2 add
+
+    $gffdb->add ($gff)
+
+Add a single GFF entry to database.
+
+=cut
+sub add {
+  my ($self, $gff, $verbose) = @_;
+  push @{$self->db}, $gff;
+  warn "...loaded GFF record ", $gff->to_string() if $verbose;
+  return $self;
+}
+
+=head2 to_string
+
+    print $gff->to_string()
+
+Output to a string in GFF format.
+
+=cut 
+sub to_string {
+  my ($self) = @_;
+
+  my $str = join ("", map ($_->to_string(), @{$self->db}));
+
+  return $str;
+
+}
+
+=head2 find_by_group
+
+    $gff->find_by_group ($key, $value)
+
+Query for GFF records matching a given key/value in the group field.
+
+=cut 
+sub find_by_group {
+  my ($self, $pKey, $pVal) = @_;
+
+  my @gffList;
+  foreach my $gff (@{$self->{db}})
+  {
+    my $group_hash = $gff->get_group_hash();
+    if (${$group_hash}{$pKey} eq $pVal) { push(@gffList, $gff); }
+  }
+
+  return \@gffList;
+}
+
+=head2 find_by_type
+
+    my $list = $gff->find_by_type ("type")
+
+Get all entries with a particular type field.
+
+=cut
+sub find_by_type {
+  my ($self, $type) = @_;
+
+  my @list;
+  foreach my $gff (@{$self->{db}}) {
+    if ($gff->type eq $type) {
+      push @list, $gff;
+    }
+  }
+
+  return \@list;
+}
+
+1
diff --git a/perl/Makefile.am b/perl/Makefile.am
new file mode 100644
index 0000000..0caca20
--- /dev/null
+++ b/perl/Makefile.am
@@ -0,0 +1,14 @@
+EXTRA_DIST = \
+	accuracy.pl\
+	cmpalign.pl \
+	dartlog.pl \
+	fasta2stockholm.pl \
+	FSA/SparseMatrices.pm \
+	FSA/Model.pm \
+	GFF.pm \
+	GFF/Database.pm \
+	prettify.pl \
+	seqdotplot.pl \
+	stockholm2fasta.pl \
+	Stockholm.pm \
+	Stockholm/Database.pm
diff --git a/perl/Makefile.in b/perl/Makefile.in
new file mode 100644
index 0000000..40ec6be
--- /dev/null
+++ b/perl/Makefile.in
@@ -0,0 +1,422 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = perl
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+EXTRA_DIST = \
+	accuracy.pl\
+	cmpalign.pl \
+	dartlog.pl \
+	fasta2stockholm.pl \
+	FSA/SparseMatrices.pm \
+	FSA/Model.pm \
+	GFF.pm \
+	GFF/Database.pm \
+	prettify.pl \
+	seqdotplot.pl \
+	stockholm2fasta.pl \
+	Stockholm.pm \
+	Stockholm/Database.pm
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign perl/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign perl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic cscopelist-am \
+	ctags-am distclean distclean-generic distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/perl/Stockholm.pm b/perl/Stockholm.pm
new file mode 100644
index 0000000..784bb6a
--- /dev/null
+++ b/perl/Stockholm.pm
@@ -0,0 +1,1788 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+Stockholm.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating a Stockholm multiple alignment.
+Can load Stockholm, multi-FASTA (MFA), CLUSTAL and MSF alignments.
+Can print Stockholm and MFA aligments.
+
+The original Stockholm module was written by Ian Holmes for his DART library.
+This version has been modified and extended by Robert Bradley.
+
+=head1 METHODS
+
+=cut
+
+package Stockholm;
+
+use strict;
+use vars '@ISA';
+
+use Carp qw(carp cluck croak);
+
+# define the gap alphabet
+my $gapChars = '-._';
+
+# define percent id annotation
+my $percentid_annot = 'Percent_id';
+
+# define gap fraction annotation
+my $gapfraction_annot = 'Gap_fraction';
+
+
+=head2 new
+
+    my $stock = Stockholm->new();
+
+Creates an empty Stockholm object.
+
+=cut
+sub new {
+  my ($class) = @_;
+
+  my $self = {
+	      'seqname' => [],  # order of sequences
+	      'seqdata' => {},  # sequence data itself
+	      'gf' => {},       # Generic File annotation (freeform)
+	      'gc' => {},       # Generic Consensus annotation (by-column)
+	      'gs' => {},       # Generic Sequence annotation (by-sequence, freeform)
+	      'gr' => {},       # Generic by-Row annotation (by-sequence, by-column)
+	      'gforder' => []   # order of GF lines
+	     };
+
+  bless $self, ref ($class) || $class;
+
+  return $self;
+}
+
+=head2 from_file
+
+    my $stock = Stockholm->from_file ($filename);
+    my $stock = Stockholm->from_file ($filename, 1);
+
+Creates a new Stockholm object and reads it from a file.
+Attempts to automatically detect the format of the input file
+and parse accordingly.
+
+If last argument is true, then call strip_leading_chr to remove
+the 'chr' frequently prepended to chromosome names.
+
+=cut
+sub from_file {
+  my ($class, $filename, $remove_chr) = @_;
+
+  my $self;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  # FASTA
+  if ($class->detect_FASTA ($filename)) {
+    local *FILE;
+    open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+    $self = $class->from_filehandle_FASTA (\*FILE, $remove_chr);
+    close FILE;
+  }
+
+  # CLUSTAL
+  elsif ($class->detect_CLUSTAL ($filename)) {
+    local *FILE;
+    open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+    $self = $class->from_filehandle_CLUSTAL (\*FILE, $remove_chr);
+    close FILE;
+  }
+
+  # MSF
+  elsif ($class->detect_MSF ($filename)) {
+    local *FILE;
+    open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+    $self = $class->from_filehandle_MSF (\*FILE, $remove_chr);
+    close FILE;
+  }
+
+  # Stockholm
+  else {
+    local *FILE;
+    open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+    $self = $class->from_filehandle_Stockholm (\*FILE, $remove_chr);
+    close FILE;
+  }
+
+  return $self;
+
+}
+
+=head2 detect_FASTA
+
+    detect_FASTA ($filename);
+
+Detects whether the alignment is FASTA format.
+Looks for lines of the form
+>seqname
+
+=cut
+sub detect_FASTA {
+  my ($class, $filename) = @_;
+
+  local *FILE;
+  open FILE, "<$filename" or croak "Couldn't open '$filename'.\n";
+  while (<FILE>) {
+    if (/^\s*>\s*\S+/) { return 1; }
+  }
+  close FILE;
+
+  return 0;
+}
+
+=head2 from_filehandle_FASTA
+
+    $self->from_filehandle_FASTA ($filehandle);
+
+Creates a new Stockholm object and reads it from a filehandle.
+
+=cut
+sub from_filehandle_FASTA {
+  my ($class, $filehandle, $remove_chr) = @_;
+  
+  my $self = $class->new;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  my $name = "";
+  my $data = "";
+
+  # perform a first pass through the data to put each alignment row
+  # onto a single line
+  # this *dramatically* speeds up reading in FASTA alignments
+  local $_;
+  my $str = "";
+  while (<$filehandle>) {
+    if (/^\s*>/) { $str .= "\n$_"; next; }
+    chomp;
+    $str .= $_;
+  }
+
+  # now read in this compressed format
+  my $str_handle;
+  open ($str_handle, "<",  \$str);
+  while (<$str_handle>) {
+    chomp;
+
+    # if beginning of new sequence
+    if (/^\s*>/) {
+
+      # store previous sequence if available
+      if ($name ne "") {
+	push @{$self->seqname}, $name;
+	$self->seqdata->{$name} = $data;
+	$data = ""; # reset data
+      }
+
+      # store new name
+      unless (/^\s*>\s*(\S+)/) { croak "Couldn't parse out sequence name from line: $_\n"; }
+      $name = $1;
+      if ($remove_chr) { $name = $self->strip_leading_chr ($name); }
+    }
+
+    # else store data
+    else {
+      $data .= $_;
+      $data =~ s/\s//g; # remove whitespace
+    }
+
+  }
+  close $str_handle;
+
+  # catch last sequence
+  push @{$self->seqname}, $name;
+  $self->seqdata->{$name} = $data;
+  
+  return $self;
+
+}
+
+=head2 detect_CLUSTAL
+
+    detect_CLUSTAL ($filename);
+
+Detects whether the alignment is CLUSTAL format.
+
+=cut
+sub detect_CLUSTAL {
+  my ($class, $filename) = @_;
+
+  local *FILE;
+  open FILE, "<$filename" or croak "Couldn't open '$filename'.\n";
+  while (<FILE>) {
+    if (/^\s*CLUSTAL/) { return 1; }
+  }
+  close FILE;
+
+  return 0;
+}
+
+=head2 from_filehandle_CLUSTAL
+
+    $self->from_filehandle_CLUSTAL ($filehandle);
+
+Creates a new Stockholm object and reads it from a filehandle.
+
+=cut
+sub from_filehandle_CLUSTAL {
+  my ($class, $filehandle, $remove_chr) = @_;
+  
+  my $self = $class->new;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  local $_;
+  while (<$filehandle>) {
+    chomp;
+
+    # skip conservation lines with * : .
+    next if (/^(\s*[\*:\.]*\s*)+$/);
+
+    # sequence data
+    my @a = split;
+    next unless @a == 2;
+    my ($seq, $data) = @a;
+    if ($remove_chr) { $seq = $self->strip_leading_chr ($seq); }
+
+    if (defined $self->seqdata->{$seq}) {
+      $self->seqdata->{$seq} .= $data;
+    } else {
+      push @{$self->seqname}, $seq;
+      $self->seqdata->{$seq} = $data;
+    }
+
+  }
+
+  return $self;
+  
+}
+
+=head2 detect_MSF
+
+    detect_MSF ($filename);
+
+Detects whether the alignment is MSF format.
+Looks for the special line containing
+"MSF:", "Type:" , and "Check:" and ending with two dots.
+Specification taken from:
+http://biobug.life.nthu.edu.tw/predictprotein/Dexa/optin_msfDes.html
+
+=cut
+sub detect_MSF {
+  my ($class, $filename) = @_;
+
+  local *FILE;
+  open FILE, "<$filename" or croak "Couldn't open '$filename'.\n";
+  while (<FILE>) {
+    # "MSF:", "Type:" , and "Check:" and ending with two dots.
+    if (/(MSF:){1}.*(Type:){1}.*(Check:){1}.*(\.\.){1}/i) { return 1; }
+  }
+  close FILE;
+
+  return 0;
+}
+
+=head2 from_filehandle_MSF
+
+    $self->from_filehandle_MSF ($filehandle);
+
+Creates a new Stockholm object and reads it from a filehandle.
+
+=cut
+sub from_filehandle_MSF {
+  my ($class, $filehandle, $remove_chr) = @_;
+  
+  my $self = $class->new;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  my $in_body = 0;
+
+  local $_;
+  while (<$filehandle>) {
+    chomp;
+
+    # alignment header
+    if (!$in_body) {
+
+      # if a sequence descriptor in the alignment description,
+      # store the sequence name and initialize the sequence data
+      if (/^\s*Name:\s*(\S+)\s*/) {
+	my $name = $1;
+	if ($remove_chr) { $name = $self->strip_leading_chr ($name); }
+	push @{$self->seqname}, $name;
+	if (defined $self->seqdata->{$name}) {
+	  croak "Duplicate sequence name '$name' in MSF alignment descriptor; I'm quitting.\n";
+	}
+	$self->seqdata->{$name} = "";
+      }
+
+      # termination of header list
+      elsif (/^\s*\/\/\s*$/) { $in_body = 1; }
+
+    }
+
+    # alignment body 
+    else {
+
+      # if a sequence line
+      if (/^\s*(\S+)\s+(\S+.*)+\s*$/) {  # allows empty sequence lines
+	my $name = $1;
+	if ($remove_chr) { $name = $self->strip_leading_chr ($name); }
+	if (!defined $self->seqdata->{$name}) {
+	  warn "Skipping line because I don't recognize the sequence '$name':\n$_\n";
+	}
+	$self->seqdata->{$name} .= $2;
+	$self->seqdata->{$name} =~ s/\s//g; # remove whitespace
+      }
+
+    }
+
+  }
+
+  return $self;
+  
+}
+
+=head2 detect_Stockholm
+
+    detect_Stockholm ($filename);
+
+Detects whether the alignment is Stockholm format.
+Doesn't allow empty sequence lines.
+
+=cut
+sub detect_Stockholm {
+  my ($class, $filename) = @_;
+
+  local *FILE;
+  open FILE, "<$filename" or croak "Couldn't open '$filename'.\n";
+
+  while (<FILE>) {
+
+    # look for Stockholm header
+    if (/\# STOCKHOLM/) { return 1; }
+
+    # look for Stockholm comment lines
+    elsif (/^\s*\#=[GF|GS|GC|GR]/) { return 1; }
+
+    # skip unrecognized comment lines
+    elsif (/^\s*\#.*$/) { next; }
+
+    # skip alignment separators
+    elsif (/^\s*\/\/\s*$/) { next; }
+
+    # confirm that format of sequence lines is Stockholm-compatible
+    elsif (/^\s*(\S+)\s+(\S+)\s*$/) { next; } # don't allow empty sequence lines
+
+    # else declare it not Stockholm format
+    else { return 0; }
+
+  }
+  close FILE;
+
+  return 1;
+}
+
+
+=head2 from_filehandle_Stockholm
+
+    my $stock = Stockholm->from_filehandle_Stockholm ($filehandle);
+
+Creates a new Stockholm object and reads it from a filehandle.
+
+=cut
+sub from_filehandle_Stockholm {
+  my ($class, $filehandle, $remove_chr) = @_;
+
+  my $self = $class->new;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  local $_;
+  while (<$filehandle>) {
+    last if $self->parse_input_line ($_, $remove_chr);
+  }
+  carp "Warning: alignment is not flush" unless $self->is_flush();
+
+  return $self;
+}
+
+=head2 to_file
+
+    $stock->to_file ($filename);
+
+Writes a Stockholm object to a file.
+
+=cut
+sub to_file {
+  my ($self, $filename, $maxcols) = @_;
+
+  local *FILE;
+  open FILE, ">$filename" or croak "Couldn't open '$filename' for writing: $!";
+  print FILE $self->to_string ($maxcols);
+  close FILE or croak "Couldn't close '$filename': $!";;
+
+  return $filename;
+}
+
+=head2 to_string_FASTA
+
+   print $fasta->to_string_FASTA();
+   print $fasta->to_string_FASTA (0);
+
+Returns the object as a multi-FASTA or ungapped FASTA formatted string.
+
+=cut
+sub to_string_FASTA {
+  my ($self, $ungapped) = @_;
+  
+  my $fasta;
+
+  # write MFA rather than ungapped FASTA by default
+  if (!defined $ungapped) { $ungapped = 0; }
+  
+  foreach my $seq (@{$self->seqname}) {
+    $fasta .= ">$seq\n";
+    my $newseq = $self->seqdata->{$seq};
+    if ($ungapped) { $newseq =~ s/[$gapChars]//g; } # remove gaps if requested
+    $fasta .= $newseq . "\n";
+  }
+
+  return $fasta;
+
+}
+
+=head2 to_string
+
+    print $stock->to_string ($maxcols)
+    print $stock->to_string ($maxcols, ARG1=>VAL1, ARG2=>VAL2 ...)
+    print $stock->to_string (MAXCOLS=>$maxcols, ARG1=>VAL1, ARG2=>VAL2 ...)
+
+Returns the object as a Stockholm-formatted string.
+
+ARGs can include...
+        MAXCOLS    -- limit maximum number of columns (can also be specified as a single scalar arg)
+        NOSEQDATA  -- don\'t print any sequence data (can be used this to compress output)
+
+=cut
+sub to_string {
+  my ($self, @args) = @_;
+
+  my (%args, $maxcols);
+  if (@args % 2 == 1) {
+    $maxcols = shift @args;
+    %args = @args;
+  } else {
+    %args = @args;
+    $maxcols = $args{'MAXCOLS'};
+  }
+  $maxcols = 80 unless defined $maxcols; # default 80-column output
+
+  # init output array
+  my @out;
+  push @out, "# STOCKHOLM 1.0";
+
+  # determine alignment columns, legend columns & effective columns per line
+  my $acols = $self->columns();
+  my $lcols = $self->lcols();
+  my $colstep = $maxcols < 1 ? $acols : $maxcols - $lcols - 1;
+  $colstep = $maxcols if $colstep < 1; # protect against negative and 0 colstep...
+
+  # GF lines
+  # check for gforder (insane, fragile Stockholm line ordering strikes again)
+  if (@{$self->gforder} == map { (@$_) } values %{$self->gf}) { # gforder same number of lines as #=GF block?
+    my %gfCursor = map (($_ => 0), keys %{$self->gf});
+    foreach my $feature (@{$self->gforder}) {
+      push @out, $self->prettify ($lcols, "#=GF $feature", $self->gf_($feature)->[$gfCursor{$feature}++]);
+    }
+  } else {
+    @{$self->gforder} = ();	# gforder is useless, so flush it
+    foreach my $feature (sort { $a cmp $b } keys %{$self->gf}) {
+      push @out, $self->prettify ($lcols, "#=GF $feature", @{$self->gf_($feature)});
+    }
+  }
+
+  # GS lines
+  my @gs_seqname = @{$self->seqname};
+  my %gs_seqname_hash = map (($_=>1), grep (!exists $self->seqdata->{$_}, map (keys(%{$self->gs_($_)}), keys %{$self->gs})));
+  push @gs_seqname, keys %gs_seqname_hash;
+  foreach my $feature (sort { $a cmp $b } keys %{$self->gs}) {
+    my $hash = $self->gs_($feature);
+    foreach my $seqname (grep (exists($hash->{$_}), @gs_seqname)) {
+      push @out, $self->prettify ($lcols, "#=GS $seqname $feature", @{$hash->{$seqname}});
+    }
+  }
+
+  my @gcfeat = sort { $a cmp $b } keys %{$self->gc};
+  my @gr_seqname = @{$self->seqname};
+  my %gr_seqname_hash = map (($_=>1), grep (!exists $self->seqdata->{$_}, map (keys(%{$self->gr_($_)}), keys %{$self->gr})));
+  push @gr_seqname, keys %gr_seqname_hash;
+
+  # Loop over columns
+  for (my $col = 0; $col < $acols; $col += $colstep) {
+
+    # GC lines
+    foreach my $feature (@gcfeat) {
+      push @out, $self->prettify ($lcols, "#=GC $feature",
+				  substr ($self->gc_($feature), $col, $colstep));
+    }
+    for (my $i = 0; $i < @gr_seqname; ++$i) {
+      my $seqname = $gr_seqname[$i];
+      # Sequences
+      #	    warn "Writing cols $col+$colstep for $seqname";
+      push @out, $self->prettify ($lcols, $seqname,
+				  substr ($self->seqdata->{$seqname}, $col, $colstep))
+	if exists $self->seqdata->{$seqname}
+	  && !$args{'NOSEQDATA'};
+      # GR lines
+      foreach my $feature (grep (exists ($self->gr->{$_}->{$seqname}), keys %{$self->gr})) {
+	#		warn "Writing cols $col+$colstep for $seqname $feature";
+	push @out, $self->prettify ($lcols, "#=GR $seqname $feature",
+				    substr ($self->gr_($feature)->{$seqname}, $col, $colstep));
+      }
+    }
+    push @out, "";
+  }
+
+  # alignment separator
+  push @out, "//";
+
+  # convert output array to string & return
+  return join ("", map ("$_\n", @out));
+}
+
+=head2 copy
+
+    my $newStock = $stock->copy();
+
+Does a deep-copy, duplicating all information.
+
+=cut
+sub copy {
+  my ($self) = @_;
+
+  my $stock = Stockholm->new;
+
+  # Sequence names & data
+  @{$stock->seqname} = @{$self->seqname};
+  %{$stock->seqdata} = %{$self->seqdata};
+
+  #=GF
+  while (my ($feature, $arrayRef) = each %{$self->gf}) {
+    $stock->gf->{$feature} = [@$arrayRef];
+  }
+  @{$stock->gforder} = @{$self->gforder};
+
+  #=GC
+  while (my ($feature, $string) = each %{$self->gc}) {
+    $stock->gc->{$feature} = $string;
+  }
+
+  #=GR
+  while (my ($feature, $seqHash) = each %{$self->gr}) {
+    $stock->gr->{$feature} = {%$seqHash};
+  }
+
+  #=GS
+  while (my ($feature, $seqHash) = each %{$self->gs}) {
+    $stock->gs->{$feature} = {%$seqHash};
+  }
+
+  # Return
+  return $stock;
+}
+
+=head2 columns
+
+    my $cols = $stock->columns()
+
+Returns the number of columns in this alignment.
+The value is recalculated each time because the
+sequence or annotation data may have changed since
+the method was last called.
+
+=cut
+sub columns {
+  my ($self) = @_;
+
+  return max (map (length ($_),
+		   values (%{$self->seqdata}),
+		   values (%{$self->gc}),
+		   map (values (%$_), values (%{$self->gr}))));
+
+}
+
+=head2 sequences
+
+    my $cols = $stock->sequences()
+
+Returns the number of sequences (rows) in this alignment.
+
+=cut
+sub sequences {
+  my ($self) = @_;
+  return @{$self->seqname} + 0;
+}
+
+=head2 seqname
+
+    my $rowName = $stock->seqname->[$rowIndex];
+
+Returns a reference to an array of sequence names.
+
+=head2 seqdata
+
+    my $row = $stock->seqdata->{$rowName};
+
+Returns a reference to a hash of alignment rows, keyed by sequence name.
+
+=head2 gf
+
+    my @gf = @{$stock->gf->{FEATURE}};
+    my @gf = @{$stock->gf_FEATURE};
+
+Returns a reference to an array of all the lines beginning '#=GF FEATURE ...'
+
+=head2 gc
+
+    my $gc = $stock->gc->{FEATURE};
+    my $gc = $stock->gc_FEATURE;
+
+Returns the line beginning '#=GC FEATURE ...'
+
+=head2 gs
+
+    my @gs = @{$stock->gs->{FEATURE}->{SEQNAME}};
+    my @gs = @{$stock->gs_FEATURE->{SEQNAME}};
+
+Returns a reference to an array of all the lines beginning '#=GS SEQNAME FEATURE ...'
+
+=head2 gr
+
+    my $gr = $stock->gr->{FEATURE}->{SEQNAME};
+    my $gr = $stock->gr_FEATURE->{SEQNAME};
+
+Returns the line beginning '#=GR SEQNAME FEATURE ...'
+
+Catches all methods by default.
+
+=cut
+sub AUTOLOAD {
+  my ($self, @args) = @_;
+  my $sub = our $AUTOLOAD;
+  $sub =~ s/.*:://;
+
+  # check for DESTROY
+  return if $sub eq "DESTROY";
+
+  # check for GF, GC, GS, GR tag_feature accessors
+  # e.g. $self->GF_ID
+  # can also use $self->GF_('ID')
+  if ($sub =~ /^(gf|gc|gs|gr)_(\S*)$/i) {
+    my ($tag, $feature) = ($1, $2);
+    $tag = lc $tag;
+    $feature = shift(@args) unless length $feature;
+    my $hash = $self->{$tag};
+    if (@args) {
+      $hash->{$feature} = shift(@args);	# TODO: check ref-type of arg
+    }
+    cluck "Warning: ignoring extra arguments to ${tag}_$feature"
+      if @args > 0;
+    if (!defined $hash->{$feature}) {
+      $hash->{$feature} = 
+	$tag eq "gf" ? [] :
+	  $tag eq "gc" ? "" :
+	    $tag eq "gs" ? {} :
+	      $tag eq "gr" ? {} :
+		croak "Unreachable";
+    }
+    return $hash->{$feature};
+  }
+
+  # check for ordinary accessors
+  if (exists $self->{$sub}) {
+    croak "Usage: $sub() or $sub(newValue)" if @args > 1;
+    return
+      @args
+	? $self->{$sub} = $args[0]
+	  : $self->{$sub};
+  }
+
+  # croak
+  croak "Unsupported method: $sub";
+}
+
+
+=head2 prettify
+
+    prettify ($lcols, $legend, @data);
+
+Format a line.
+
+=cut
+sub prettify {
+  my ($self, $lcols, $legend, @data) = @_;
+
+  # This horribly inefficient/redundant series of transformations comes out with something I like (IH, 7/24/07)
+  # Trim it down? pah! Like I have nothing better to do
+  $legend = sprintf ("% ${lcols}s", $legend);
+  $legend =~ s/^(\s+)(\#=\S\S)(\s+\S+)$/$2$1$3/;
+  $legend =~ s/^(\s+)(\#=\S\S\s+\S+)(\s+\S+)$/$2$1$3/;
+  $legend =~ s/^(\s\s\s\s\s)(\s+)([^\#]\S+)/$1$3$2/;
+
+  return map ("$legend $_", @data);
+}
+
+=head2 lcols
+
+    lcols();
+
+Get legend width.
+Subtract this from maxcols - 1 to get the number of columns
+available for sequence display.
+
+=cut
+sub lcols {
+  my ($self) = @_;
+  my $lcols = max ($self->maxNameLen,
+		   map(length("#=GF $_"), keys(%{$self->gf})),
+		   map(length("#=GC $_"), keys(%{$self->gc})));
+  while (my ($gr_key, $gr_hash) = each %{$self->gr}) {
+    $lcols = max ($lcols, map(length("#=GR $gr_key $_"), keys(%$gr_hash)));
+  }
+  while (my ($gs_key, $gs_hash) = each %{$self->gs}) {
+    $lcols = max ($lcols, map(length("#=GS $gs_key $_"), keys(%$gs_hash)));
+  }
+  return $lcols;
+}
+
+=head2 add_gf
+
+    $stock->add_gf (FEATURE, $line)
+    $stock->add_gf (FEATURE, $line1, $line2, ...)
+    $stock->add_gf (FEATURE, @lines)
+    $stock->add_gf (FEATURE, "$line1\n$line2\n$...")
+
+Add '#=GF FEATURE' annotation, preserving the order of the '#=GF' lines.
+
+Each list entry gets printed on its own line.
+
+=cut
+sub add_gf {
+  my ($self, $feature, @data) = @_;
+  unless (@data > 0) {
+    carp "Missing parameters to 'add_gf'; nothing will be done";
+    return;
+  }
+
+  foreach my $line (map {$_ eq '' ? '' : split ("\n", $_, -1)} @data) {
+    push @{$self->gf_($feature)}, $line;
+    push @{$self->gforder}, $feature;
+  }
+}
+
+=head2 set_gf
+
+    $stock->set_gf (FEATURE, $line)
+    $stock->set_gf (FEATURE, $line1, $line2, ...)
+    $stock->set_gf (FEATURE, @lines)
+    $stock->set_gf (FEATURE, "$line1\n$line2\n$...")
+
+Set a '#=GF FEATURE ...' annotation.
+The difference between this and 'add_gf' is that here, if this sequence and
+feature have an annotation already, it will be overwritten instead of appended to.
+
+As with add_gf, each list entry gets printed on its own line.
+
+=cut
+sub set_gf {
+  my ($self, $feature, @data) = @_;
+
+  unless (defined $self->{gf}->{$feature}) {
+    carp "No #=GF feature '$feature' to set, creating new";
+    $self->add_gf ($feature, @data);
+    return;
+  }
+  @data = map {$_ eq '' ? '' : split ("\n", $_, -1)} @data;
+
+  ### go to insane lengths to preserve original line ordering
+
+  my %gfCursor = map {$_ => 0} keys %{$self->{gf}};
+  my (%new_gfFeature, @new_gforder);
+
+  foreach my $curFeat (@{$self->{gforder}}) {
+    $new_gfFeature{$curFeat} = [] unless defined $new_gfFeature{$curFeat};
+
+    if ($curFeat eq $feature) {
+      if (@data) {
+	push (@{$new_gfFeature{$curFeat}}, shift @data);
+	push (@new_gforder, $curFeat);
+      }
+    } else {
+      push (@{$new_gfFeature{$curFeat}},
+	    $self->{gf}->{$curFeat}->[$gfCursor{$curFeat}++]);
+      push (@new_gforder, $curFeat);
+    }
+  }
+
+  # still have lines left, insert them after last occurence of feature tag
+  if (@data) {
+    my $insertAt = $#new_gforder;
+    $insertAt-- while $new_gforder[$insertAt] ne $feature;
+    splice (@new_gforder, ++$insertAt, 0, map {$feature} @data);
+    push (@{$new_gfFeature{$feature}}, @data);
+  }
+
+  $self->{gf} = {%new_gfFeature};
+  $self->{gforder} = [@new_gforder];
+}
+
+=head2 get_gf
+
+    my $gf = $stock->get_gf (FEATURE)
+
+Get a #=GF annotation.
+Concatenates and returns all lines beginning '#=GF FEATURE ...'
+
+=cut
+sub get_gf {
+  my ($self, $feature) = @_;
+  if (defined $self->{gf}->{$feature}) {
+    return join ("\n", @{$self->{gf}->{$feature}});
+  } else {
+    #carp "No #=GF feature '$feature' in Stockholm object, returning undef";
+    return undef;
+  }
+}
+
+=head2 add_gs
+
+    $stock->add_gs (SEQNAME, FEATURE, $line)
+    $stock->add_gs (SEQNAME, FEATURE, $line1, $line2, ...)
+    $stock->add_gs (SEQNAME, FEATURE, @lines)
+    $stock->add_gs (SEQNAME, FEATURE, "$line1\n$line2\n$...")
+
+Add a GS annotation: '#=GS SEQNAME FEATURE ...'
+
+If such a line already exists for this sequence and feature, append to it.
+
+Each list entry gets printed on its own line.
+
+=cut
+sub add_gs {
+  my ($self, $seq, $feature, @text) = @_;
+  unless (@text > 0) {
+      carp "Missing parameters to 'add_gs' method; nothing will be done";
+      return;
+  }
+  @text = map {$_ eq '' ? '' : split ("\n", $_, -1)} @text;
+  push (@{$self->{gs}->{$feature}->{$seq}}, @text);
+}
+
+=head2 set_gs
+
+    $stock->set_gs (SEQNAME, FEATURE, $line)
+    $stock->set_gs (SEQNAME, FEATURE, $line1, $line2, ...)
+    $stock->set_gs (SEQNAME, FEATURE, @lines)
+    $stock->set_gs (SEQNAME, FEATURE, "$line1\n$line2\n$...")
+
+Set a GS annotation: '#=GS SEQNAME FEATURE ...'
+
+The difference between this and 'add_gs' is that here, if this sequence and
+feature have an annotation already, it will be overwritten instead of appended to.
+
+Each list entry gets printed on its own line.
+
+=cut
+sub set_gs {
+  my ($self, $seq, $feature, @text) = @_;
+  unless (@text > 0) {
+      carp "Missing parameters to 'set_gs' method; nothing will be done";
+      return;
+  }
+  @text = map {$_ eq '' ? '' : split ("\n", $_, -1)} @text;
+  $self->{gs}->{$feature}->{$seq} = [@text];
+}
+
+=head2 get_gs
+
+    my $gs = $stock->get_gs (SEQNAME, FEATURE)
+
+Get a #=GS annotation.
+Concatenates and returns all lines beginning '#=GS SEQNAME FEATURE ...'
+
+=cut
+sub get_gs {
+  my ($self, $seq, $feature) = @_;
+  unless (defined $feature) {
+      carp "Missing parameters to 'get_gs' method; nothing will be done";
+      return undef;
+  }
+  if (defined $self->{gs}->{$feature}->{$seq}) {
+      return join ("\n", @{$self->{gs}->{$feature}->{$seq}});
+  }
+  else {
+      #carp "Annotation for sequence $seq, feature $feature not found; returning empty string";
+      return undef;
+  }
+}
+
+=head2 drop_columns
+
+    my $success = $stock->drop_columns (@columns)
+
+Drops a set of columns from the alignment and the GC and GR annotations.  Note
+that this may break annotations where the column annotations are not
+independent (e.g. you might drop one base in an RNA base pair, but not the
+other).  The caller is responsible for making sure the set of columns passed
+in does not mess up the annoation.
+
+Arguments: a list of scalar, zero-based column indices to drop.
+
+Returns success of operation (1 for success, 0 for failure)
+
+=cut
+sub drop_columns {
+  my ($self, @columns) = @_;
+
+  unless ($self->is_flush()) {
+    carp "File is not flush; cannot (should not) drop columns";
+    return 0;
+  }
+
+  # drop from sequences and per-column annotations
+  foreach my $seq_or_annot ($self->{seqdata}, $self->{gc})
+    {
+      # for each sequence or annotation string
+      foreach my $key (keys %$seq_or_annot)
+	{
+	  # convert string to array form
+	  my @data = split (//, $seq_or_annot->{$key});
+	  foreach my $col (@columns)
+	    {
+	      if ( ($col < 0) or ($col >= @data) ) {
+		carp "Column $col is out of range [1, ", scalar(@data),
+		  "] in $key; can't drop, skipping";
+	      }
+	      else {
+		# blank out the column that should get dropped
+		$data[$col] = '';
+	      }
+	    }
+	  # re-assemble back to string
+	  $seq_or_annot->{$key} = join ('', @data);
+	}
+    }
+
+  # drop from per-column/per-sequence annotations
+  foreach my $feat_key (keys %{$self->{gr}})
+    {
+      foreach my $seq_key (keys %{$self->{gr}->{$feat_key}})
+	{
+	  my @data = split (//, $self->{gr}->{$feat_key}->{$seq_key});
+	  foreach my $col (@columns)
+	    {
+	      if ( ($col < 0) or ($col >= @data) ) {
+		carp "Column $col is out of range [1, ", scalar(@data),
+		  "] in $feat_key, $seq_key; can't drop, skipping";
+	      }
+	      else {
+		# blank out the column that should get dropped
+		$data[$col] = '';
+	      }
+	    }
+	  # re-assemble back to string
+	  $self->{gr}->{$feat_key}->{$seq_key} = join ('', @data);
+	}
+    }
+
+  return 1;
+}
+
+# parse line of Stockholm format file
+# returns true if it finds a separator
+sub parse_input_line {
+  my ($self, $line, $remove_chr) = @_;
+
+  # by default don't remove the leading 'chr'
+  if (!defined $remove_chr) { $remove_chr = 0; }
+
+  $line = $_ unless defined $line;
+
+  # "#=GF [feature] [data]" line
+  if ($line =~ /^\s*\#=GF\s+(\S+)\s+(\S.*)\s*$/) { 
+    my ($feature, $data) = ($1, $2);
+    $self->add_gf ($feature, $data); # preserve order of #=GF lines, for crazy context-sensitive Stockholm semantics
+  }
+
+  # "#=GC [feature] [data]" line
+  elsif ($line =~ /^\s*\#=GC\s+(\S+)\s+(\S+)\s*$/) { 
+    my ($feature, $data) = ($1, $2, $3);
+    $self->gc->{$feature} .= $data; 
+  }
+
+  # "#=GS [seqname] [feature] [data]" line
+  elsif ($line =~ /^\s*\#=GS\s+(\S+)\s+(\S+)\s+(\S.*)\s*$/) { 
+    my ($seqname, $feature, $data) = ($1, $2, $3);
+    if ($remove_chr) { $seqname = $self->strip_leading_chr ($seqname); }
+    my $gs = $self->gs_($feature);
+    $gs->{$seqname} = [] unless exists $gs->{$seqname};
+    push @{$gs->{$seqname}}, $data;
+  }
+
+  # "#=GR [seqname] [feature] [data]" line
+  elsif ($line =~ /^\s*\#=GR\s+(\S+)\s+(\S+)\s+(\S+)\s*$/) { 
+    my ($seqname, $feature, $data) = ($1, $2, $3);
+    if ($remove_chr) { $seqname = $self->strip_leading_chr ($seqname); }
+    my $gr = $self->gr_($feature);
+    $gr->{$seqname} = "" unless exists $gr->{$seqname};
+    $gr->{$seqname} .= $data; 
+  }
+
+  # Unrecognised "#" line
+  elsif ($line =~ /^\s*\#.*$/) {
+    #	warn "Comment line $line";
+  }
+
+  # Alignment separator: return true to indicate loop exit
+  elsif ($line =~ /^\s*\/\/\s*$/) { 
+    return 1;
+  }
+
+  # Sequence line
+  elsif ($line =~ /^\s*(\S+)\s*(\S*)\s*$/) { # allows empty sequence lines
+    my ($seqname, $data) = ($1, $2);
+    if ($remove_chr) { $seqname = $self->strip_leading_chr ($seqname); }
+    unless (defined $self->seqdata->{$seqname}) {
+      $self->seqdata->{$seqname} = "";
+      push @{$self->seqname}, $seqname;	# preserve sequence order, for tidiness
+    }
+    $self->seqdata->{$seqname} .= $data;
+  } elsif ($line =~ /\S/) { 
+    carp "Ignoring line: $_";
+  }
+
+  # This line wasn't a alignment separator: return false
+  return 0;
+}
+
+=head2 empty
+
+    my $isEmpty = $stock->empty
+
+Returns true if the alignment is empty (i.e. there are no sequences).
+
+=cut
+sub empty {
+  my ($self) = @_;
+  return @{$self->seqname} == 0;
+}
+
+=head2 ungapped_length
+
+   my $seqlength = $stock->ungapped_length (SEQNAME)
+
+Calculates the length of the ungapped sequence.
+
+=cut
+sub ungapped_length {
+  my ($self, $name) = @_;
+
+  if (!defined $self->seqdata->{$name}) { croak "No sequence exists for '$name':\n", $self->to_string; }
+
+  my $numgaps = $self->seqdata->{$name} =~ tr/-._//;
+  return (length ($self->seqdata->{$name}) - $numgaps);
+
+}
+
+=head2 subseq
+
+    my $subseq = $stock->subseq (SEQNAME, $startPos)
+    my $subseq = $stock->subseq (SEQNAME, $startPos, $length)
+
+Returns a subsequence of the named alignment row.
+
+Note that the coordinates are with respect to the alignment columns (starting at zero), NOT sequence positions.
+That is, gaps are counted.
+
+If $length is omitted, this call returns the subsequence from $startPos to the end of the row.
+
+=cut
+sub subseq {
+  my ($self, $name, $start, $len) = @_;
+
+  if (!defined $self->seqdata->{$name}) { croak "No sequence exists for '$name'."; }
+
+  if (!defined $len) { carp "Setting undefined length to 0."; $len = 0; }
+
+  my $seqlength = length $self->seqdata->{$name};
+
+  # check start position sane
+  if (!defined $start) { croak "Start position undefined."; }
+  elsif (($start > $seqlength) or ($start < 0)) {
+    carp
+      "Subsequence start position $start is outside of sequence bounds ",
+	"[0, " . $seqlength-1 . "]; returning empty string for subsequence of $name\n";
+    return '';
+  }
+
+  return substr ($self->seqdata->{$name}, $start, $len);
+}
+
+=head2 get_column
+
+    my $column = $stock->get_column ($colNum)
+
+Extracts the specified column and returns it as a string.
+
+The column number $colNum uses zero-based indexing.
+
+=cut
+sub get_column {
+  my ($self, $col_num) = @_;
+  my $col_as_string;
+
+  unless ($self->is_flush()) {
+    carp "File is not flush; cannot (should not) get column";
+    return 0;
+  }
+
+  my $align_length = $self->columns();
+
+  if ( ($col_num >= $align_length) or ($col_num < 0) ) {
+    carp
+      "Column index $col_num is outside of alignment bounds ",
+	"[1, $align_length]; returning empty string for column $col_num\n";
+    return '';
+  }
+  else {
+    foreach my $seq (@{$self->{seqname}}) {
+      $col_as_string .= substr ($self->{seqdata}->{$seq}, $col_num, 1);
+    }
+    return $col_as_string;
+  }
+}
+
+=head2 map_align_to_seq_coords
+
+    my ($start, $end) = $stock->map_align_to_seq_coords ($colStart, $colEnd, $seqName);
+    croak "Failed" unless defined ($start);
+
+    my ($start, $end) = $stock->map_align_to_seq_coords ($colStart, $colEnd, $seqName, $seqStart);
+    croak "Failed" unless defined ($start);
+
+Given a range of column indices ($colStart, $colEnd), returns the coordinates
+of sequence $seqName contained within that range, accounting for gaps.
+
+Returns start and end coordinates as a 2-ple list, or returns the empty list
+if there is no sequence in the given range (i.e. range contains all gaps in
+$seqName).
+
+You can provide $seqStart, which is the coordinate of the first non-gap
+character in $seqName.  If you don\'t, the default is that the sequence starts
+at 0 (0-based indexing).
+
+=cut
+sub map_align_to_seq_coords {
+  my ($self, $colStart, $colEnd, $seqName, $seqStart) = @_;
+  $seqStart = 0 unless defined $seqStart;
+
+  my $seq = $self->subseq ($seqName, $colStart, ($colEnd - $colStart + 1));
+
+  if (my @seq = $seq =~ /[^$gapChars]/g)
+  {
+    my $rangeStart;
+
+    if ($colStart == 0) {
+      # special case: range starts in the first column
+      $rangeStart = $seqStart;
+    }
+    else {
+      my $prefix = $self->subseq ($seqName, 0, $colStart);
+      $rangeStart = $seqStart + length (join ('', ($prefix =~ /[^$gapChars]/g)));
+    }
+
+    return ($rangeStart, ($rangeStart + @seq - 1));
+  }
+  else {
+    # no sequence in desired range (i.e. all gaps)
+    return ();
+  }
+}
+
+=head2 map_seq_to_align_coords
+
+    my ($start, $end) = $stock->map_seq_to_align_coords ($seq, $start, $end);
+
+Given a range of sequence position indices ($start, $end),
+returns the alignment coordinates corresponding to that range.
+Returns undef if can't map coordinates.
+
+Returns start and end coordinates as a duple.
+
+=cut
+sub map_seq_to_align_coords {
+  my ($self, $seq, $start, $end) = @_;
+
+  # sanity check
+  if (!defined $self->seqdata->{$seq}) { croak "Can't find sequence '$seq'.\n"; }
+  if ($end < $start) { croak "Invalid coordinates.\n"; }
+
+  # do the mapping with a linear search
+  my ($s, $e);    # alignment coordinates
+  my $seqpos = 0; # position within the sequence
+
+  # NB: This operation can be quite slow,
+  # although the time hit is worth it if the desired
+  # coordinates are deep into the alignment
+  # (substr to pull out each character becomes expensive)
+  # unpack seems to be slightly faster than split
+  my @data = unpack 'a' x  length $self->seqdata->{$seq}, $self->seqdata->{$seq};
+
+  my $cols = $self->columns();
+  for (my $alignpos = 0; $alignpos < $cols; ++$alignpos) {
+
+    # keep going if it's a gap
+    if ($data[$alignpos] =~ /[$gapChars]/) { next; }
+
+    # else see if we've reached a boundary
+    if ($seqpos == $start) { $s = $alignpos; }
+    if ($seqpos == $end) { $e = $alignpos; last; }
+
+    # increment coords
+    ++$seqpos;
+
+  }
+
+  return ($s, $e);
+}
+
+=head2 build_seq_to_align_coords_map
+
+    my $map = $stock->build_seq_to_align_coords_map ($seq);
+
+Returns a map from sequence to alignment coordinates
+for a particular sequence as an array reference.
+
+=cut
+sub build_seq_to_align_coords_map {
+  my ($self, $seq, $verbose) = @_;
+
+  if ($verbose) {
+    print STDERR "Building coordinate index for '$seq'...";
+  }
+
+  # sanity check
+  if (!defined $self->seqdata->{$seq}) { croak "Can't find sequence '$seq'.\n"; }
+
+  my @map;
+
+  # do the mapping with a linear search
+  my ($s, $e);    # alignment coordinates
+  my $seqpos = 0; # position within the sequence
+
+  # assemble sequence data as character arrays for fast access
+  # (avoid having to use substr, which is slow)
+  # unpack seems to be slightly faster than split
+  my @data = unpack 'a' x  length $self->seqdata->{$seq}, $self->seqdata->{$seq};
+
+  my $cols = $self->columns();
+  for (my $alignpos = 0; $alignpos < $cols; ++$alignpos) {
+
+    # keep going if it's a gap
+    if ($data[$alignpos] =~ /[$gapChars]/) { next; }
+
+    # else store the record
+    $map[$seqpos++] = $alignpos;
+
+  }
+
+  if ($verbose) {
+    print STDERR "done.\n";
+  }
+
+  return \@map;
+
+}
+
+
+=head2 is_gap
+
+    $stock->is_gap (SEQNAME, $colNum)
+
+Return true if a given (SEQNAME,column) coordinate is a gap.
+
+=cut
+sub is_gap {
+  my ($self, $row_name, $col) = @_;
+  my $c = substr ($self->seqdata->{$row_name}, $col, 1);
+  return $c =~ /[$gapChars]/;
+}
+
+=head2 is_allgaps_col
+
+    $stock->is_allgaps_col ($col)
+
+Returns true if a given column is all gaps.
+
+=cut
+sub is_allgaps_col {
+  my ($self, $c) = @_;
+  my $is = 1;
+  foreach my $seqname (@{$self->seqname}) {
+    if (!$self->is_gap ($seqname, $c)) {
+      $is = 0;
+    }
+  }
+  return $is;
+}
+
+=head2 drop_allgaps_columns
+
+    $stock->drop_allgaps_columns()
+
+Drops columns which are all gaps from an alignment.
+
+=cut
+sub drop_allgaps_columns {
+  my ($self) = @_;
+
+  my $cols = $self->columns();
+  my @drop; # columns to drop
+  for (my $c = 0; $c < $cols; ++$c) {
+    if ($self->is_allgaps_col ($c)) {
+      push @drop, $c;
+    }
+  }
+
+  $self->drop_columns (@drop);
+
+}
+
+=head2 subalign
+
+    my $substock = $stock->subalign ($start, $len)
+    my $substock = $stock->subalign ($start, $len, $strand)
+
+Subalignment accessor.
+Returns a Stockholm object representing a sub-alignment of the current alignment,
+starting at column $start (zero-based) and containing $len columns.
+
+If $strand is supplied and is equal to '-', then the sub-alignment will be reverse-complemented.
+
+=cut
+sub subalign {
+  my ($self, $start, $len, $strand) = @_;
+
+  # check strand sane
+  if (!defined $strand) {
+    $strand = '+';
+  } elsif (($strand ne '-') && ($strand ne '+')) {
+    warn "Unrecognized strand '$strand'; using positive strand.\n";
+    $strand = '+';
+  }
+
+  # init subalign
+  my $subalign = Stockholm->new;
+
+  # sequence data
+  foreach my $seqname (@{$self->seqname}) {
+    $subalign->seqdata->{$seqname} = substr ($self->seqdata->{$seqname}, $start, $len);
+    if ($strand eq '-') {
+      $subalign->seqdata->{$seqname} = revcomp ($subalign->seqdata->{$seqname});
+    }
+  }
+  @{$subalign->seqname} = @{$self->seqname};
+
+  # GF lines
+  while (my ($feature, $arrayRef) = each %{$self->gf}) {
+    $subalign->gf->{$feature} = [@$arrayRef];
+  }
+  @{$subalign->gforder} = @{$self->gforder};
+
+  # GC lines
+  foreach my $tag (keys %{$self->gc}) {
+    $subalign->gc->{$tag} = substr ($self->gc->{$tag}, $start, $len);
+    if ($strand eq '-') {
+      $subalign->gc->{$tag} = reverse $subalign->gc->{$tag};
+    }
+  }
+
+  # GR lines
+  foreach my $tag (keys %{$self->gr}) {
+    foreach my $seqname (keys %{$self->gr->{$tag}}) {
+      $subalign->gr->{$tag}->{$seqname} = substr ($self->gr->{$tag}->{$seqname}, $start, $len);
+      if ($strand eq '-') {
+	$subalign->gr->{$tag}->{$seqname} = reverse ($subalign->gr->{$tag}->{$seqname});
+      }
+    }
+  }
+
+
+  #=GS
+  while (my ($feature, $seqHash) = each %{$self->gs}) {
+    $subalign->gs->{$feature} = {%$seqHash};
+  }
+
+  return $subalign;
+}
+
+=head2 concatenate
+
+    $stock->concatenate ($stock2)
+
+Concatenates another alignment onto the end of this one.
+
+=cut
+sub concatenate {
+  my ($self, $stock) = @_;
+
+  # get widths
+  my $cols = $self->columns;
+  my $catcols = $stock->columns;
+
+  # Sequence data
+  foreach my $seqname (@{$stock->seqname}) {
+    if (exists $self->seqdata->{$seqname}) {
+      $self->seqdata->{$seqname} .= $stock->seqdata->{$seqname};
+    } else {
+      push @{$self->seqname}, $seqname;
+      $self->seqdata->{$seqname} = "." x $cols . $stock->seqdata->{$seqname};
+    }
+  }
+  foreach my $seqname (@{$self->seqname}) {
+    unless (exists $stock->seqdata->{$seqname}) {
+      $self->seqdata->{$seqname} .= "." x $catcols;
+    }
+  }
+
+  # GC lines
+  foreach my $tag (keys %{$stock->gc}) {
+    if (exists $self->gc->{$tag}) {
+      $self->gc->{$tag} .= $stock->gc->{$tag};
+    } else {
+      $self->gc->{$tag} = "." x $cols . $stock->gc->{$tag};
+    }
+  }
+  foreach my $tag (keys %{$self->gc}) {
+    unless (exists $stock->gc->{$tag}) {
+      $self->gc->{$tag} .= "." x $catcols;
+    }
+  }
+
+  # GR lines
+  foreach my $tag (keys %{$stock->gr}) {
+    if (exists $self->gr->{$tag}) {
+      foreach my $seqname (keys %{$stock->gr->{$tag}}) {
+	if (exists $self->gr->{$tag}->{$seqname}) {
+	  $self->gr->{$tag}->{$seqname} .= $stock->gr->{$tag}->{$seqname};
+	} else {
+	  $self->gr->{$tag}->{$seqname} = "." x $cols . $stock->gr->{$tag}->{$seqname};
+	}
+      }
+    } else {
+      $self->gr->{$tag} = {};
+      foreach my $seqname (keys %{$stock->gr->{$tag}}) {
+	$self->gr->{$tag}->{$seqname} = "." x $cols . $stock->gr->{$tag}->{$seqname};
+      }
+    }
+  }
+  foreach my $tag (keys %{$self->gr}) {
+    foreach my $seqname (keys %{$self->gr->{$tag}}) {
+      unless (exists $stock->gr->{$tag} && exists $stock->gr->{$tag}->{$seqname}) {
+	$self->gr->{$tag}->{$seqname} .= "." x $catcols;
+      }
+    }
+  }
+
+  # GF and GS lines
+  foreach my $tag (keys %{$stock->gf}) {
+    $self->gf->{$tag} = [] unless exists $self->gf->{$tag};
+    push @{$self->gf->{$tag}}, @{$stock->gf->{$tag}};
+  }
+
+  foreach my $tag (keys %{$stock->gs}) {
+    $self->gs->{$tag} = {} unless exists $self->gs->{$tag};
+    foreach my $seqname (keys %{$stock->gs->{$tag}}) {
+      $self->gs->{$tag}->{$seqname} = [] unless exists $self->gs->{$tag}->{$seqname};
+      push @{$self->gs->{$tag}->{$seqname}}, @{$stock->gs->{$tag}->{$seqname}};
+    }
+  }
+}
+
+# add_row method
+sub add_row {
+    my ($self, $seqname, $rowdata) = @_;
+    die "Attempt to add duplicate row" if exists $self->seqdata->{$seqname};
+    push @{$self->seqname}, $seqname;
+    $self->seqdata->{$seqname} = $rowdata;
+    return @{$self->seqname} - 1;  # new row index
+}
+
+
+# Reverse complement a sequence
+sub revcomp {
+  my ($arg0, $arg1) = @_;
+  my $seq;
+
+  if (defined ($arg1)) {  # must have been called externally (as method or package sub)
+    $seq = $arg1;
+  } else {
+    $seq = $arg0;
+  }
+
+  $seq =~ tr/acgtuACGTU/tgcaaTGCAA/;
+  $seq = reverse $seq;
+  return $seq;
+}
+
+# Determine maximum sequence name length
+sub maxNameLen {
+  my ($self) = @_;
+  return max (map ( length ($_), @{$self->seqname}));
+}
+
+=head2 is_flush
+
+    my $flush = $stock->is_flush()
+
+Returns true if the alignment is "flush", i.e. all sequence and annotation lines have the same length.
+
+=cut
+sub is_flush {
+  my ($self) = @_;
+  my $columns = $self->columns();
+
+  # do stuff that has one key
+
+  map {
+    if (length ($self->{seqdata}->{$_}) != $columns) {
+      carp "Sequence $_ is not flush!";
+      return 0;
+    }
+  } keys %{$self->{seqdata}};
+
+  map {
+    if (length($self->{gc}->{$_}) != $columns) {
+      carp "#=GC annotation for feature $_ is not flush!";
+      return 0;
+    }
+  } keys %{$self->{gc}};
+
+  # do stuff that has two keys
+
+  map {
+    if (length($_) != $columns) {
+      carp "#=GR annotation is not flush! ($_)";
+      return 0;
+    }
+  } map { values %{$self->{gr}->{$_}} } keys %{$self->{gr}};
+
+  return 1;  # if we got this far, everything must be flush
+}
+
+=head2 assert_flush
+
+    $stock->assert_flush()
+
+Dies if the alignment isn't "flush."
+
+=cut
+sub assert_flush {
+  my ($self) = @_;
+
+  unless ($self->is_flush()) {
+    die "Alignment not flush (rows are not the same length).\n";
+  }
+}
+
+
+# Determine the list maximum value.
+sub max  {
+  my ($x, @y) = @_;
+  foreach my $y (@y) 
+  { 
+    $x = $y if !defined($x) || (defined($y) && $y > $x)
+  }
+  return $x;
+}
+
+=head2 NH
+
+    $self->NH();
+    $self->NH ($newtree);
+
+Get/set the New Hampshire tree.
+
+=cut
+sub NH {
+  my ($self, $newval) = @_;
+  if (defined $newval) {
+    @{$self->gf_NH} = ($newval);
+  }
+  return join ("", @{$self->gf_NH});
+}
+
+=head2 gapfraction
+
+   $self->gapfraction()
+
+Calculate fraction of gaps (# gaps / total # of characters)
+in the alignment.
+
+=cut
+sub gapfraction {
+  my ($self) = @_;
+
+  my ($num, $denom) = (0, 0);
+  map { $num += $self->ungapped_length ($_); $denom += length ($self->seqdata->{$_}); } keys %{$self->seqdata};
+
+  return ($num / $denom);
+}
+
+=head2 percentid_annot
+
+    $self->percentid_annot()
+
+Annotation for #=GF Percent_id line.
+
+=cut
+sub percentid_annot {
+  my $self = shift;
+  return $percentid_annot;
+}
+
+=head2 gapfraction_annot
+
+    $self->gapfraction_annot()
+
+Annotation for #=GF Gap_fraction line.
+
+=cut
+sub gapfraction_annot {
+  my $self = shift;
+  return $gapfraction_annot;
+}
+
+=head2 percentid
+
+    $self->percentid();
+    $self->percentid ($seqs);
+
+Calculate percent id for two or more sequences of the alignment.
+Calculates per-column percent id as:
+(# of times most common non-gap character in column appears) / (# non-gap characters in column)
+Reports the average per-column percent id.
+
+Considers gaps during calculation if requested.
+
+=cut
+sub percentid {
+  my ($self, $seqs, $countgaps) = @_;
+
+  # must be at least 2 seqs
+  # ($seqs = ref to array of sequence names)
+  if (!defined $seqs) { $seqs = $self->seqname; }
+  unless (@$seqs >= 2) { croak "Must be at least 2 sequences.\n"; }
+
+  # don't count gaps by default
+  if (!defined $countgaps) { $countgaps = 0; }
+
+  # assemble sequence data as character arrays for fast access
+  my $data;
+  foreach my $seq (@$seqs) {
+    croak "Sequence '$seq' not defined.\n" unless exists $self->seqdata->{$seq};
+    @{$data->{$seq}} = unpack 'a' x  length $self->seqdata->{$seq}, $self->seqdata->{$seq};
+  }
+
+  # assert flush
+  croak "Alignment is not flush.\n" unless $self->is_flush();
+
+  my $sum = 0;
+  my $n = 0;
+
+  for (my $c = 0; $c < $self->columns; ++$c) {
+    my %f;
+    my $count = 0; # ungapped
+    my $countall = 0; # gaps as well
+    for (my $i = 0; $i < @$seqs; ++$i) {
+      my $char = lc $data->{$seqs->[$i]}->[$c];
+      if ($char ne '-' && $char ne '.') {
+	++$f{$char};
+	++$count;
+      }
+      ++$countall;
+    }
+    # unless $countgaps, only count columns with > 1 non-gap character
+    if (!$countgaps && ($count > 1)) {
+      my @sym = sort { $f{$b} <=> $f{$a} } keys %f;
+
+      my $id;
+      # if no character appears more than once, then % id = 0
+      if ($f{$sym[0]} == 1) {
+	$id = 0;
+      }
+      # else calculate % id as (# most common character) / (# non-gap characters in column)
+      else {
+	$id = $f{$sym[0]} / $count;
+      }
+      $sum += $id;
+      ++$n;
+    }
+    # if $countsgaps, count columns with >= 1 non-gap character
+    elsif ($countgaps && ($count >= 1)) {
+      my @sym = sort { $f{$b} <=> $f{$a} } keys %f;
+
+      my $id;
+      # if no character appears more than once, then % id = 0
+      if ($f{$sym[0]} == 1) {
+	$id = 0;
+      }
+      # else calculate % id as (# most common character) / (# total characters in column)
+      else {
+	$id = $f{$sym[0]} / $countall;
+      }
+      $sum += $id;
+      ++$n;
+    }
+
+  }
+
+  if ($n == 0) {
+    return 0;
+  }
+  
+  return $sum / $n;
+}
+
+=head2 strip_leading_chr
+
+    strip_leading_chr ("chr2R");
+
+Removed the leading 'chr' frequently prepended to chromosome names.
+
+=cut
+sub strip_leading_chr {
+
+  my ($class, $str) = @_;
+
+  $str =~ s/^chr//;
+
+  return $str;
+
+}
+
+1
diff --git a/perl/Stockholm/Database.pm b/perl/Stockholm/Database.pm
new file mode 100644
index 0000000..c76a13c
--- /dev/null
+++ b/perl/Stockholm/Database.pm
@@ -0,0 +1,284 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+Stockholm::Database.pm
+
+=head1 SYNOPSIS
+
+Perl module encapsulating a flatfile database of Stockholm multiple alignments.
+
+The original Stockholm::Database module was written by Ian Holmes for his DART library.
+
+=head1 GENERAL USAGE
+
+A Stockholm::Database object is a blessed array reference.
+(This is in contrast to most Perl objects, which are blessed hash references.)
+
+The referenced array contains the constituent Stockholm objects.
+So, if $db is a Stockholm::Database, then @$db is simply an array of Stockholm objects.
+
+=head1 METHODS
+
+=cut
+
+package Stockholm::Database;
+
+use strict;
+use vars '@ISA';
+
+use Stockholm;
+use Carp;
+
+=head2 new
+
+    my $db = Stockholm::Database->new();
+
+Creates an empty Stockholm::Database object.
+
+=cut
+
+# constructor
+sub new {
+    my ($class) = @_;
+    my $self = [];
+    bless $self, $class;
+    return $self;
+}
+
+=head2 align_callback
+
+    Stockholm::Database->align_callback (sub
+					 {
+					     my $stock = shift;  # Stockholm object
+					     # ...do something with the alignment...
+					 })
+
+Streams through alignments in a file, calling a callback function on each alignment as it is parsed.
+
+This method can be used as an efficient alternative to reading the entire database into memory with the from_file method, for some applications.
+
+=cut
+
+# align_callback method
+# streams through alignments in a file, calling a callback function as it parses each one
+# can use in place of from_file method for some applications
+sub align_callback {
+    my ($class, $filename, $callback) = @_;
+
+    my $self = $class->new;
+    my $stock;
+
+    local *FILE;
+    local $_;
+    open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+    while (<FILE>) {
+	next unless /\S+/;  # skip blank lines
+	$stock = Stockholm->new unless defined $stock;
+	if ($stock->parse_input_line ($_)) {
+	    &$callback ($stock);
+	    $stock = undef;
+	}
+    }
+    close FILE;
+    &$callback ($stock) if defined $stock;
+
+    return $self;
+}
+
+=head2 from_file
+
+    my $db = Stockholm::Database->from_file ($filename)
+    my $db = Stockholm::Database->from_file ($filename, 0)
+
+Creates a Stockholm::Database object and populates it from a named Stockholm flatfile.
+
+Reading a large database (e.g. PFAM) can take a while.
+By default, a message is printed when each alignment is loaded.
+The second form of the method suppresses these verbose messages.
+
+=cut
+
+# from_file method
+sub from_file {
+    my ($class, $filename, $verbose) = @_;
+    $verbose = 1 unless defined $verbose;  # default
+
+    my $self;
+
+    # FASTA
+    if (Stockholm->detect_FASTA ($filename)) {
+      local *FILE;
+      open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+      my $stock = Stockholm->from_filehandle_FASTA (\*FILE);
+      close FILE;
+      $self = $class->new;
+      $self->add_alignment ($stock, $verbose);
+    }
+    
+    # CLUSTAL
+    elsif (Stockholm->detect_CLUSTAL ($filename)) {
+      local *FILE;
+      open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+      my $stock = Stockholm->from_filehandle_CLUSTAL (\*FILE);
+      close FILE;
+      $self = $class->new;
+      $self->add_alignment ($stock, $verbose);
+    }
+
+    # MSF
+    elsif (Stockholm->detect_MSF ($filename)) {
+      local *FILE;
+      open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+      my $stock = Stockholm->from_filehandle_MSF (\*FILE);
+      close FILE;
+      $self = $class->new;
+      $self->add_alignment ($stock, $verbose);
+    }
+
+    # Stockholm
+    else {
+      local *FILE;
+      open FILE, "<$filename" or croak "Couldn't open $filename: $!";
+      $self = $class->from_filehandle (\*FILE, $verbose);
+      close FILE;
+    }
+
+    return $self;
+
+}
+
+=head2 from_filehandle
+
+    my $db = Stockholm::Database->from_filehandle ($filehandle)
+    my $db = Stockholm::Database->from_filehandle ($filehandle, 0)
+
+Creates a Stockholm::Database object and populates it from a Stockholm flatfile, pointed to by a given filehandle.
+
+Reading a large database (e.g. PFAM) can take a while.
+By default, a message is printed when each alignment is loaded.
+The second form of the method suppresses these verbose messages.
+
+=cut
+
+# from_filehandle method
+sub from_filehandle {
+    my ($class, $filehandle, $verbose) = @_;
+    $verbose = 1 unless defined $verbose;  # default
+
+    my $self = $class->new;
+    my $stock;
+    local $_;
+    while (<$filehandle>) {
+	next unless /\S+/;  # skip blank lines
+	$stock = Stockholm->new unless defined $stock;
+	if ($stock->parse_input_line ($_)) {
+	    $self->add_alignment ($stock, $verbose);
+	    $stock = undef;
+	}
+    }
+    $self->add_alignment ($stock, $verbose) if defined $stock;
+
+    return $self;
+}
+
+
+=head2 from_string
+
+    $db->from_string ($string)
+    $db->from_string ($string, 0)
+
+Creates a Stockholm::Database object and populates it from a Stockholm-format string.
+
+Reading a large database (e.g. PFAM) can take a while.
+By default, a message is printed when each alignment is loaded.
+The second form of the method suppresses these verbose messages.
+
+=cut
+
+# from_string
+sub from_string {
+    my ($class, $text, $verbose) = @_;
+    my @text = map (split(/\n/), $text);
+
+    my $self = $class->new;
+    my $stock;
+
+    foreach my $line (@text) {
+	next unless $line =~ /\S+/;  # skip blank lines
+	$stock = Stockholm->new unless defined $stock;
+	if ($stock->parse_input_line ($line)) {
+	    $self->add_alignment ($stock, $verbose);
+	    $stock = undef;
+	}
+    }
+    $self->add_alignment ($stock, $verbose) if defined $stock;
+
+    return $self;
+}
+
+=head2 to_file
+
+    $db->to_file ($filename)
+    $db->to_file ($filename, $maxcols)
+
+Saves a Stockholm::Database to a named file.
+
+The second form of the method sets the maximum column width for the Stockholm::to_string method.
+
+=cut
+
+# to_file method
+sub to_file {
+    my ($self, $filename, $maxcols) = @_;
+
+    local *FILE;
+    open FILE, ">$filename" or croak "Couldn't open '$filename' for writing: $!";
+    print FILE $self->to_string ($maxcols);
+    close FILE or croak "Couldn't close '$filename': $!";;
+
+    return $filename;
+}
+
+=head2 to_string
+
+    $db->to_string()
+    $db->to_string ($maxcols)
+
+Renders a Stockholm::Database as a (Stockholm-format) string.
+
+The second form of the method sets the maximum column width for the Stockholm::to_string method.
+
+=cut
+
+# to_string
+sub to_string {
+    my ($self, $maxcols) = @_;
+    return join ("", map ($_->to_string ($maxcols), @$self));
+}
+
+
+=head2 add_alignment
+
+    $db->add_alignment ($stock)
+    $db->add_alignment ($stock, 0)
+
+Adds a Stockholm alignment to a Stockholm::Database.
+
+By default, a message is printed when the alignment is added.
+The second form of the method suppresses these verbose messages.
+
+=cut
+
+# add_alignment method
+sub add_alignment {
+    my ($self, $stock, $verbose) = @_;
+    push @$self, $stock;
+    my $id = $stock->get_gf ('ID');
+    warn "...loaded Stockholm alignment", defined $id ? " '$id'" : '', " (", $stock->sequences, " sequences)\n" if $verbose;
+    return $self;
+}
+
+# end of package
+
+1
diff --git a/perl/accuracy.pl b/perl/accuracy.pl
new file mode 100755
index 0000000..5526104
--- /dev/null
+++ b/perl/accuracy.pl
@@ -0,0 +1,97 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+accuracy.pl
+
+=head1 SYNOPSIS
+
+Compute expected accuracy of an alignment under FSA's statistical model.
+
+Written by Robert Bradley.
+
+=cut
+
+use strict;
+
+use Stockholm;
+use FSA::Model;
+
+my $acc_threshold = 0.9;
+my $cert_threshold = 5.0;
+my $usage = "\nUsage: $0 -f <sequence file> [-p <.probs file>] [<MFA file(s)> <Stockholm file(s)>]
+
+Calculates Acc, Sn, PPV, Certainty and Consistency for input alignments.
+
+     [--annotate] annotates the input alignment and prints it as a Stockholm-format alignment
+     [--accuracy-threshold <double>] threshold for calling a character correctly aligned (default is $acc_threshold)
+     [--certainty-threshold <double>] threshold for calling a character certain (default is $cert_threshold)
+     [--hard] use a hard cutoff for certainty calculation instead of a \"soft\" logarithmic transform
+     [--model-certainty-dist] show distribution of \"slopes\" for model certainty; suppress all other output
+     [--precision <double>] precision of output
+     [--terse] terse output format
+
+";
+
+my @alignments;
+my ($seqfile, $probsfile);
+my $annotate = 0;
+my $use_log = 1;
+my $certainty_slopes = 0;
+my $precision = 3;
+my $terse = 0;
+
+while (@ARGV) {
+  my $arg = shift;
+  if ($arg =~ /^-/) {
+    if (($arg eq "-h") || ($arg eq "--help")) { print $usage; exit; }
+    elsif (($arg eq "-f")) { $seqfile = shift; }
+    elsif (($arg eq "-p")) { $probsfile = shift; }
+    elsif (($arg eq "--annotate")) { $annotate = 1; }
+    elsif (($arg eq "--accuracy-threshold")) { $acc_threshold = shift; }
+    elsif (($arg eq "--certainty-threshold")) { $cert_threshold = shift; }
+    elsif (($arg eq "--hard")) { $use_log = 0; }
+    elsif (($arg eq "--model-certainty-dist")) { $certainty_slopes = 1; }
+    elsif (($arg eq "--precision")) { $precision = shift; }
+    elsif (($arg eq "--terse")) { $terse = 1; }
+    else { die $arg, "\n", $usage; }
+  }
+  else { push @alignments, $arg; }
+}
+
+# test files ok
+unless (defined $seqfile && -r $seqfile) { die "You must provide a readable FSA input sequence file (don't forget the -f switch!).\n"; }
+if (!defined $probsfile) { $probsfile = $seqfile . ".probs"; }
+if (! -r $probsfile) { die ".probs file '$probsfile' not readable."; }
+
+# initialize FSA::Model object
+my $model = FSA::Model->from_probsfile ($seqfile, $probsfile);
+
+# loop over alignments
+foreach my $align (@alignments) {
+
+  my $stock = Stockholm->from_file ($align);
+  $stock->assert_flush();
+  $stock->drop_allgaps_columns();
+  if (!$terse) {
+    print "Looking at alignment '$align'...\n";
+  }
+  
+  # if requested, just show the distribution of certainty slopes
+  if ($certainty_slopes) {
+    $model->sparse_matrices->show_model_certainty_slopes ($precision);
+    exit 0;
+  }
+
+  # calculate accuracies
+  $model->calc_accuracies ($stock, $acc_threshold, $cert_threshold, $use_log);
+
+  # print the annotated alignment if requested
+  if ($annotate) {
+    $model->annotate_alignment ($stock, $precision);
+    print $stock->to_string();
+  }
+  # else just show results
+  $model->show_accuracies ($precision, $terse);
+
+}
diff --git a/perl/cmpalign.pl b/perl/cmpalign.pl
new file mode 100755
index 0000000..a90be9c
--- /dev/null
+++ b/perl/cmpalign.pl
@@ -0,0 +1,277 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+cmpalign.pl
+
+=head1 SYNOPSIS
+
+Compare two alignments.
+
+Written by Robert Bradley.
+
+=cut
+
+use strict;
+use Stockholm;
+use Stockholm::Database;
+
+my $usage = "\nUsage: $0 <reference alignment> <comparison alignment>
+
+Compares two alignments.
+Aligments can be in Stockholm, multi-FASTA, ClustalW or MSF formats.
+
+     [--precision <double>] precision of output
+     [--terse] terse output format
+     [--log] log progress
+     [--lazy] allow sequence data in two alignments to differ
+     [--rna] allow U and T to be interchangeable
+     [--pairwise-reference] reference alignment is a Stockholm database of pairwise alignments
+                             (for e.g. SABmark, which provides pairwise reference alignments)
+
+\n";
+
+my $lazy = 0;
+my $rna = 0;
+my $log = 0;
+my ($reffile, $cmpfile);
+my $precision = 3;
+my $terse = 0;
+my $pairwiseref = 0;
+
+my @argv;
+while (@ARGV) {
+  my $arg = shift;
+  if ($arg =~ /^-/) {
+    if (($arg eq "-h") || ($arg eq "--help")) { print $usage; exit; }
+    elsif ($arg eq "--precision") { $precision = shift; }
+    elsif ($arg eq "--terse") { $terse = 1; }
+    elsif ($arg eq "--log") { $log = 1; }
+    elsif ($arg eq "--lazy") { $lazy = 1; }
+    elsif ($arg eq "--rna") { $rna = 1; }
+    elsif ($arg eq "--pairwise-reference") { $pairwiseref = 1; }
+    else { die $usage; }
+  } else {
+    push @argv, $arg;
+  }
+}
+if (@argv == 2) {
+  ($reffile, $cmpfile) = @argv;
+}
+else {
+  die $usage;
+}
+
+my $gapChars = '-._';
+
+my $refdb;  # fake a Stockholm::Database
+if ($pairwiseref) { $refdb = Stockholm::Database->from_file ($reffile); }
+else { push @{$refdb}, Stockholm->from_file ($reffile); }
+my $cmp = Stockholm->from_file ($cmpfile);
+$cmp->assert_flush();
+$cmp->drop_allgaps_columns();
+
+# make sure that the 2 alignments contain the same sequence names and data
+# convert seqs to uppercase as side effect
+my %seqname;
+foreach my $ref (@{$refdb}) {
+  foreach my $seq (@{$ref->seqname}) {
+    $seqname{$seq} = 1;
+
+    $ref->assert_flush();
+    $ref->drop_allgaps_columns();
+
+    unless (defined $cmp->seqdata->{$seq}) { die "Sequence data for '$seq' not in comparison alignment; I'm bailing.\n"; }
+    # make sure that they're the same sequence
+    if (ungapped ($ref->seqdata->{$seq}, $rna) ne ungapped ($cmp->seqdata->{$seq}, $rna)) {
+      if ($lazy) { warn "Sequence data for '$seq' doesn't match:\n",ungapped ($ref->seqdata->{$seq}, $rna),"\n",ungapped ($cmp->seqdata->{$seq}, $rna),"\n  (but I'm doing the comparison regardless)\n"; }
+      else { die "Sequence data for '$seq' doesn't match:\n",ungapped ($ref->seqdata->{$seq}, $rna),"\n",ungapped ($cmp->seqdata->{$seq}, $rna),"\n"; }
+    }
+
+    # convert everything to uppercase for safety
+    $ref->seqdata->{$seq} = uc ($ref->seqdata->{$seq});
+    $cmp->seqdata->{$seq} = uc ($cmp->seqdata->{$seq});
+
+  }
+}
+
+# keep seqnames sorted (otherwise nasty things happen!)
+my @seqname_sorted = sort keys %{seqname};
+
+# total number of characters (sum-of-pairs)
+my $total_char = 0;
+# total number of residue pairs (sum-of-pairs) in each alignment
+my ($sn1, $sn2) = (0, 0); # (ref, cmp)
+
+# (num_aligned_pairs, num_unaligned_1, num_unaligned_2)
+my @overlap = (0,0,0);
+
+# (num_aligned_pairs, num_unaligned_1, num_unaligned_2)
+my @stats_ref = (0,0,0);
+my @stats_cmp = (0,0,0);
+
+# for each pair of sequences
+
+# for logging
+my $num_seqs = scalar @seqname_sorted;
+my $num_seq_pairs = $num_seqs * ($num_seqs - 1) / 2;
+my $cnt = 0;
+for (my $s1 = 0; $s1 < @seqname_sorted; $s1++) {
+  for (my $s2 = $s1+1; $s2 < @seqname_sorted; $s2++) {
+    my ($seqname1, $seqname2) = ($seqname_sorted[$s1], $seqname_sorted[$s2]);
+
+    # get the reference alignment containing the sequences
+    # (necessary for the case where the reference alignment is a Stockholm::Database
+    # of pairwise comparisons)
+    my $ref = get_alignment_with ($refdb, $seqname1, $seqname2);
+
+    # increment total number of characters
+    $total_char += length (ungapped ($ref->seqdata->{$seqname1}, $rna)) + length (ungapped ($ref->seqdata->{$seqname2}, $rna));
+
+    # for the reference alignment
+    # $align_cmp->{$i} = $j means that the positions ($i,$j) are aligned
+    my ($row0, $row1) = ($ref->seqdata->{$seqname1}, $ref->seqdata->{$seqname2});
+    my $align_ref = aligned_pairwise ($row0, $row1);
+    my @indel_ref = @{indel_single ($row0,$row1)};
+    $stats_ref[0] += scalar keys %$align_ref;
+    $stats_ref[1] += scalar keys %{$indel_ref[0]};
+    $stats_ref[2] += scalar keys %{$indel_ref[1]};
+
+    # for the other alignment
+    ($row0, $row1) = ($cmp->seqdata->{$seqname1}, $cmp->seqdata->{$seqname2});
+    my $align_cmp = aligned_pairwise ($row0, $row1);
+    my @indel_cmp = @{indel_single ($row0,$row1)};
+    $stats_cmp[0] += scalar keys %$align_cmp;
+    $stats_cmp[1] += scalar keys %{$indel_cmp[0]};
+    $stats_cmp[2] += scalar keys %{$indel_cmp[1]};
+
+    # compare aligned characters
+    foreach my $i (sort { $a <=> $b } keys %{$align_ref}) {
+      if (defined (my $j = $align_ref->{$i})) {
+	$sn1++; # reference alignment
+	if (defined $align_cmp->{$i} && $j == $align_cmp->{$i}) { # b/c $i isn't necessarily aligned in cmp
+	  ++$overlap[0];
+	}
+      }
+    }
+
+    # compare unaligned (gapped) characters
+    foreach my $i (sort { $a <=> $b } keys %{$indel_ref[0]}) {
+      if (defined $indel_cmp[0]->{$i}) { ++$overlap[1]; }
+    }
+    foreach my $i (sort { $a <=> $b } keys %{$indel_ref[1]}) {
+      if (defined $indel_cmp[1]->{$i}) { ++$overlap[2]; }
+    }
+
+    # now get counts for comparison alignment (for e.g. specificity measure)
+    foreach my $i (sort { $a <=> $b } keys %{$align_cmp}) {
+      if (defined (my $j = $align_cmp->{$i})) {
+	$sn2++;
+      }
+    }
+
+    # log progress if desired
+    if (($cnt++ % 100 == 0) && $log) {
+      my $percent_done = int (100 * $cnt / $num_seq_pairs + 0.5);
+      warn "Processed sequence pair '$seqname1' and '$seqname2'; ", $percent_done, "% (", $cnt, "/", $num_seq_pairs, ") complete.\n";
+    }
+
+  }
+}
+
+# calculate and print the results
+my $acc  = (2*$overlap[0] + $overlap[1]+ $overlap[2]) / $total_char;
+my $sn = ($sn1 > 0) ? $overlap[0] / $sn1 : 0;
+my $ppv = ($sn2 > 0) ? $overlap[0] / $sn2 : 0;
+
+my $summary = $stats_ref[0] . " " . $stats_ref[1] . " " . $stats_ref[2]
+  . " " . $stats_cmp[0] . " " . $stats_cmp[1] . " " . $stats_cmp[2]
+  . " " . $overlap[0] . " " . $overlap[1] . " " . $overlap[2];
+
+# terse results only if requested
+if ($terse) {
+  print "$summary\n";
+}
+
+# else pretty results
+else {
+  print "Alignment '$reffile' has ", $stats_ref[0], " aligned character pairs, ", $stats_ref[1], " insertions, ", $stats_ref[2], " deletions.\n";
+  print "Alignment '$cmpfile' has ", $stats_cmp[0], " aligned character pairs, ", $stats_cmp[1], " insertions, ", $stats_cmp[2], " deletions.\n";
+  print "Overlap is ", $overlap[0], " aligned character pairs, ", $overlap[1], " insertions, ", $overlap[2], " deletions.\n";
+  printf "Acc %.${precision}f\n", $acc;
+  printf "Sn  %.${precision}f\n", $sn;
+  printf "PPV %.${precision}f\n", $ppv;
+  print "Summary: $summary\n";
+}
+
+# Remove gaps from a string.
+# Convert to uppercase for safety.
+# Converts T to U if requested.
+sub ungapped {
+  my ($row, $rna) = @_;
+  if (!defined $rna) { $rna = 0; }
+
+  my $new = uc ($row);
+  if ($rna) { $new =~ tr/T/U/; }
+  $new =~ s/[$gapChars]//g;
+
+  return $new;
+}
+
+# Takes 2 strings (alignments rows) as input.
+# Returns a hash reference where $align_cmp->{$i} = $j means that the positions ($i,$j) are aligned.
+sub aligned_pairwise {
+  my ($row0, $row1) = @_;
+
+  my $align_cmp = {};
+  my $cols = length ($row0);
+  my ($i, $j) = (0, 0); # keep track of positions in seq0, seq1
+  for (my $col = 0; $col < $cols; $col++) {
+    my $c0 = substr ($row0, $col, 1);
+    my $c1 = substr ($row1, $col, 1);
+    if (!($c0 =~ /[$gapChars]/)) {
+      if (!($c1 =~ /[$gapChars]/)) {
+	$align_cmp->{$i} = $j;
+      }
+      $i++;
+    }
+    if (!($c1 =~ /[$gapChars]/)) {
+      $j++;
+    }
+  }
+
+  return $align_cmp;
+}
+
+# Takes 2 strings (alignment rows) as input.
+# Returns a hash reference where $indel->[0]->{$i} = 1 means that position $i (alignment coords) is gapped in sequence 0.
+sub indel_single {
+  my ($row0, $row1) = @_;
+
+  my $indel = [];
+  my $cols = length ($row0);
+  my ($i, $j) = (0, 0); # keep track of positions in seq0, seq1
+  for (my $col = 0; $col < $cols; $col++) {
+    my $c0 = substr ($row0, $col, 1);
+    my $c1 = substr ($row1, $col, 1);
+    if (!($c0 =~ /[$gapChars]/) && ($c1 =~ /[$gapChars]/)) { $indel->[0]->{$i} = 1; ++$i; } # ungapped in 0 (i)
+    elsif (($c0 =~ /[$gapChars]/) && !($c1 =~ /[$gapChars]/)) { $indel->[1]->{$j} = 1; ++$j; } # ungapped in 1 (j)
+    elsif (!($c0 =~ /[$gapChars]/) && !($c1 =~ /[$gapChars]/)) { ++$i; ++$j; }
+  }
+
+  return $indel;
+}
+
+# Find the alignment containing the passed sequences.
+sub get_alignment_with {
+  my ($db, $seq1, $seq2) = @_;
+
+  foreach my $stk (@$db) {
+    if (exists $stk->seqdata->{$seq1} && exists $stk->seqdata->{$seq2}) {
+      return $stk;
+    }
+  }
+
+  die "Couldn't find a reference alignment containing '$seq1' and '$seq2'.";
+
+}
diff --git a/perl/dartlog.pl b/perl/dartlog.pl
new file mode 100755
index 0000000..12de248
--- /dev/null
+++ b/perl/dartlog.pl
@@ -0,0 +1,168 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+dartlog.pl
+
+=head1 SYNOPSIS
+
+Follow logfiles.
+
+Written by Ian Holmes (from the DART library).
+
+=cut
+
+# set up pagers
+my $less = "less -rF";
+my $tail = "tail -f";
+my $cat = "cat";
+
+# get program name
+my $progname = $0;
+$progname =~ s/^.*\///;
+
+# initialise help string & args
+my $usage = "\n";
+$usage .= "Usage:\n";
+$usage .= "       $progname [options] <logfile(s)>\n";
+$usage .= "   or\n";
+$usage .= "       cat <logfile> | $progname [options]\n";
+$usage .= "\n";
+$usage .= "Options:\n";
+$usage .= "\t          [-h]  this help message\n";
+$usage .= "\t         [-fl]  print file & line info\n";
+$usage .= "\t         [-dt]  print date & time info\n";
+$usage .= "\t        [-lev]  print log level\n";
+$usage .= "\t        [-tag]  print tags\n";
+$usage .= "\t   [-f,-fancy]  synonym for \"-fl -dt -lev -tag\"\n";
+$usage .= "\t        [-cat]  pipe file through '$cat' instead of '$less'\n";
+$usage .= "\t       [-tail]  pipe file from '$tail' and through '$cat' instead of '$less'\n";
+$usage .= "\t[-min <level>]  only display log messages above this log level\n";
+$usage .= "\t [-skip <tag>]  skip log messages with this tag\n";
+$usage .= "\t [-show <tag>]  show log messages with this tag (overrides -min and -skip)\n";
+
+my $print_file_and_line = 0;
+my $print_date_and_time = 0;
+my $print_level = 0;
+my $print_tags = 0;
+my $pipe_from_tail = 0;
+my $pipe_to_cat = 0;
+my $tab = "";
+my $minlev;
+my %show;
+my %skip;
+
+# parse cmd-line opts
+my @argv;
+while (@ARGV) {
+    my $arg = shift;
+    if ($arg eq "-h") {
+	die $usage;
+    } elsif ($arg eq "-lev") {
+	$print_level = 1;
+    } elsif ($arg eq "-fl") {
+	$print_file_and_line = 1;
+    } elsif ($arg eq "-dt") {
+	$print_date_and_time = 1;
+    } elsif ($arg eq "-tag") {
+	$print_tags = 1;
+    } elsif ($arg eq "-f" || $arg eq "-fancy") {
+	unshift @ARGV, qw(-fl -dt -lev -tag);
+    } elsif ($arg eq "-cat") {
+	$pipe_to_cat = 1;
+    } elsif ($arg eq "-tail") {
+	$pipe_from_tail = $pipe_to_cat = 1;
+    } elsif ($arg eq "-min") {
+	defined ($minlev = shift) or die $usage;
+    } elsif ($arg eq "-skip") {
+	my $tag = shift;
+	defined ($tag) or die $usage;
+	$skip{$tag} = 1;
+    } elsif ($arg eq "-show") {
+	my $tag = shift;
+	defined ($tag) or die $usage;
+	$show{$tag} = 1;
+    } else {
+	push @argv, $arg;
+    }
+}
+ at argv = qw(-) unless @argv;
+
+# open less pager
+my $pager = $pipe_to_cat ? $cat : $less;
+local *LESS;
+open (LESS, "|$pager") or open (LESS, ">-");
+
+# autoflush
+select LESS;
+$| = 1;
+select STDOUT;
+
+# set up ANSI color codes
+my @col = (map (e(7).e(23).e($_), reverse (31..35), 37),  # inverse, not-italics, (magenta..red,white)
+	   map (e(27).e(23).e($_), 31..37),  # not-inverse, not-italics, (red..white)
+	   e(7).e(23).e(36));  # inverse, not-italics, cyan
+
+
+my $w = e(27).e(23).e(37);  # not-inverse, not-italics, white
+my $invw = e(7).e(23).e(37);  # inverse, not-italics, white
+my $invr = e(7).e(23).e(31);  # inverse, not-italics, red
+my $invg = e(7).e(23).e(32);  # inverse, not-italics, green
+my $invy = e(7).e(23).e(33);  # inverse, not-italics, yellow
+my $invb = e(7).e(23).e(34);  # inverse, not-italics, blue
+my $invm = e(7).e(23).e(35);  # inverse, not-italics, magenta
+my $invc = e(7).e(23).e(36);  # inverse, not-italics, cyan
+
+# parse logfile
+my ($date, $time, $file, $line, $tags) = map ("", 1..5);
+my ($last_date, $last_time, $last_file, $last_line, $last_tags) = map ("", 1..5);
+my ($lev, $last_lev) = (9, 9);
+my @tag;
+my $c = "";
+foreach my $infile (@argv) {
+    local *INFILE;
+    if ($pipe_from_tail) {
+	open INFILE, "$tail $infile|" or die "Couldn't run '$tail $infile'";
+    } else {
+	open INFILE, "<$infile" or die "Couldn't open $infile";
+    }
+    while (<INFILE>) {
+	my $text = $_;
+	if ($text =~ /<log.*>/) {
+	    if (/date="(\S+)"/) { $date = $1 }
+	    if (/time="(\S+)"/) { $time = $1 }
+	    if (/file="(\S+)"/) { $file = $1 }
+	    if (/line=(\d+)/)   { $line = $1 }
+	    if (/level=(\-?\d+)/) { $lev = $1 }
+
+	    $c = $col [$lev<-5 ? 0 : ($lev+5>=@col ? @col-1 : $lev+5)];
+	    if (/tags=\"([^\"]+)\"/) {
+		$tags = $1;
+		@tag = split /\s+/, $tags;
+	    } else {
+		$tags = "";
+		@tag = ();
+	    }
+	} else {
+	    my $show = grep (exists($show{$_}), @tag);
+	    next if !$show && defined($minlev) && $lev < $minlev;
+	    next if !$show && %skip && grep (exists($skip{$_}), @tag);
+	    my $info = 0;
+	    if ($print_level) {	print LESS $invc, ($lev == $last_lev ? ("  ") : (($lev<0||$lev>9?():(' ')), $lev)), $invc, $w, ' ' }
+	    if ($print_file_and_line && ($file ne $last_file || $line ne $last_line)) { print LESS $invr, $file, '#', $line, $invr, $w; $last_file = $file; $last_line = $line; $info = 1 }
+	    if ($print_date_and_time && $time ne $last_time) { print LESS $invg, $time, $invg, $w; $last_time = $time; $info = 1 }
+	    if ($print_date_and_time && $date ne $last_date) { print LESS $invm, $date, $invm, $w; $last_date = $date; $info = 1 }
+	    if ($print_tags && $tags ne $last_tags) { print LESS $invy, $tags, $invy, $w; $last_tags = $tags; $info = 1 }
+	    print LESS "\t" if $info;
+	    chomp $text;
+	    print LESS $w, $c, $text, $c, $w, "\n";  # sandwiching with $w$c allows paging back with 'less'
+	}
+    }
+    close INFILE;
+}
+
+# escape code subroutine
+sub e {
+    my $code = shift;
+    return chr(27)."[$code"."m";
+}
diff --git a/perl/fasta2stockholm.pl b/perl/fasta2stockholm.pl
new file mode 100755
index 0000000..228ce20
--- /dev/null
+++ b/perl/fasta2stockholm.pl
@@ -0,0 +1,59 @@
+#!/usr/bin/perl -w
+
+my $usage = "Usage: $0 <gapped FASTA alignment file(s)>\n";
+
+my @argv;
+while (@ARGV) {
+    my $arg = shift;
+    if ($arg =~ /^-/) {
+	if ($arg eq "-h") { print $usage; exit }
+	else { die $usage }
+    } else {
+	push @argv, $arg;
+    }
+}
+push @argv, "-" unless @argv;
+
+# loop through FASTA files
+foreach my $fasta (@argv) {
+# read FASTA file
+    my %seq;
+    my @name;
+    my $name;
+    open FASTA, "<$fasta" or die "Couldn't open '$fasta': $!";
+    while (<FASTA>) {
+	if (/^\s*>\s*(\S+)/) {
+	    $name = $1;
+	    push @name, $name;
+	} else {
+	    if (/\S/ && !defined $name) {
+		warn "Ignoring: $_";
+	    } else {
+		s/\s//g;
+		$seq{$name} .= $_;
+	    }
+	}
+    }
+    close FASTA;
+
+# check all seqs are same length
+    my $length;
+    my $lname;
+    foreach my $name (@name) {
+	my $l = length $seq{$name};
+	if (defined $length) {
+	    die "Sequences not all same length ($lname is $length, $name is $l)" unless $length == $l;
+	} else {
+	    $length = length $seq{$name};
+	    $lname = $name;
+	}
+    }
+
+# print Stockholm output
+    print "# STOCKHOLM 1.0\n";
+    foreach my $name (@name) {
+	print $name, " ", $seq{$name}, "\n";
+    }
+    print "//\n";
+}
+
diff --git a/perl/prettify.pl b/perl/prettify.pl
new file mode 100755
index 0000000..f342ce7
--- /dev/null
+++ b/perl/prettify.pl
@@ -0,0 +1,36 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+prettify.pl
+
+=head1 SYNOPSIS
+
+Prettify (make human-readable) an alignment.
+
+Written by Robert Bradley.
+
+=cut
+
+use Stockholm;
+
+my $usage = "\nUsage: $0 <alignment file>
+
+Prints a human-readable alignment in Stockholm format.
+
+\n";
+
+# make everything look nice
+# drop all-gap columns
+
+my $file = shift;
+if (!defined $file) { die $usage; }
+
+my $stk = Stockholm->from_file ($file);
+$stk->assert_flush();
+
+# drop all-gap columns
+$stk->drop_allgaps_columns();
+
+# display
+print $stk->to_string();
diff --git a/perl/seqdotplot.pl b/perl/seqdotplot.pl
new file mode 100755
index 0000000..18a69c1
--- /dev/null
+++ b/perl/seqdotplot.pl
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+
+=head1 NAME
+
+seqdotplot.pl
+
+=head1 SYNOPSIS
+
+Plot alignment posterior probabilities.
+
+Written by Ian Holmes (from the DART library).
+
+=cut
+
+use GD;
+
+# usage string
+my $usage = "Usage: $0 [-diag] [-noscale] [-notext] <file>\n";
+
+# default opts
+my $diag = 0;
+my $printScale = 1;
+my $noText = 0;
+
+# parse args
+my @argv;
+while (@ARGV) {
+    my $arg = shift;
+    if ($arg eq "-diag") { $diag = 1 }
+    elsif ($arg eq "-noscale") { $printScale = 0 }
+    elsif ($arg eq "-notext") { $noText = 1 }
+    elsif ($arg =~ /^-/) { die $usage }
+    else { push @argv, $arg }
+}
+ at ARGV = @argv;
+
+my $file = $argv[0];
+
+# read data
+my $xAxis = <>;
+chomp $xAxis;
+my ($dummy, @xAxis) = split /\s+/, $xAxis;
+
+my @data;
+my @yAxis;
+while (my $data = <>) {
+    chomp $data;
+    my ($yCoord, @row) = split /\s+/, $data;
+    push @yAxis, $yCoord;
+    push @data, \@row;
+}
+
+# if -diag specified, check dimensions match
+if ($diag && @xAxis != @yAxis) { die "-diag option specified, but x & y sequences don't match" }
+
+# get font
+my $font = gdTinyFont;
+my $charWidth = $font->width;
+my $charHeight = $font->height;
+
+# make it square
+my ($cellWidth, $cellHeight) = ($charWidth, $charHeight);
+if ($noText) { $cellWidth = $cellHeight = 2 }
+else { if ($cellWidth > $cellHeight) { $cellHeight = $cellWidth } else { $cellWidth = $cellHeight } }
+
+# create a new image
+my $imWidth = $cellWidth * (@xAxis + 2);
+my $imHeight = $cellHeight * (@yAxis + ($printScale ? 3 : 2));
+my $im = new GD::Image ($imWidth, $imHeight);
+
+# allocate some colors
+my $black = $im->colorAllocate(0,0,0);
+my $green = $im->colorAllocate(0,255,0);
+my $blue = $im->colorAllocate(0,0,255);
+my $yellow = $im->colorAllocate(180,180,0);
+my $purple = $im->colorAllocate(180,0,180);
+my $grey = $im->colorAllocate(16,16,16);
+my @col = ($black);
+my $shades = 250;
+for (my $i = 1; $i <= $shades; ++$i) {
+    my $r = 32 + 224 * (3 * $i) / $shades;
+    my $g = 256 * (3 * $i - $shades) / $shades;
+    my $b = 256 * (3 * $i - 2*$shades) / $shades;
+    if ($r > 255) { $r = 255 } elsif ($r < 0) { $r = 0 }
+    if ($g > 255) { $g = 255 } elsif ($g < 0) { $g = 0 }
+    if ($b > 255) { $b = 255 } elsif ($b < 0) { $b = 0 }
+    push @col, $im->colorAllocate ($r, $g, $b);
+}
+my $white = $col[@col-1];
+my %charCol = ('a' => $purple, 't' => $blue, 'u' => $blue,
+	       'c' => $green, 'g' => $yellow, '*' => $white);
+
+# plot color scale
+if ($printScale) {
+    my $ltext = "Probability: 0 ";
+    my $rtext = " 1";
+    my $lchars = length ($ltext);
+    my $rchars = length ($rtext);
+    my $barWidth = ($imWidth - $charWidth * ($lchars + $rchars)) / @col;
+    for (my $c = 0; $c < @col; ++$c) {
+	$im->filledRectangle ($charWidth * $lchars + $c * $barWidth, $imHeight - $charHeight,
+			      $charWidth * $lchars + ($c + 1) * $barWidth - 1, $imHeight,
+			      $col[$c]);
+    }
+    $im->string ($font, 0, $imHeight - $charHeight, $ltext, $white);
+    $im->string ($font, $imWidth - $charWidth * $rchars, $imHeight - $charHeight, $rtext, $white);
+}
+
+
+# plot data
+for (my $y = 0; $y < @yAxis; ++$y) {
+    for (my $x = $diag ? $y+1 : 0; $x < @xAxis; ++$x) {
+	my $datum = $data[$y]->[$x];
+	if ($datum eq ".") { $datum = 0 }
+	my $colIndex = int ($datum * @col);
+	if ($colIndex >= @col) { $colIndex = @col - 1}
+	elsif ($colIndex < 0) { $colIndex = 0 }
+	$im->filledRectangle (($x + 1) * $cellWidth, ($y + 1) * $cellHeight,
+			      ($x + 2) * $cellWidth - 1, ($y + 2) * $cellHeight - 1,
+			      $col[$colIndex]);
+    }
+}
+
+# plot sequence axes
+if ($diag) {
+    my $len = @xAxis;
+#    my $triangle = new GD::Polygon;
+#    $triangle->addPt (0, 0);
+#    $triangle->addPt (0, ($len+1)*$cellHeight);
+#    $triangle->addPt (($len+1)*$cellWidth, ($len+1)*$cellHeight);
+#    $im->filledPolygon ($triangle, $white);
+
+    renderAxis ($im, \@xAxis, $cellWidth, 0, $cellWidth, 0);
+    renderAxis ($im, \@xAxis, $cellWidth, $cellHeight, $cellWidth, $cellHeight);
+    renderAxis ($im, \@xAxis, $imWidth - $cellWidth, $cellHeight, 0, $cellHeight);
+} else {
+    renderAxis ($im, \@xAxis, $cellWidth, 0, $cellWidth, 0);
+    renderAxis ($im, \@xAxis, $cellWidth, $imHeight - ($printScale ? 2 : 1) * $cellHeight, $cellWidth, 0);
+    renderAxis ($im, \@yAxis, 0, $cellHeight, 0, $cellHeight);
+    renderAxis ($im, \@yAxis, $imWidth - $cellWidth, $cellHeight, 0, $cellHeight);
+}
+
+# make sure we are writing to a binary stream
+binmode STDOUT;
+
+# Convert the image to PNG and print it on standard output
+open OUTPUT, ">$file.png";
+print OUTPUT $im->png;
+
+print "Created '$file.png'.\n";
+
+# subroutine to render an axis
+sub renderAxis {
+    my ($im, $axisRef, $x, $y, $xStep, $yStep) = @_;
+    warn "Drawing sequence from ($x,$y) to (", $x+$xStep*@$axisRef, ",", $y+$yStep*@$axisRef, ")\n";
+    my $xOffset = ($cellWidth - $charWidth) / 2;
+    my $yOffset = ($cellHeight - $charHeight) / 2;
+    for (my $i = 0; $i < @$axisRef; ++$i) {
+	my $c = $axisRef->[$i];
+	fillCell ($im, $x, $y, $charCol{lc$c});
+	if ($cellWidth >= $charWidth && $cellHeight >= $charHeight) {
+	    $im->char ($font, $x + $xOffset, $y + $yOffset, $c, $black);
+	}
+	$x += $xStep;
+	$y += $yStep;
+    }
+}
+
+# low-level drawing subroutine to fill a cell
+sub fillCell {
+    my ($im, $x, $y, $col) = @_;
+    $im->filledRectangle ($x, $y, $x + $cellWidth - 1, $y + $cellHeight - 1, $col);
+}
diff --git a/perl/stockholm2fasta.pl b/perl/stockholm2fasta.pl
new file mode 100755
index 0000000..c2e1e70
--- /dev/null
+++ b/perl/stockholm2fasta.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl -w
+
+my $columns = 50;
+my $gapped = 0;
+
+my $progname = $0;
+$progname =~ s/^.*?([^\/]+)$/$1/;
+
+my $usage = "Usage: $progname [<Stockholm file(s)>]\n";
+$usage .=   "             [-h] print this help message\n";
+$usage .=   "             [-g] write gapped FASTA output\n";
+$usage .=   "             [-s] sort sequences by name\n";
+$usage .=   "      [-c <cols>] number of columns for FASTA output (default is $columns)\n";
+# parse cmd-line opts
+my @argv;
+while (@ARGV) {
+    my $arg = shift;
+    if ($arg eq "-h") {
+	die $usage;
+    } elsif ($arg eq "-g") {
+	$gapped = 1;
+    } elsif ($arg eq "-s"){
+	$sorted = 1;
+    } elsif ($arg eq "-c") {
+	defined ($columns = shift) or die $usage;
+    } else {
+	push @argv, $arg;
+    }
+}
+ at ARGV = @argv;
+
+my %seq;
+while (<>) {
+    next unless /\S/;
+    next if /^\s*\#/;
+    if (/^\s*\/\//) { printseq() }
+    else {
+	chomp;
+	my ($name, $seq) = split;
+	$seq =~ s/[\.\-]//g unless $gapped;
+	$seq{$name} .= $seq;
+    }
+}
+printseq();
+
+sub printseq {
+	if($sorted){
+		foreach $key (sort keys %seq){
+			print ">$key\n";
+			for (my $i = 0; $i < length $seq{$key}; $i += $columns){
+				print substr($seq{$key}, $i, $columns), "\n";
+			}
+		}
+	} else{
+    		while (my ($name, $seq) = each %seq) {
+			print ">$name\n";
+			for (my $i = 0; $i < length $seq; $i += $columns) {
+	    			print substr ($seq, $i, $columns), "\n";
+			}
+   	 	}
+	}
+    %seq = ();
+}
diff --git a/src/annealing/Makefile.am b/src/annealing/Makefile.am
new file mode 100644
index 0000000..08411e3
--- /dev/null
+++ b/src/annealing/Makefile.am
@@ -0,0 +1,35 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+LDADD = \
+	libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a
+
+if HAVE_CONDOR
+AM_CPPFLAGS += -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+
+AM_LDFLAGS = -static -L$(top_builddir)/MW/lib
+LDADD += \
+	-lMW \
+	-lMWRMComm \
+	-lMWutil \
+	-lNWS \
+	-lMWsocketmaster \
+    -lpthread
+endif
+
+noinst_LIBRARIES = libannealing.a
+libannealing_a_SOURCES = \
+	alignment_DAG.cc \
+	dotplot.cc \
+	tree_weights.cc
+
+noinst_HEADERS = \
+	SparseMatrix.h \
+	alignment_DAG.h \
+	dotplot.h \
+	tree_weights.h
diff --git a/src/annealing/Makefile.in b/src/annealing/Makefile.in
new file mode 100644
index 0000000..14df81f
--- /dev/null
+++ b/src/annealing/Makefile.in
@@ -0,0 +1,569 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at HAVE_CONDOR_TRUE@am__append_1 = -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+ at HAVE_CONDOR_TRUE@am__append_2 = \
+ at HAVE_CONDOR_TRUE@	-lMW \
+ at HAVE_CONDOR_TRUE@	-lMWRMComm \
+ at HAVE_CONDOR_TRUE@	-lMWutil \
+ at HAVE_CONDOR_TRUE@	-lNWS \
+ at HAVE_CONDOR_TRUE@	-lMWsocketmaster \
+ at HAVE_CONDOR_TRUE@    -lpthread
+
+subdir = src/annealing
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libannealing_a_AR = $(AR) $(ARFLAGS)
+libannealing_a_LIBADD =
+am_libannealing_a_OBJECTS = alignment_DAG.$(OBJEXT) dotplot.$(OBJEXT) \
+	tree_weights.$(OBJEXT)
+libannealing_a_OBJECTS = $(am_libannealing_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libannealing_a_SOURCES)
+DIST_SOURCES = $(libannealing_a_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src $(am__append_1)
+LDADD = libannealing.a $(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a $(am__append_2)
+ at HAVE_CONDOR_TRUE@AM_LDFLAGS = -static -L$(top_builddir)/MW/lib
+noinst_LIBRARIES = libannealing.a
+libannealing_a_SOURCES = \
+	alignment_DAG.cc \
+	dotplot.cc \
+	tree_weights.cc
+
+noinst_HEADERS = \
+	SparseMatrix.h \
+	alignment_DAG.h \
+	dotplot.h \
+	tree_weights.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/annealing/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/annealing/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libannealing.a: $(libannealing_a_OBJECTS) $(libannealing_a_DEPENDENCIES) $(EXTRA_libannealing_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libannealing.a
+	$(AM_V_AR)$(libannealing_a_AR) libannealing.a $(libannealing_a_OBJECTS) $(libannealing_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libannealing.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/alignment_DAG.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dotplot.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/tree_weights.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/annealing/SparseMatrix.h b/src/annealing/SparseMatrix.h
new file mode 100644
index 0000000..cc12a09
--- /dev/null
+++ b/src/annealing/SparseMatrix.h
@@ -0,0 +1,530 @@
+
+/**
+ * \file SparseMatrix.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Chuong Do.
+ * Robert Bradley wrote the Post_probs struct, corresponding
+ * SparseMatrix constructor and write_gui_output.
+ * Jaeyoung Do wrote a SparseMatrix constructor, 
+ * add_probability and finishing_adding_probability
+ * to construct a SparseMatrix with probabilities transfered
+ * from Database or MW workers  on-the-fly.
+ */
+
+#ifndef SPARSEMATRIX_INCLUDED
+#define SPARSEMATRIX_INCLUDED
+
+// Note that the SparseMatrix class uses 1-based indexing for positions in sequences.
+// This is IN CONTRAST to the rest of FSA, which uses 0-based indexing.
+
+#define DOUBLE_TINY 0.001
+#define DOUBLE_VERY_TINY 0.000001
+#define PRECISION_DEFAULT 5
+
+#include <iostream>
+#include <iomanip>
+
+#include "util/logfile.h"
+#include "manager/db_misc.h"
+
+namespace fsa {
+
+  /**
+   * \brief Sparse matrix entry type
+   *
+   * (column, value)
+   */
+  typedef std::pair<unsigned, float> Matrix_entry;
+
+  /**
+   * \brief Representation of a single posterior probability.
+   *
+   * Assumes 0-based coordinates.
+   */
+  struct Post_prob {
+
+    unsigned x;     ///< coordinate in first sequence
+    unsigned y;     ///< coordinate in second sequence
+    float prob;     ///< posterior probability entry
+
+    /**
+     * \brief Constructor.
+     */
+    Post_prob (unsigned x, unsigned y, float prob)
+    : x (x), y (y), prob (prob)
+    { }
+
+    /**
+     * \brief Lexical order on the coordinates x and y.
+     */
+    bool operator< (const Post_prob& r) const {
+      if (x == r.x)
+	return y < r.y;
+      else
+	return x < r.x;
+    }
+
+    /**
+     * \brief Output operator.
+     *
+     * Output in 0-based coordinates (which Post_probs uses).
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Post_prob& post_prob)  {
+      o << "[" << post_prob.x << ", " << post_prob.x << "] ~ [" << post_prob.y << ", " << post_prob.y << "]" << " => "
+	<< std::setprecision (PRECISION_DEFAULT) << post_prob.prob;
+      return o;
+    }
+
+  };
+
+  /**
+   * \brief Sparse representation of a set of posterior probabilities.
+   */
+  typedef std::vector<Post_prob> Post_probs;
+
+
+  /**
+   * \brief Sparse matrix.
+   *
+   * Uses 1-based coordinates internally.
+   */
+  class SparseMatrix {
+
+    size_t xidx;                                                ///< numerical index of the first sequence
+    size_t yidx;                                                ///< numerical index of the second sequence
+    size_t seq1Length, seq2Length;                              ///< dimensions of matrix
+    std::vector<size_t> rowSize;                                ///< rowSize[i] = # of cells in row i
+    std::vector<Matrix_entry> data;                             ///< data values
+    std::vector<std::vector<Matrix_entry>::iterator> rowPtrs;   ///< pointers to the beginning of each row
+
+    std::vector<float> gapPosteriors;                           ///< gap posteriors (sum of pairs) for first and second sequences
+
+    /**
+     * \brief Default constructor.
+     */
+    SparseMatrix()
+      { }
+
+  public:
+
+#ifdef HAVE_POSTGRES
+    /**
+     * \brief Constructor.
+     *
+     * Builds a sparse matrix with posterior probabilities from Database.
+     */
+    SparseMatrix (const size_t xidx, const size_t yidx,
+		  const size_t xlen, const size_t ylen,
+		  const size_t num_cells)
+      : xidx (xidx), yidx (yidx),
+      seq1Length (xlen), seq2Length (ylen) {
+	
+      // ensure sane
+      assert (xlen >= 0);
+      assert (ylen >= 0);
+
+      // allocate memory
+      data.resize (num_cells);
+      rowSize.assign (xlen + 1, 0); rowSize[0] = 0;       // catch case of no entry!
+      rowPtrs.resize (xlen + 1); rowPtrs[0] = data.end();
+      gapPosteriors.resize (xlen + ylen + 2, 1.0);   // initialize the gap posteriors
+
+    }
+
+    void add_probability (const int pos1, const int pos2, const float prob, const int offset) {
+
+      std::vector<Matrix_entry>::iterator dataPtr = data.begin();
+      dataPtr+=offset;
+
+      if (pos1 == 0) 
+	gapPosteriors[seq1Length + pos2 + 1] = prob; 
+      else if (pos2 == 0) 
+	gapPosteriors[pos1] = prob;
+      else {
+	if (rowSize[pos1] == 0)
+	  rowPtrs[pos1] = dataPtr;
+
+	rowSize[pos1]++;
+
+	dataPtr->first  = pos2;
+	dataPtr->second = prob;
+      }
+    }
+#endif
+
+#ifdef HAVE_CONDOR
+	
+    /**
+     * \brief Constructor.
+     *
+     * Builds a sparse matrix with posterior probabilities from workers.
+     */
+    SparseMatrix (const size_t xidx, const size_t yidx,
+		  const size_t xlen, const size_t ylen,
+		  int pre_len, int len, Sparse_Matrix_Buffer *sm_buffer)
+      : xidx (xidx), yidx (yidx),
+      seq1Length (xlen), seq2Length (ylen) {
+
+      // ensure sane
+      assert (xlen >= 0);
+      assert (ylen >= 0);
+
+      // allocate memory
+      data.resize (len - xlen - ylen);
+      rowSize.assign (xlen + 1, 0); rowSize[0] = 0;       // catch case of no entry!
+      rowPtrs.resize (xlen + 1); rowPtrs[0] = data.end();
+      gapPosteriors.resize (xlen + ylen + 2, 1.0);   // initialize the gap posteriors
+
+      std::vector<Matrix_entry>::iterator dataPtr = data.begin();
+
+      int row=0;	
+
+      for (int cnt = pre_len; cnt < (pre_len + len); cnt++) {
+	if (sm_buffer[cnt].pos1 == 0)  
+	  gapPosteriors[seq1Length + sm_buffer[cnt].pos2 + 1] = sm_buffer[cnt].prob; 
+	else if (sm_buffer[cnt].pos2 == 0)  
+	  gapPosteriors[sm_buffer[cnt].pos1] = sm_buffer[cnt].prob;
+	else {
+
+	  if (row != sm_buffer[cnt].pos1) {
+	    rowSize[row] = dataPtr - rowPtrs[row];
+	    rowPtrs[sm_buffer[cnt].pos1] = dataPtr;
+	    row = sm_buffer[cnt].pos1;
+	  }
+	  dataPtr->first = sm_buffer[cnt].pos2;
+	  dataPtr->second = sm_buffer[cnt].prob;
+	  dataPtr++;
+	}
+      } //end for cnt 
+      rowSize[row] = dataPtr - rowPtrs[row]; //for the last tuple
+    }
+#endif
+
+    /**
+     * \brief Constructor.
+     *
+     *  Builds a sparse matrix from a Post_probs representation
+     * of a posterior matrix.  The coordinates stored in the Post_prob entries
+     * are assumed to be 0-based; note that this is in contrast to the 1-based coordinates
+     * used internally by the SparseMatrix class.
+     * The entries Post_prob must be in lexical order, ie
+     * sorted by first coordinate (x), then second (y).
+     * DOES NOT enforce a cutoff on posterior probabilities;
+     * because the input is sparse, assumes that all entries should be kept.
+     */
+    SparseMatrix (const size_t xidx, const size_t yidx,
+		  const size_t xlen, const size_t ylen,
+		  const Post_probs& post_probs)
+      : xidx (xidx), yidx (yidx),
+      seq1Length (xlen), seq2Length (ylen) {
+
+      // ensure sane
+      assert (xlen >= 0);
+      assert (ylen >= 0);
+
+      // calculate memory required; count the number of cells in the posterior matrix
+      const size_t num_cells = post_probs.size();
+
+      // allocate memory
+      data.resize (num_cells);
+      rowSize.assign (xlen + 1, 0); rowSize[0] = 0;       // catch case of no entry!
+      rowPtrs.resize (xlen + 1); rowPtrs[0] = data.end();
+      gapPosteriors.resize (xlen + ylen + 2, 1.0);   // initialize the gap posteriors
+
+      if (CTAGGING(-1, SPARSEMATRIX)) {
+	CTAG(-1, SPARSEMATRIX) << "Initializing SparseMatrix:" << endl;
+      }
+
+      // read the data
+      int xprev = -1; // the previous x-coordinate
+      int xcurr = -1; // the current x-coordinate
+      int yprev = -1; // the previous y-coordinate
+      std::vector<Matrix_entry>::iterator dataPtr = data.begin(); // iterator through SparseMatrix::data
+      // Note: When initializing the SparseMatrix like this, it's crucial that we iterate through the x-coordinate 
+      // in increasing order => Post_probs must be sorted properly.  If we don't do it in order
+      // then the pointers will get messed up.  Which is Very Bad.
+      for (Post_probs::const_iterator iter = post_probs.begin(); iter != post_probs.end(); ++iter) {
+
+	if (CTAGGING(-1, SPARSEMATRIX)) {
+	  CL << " " << *iter << endl;
+	}
+
+	// pull out coordinates and convert to 1-based coordinates
+	const int x = iter->x + 1;
+	const int y = iter->y + 1;
+	float prob = iter->prob;
+
+	// check sane (now we're in 1-based coordinates)
+	assert ((x >= 1) && (static_cast<size_t> (x) <= xlen));
+	assert ((y >= 1) && (static_cast<size_t> (y) <= ylen));
+
+	// don't allow prob to overflow (results in negative gap posteriors => negative weights => very bad)
+	prob = (prob > 1.) ? 1. : prob;
+
+	// if we just changed x coordinate
+	if (x != xprev) {
+
+	  // store the row size for the previous x coordinate
+	  if (xprev != -1) // catch case of first row
+	    rowSize[xprev] = dataPtr - rowPtrs[xprev];
+
+	  // then continue on to the new x coordinate
+	  xcurr = x;
+	  rowPtrs[x] = dataPtr;
+	  yprev = -1; // reset
+
+	}
+
+	// ensure that entries are ordered properly (we require lexical ordering)
+	assert (xprev <= xcurr);
+	// ensure no duplicate entries
+	assert (yprev < y);
+
+	// store this entry
+	dataPtr->first = y;
+	dataPtr->second = prob;
+	++dataPtr;
+
+	// decrement gap posteriors accordingly
+	gapPosteriors[x] -= prob;
+	gapPosteriors[xlen + y + 1] -= prob;
+
+	// sanity checks: gap posteriors can't be negative beyond roundoff error
+	// (ensure that we're actually storing a probability distribution)
+	if (gapPosteriors[x] < -DOUBLE_TINY) {
+	  (*this).Print (CL, true);
+	  THROWEXPR ("ERROR: Negative gap posterior: gapPosteriors[x = " << x << "] = " << gapPosteriors[x]);
+	}
+	if (gapPosteriors[xlen + y + 1] < -DOUBLE_TINY) {
+	  (*this).Print (CL, true);
+	  THROWEXPR ("ERROR: Negative gap posterior: gapPosteriors[y = " << y << "] = " << gapPosteriors[xlen + y + 1]);
+	}
+	// if acceptable roundoff error, then round up to zero
+	if (gapPosteriors[x] < 0.)
+	  gapPosteriors[x] = 0.;
+	if (gapPosteriors[xlen + y + 1] < 0.)
+	  gapPosteriors[xlen + y + 1] = 0.;
+
+	// prevent overflow
+	if (gapPosteriors[x] < 1e-4)
+	  gapPosteriors[x] = 1e-4;
+	if (gapPosteriors[xlen + y + 1] < 1e-4)
+	  gapPosteriors[xlen + y + 1] = 1e-4;
+
+	// increment our indices
+	xprev = xcurr;
+	yprev = y;
+      }
+
+      // catch edge case of the last row
+      if (xcurr != -1)
+	rowSize[xcurr] = dataPtr - rowPtrs[xcurr];
+
+    }
+
+    /**
+     * \brief Get row pointer.
+     *
+     * \return pointer to a particular row in the sparse matrix
+     */
+    std::vector<Matrix_entry>::iterator GetRowPtr (const unsigned row) const {
+      assert (row >= 1 && row <= seq1Length);
+      return rowPtrs[row];
+    }
+
+    /**
+     * \brief Get match probability in matrix.
+     *
+     * \param row (0-based) row position
+     * \param col (0-based) column position
+     * \return value at a particular row, column
+     */
+    float get_match_prob (const unsigned row, const unsigned col) const {
+      assert (row >= 1 && row <= seq1Length);
+      assert (col >= 1 && col <= seq2Length);
+      for (size_t i = 0; i < rowSize[row]; i++){
+	if (rowPtrs[row][i].first == col) 
+	  return rowPtrs[row][i].second;
+      }
+      return 0;
+    }
+
+    /**
+     * \brief Get row size.
+     *
+     * \return number of entries in a particular row.
+     */
+    size_t GetRowSize (const unsigned row) const {
+      assert (row >= 1 && row <= seq1Length);
+      return rowSize[row];
+    }
+
+    /**
+     * \brief Get length of X (sequence 1).
+     *
+     * \return first dimension of the matrix
+     */
+    size_t GetSeq1Length() const {
+      return seq1Length;
+    }
+
+    /**
+     * \brief Get length of Y (sequence 2).
+     *
+     * \return second dimension of the matrix
+     */
+    size_t GetSeq2Length() const {
+      return seq2Length;
+    }
+
+    /// Get number of entries in matrix.
+    /*
+     * \return number of entries
+     */
+    size_t size() const {
+      return data.size();
+    }
+
+    /**
+     * \brief Write contents of object.
+     *
+     * Position indices are 0-based in output.
+     * The SparseMatrix class uses 1-based sequence indexing internally;
+     * this is converted to 0-based indexing when formatting output.
+     */
+    void Print (std::ostream &outfile, bool show_gaps = false) const {
+      outfile << "Sparse match posteriors (0-based coords):" << endl;
+      for (unsigned i = 1; i <= seq1Length; i++) {
+	// skip zero entries
+	if (rowSize[i] == 0)
+	  continue;
+	outfile << "  " << i - 1 << ":"; // convert to 0-based indexing
+	for (unsigned j = 0; j < rowSize[i]; j++) {
+	  outfile << " (" << rowPtrs[i][j].first - 1 << "," << rowPtrs[i][j].second << ")"; // convert to 0-based indexing
+	}
+	outfile << endl;
+      }
+      if (show_gaps) {
+	outfile << "Gap posteriors 0 (0-based coords): ";
+	for (unsigned i = 1; i <= seq1Length; i++){
+	  outfile << " (" << i - 1 << "," << gapPosteriors[i] << ")";                  // convert to 0-based indexing
+	}
+	outfile << endl << "Gap posteriors 1 (0-based coords): ";
+	for (unsigned i = 1; i <= seq2Length; i++){
+	  outfile << " (" << i - 1 << "," << gapPosteriors[i + seq1Length + 1] << ")"; // convert to 0-based indexing
+	}
+	outfile << endl;
+      }
+    }
+
+    /**
+     * \brief Write output formatted for GUI.
+     *
+     * Sequence and position indices are both 0-based in output.
+     * The SparseMatrix class uses 1-based sequence indexing internally;
+     * this is converted to 0-based indexing when formatting output.
+     */
+    void write_gui_output (std::ostream& o) const {
+
+      o << "; Sparse posterior probability matrix for sequences " << xidx << " and " << yidx << endl
+	<< "; Format is:" << endl
+	<< ";   (" << xidx << ", position_1) ~ (" << yidx << ", position_2) => prob" << endl
+	<< "; which means that (" << xidx << ", position_1) is aligned to (" << yidx << ", position_2) with probability prob." << endl
+	<< ";   (" << xidx << ", position_1) ~ (" << yidx << ", -1) => prob" << endl
+	<< "; means that (" << xidx << ", position_1) is aligned to a gap in " << yidx << " with probability prob." << endl
+	<< "; sequence is 0-based and position is 0-based" << endl
+	<< endl;
+
+      o << "; match posteriors" << endl;
+      for (unsigned i = 1; i <= seq1Length; i++) {
+	// skip zero entries
+	if (rowSize[i] == 0)
+	  continue;
+	for (unsigned j = 0; j < rowSize[i]; j++) {
+	  o << "(" << xidx << ", " << i - 1 << ") ~ (" << yidx << ", " << rowPtrs[i][j].first - 1 << ") => " << rowPtrs[i][j].second << endl; // convert to 0-based indexing
+	}
+      }
+      o << endl;
+
+      o << "; gap posteriors" << endl;
+      for (unsigned i = 1; i <= seq1Length; i++)
+	o << "(" << xidx << ", " << i - 1 << ") ~ (" << yidx << ", " << "-1" << ") => " << gapPosteriors[i] << endl; // convert to 0-based indexing
+      o << endl;
+      for (unsigned j = 1; j <= seq2Length; j++)
+	o << "(" << xidx << ", " << "-1" << ") ~ (" << yidx << ", " << j - 1 << ") => " << gapPosteriors[seq1Length + j + 1] << endl; // convert to 0-based indexing
+
+      o << endl;
+    }
+
+    /**
+     * \brief Compute transpose of matrix.
+     *
+     * \return SparseMatrix which is the tranpose of the current matrix
+     */
+    SparseMatrix* ComputeTranspose() const {
+
+      // create a new sparse matrix
+      SparseMatrix* transpose = new SparseMatrix();
+      const size_t numCells = data.size();
+
+      transpose->xidx = yidx;
+      transpose->yidx = xidx;
+      transpose->seq1Length = seq2Length;
+      transpose->seq2Length = seq1Length;
+
+      // allocate memory
+      transpose->data.resize (numCells);
+      transpose->rowSize.resize (seq2Length + 1); transpose->rowSize[0] = 0;
+      transpose->rowPtrs.resize (seq2Length + 1); transpose->rowPtrs[0] = transpose->data.end();
+      transpose->gapPosteriors.resize(seq1Length + seq2Length + 2);
+
+      // compute row sizes
+      for (unsigned i = 1; i <= seq2Length; i++)
+	transpose->rowSize[i] = 0;
+      for (unsigned i = 0; i < numCells; i++)
+	transpose->rowSize[data[i].first]++;
+
+      // compute row ptrs
+      for (unsigned i = 1; i <= seq2Length; i++)
+	transpose->rowPtrs[i] = (i == 1) ? transpose->data.begin() : transpose->rowPtrs[i-1] + transpose->rowSize[i-1];
+
+      // now fill in data
+      std::vector<std::vector<Matrix_entry>::iterator> currPtrs = transpose->rowPtrs;
+
+      for (unsigned i = 1; i <= seq1Length; i++){
+	std::vector<Matrix_entry>::iterator row = rowPtrs[i];
+	for (unsigned j = 0; j < rowSize[i]; j++){
+	  currPtrs[row[j].first]->first = i;
+	  currPtrs[row[j].first]->second = row[j].second;
+	  currPtrs[row[j].first]++;
+	}
+      }
+
+      for (unsigned i = 0; i <= seq1Length; i++)
+	transpose->gapPosteriors[i + seq2Length + 1] = gapPosteriors[i];
+      for (unsigned i = 0; i <= seq2Length; i++)
+	transpose->gapPosteriors[i] = gapPosteriors[i + seq1Length + 1];
+
+      return transpose;
+    }
+
+    /**
+     * \brief Get gap probability in matrix.
+     *
+     * \param which 0 for sequence 0, 1 for sequence 1
+     * \param pos (1-based) position in sequence
+     * \return gap probability for pos
+     */
+    float get_gap_prob (const unsigned which, const unsigned pos) const {
+
+      // check no overflow of sequence lengths
+      assert ((which == 0 && pos <= seq1Length) || (which == 1 && pos <= seq2Length));
+
+      return gapPosteriors[pos + which * (seq1Length + 1)];
+    }
+
+  };
+
+}
+
+#endif /* SPARSEMATRIX_INCLUDED */
diff --git a/src/annealing/alignment_DAG.cc b/src/annealing/alignment_DAG.cc
new file mode 100644
index 0000000..dde285d
--- /dev/null
+++ b/src/annealing/alignment_DAG.cc
@@ -0,0 +1,1666 @@
+
+/**
+ * \file alignment_DAG.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Ariel Schwartz and Robert Bradley.
+ * Sudeep Juvekar wrote the iterative refinement code do_lateral_refinement.
+ * Jaeyoung Do wrote the parallelization and database code.
+ */
+
+#include <limits>
+
+#include "annealing/alignment_DAG.h"
+#include "manager/manager.h"
+
+using namespace fsa;
+
+
+// use a hash map if available; otherwise use a standard map
+#ifdef HAVE_TR1_UNORDERED_MAP
+typedef std::tr1::unordered_map<std::pair<Column*, Column*>, Edge*, column_pair_hash> Edge_table;
+#else
+typedef std::map<std::pair<Column*, Column*>, Edge*> Edge_table;
+#endif
+
+Manager*   Edge::manager = NULL;
+Manager* Column::manager = NULL;
+
+std::pair<float, float> Column::get_accuracy_normalized (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, const size_t num_seqs) const {
+
+  float p_match = 0.;
+  float p_gap = 0.;
+  float denom = 0.;    // denominator of expected accuracy calculation: number of (sum-of-pairs) characters
+  for (Seq_pos_map::const_iterator seq_pos = seq_pos_map.begin(); seq_pos != seq_pos_map.end(); seq_pos++) {
+    const size_t i = seq_pos->first;
+    const unsigned ii = seq_pos->second;
+
+    for (size_t j = 0; j < num_seqs; j++) {
+
+      if (i == j)
+	continue;
+
+      // do we have the (i,j) posterior probability matrix available?
+      // if not, go to the next matrix
+      if (sparse_matrices[i][j] == 0 && !manager->get_sparse_matrix (sparse_matrices, i, j)) 
+	continue;
+      const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+
+      // does this column contains sequence j?
+      const Seq_pos_map::const_iterator jj = seq_pos_map.find (j);
+
+      // if seq j isn't present in this column, then increment p_gap accordingly
+      if (jj == seq_pos_map.end()) {
+	p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (0, ii + 1);
+	denom += tree_weights (i, j);
+      }
+
+      // if it is, then increment p_match
+      else if (i < j) {
+	p_match += tree_weights (i, j) * ijMatrix->get_match_prob (ii + 1, jj->second + 1);
+	denom += tree_weights (i, j) * 2;
+      }
+
+    }
+  }
+
+  return std::make_pair (2 * p_match + p_gap, denom);
+}
+
+float Column::expected_score (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, size_t num_seqs) const {
+
+  float p_match = 0.;
+  float p_gap = 0.;
+  for (Seq_pos_map::const_iterator seq_pos = seq_pos_map.begin(); seq_pos != seq_pos_map.end(); seq_pos++) {
+    const size_t i = seq_pos->first;
+    const unsigned ii = seq_pos->second;
+
+    for (size_t j = 0; j < num_seqs; j++) {
+
+      if (i == j) 
+	continue;
+
+      // do we have the (i,j) posterior probability matrix available?
+      // if not, go to the next matrix
+
+      if (sparse_matrices[i][j] == 0 && !manager->get_sparse_matrix (sparse_matrices, i, j))
+	continue;
+      const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+
+      // does this column contains sequence j?
+      const Seq_pos_map::const_iterator jj = seq_pos_map.find (j);
+
+      // if seq j isn't present in this column, then increment p_gap accordingly
+      if (jj == seq_pos_map.end())
+	p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (0, ii + 1);
+
+      // if it is, then increment p_match
+      else if (i < j) {
+	p_match += tree_weights (i, j) * ijMatrix->get_match_prob (ii + 1, jj->second + 1);
+      }
+    }
+  }
+
+  return (2 * p_match + gap_factor * p_gap);
+}
+
+float Column::change_in_expected_score (const Seq_pos& seq_pos, std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, size_t num_seqs, bool skip_seq_pos /* = false */) const {
+
+  // sequence and position of the character to be aligned
+  const size_t i = seq_pos.first;
+  const unsigned ii = seq_pos.second;
+
+  // if so requested, make sure that sequence i doesn't already have a character in this column
+  if (!skip_seq_pos && contains_seq (i))
+    return INVALID_EDGE;
+
+  // if not, then calculate the change in expected accuracy associated with aligning it to this column
+  float p_match = 0.;
+  float p_gap = 0.;
+  for (size_t j = 0; j < num_seqs; j++) {
+
+    if (i == j)
+      continue;
+
+    // do we have the (i,j) posterior probability matrix available?
+    // if not, go to the next matrix
+    if (sparse_matrices[i][j] == 0  && !manager->get_sparse_matrix (sparse_matrices, i, j))
+      continue;
+    const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+
+    // does this column contains sequence j?
+    const Seq_pos_map::const_iterator jj = seq_pos_map.find (j);
+
+    // 2 cases for sequence j:
+    // if gapped, then increment p_gap
+    if (jj == seq_pos_map.end())
+      p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (0, ii + 1);
+
+    // if aligned, then increment p_match and decrement p_gap
+    else {
+      p_match += tree_weights (i, j) * ijMatrix->get_match_prob (ii + 1, jj->second + 1);
+      p_gap -= tree_weights (i, j) * ijMatrix->get_gap_prob (1, jj->second + 1);
+    }
+
+  }
+
+  return (2 * p_match + gap_factor * p_gap);
+}
+
+bool Edge::update_weight_tgf (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, bool update_weight /* = true */) {
+
+  // NB: It's crucial that at this point the Edge be between
+  // the current (after merges) source and dest columns;
+  // this must be assured by the calling function.
+
+  float p_match = 0.;
+  float p_gap = 0.;
+
+  // for all pairs of positions (i, ii) ~ (j, jj) in each column which will be aligned after the merge
+  const Seq_pos_map& source_seq_pos_map = source->get_seq_pos_map();
+  const Seq_pos_map& dest_seq_pos_map = dest->get_seq_pos_map();
+
+  // loop over seqs i,j and associated seq positions ii,jj in columns joined by edge
+  for (Seq_pos_map::const_iterator source_seq_pos = source_seq_pos_map.begin(); source_seq_pos != source_seq_pos_map.end(); ++source_seq_pos) {
+    const size_t i = source_seq_pos->first;       // sequence i
+    const unsigned ii = source_seq_pos->second;   // position ii
+
+    for (Seq_pos_map::const_iterator dest_seq_pos = dest_seq_pos_map.begin(); dest_seq_pos != dest_seq_pos_map.end(); ++dest_seq_pos) {
+      const size_t j = dest_seq_pos->first;       // sequence j
+      const unsigned jj = dest_seq_pos->second;   // position jj
+
+      // simplest consistency check
+      if (i == j)
+	return true;
+
+      // do we have the (i,j) posterior probability matrix available?
+      // if not, go to the next matrix
+      if (sparse_matrices[i][j] == 0 && !manager->get_sparse_matrix (sparse_matrices, i, j))
+	continue;
+      const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+
+      p_match += tree_weights (i, j) * ijMatrix->get_match_prob (ii + 1, jj + 1);
+      p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (0, ii + 1); // so p_gap gets incremented as:
+      p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (1, jj + 1); // for each (seq,position) pair (i,ii) and (j,jj), 
+      //  add P(position ii in seq i is gapped) and P(position jj in seq j is gapped)
+
+      // Here's a long-winded explanation of p_match and p_gap:
+      // Consider merging column 1 with n non-gap characters and column 2 with m non-gap characters.
+      // P_match should have (n + m choose 2) terms, 
+      // one for each pair of aligned characters in the newly-created column.  
+      // P_gap should have 2 * (n + m choose 2) terms, 
+      // two for each pair of aligned characters in the newly-created column.
+      // Because P_gap is actually incremented at each merging operation rather than being calculated anew, 
+      // the incremental increase in P_gap after a merge operation has (n * m + m * n) = (2 * n * m terms).
+
+    }
+  }
+
+  // update weight if requested
+  if (update_weight) {
+    if (CTAGGING(3,ANNEALING_VERBOSE)) {
+      CL << " updated weight: " << weight << " (p_match = " << p_match << "; p_gap = " << p_gap << ") -> " << 2 * p_match / p_gap << endl;
+    }
+
+    // update weight of edge:
+    // calculated like eq (4) in the AMAP paper,
+    // but gap factor scaled s.t. value of 1 (instead of 1/2) gives accuracy
+    weight = 2 * p_match / p_gap;
+
+  }
+
+  // keep track of the size of the nodes
+  // (for tracking whether the re-weighting needs to be redone
+  // after edge re-insertion onto heap)
+  weight_size = source->size() + dest->size();
+
+  return false;
+}
+
+bool Edge::update_weight_maxstep (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, bool update_weight /* = true */) {
+
+  // NB: It's crucial that at this point the Edge be between
+  // the current (after merges) source and dest columns;
+  // this must be assured by the calling function.
+
+  float p_match = 0.;
+  float p_gap = 0.;
+
+  // for all pairs of positions (i, ii) ~ (j, jj) in each column which will be aligned after the merge
+  const Seq_pos_map& source_seq_pos_map = source->get_seq_pos_map();
+  const Seq_pos_map& dest_seq_pos_map = dest->get_seq_pos_map();
+
+  // for all pairs of positions (i, ii) ~ (j, jj) in each column which will be aligned after the merge
+  for (Seq_pos_map::const_iterator source_seq_pos = source_seq_pos_map.begin(); source_seq_pos != source_seq_pos_map.end(); ++source_seq_pos) {
+    const size_t i = source_seq_pos->first;
+    const unsigned ii = source_seq_pos->second;
+
+    for (Seq_pos_map::const_iterator dest_seq_pos = dest_seq_pos_map.begin(); dest_seq_pos != dest_seq_pos_map.end(); ++dest_seq_pos) {
+      const size_t j = dest_seq_pos->first;
+      const unsigned jj = dest_seq_pos->second;
+
+      // simplest consistency check
+      if (i == j)
+	return true;
+
+      // do we have the (i,j) posterior probability matrix available?
+      // if not, go to the next matrix
+      if (sparse_matrices[i][j] == 0 && !manager->get_sparse_matrix (sparse_matrices, i, j))
+	continue;
+      const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+
+      p_match += tree_weights (i, j) * ijMatrix->get_match_prob (ii + 1, jj + 1);
+      p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (0, ii + 1);
+      p_gap += tree_weights (i, j) * ijMatrix->get_gap_prob (1, jj + 1);
+
+    }
+  }
+
+  // update weight if requested
+  if (update_weight) {
+    if (CTAGGING(3,ANNEALING_VERBOSE)) {
+      CL << " updated weight: " << weight << " (p_match = " << p_match << "; p_gap = " << p_gap << ") -> " << (2 * p_match - gap_factor * p_gap) << endl;
+    }
+
+    // update weight of edge
+    weight = (2 * p_match - gap_factor * p_gap) / (source_seq_pos_map.size() * dest_seq_pos_map.size());
+
+  }
+
+  // keep track of the size of the nodes
+  // (for tracking whether the re-weighting needs to be redone
+  // after edge re-insertion onto heap)
+  weight_size = source->size() + dest->size();
+
+  return false;
+
+}
+
+Alignment_DAG::Alignment_DAG (const Sequence_database& seq_db)
+  : seq_db (seq_db),
+    num_seqs (seq_db.size()), num_columns (0) {
+
+  // get maximum sequence length
+  size_t maxlen = 0;
+  for (size_t seq = 0; seq < seq_db.size(); ++seq) {
+    const Sequence& sequence = seq_db.get_seq (seq);
+    maxlen = std::max (maxlen, sequence.length());
+  }
+
+  // initialize seq_pos_col_maps for sequences
+  // use 0-based indexing
+  seq_pos_col_maps.resize (num_seqs);
+  for (size_t r = 0; r < num_seqs; ++r)
+    seq_pos_col_maps[r].resize (seq_db.get_seq (r).length(), NULL);
+
+  // store sequence data
+  num_columns = 0;
+  for (unsigned pos = 0; pos < maxlen; ++pos) {        // position within the sequences
+    for (size_t seq = 0; seq < num_seqs; ++seq) {
+
+      // are we done with this sequence?
+      const Sequence& sequence = seq_db.get_seq (seq);
+      if (pos >= sequence.length())
+	continue;
+
+      // store character
+      columns.push_back (new Column (num_columns++));  // 0-based indexing for Column::index
+      const Seq_pos seq_pos (seq, pos);
+      (*(--columns.end()))->add_seq_pos (seq_pos);
+      set_seq_pos_col (seq_pos, *(--columns.end()));
+    }
+  }
+
+}
+
+Alignment_DAG::Alignment_DAG (const Sequence_database& seq_db, const Stockholm& stock)
+  : seq_db (seq_db),
+    num_seqs (seq_db.size()), num_columns (stock.columns()) {
+
+  // initialize seq_pos_col_maps for sequences
+  // use 0-based indexing
+  seq_pos_col_maps.resize (num_seqs);
+  for (size_t seq = 0; seq < num_seqs; ++seq)
+    seq_pos_col_maps[seq].resize (seq_db.get_seq (seq).length(), NULL);
+
+  // create columns
+  for (size_t c = 0; c < num_columns; ++c)
+    columns.push_back (new Column (c));  // 0-based indexing for Column::index
+
+  // store sequence data
+  for (size_t seq = 0; seq < num_seqs; ++seq) {
+
+    // reset position within current sequence
+    unsigned pos = 0;
+
+    // iterate over columns, storing (seq, pos) information as we go
+    for (std::vector<Column*>::iterator col = columns.begin(); col != columns.end(); ++col) {
+
+      // if seq has a character in column col
+      if (!stock.is_gapped (seq, (*col)->get_index())) {
+	const Seq_pos seq_pos (seq, pos++);
+	(*col)->add_seq_pos (seq_pos);
+	set_seq_pos_col (seq_pos, *col);
+      }
+
+      // else seq must be gapped in column col, so store nothing
+
+    }
+
+  }
+
+  // drop all-gaps columns (if they were present in the input Stockholm alignment)
+  drop_all_gaps_columns();
+
+}
+
+Alignment_DAG::~Alignment_DAG() {
+
+  // columns
+  for (std::vector<Column*>::iterator col = columns.begin(); col != columns.end(); ++col)
+    (*col)->set_merged_into (NULL);
+  for (std::vector<Column*>::iterator col = columns.begin(); col != columns.end(); ++col) {
+    Column* colPtr = *col;
+    *col = NULL;
+    delete colPtr;
+  }
+  columns.clear();
+
+  Edge::manager   = NULL;
+  Column::manager = NULL;
+
+}
+
+void Alignment_DAG::drop_all_gaps_columns() {
+
+  // drop all-gaps columns
+  std::vector<Column*> sans_allgaps;
+  size_t idx = 0;
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+    if ((*col)->size()) {
+      (*col)->set_index (idx++);
+      sans_allgaps.push_back (*col);
+    }
+  }
+
+  columns.assign (sans_allgaps.begin(), sans_allgaps.end());
+  num_columns = columns.size();
+
+}
+
+void Alignment_DAG::dfs_topological_sort() {
+
+  CTAG(7,ANNEALING ANNEALING_VERBOSE DAG) << "Finding the most-parsimonious indel structure." << endl;
+
+  // unmark all nodes
+  unmark (columns);
+
+  // initialize stack of nodes by pushing on columns holding the first characters of all sequences
+  std::stack<Column*> nodes;
+  std::vector<bool> on_stack (columns.size(), false);
+  std::vector<int> finishing_times (columns.size(), -1);
+  std::vector<Column*> starting_cols;
+  for (size_t s = 0; s < num_seqs; ++s) {
+    if (seq_db.get_seq (s).length() == 0)            // handle case of 0-length sequences
+      continue;
+    Column* node = get_seq_pos_col (Seq_pos (s, 0)); // remember 0-based indexing
+    assert (!node->is_dead());
+    if (!on_stack[node->get_index()]) {
+      starting_cols.push_back (node);
+      on_stack[node->get_index()] = true;
+    }
+  }
+  // now sort these starting columns (MUST preserve the partial order!)
+  std::sort (starting_cols.begin(), starting_cols.end(), smaller_index());
+  for (std::vector<Column*>::iterator col = starting_cols.begin(); col != starting_cols.end(); ++col)
+    nodes.push (*col);
+
+  // perform a postorder traversal to get finishing times for columns
+  unsigned time = 0;
+  while (!nodes.empty()) {
+
+    // get next node on stack
+    Column* node = nodes.top();
+    nodes.pop();
+    assert (!node->is_dead());
+
+    // if the node which we've just popped is marked, then we're finished with it
+    if (node->is_marked()) {
+      finishing_times[node->get_index()] = time++;
+      continue;
+    }
+
+    // else mark the node and push it on the stack
+    node->mark();
+    nodes.push (node);
+
+    // continue DFS: explore node's neighbors
+    std::vector<Column*> neighbors;
+    const Seq_pos_map& seq_pos_map = node->get_seq_pos_map();
+    for (Seq_pos_map::const_iterator seq_pos_iter = seq_pos_map.begin(); seq_pos_iter != seq_pos_map.end(); ++seq_pos_iter) {
+
+      // get the next position in this sequence
+      const Seq_pos next_seq_pos = Seq_pos (seq_pos_iter->first, seq_pos_iter->second + 1);
+
+      // have we reached the end of this sequence?
+      if (next_seq_pos.second >= seq_db.get_seq (next_seq_pos.first).length())
+	continue;
+
+      // if not, then continue DFS on neighbors
+      Column* w = get_seq_pos_col (next_seq_pos);
+
+      // store the neighbors (if they're not already on the stack)
+      if (!on_stack[w->get_index()]) {
+	neighbors.push_back (w);
+	on_stack[w->get_index()] = true;
+      }
+
+    }
+
+    // now a *critical* step: use the current total order
+    // to impose the correct partial order on the neighboring nodes
+    // (otherwise we won't be doing a postorder traversal => things will break mysteriously)
+    std::sort (neighbors.begin(), neighbors.end(), smaller_index()); // not doing this will MESS EVERYTHING UP!!
+
+    // then store
+    for (std::vector<Column*>::iterator column = neighbors.begin(); column != neighbors.end(); ++column)
+      nodes.push (*column);
+
+  } // end DFS loop
+
+  // construct list of live columns for sorting
+  std::vector<Column*> columns_tmp;
+  for (std::vector<Column*>::iterator column = columns.begin(); column != columns.end(); ++column) {
+    if (!(*column)->is_dead()) {
+      columns_tmp.push_back (*column);
+      assert (finishing_times[(*column)->get_index()] >= 0);        // assert node finished in postorder traversal
+      (*column)->set_index (finishing_times[(*column)->get_index()]); // store finishing times as indices
+    }
+  }
+  assert (num_columns == columns_tmp.size());
+
+  // now (reverse) sort according to finishing times
+  std::sort (columns_tmp.begin(), columns_tmp.end(), greater_index());
+
+  // store and make column indices sane as we go
+  columns.clear();
+  for (size_t idx = 0; idx < columns_tmp.size(); ++idx) {
+    columns.push_back (columns_tmp[idx]);
+    columns[idx]->set_index (idx);
+  }
+
+}
+
+Stockholm Alignment_DAG::get_stockholm() const {
+
+  // store alignment as matrix of booleans,
+  // with each row representing the alignment for a particular sequence
+  // (see Alignment_row::Row_path)
+  std::vector<Alignment_row::Row_path*> align_matrix (num_seqs, NULL);
+  for (std::vector<Alignment_row::Row_path*>::iterator row_path = align_matrix.begin(); row_path != align_matrix.end(); ++row_path)
+    *row_path = new Alignment_row::Row_path (num_columns, false);
+
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+
+    // skip dead columns
+    if ((*col)->is_dead())
+      continue;
+
+    for (size_t seq = 0; seq < num_seqs; seq++) {
+      if ((*col)->contains_seq (seq))
+	(*align_matrix[seq])[(*col)->get_index()] = true;
+    }
+
+  }
+
+  // now add the sequence data
+  Stockholm stock (const_cast<Sequence_database&> (seq_db)); // hacky cast away const
+  for (size_t r = 0; r < num_seqs; ++r)
+    stock.set_row (seq_db.get_seq (r).name, align_matrix[r]);
+
+  stock.assert_flush();
+
+  return stock;
+}
+
+Stockholm Alignment_DAG::get_stockholm (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights) const {
+
+  // get the base alignment
+  Stockholm stock = get_stockholm();
+
+  // clear out the unnormalized accuracy annotations and 
+  // store the properly normalized ones
+  stock.clear_annot();
+  std::pair<float, std::string> accuracy_pair = get_accuracy_annotation_normalized (sparse_matrices, tree_weights);
+  std::string acc = Util::to_string (accuracy_pair.first);
+  stock.add_gf_annot (ACCURACY_ANNOT, acc);
+  stock.set_gc_annot (ACCURACY_ANNOT, accuracy_pair.second);
+
+  stock.assert_flush();
+
+  return stock;
+}
+
+void Alignment_DAG::anneal (std::vector<std::vector<SparseMatrix*> >& sparse_matrices,
+			    Manager& manager,
+			    const bool use_tgf,
+			    const float gap_factor, const bool enable_dynamic_weights, const float edge_weight_threshold,
+			    const size_t num_refinement_steps,
+			    const bool output_for_gui, const std::string gui_prefix) {
+
+  // initialize dummy Tree_weights (returns all weights as 1.0)
+  Tree_weights tree_weights;
+  anneal (sparse_matrices, tree_weights,
+	  manager,
+	  use_tgf,
+	  gap_factor, enable_dynamic_weights, edge_weight_threshold,
+	  num_refinement_steps,
+	  output_for_gui, gui_prefix);
+
+}
+
+void Alignment_DAG::anneal (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights,
+			    Manager& manager,
+			    const bool use_tgf,
+			    const float gap_factor, const bool enable_dynamic_weights, const float edge_weight_threshold,
+			    const size_t num_refinement_steps,
+			    const bool output_for_gui, const std::string gui_prefix) {
+
+  // set db manager to Column class and Edge class
+  Edge::manager   = &manager;
+  Column::manager = &manager;
+
+  // log
+  CTAG(6,ANNEALING DAG ANNEALING_VERBOSE) << "Creating candidate edge list." << endl;
+
+  // pre-count the number of sequence pairs which we have SparseMatrix entries for
+  // as well as the maximum possible number of edges
+  size_t seq_pairs = 0;
+  size_t num_max_edges = 0;
+  for (size_t i = 0; i < num_seqs; ++i)
+    for (size_t j = i + 1; j < num_seqs; ++j) {
+      if ((sparse_matrices[i][j] != 0) || (sparse_matrices[j][i] != 0 || manager.is_sparse_matrix_available (i, j))) {
+	++seq_pairs;
+	num_max_edges += std::min (seq_db.get_seq (i).length(), seq_db.get_seq (j).length());
+      }
+    }
+
+  // gui output
+  const std::string gui_filename = gui_prefix + GUI_FILENAME_DAG_SUFFIX;
+  std::ofstream gui_file;
+  // show initial DAG
+  if (output_for_gui) {
+    gui_file.open (gui_filename.c_str());
+    if (!gui_file.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << gui_filename << "'.");
+    write_gui_output (gui_file);
+    gui_file << "; Merges (added edges)" << endl
+	     << "; Format is:" << endl
+	     << ";   source_column -> dest_column => accuracy_change" << endl
+	     << "; (new accuracy is source_column_accuracy + dest_column_accuracy + accuracy_change)" << endl
+	     << "; (note that all accuracies are unnormalized)" << endl
+	     << endl;
+  }
+
+  // gui output: post prob matrices
+  if (output_for_gui) {
+    const std::string prob_filename = gui_prefix + GUI_FILENAME_PROB_SUFFIX;
+    std::ofstream prob_file;
+    prob_file.open (prob_filename.c_str());
+    if (!prob_file.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << prob_filename << "'.");
+    for (size_t i = 0; i < num_seqs; ++i)
+      for (size_t j = i + 1; j < num_seqs; ++j) {
+	if (sparse_matrices[i][j] != 0)
+	  sparse_matrices[i][j]->write_gui_output (prob_file);
+	else if (sparse_matrices[j][i] != 0)
+	  sparse_matrices[j][i]->write_gui_output (prob_file);
+	else if (manager.get_sparse_matrix (sparse_matrices, i, j))
+	  sparse_matrices[i][j]->write_gui_output (prob_file);
+
+      }
+    prob_file.close();
+    CTAG(9,ANNEALING ANNEALING_VERBOSE) << "Created GUI output file '" << prob_filename << "'." << endl;
+  }
+
+  // create priority queue of candidate edges
+  std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> edges;
+
+  // if relevant, get edges from database
+  if (manager.is_edges_available()) {
+
+#if defined(HAVE_CONDOR) || defined(HAVE_POSTGRES)
+
+    // log
+    CTAG(8,ANNEALING DAG ANNEALING_VERBOSE) << "Getting candidate edges from database." << endl;
+    manager.get_edges (edges, seq_pos_col_maps);	
+    // log
+    CTAG(8,ANNEALING DAG ANNEALING_VERBOSE) << "Got all candidate edges." << endl;
+
+#endif
+
+  }
+
+  else {
+    // loop through upper-triangle of sequences:
+    //  calculate weights (maxstep or tgf) for each potential edge;
+    //  store edges whose weights meet edge_weight_threshold and
+    //  have a weight >= the gap_factor (if using tgf)
+    CTAG(9,ANNEALING DAG ANNEALING_VERBOSEs) << "Assembling list of candidate edges." << endl;
+    size_t seq_pairs_processed = 0;
+
+    for (size_t i = 0; i < num_seqs; ++i) {
+      const size_t xlen = seq_db.get_seq (i).length();
+
+      for (size_t j = i + 1; j < num_seqs; ++j) {
+
+	const SparseMatrix* ijMatrix = sparse_matrices[i][j];
+	// do we have the (i,j) posterior probability matrix available?
+	// if not, go to the next matrix
+	if (ijMatrix == 0)
+	  continue;
+
+	// for all entries in the SparseMatrix, calculate the corresponding weight
+	// and store the edge
+	for (unsigned ii = 0; ii < xlen; ii++) { // note 0-based indexing for sequences
+	  const float p_gap_ii = ijMatrix->get_gap_prob (0, ii + 1);
+
+	  for (std::vector<Matrix_entry>::iterator rowPtr = ijMatrix->GetRowPtr (ii + 1),
+		 rowEnd = rowPtr + ijMatrix->GetRowSize (ii + 1); rowPtr != rowEnd; rowPtr++) {
+	    const unsigned jj = rowPtr->first - 1; // convert from SparseMatrix's 1-based coords to the 0-based coords which we use here
+
+	    const float p_match = tree_weights (i, j) * rowPtr->second;
+	    if (!p_match)
+	      continue;
+	    const float p_gap = tree_weights (i, j) * (p_gap_ii + ijMatrix->get_gap_prob (1, jj + 1));
+	    const float weight = use_tgf ? (2 * p_match / p_gap) : (2 * p_match - gap_factor * p_gap);
+
+	    // if the edge already scores too low to ever be accepted, then skip it
+	    if ((weight < edge_weight_threshold) || (use_tgf && weight < gap_factor))
+	      continue;
+
+	    // else create and store it
+	    // magic number 2 = 1 + 1 = size of columns
+
+	    Edge* edge = new Edge (get_seq_pos_col (Seq_pos (i, ii)), get_seq_pos_col (Seq_pos (j, jj)),
+				   weight, 2);
+	    edges.push (edge);
+
+	    if (CTAGGING(-1,ANNEALING_VERBOSE)) {
+	      CL << "Stored candidate edge: " << *edge << "." << endl;
+	      CL << "  p_match = " << p_match << "; p_gap = " << p_gap << endl;
+	    }
+	  }
+	}
+
+	// log progress
+	++seq_pairs_processed;
+	const unsigned percent_done = static_cast<unsigned> (std::floor ((100.0 * seq_pairs_processed / seq_pairs) + 0.5));
+	if (CTAGGING(7,ANNEALING DAG ANNEALING_VERBOSE) && (seq_pairs_processed % 100 == 0)) {
+	  CTAG(7,ANNEALING DAG ANNEALING_VERBOSE) << "Stored candidate edges from " << seq_pairs_processed << "/" << seq_pairs << " sequence pairs (" << percent_done << "% done)." << endl;
+	}
+
+      }
+    }
+
+  }
+
+  // assert a greedy algorithm
+  //#ifndef NDEBUG  
+  //  float prev_weight = std::numeric_limits<float>::max();
+  //#endif
+  // see comment near endif directive
+
+  // keep track of candidate edges:
+  // - edges which were previously re-inserted in the heap
+  //   (in order to prevent unnecessary re-weighting of duplicate edges)
+  // - edges which were found to be inconsistent
+  //   (for these, store a NULL value)
+  Edge_table edge_table;
+
+  // anneal:
+  // loop through the priority queue of edges,
+  // greedily adding edges based on their (updated) weights
+  CTAG(9,ANNEALING DAG ANNEALING_VERBOSE) << "Annealing by adding edges to the DAG." << endl;
+
+  size_t edges_annealed = 0; // for logging progress
+  const size_t num_orig_edges = manager.get_edges_size (edges);
+  size_t sequential_skips = 0; // number of sequential edges skipped because they created a cycle
+  while (!edges.empty()) {
+
+    // get candidate edge
+    Edge *edge = manager.get_next_top_edge (edges, seq_pos_col_maps);
+
+    // log
+    if (CTAGGING(3,ANNEALING_VERBOSE)) {
+      CL << "Popped edge: " << *edge << endl;
+    }
+
+    // lookup current columns for edge:
+    // note that this can be linear in the number of merges,
+    // although this shouldn't be too bad for common alignments
+    while (edge->source != edge->source->get_merged_into())
+      edge->source = edge->source->get_merged_into();
+    while (edge->dest != edge->dest->get_merged_into())
+      edge->dest = edge->dest->get_merged_into();
+
+    // fast check for redundant edges
+    // (edges specifying columns which have already been constructed)
+    // (wrapped in braces to prevent compiler complaints about
+    // 'jump to label skipping initialization of variables' blah blah blah...)
+    {
+      if (edge->source == edge->dest) {
+	if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	  CL << "Inconsistent (redundant) edge: " << *edge << endl;
+	}
+	goto DELETE_EDGE;
+      }
+    }
+
+    // now DFS for full-blown consistency-checking
+    // this is also where the actual Pearce-Kelly takes place
+    // (assuming the edge is consistent)
+    {
+
+      // check whether this is a duplicate edge:
+      // do we already have an edge corresponding to merging these columns
+      // in our table of candidate edges edge_table?
+      Edge_table::iterator edge_in_table_iter = edge_table.find (std::make_pair (edge->source, edge->dest));
+
+      // use symmetry: edge can be in either direction
+      if (edge_in_table_iter == edge_table.end())
+	edge_in_table_iter = edge_table.find (std::make_pair (edge->dest, edge->source));
+
+      // have we seen the current edge previously?
+      bool in_table = false;
+      Edge* edge_in_table = NULL;
+      if (edge_in_table_iter != edge_table.end()) {
+	in_table = true;
+	edge_in_table = edge_in_table_iter->second;
+      }
+
+      // is this a previously-seen inconsistent edge?
+      if (in_table && (edge_in_table == 0)) { // test for NULL
+	if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	  CL << "Inconsistent (previously-seen) edge: " << *edge << endl;
+	}
+	goto DELETE_EDGE;
+      }
+
+      // is this a duplicate edge?
+      // if we already have a different edge corresponding to this merge
+      // (with an updated, "current" weight),
+      // then this is a duplicate edge, so get rid of it
+      // (it conveys no new information)
+      if (in_table && (edge_in_table != edge)) {
+	assert (edge_in_table_iter != edge_table.end());
+	assert (edge_in_table != 0);
+
+	// if the weight is current, meaning that the columns
+	// joined by the edges have not been affected by other merges
+	// since the weight was last calculated, then the weight
+	// for edge_in_table is correct and we can just delete
+	// the current edge
+	if (!edge_in_table->weight_outdated()) {
+	  if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	    CL << "Ignoring edge: " << *edge << " (" << edge << " != " << edge_in_table << ")" << endl;
+	  }
+	  goto DELETE_EDGE;
+	}
+
+	// if the weight isn't current, meaning that the columns
+	// joined by the edges have been affected by other merges
+	// since the weight was last calculated, then we need to re-weight it
+	// in order to ensure that we maintain greediness
+	// (otherwise it won't be a steepest ascent algorithm)
+	// use a quasi-hack to accomplish this:
+	// replace the stored edge with the current one;
+	else {
+	  edge_table.erase (edge_in_table_iter);
+	  edge_in_table_iter = (edge_table.insert (std::make_pair (std::make_pair (edge->source, edge->dest), edge))).first; // get new iterator
+	  if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	    CL << "Erased and re-inserted edge to force re-weighting." << endl;
+	  }
+	}
+
+      }
+
+      // recalculate edge weight if using dynamic edge weights
+      // as a byproduct, calculate the change in expected accuracy from adding the edge
+      if (edge->weight_outdated() && enable_dynamic_weights) {
+
+	// the second argument enable_dynamic_weights is now obsolete;
+	// originally the update_weight_{tgf,maxstep} functions were used
+	// to calculate changes to the expected accuracy after each merge,
+	// but this functionality is retired for speed when 
+	// dynamic weighting is disabled
+	bool conflict = false;
+	if (use_tgf) {
+	  conflict = (edge->update_weight_tgf) (sparse_matrices, tree_weights, enable_dynamic_weights);
+	}
+	else {
+	  conflict = (edge->update_weight_maxstep) (sparse_matrices, tree_weights, gap_factor, enable_dynamic_weights);
+	}
+
+	// if an inconsistency detected, record it and delete edge
+	if (conflict) {
+
+	  // log
+	  if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	    CL << "Inconsistent edge: " << *edge << endl;
+	  }
+
+	  // if present, mark record as inconsistent
+	  if (in_table)
+	    edge_in_table_iter->second = (Edge*) NULL;
+	  // else record it as inconsistent
+	  else
+	    edge_table.insert (std::make_pair (std::make_pair (edge->source, edge->dest), (Edge*) NULL));
+
+	  goto DELETE_EDGE;
+	}
+
+	// if priority queue sorting is wrong, then push and go to the next
+	if (edge->weight < edges.top()->weight) {
+
+	  // if this is the first time we've seen this edge, record it
+	  if (!in_table) {
+	    if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	      CL << "Recorded new edge: " << *edge << endl;
+	    }
+	    edge_table.insert (std::make_pair (std::make_pair (edge->source, edge->dest), edge));
+	  }
+
+	  // log
+	  if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	    CL << "Re-inserted edge: " << *edge << endl;
+	  }
+
+	  // push back on heap
+	  manager.push_edge (edges, edge);
+	  
+	  continue;
+	}
+
+      } // 	if (edge->weight_outdated() && enable_dynamic_weights)
+
+      // if best edge has weight < edge_weight_threshold or has
+      // a weight < gap_factor (if using tgf), then we're done with sequence annealing
+      // only relevant for dynamic weights;
+      // edges whose initial weights don't satisfy these criteria are never
+      // stored on the heap as candidate edges
+      if (enable_dynamic_weights
+	  && ((edge->weight < edge_weight_threshold) || (use_tgf && (edge->weight < gap_factor)))) {
+	while (!edges.empty()) {
+	  edge = edges.top();
+	  edges.pop();
+	  delete edge;
+	}
+	break;
+      }
+
+      // now actually perform the consistency check and Pearce-Kelly
+
+      // NB: Do NOT NOT NOT forget to unmark nodes after visiting!
+      // Crucial and easy to forget.
+      std::vector<Column*> R_forward;
+
+      // get the lower and upper bounds of the depth-first searches
+      // (we have already imposed a total order on columns)
+      Column *l_bound, *u_bound;
+      if (*(edge->source) < *(edge->dest)) {
+	l_bound = edge->source;
+	u_bound = edge->dest;
+      } else {
+	l_bound = edge->dest;
+	u_bound = edge->source;
+      }
+
+      // if edge is inconsistent (induces cycle)
+      if (induces_cycle (edge, l_bound, u_bound, R_forward)) {
+
+	// log
+	if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	  CL << "Inconsistent edge: " << *edge << endl;
+	}
+
+	// erase record if present
+	if (in_table)
+	  edge_in_table_iter->second = (Edge*) NULL;
+	// else record it as inconsistent
+	else
+	  edge_table.insert (std::make_pair (std::make_pair (edge->source, edge->dest), (Edge*) NULL));
+
+	goto DELETE_EDGE;
+      }
+
+      // if edge is consistent (doesn't induce cycle)
+      else {
+
+	// add edge with the Pearce-Kelly algorithm
+	add_edge (edge, l_bound, u_bound, R_forward);
+
+	// log
+	if (CTAGGING(4,ANNEALING DAG ANNEALING_VERBOSE)) {
+	  CL << "Added edge: " << *edge << endl;
+	}
+
+	// we've added the edge, so remove the record
+	if (in_table) {
+	  edge_table.erase (edge_in_table_iter);
+	  if (CTAGGING(3,ANNEALING_VERBOSE)) {
+	    CL << "Erased added edge: " << *edge_in_table << endl;
+	  }
+	}
+
+#ifndef NDEBUG
+	//	if (use_tgf)
+	//	  assert (edge->weight - prev_weight < DOUBLE_TINY);
+	//	prev_weight = edge->weight;
+	// comment in to check that sequence annealing is truly steepest ascent
+	// note that this check can fail due to floating-point error if the weights are large (ie the max 10000)
+	//  -- RKB 10/21/08
+#endif
+
+	++edges_annealed;     // increment counter
+	sequential_skips = 0; // reset counter
+
+	//log
+	if (CTAGGING(-1,DAG)) {
+	  CL << "DAG after annealing " << edges_annealed << "/" << num_orig_edges << " candidate edges." << endl;
+	  this->show (CL, true);
+	}
+
+	// write gui output if requested
+	if (output_for_gui) {
+	  edge->write_gui_output (gui_file);
+	}
+
+      } // end if edge doesn't induce cycle
+
+    } // end block for DFS
+
+
+
+    // clean up: delete edge and log progress
+    // goto is ugly but appropriate here...
+  DELETE_EDGE:
+
+    delete edge;
+
+    // check whether we've skipped more than 10 * (maximum possible number of remaining edges to anneal) edges;
+    // if so, then stop annealing
+    if (sequential_skips >= 10 * (num_max_edges - edges_annealed)) {
+      CTAG(7,ANNEALING ANNEALING_VERBOSE) << "Skipped more than 10 * (maximum possible number of remaining edges to anneal) sequential edges; breaking." << endl;
+      while (!edges.empty()) {
+	edge = edges.top();
+	edges.pop();
+	delete edge;
+      }
+      break;
+    }
+
+    const size_t edges_size = manager.get_edges_size (edges);
+
+    // log progress
+    if (CTAGGING(7,ANNEALING ANNEALING_VERBOSE) && (((edges_annealed % 10000) == 0) || (((num_orig_edges - edges_size) % 10000) == 0))) {
+      const unsigned percent_done = static_cast<unsigned> (std::floor ((100.0 * edges_annealed / num_orig_edges) + 0.5));
+      const unsigned percent_remaining = static_cast<unsigned> (std::floor ((100.0 * edges_size / num_orig_edges) + 0.5));
+      CTAG(7,ANNEALING ANNEALING_VERBOSE) << "Annealed " << edges_annealed << "/" << num_orig_edges << " (" << percent_done << "%) candidate edges;"
+					  << " " << edges_size << "/" << num_orig_edges << " (" << percent_remaining << "%) remaining candidate edges to process." << endl;
+    }
+
+  } // while (!edges.empty())
+
+  // we're done with annealing!
+  CTAG(8,ANNEALING DAG ANNEALING_VERBOSE) << "Finished adding edges to the DAG." << endl;
+
+  // perform iterative refinement if requested
+  // use "lateral shift"
+  if (num_refinement_steps > 0) {
+
+    CTAG(9,ANNEALING REFINEMENT) << "Beginning iterative refinement." << endl;
+
+    // do hill-climbing refinement
+    float curr_score = expected_score (sparse_matrices, tree_weights, gap_factor);
+    size_t step = 0;
+    for (step = 0; step < num_refinement_steps; ++step) {
+
+      // refine
+      do_lateral_refinement (sparse_matrices, tree_weights, gap_factor);
+
+      // log
+      if (CTAGGING(8,ANNEALING REFINEMENT) && ((step % 5) == 0)) {
+	CTAG(8,ANNEALING REFINEMENT) << "Completed " << step + 1 << " iterative refinement steps." << endl;
+      }
+
+      // did we improve?
+      // if not, then stop iterative refinement
+      const float score = expected_score (sparse_matrices, tree_weights, gap_factor);
+      if (score > curr_score)
+	curr_score = score;
+      else {
+	if (score + DOUBLE_TINY < curr_score) // warn if score has decreased (shouldn't be able to!)
+	  CTAG(8,ANNEALING REFINEMENT) << "WARNING: Expected score dropped from " << curr_score << " to " << score << " during iterative refinement!" << endl;
+	break;
+      }
+
+    }
+
+    // log (if didn't just do so)
+    if (CTAGGING(8,ANNEALING REFINEMENT) && ((step % 5) != 0)) {
+      CTAG(8,ANNEALING REFINEMENT) << "Finished iterative refinement (" << step + 1 << " steps)." << endl;
+    }
+
+  }
+
+  // close gui file
+  if (output_for_gui) {
+    gui_file.close();
+    CTAG(9,ANNEALING) << "Created GUI output file '" << gui_filename << "'." << endl;
+  }
+
+}
+
+void Alignment_DAG::show (std::ostream& o, const bool aligned_only /* = false */) const {
+
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+
+    if ((*col)->is_dead())
+      continue;
+    if (aligned_only && ((*col)->get_seq_pos_map().size() < 2))
+      continue;
+
+    // show the column and its forward and back edges
+    o << **col << endl;
+
+    // incoming cols
+    const Seq_pos_map& seq_pos_map = (*col)->get_seq_pos_map();
+    for (Seq_pos_map::const_iterator seq_pos_iter = seq_pos_map.begin(); seq_pos_iter != seq_pos_map.end(); ++seq_pos_iter) {
+
+      // have we reached the beginning of this sequence?
+      // (remember that sequence coordinates are 0-based)
+      if (seq_pos_iter->second == 0)
+	continue;
+
+      // get the previous position in this sequence
+      const Seq_pos prev_seq_pos = Seq_pos (seq_pos_iter->first, seq_pos_iter->second - 1);
+
+      // show this column
+      const Column* w = get_seq_pos_col (prev_seq_pos);
+      o << " <- " << *w << endl;
+
+    }
+
+    // check outgoing cols
+    for (Seq_pos_map::const_iterator seq_pos_iter = seq_pos_map.begin(); seq_pos_iter != seq_pos_map.end(); ++seq_pos_iter) {
+
+      // get the next position in this sequence
+      const Seq_pos next_seq_pos = Seq_pos (seq_pos_iter->first, seq_pos_iter->second + 1);
+
+      // have we reached the end of this sequence?
+      if (next_seq_pos.second >= seq_db.get_seq (next_seq_pos.first).length())
+	continue;
+
+      // show this column
+      const Column* w = get_seq_pos_col (next_seq_pos);
+      o << " -> " << *w << endl;
+
+    }
+
+  }
+
+}
+
+void Alignment_DAG::write_gui_output (std::ostream& o, bool show_edges /* = false */) const {
+
+  o << "; Initial DAG" << endl
+    << "; Format is:" << endl
+    << ";   column: (sequence, position) => initial_accuracy" << endl
+    << "; sequence is 0-based and position is 0-based" << endl
+    << endl;
+
+  // first show column indices and the corresponding sequence positions, as well as initial accuracies
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+
+    assert (!(*col)->is_dead());
+
+    // show the column and its forward and back edges
+    const Seq_pos_map& seq_pos_map = (*col)->get_seq_pos_map();
+    assert (seq_pos_map.size() == 1);
+
+    o << (*col)->get_orig_index() << ": (" << seq_pos_map.begin()->first << ", " << seq_pos_map.begin()->second << ")" << endl;
+  }
+
+  o << endl;
+
+  // show edges if requested
+  if (show_edges) {
+
+    o << "; Initial edges" << endl;
+    o << "; Format is:" << endl;
+    o << ";   source_column -> dest_column" << endl;
+    o << endl;
+
+    // now show forward edges
+    for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+
+      const Seq_pos_map& seq_pos_map = (*col)->get_seq_pos_map();
+
+      // get the next position in this sequence
+      const Seq_pos next_seq_pos = Seq_pos (seq_pos_map.begin()->first, seq_pos_map.begin()->second + 1);
+
+      // have we reached the end of this sequence?
+      if (next_seq_pos.second >= seq_db.get_seq (next_seq_pos.first).length())
+	continue;
+
+      // else show this edge
+      const Column* w = get_seq_pos_col (next_seq_pos);
+      o << (*col)->get_orig_index() << " -> " << w->get_orig_index() << endl;
+
+    }
+
+    o << endl;
+  }
+
+}
+
+bool Alignment_DAG::dfs_f (Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward) {
+
+  // init stack of nodes with the start node l_bound
+  std::stack<Column*> nodes;
+  const size_t offset = l_bound->get_index();
+  std::vector<bool> on_stack ((u_bound->get_index() - offset + 1), false);
+
+  nodes.push (l_bound);
+  on_stack[l_bound->get_index() - offset] = true;
+
+  while (!nodes.empty()) {
+
+    // get next node on stack
+    Column* node = nodes.top();
+    nodes.pop();
+
+    // if we've already seen node, then continue with the next
+    if (node->is_marked())
+      continue;
+
+    // else mark as visited and store it
+    node->mark();
+    R_forward.push_back (node);
+
+    // continue DFS: explore node's neighbors
+    const Seq_pos_map& seq_pos_map = node->get_seq_pos_map();
+    for (Seq_pos_map::const_iterator seq_pos_iter = seq_pos_map.begin(); seq_pos_iter != seq_pos_map.end(); ++seq_pos_iter) {
+
+      // get the next position in this sequence
+      const Seq_pos next_seq_pos = Seq_pos (seq_pos_iter->first, seq_pos_iter->second + 1);
+
+      // have we reached the end of this sequence?
+      if (next_seq_pos.second >= seq_db.get_seq (next_seq_pos.first).length())
+	continue;
+
+      // if not, then continue DFS on neighbors
+      Column* w = get_seq_pos_col (next_seq_pos);
+
+      // have we found a cycle?
+      if (*w == *u_bound)
+	return true;
+
+      // if not, then continue DFS
+      // it's critical that the conditional is ordered like this to prevent overflowing on_stack
+      // if *w > *u_bound!
+      else if (!(w->is_marked()) && (*w < *u_bound) && !on_stack[w->get_index() - offset]) {
+	nodes.push (w);
+	on_stack[w->get_index() - offset] = true;
+      }
+
+    }
+
+  }
+
+  // DFS terminated successfully, so no cycles found!
+  return false;
+}
+
+void Alignment_DAG::dfs_b (Column* u_bound, Column* l_bound, std::vector<Column*>& R_backward) {
+
+  // init stack of nodes with the start node u_bound
+  std::stack<Column*> nodes;
+  const size_t offset = l_bound->get_index();
+  std::vector<bool> on_stack ((u_bound->get_index() - offset + 1), false);
+
+  nodes.push (u_bound);
+  on_stack[l_bound->get_index() - offset] = true;
+
+  while (!nodes.empty()) {
+
+    // get next node on stack
+    Column* node = nodes.top();
+    nodes.pop();
+
+    // if we've already seen node, then continue with the next
+    if (node->is_marked())
+      continue;
+
+    // else mark as visited and store it
+    node->mark();
+    R_backward.push_back (node);
+
+    // continue DFS: explore node's neighbors
+    const Seq_pos_map& seq_pos_map = node->get_seq_pos_map();
+    for (Seq_pos_map::const_iterator seq_pos_iter = seq_pos_map.begin(); seq_pos_iter != seq_pos_map.end(); ++seq_pos_iter) {
+
+      // have we reached the beginning of this sequence?
+      // (remember that sequence coordinates are 0-based)
+      if (seq_pos_iter->second == 0)
+	continue;
+
+      // get the previous position in this sequence (remember that we're searching backwards)
+      Seq_pos prev_seq_pos = Seq_pos (seq_pos_iter->first, seq_pos_iter->second - 1);
+
+      // if not, then continue DFS on neighbors
+      Column* w = get_seq_pos_col (prev_seq_pos);
+
+      // note that there's no need to check for cycles here,
+      // since we've already done so in the dfs_f() call
+
+      // continue DFS
+      if (!(w->is_marked()) && (*l_bound < *w) && !on_stack[w->get_index() - offset]) {
+	nodes.push (w);
+	on_stack[w->get_index() - offset] = true;
+      }
+    }
+
+  }
+
+}
+
+void Alignment_DAG::reorder (std::vector<Column*>& R_forward, std::vector<Column*>& R_backward) {
+
+  // sort nodes in deltaB and deltaF
+  std::sort (R_backward.begin(), R_backward.end(), smaller_index());
+  std::sort (R_forward.begin(), R_forward.end(), smaller_index());
+
+  // assemble list of indices from nodes in deltaB and deltaF
+  // R_indices is R, the pool of available indices, in the Pearce and Kelly paper
+  std::vector<size_t> R_indices;
+  std::vector<Column*> L_columns;
+  // deltaB
+  for (std::vector<Column*>::const_iterator column = R_backward.begin(); column != R_backward.end(); ++column) {
+    L_columns.push_back (*column);
+    R_indices.push_back ((*column)->get_index());
+  }
+  // deltaF
+  for (std::vector<Column*>::const_iterator column = R_forward.begin(); column  != R_forward.end(); ++column) {
+    L_columns.push_back (*column);
+    R_indices.push_back ((*column)->get_index());
+  }
+  // sort indices
+  std::sort (R_indices.begin(), R_indices.end());
+
+  // allocate indices to nodes in deltaB and deltaF
+  for (size_t i = 0; i < R_indices.size(); ++i) {
+    Column* col = L_columns[i];
+    const size_t index = R_indices[i];
+    assert (index < this->columns.size()); // remember 0-based indexing for Column::index
+    col->set_index (index);
+    this->columns[index] = col;
+  }
+
+}
+
+void Alignment_DAG::unmark (std::vector<Column*>& cols) {
+  for (std::vector<Column*>::iterator column = cols.begin(); column != cols.end(); ++column)
+    (*column)->unmark();
+}
+
+void Alignment_DAG::merge (Edge* edge) {
+  Column* source = edge->source;
+  Column* dest = edge->dest;
+
+  // add dest sequence positions to source
+  const Seq_pos_map& dest_seq_pos_map = dest->get_seq_pos_map();
+  for (Seq_pos_map::const_iterator seq_pos = dest_seq_pos_map.begin(); seq_pos != dest_seq_pos_map.end(); ++seq_pos) {
+    source->add_seq_pos (*seq_pos);
+    set_seq_pos_col (*seq_pos, source);
+  }
+
+  // merge dest into source
+  dest->set_merged_into (source);
+
+}
+
+bool Alignment_DAG::induces_cycle (Edge* edge, Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward) {
+
+  // does this edge induce a cycle in the graph?
+  if (dfs_f (l_bound, u_bound, R_forward)) {
+
+    // sanity check: must be at least one node (l_bound)
+    assert (R_forward.size());
+
+    // unmark marked nodes
+    unmark (R_forward);
+
+    return true;
+  }
+
+  // sanity check: must be at least one node (l_bound)
+  assert (R_forward.size());
+
+  return false;
+
+}
+
+void Alignment_DAG::add_edge (Edge* edge, Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward) {
+
+  Column* source = edge->source;
+  Column* dest = edge->dest;
+
+  // NB: It's crucial that at this point the Edge be between
+  // the current (after merges) source and dest columns;
+  // this must be assured by the calling function.
+
+  // we assume that induces_cycle has been called,
+  // thereby ensuring that the edge doesn't induce a cycle
+  // and populating R_forward; now we just need to perform
+  // the backward depth-first search, storing nodes as the search proceeds
+  std::vector<Column*> R_backward;
+  dfs_b (u_bound, l_bound, R_backward);
+
+  // sanity check: must be at least one node (l_bound and u_bound respectively)
+  assert (R_forward.size());
+  assert (R_backward.size());
+
+  // unmark visited nodes
+  unmark (R_forward);
+  unmark (R_backward);
+
+  // impose a new total order via the Pearce-Kelly Reorder() procedure
+  if (R_forward.size() == 1) {    // catch edge cases
+    source = u_bound;
+    dest = l_bound;
+  } else if (R_backward.size() == 1) {
+    source = l_bound;
+    dest = u_bound;
+  } else {
+    reorder (R_forward, R_backward);
+  }
+
+  // modify the DAG: merge the (current) source and dest columns
+  edge->source = source;
+  edge->dest = dest;
+  merge (edge);
+
+  // mark the dest column as dead
+  // (note that this is /much/ faster than erasing it!)
+  dest->set_dead();
+
+  // decrement the number of columns in the alignment accordingly
+  --num_columns;
+
+}
+
+// (sequence position to shift, (original column, new column))
+typedef std::pair<Seq_pos, std::pair<size_t, size_t> > Shift;
+
+
+void Alignment_DAG::do_lateral_refinement (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor) {
+
+  // create priority queue of sequence positions to shift
+  std::priority_queue<std::pair<float, Shift> > shifts;
+
+  // create vector of (non-dead) columns
+  std::vector<Column*> tmp_columns;
+  for (std::vector<Column*>::iterator col = columns.begin(); col != columns.end(); ++col) {
+    if (!(*col)->is_dead())
+      tmp_columns.push_back (*col);
+  }
+
+  // for each column
+  //   for each (seq, pos) in the column, consider shifting it
+  //   left or right
+  for (size_t i = 0; i < tmp_columns.size(); i++) {
+
+    Column* curr_col = tmp_columns[i];
+
+    // consider shifting each character
+    const Seq_pos_map& seq_pos_map = curr_col->get_seq_pos_map();
+    for (Seq_pos_map::const_iterator seq_pos = seq_pos_map.begin(); seq_pos != seq_pos_map.end(); ++seq_pos) {
+
+      // column with the greatest change in expected accuracy from adding *seq_pos
+      // initialize to the original column holding this Seq_pos
+      size_t best_j = i;
+      // best change in expected accuracy from adding *seq_pos to another column
+      float best_score_change;
+
+      // initialize best_score_change to change in score corresponding to current column
+      // (corresponding to removing *seq_pos from curr_col, calculating expected change and then re-adding)
+      best_score_change = curr_col->change_in_expected_score (*seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs, true); // skip_seq_pos = true
+
+      // now search over other columns: search right
+      for (size_t j = i + 1; j < tmp_columns.size(); ++j) {
+
+	// get the column
+	Column* col = tmp_columns[j];
+	assert (!col->is_dead());
+	while (col != col->get_merged_into())
+	  col = col->get_merged_into();
+
+	// if col contains a character from the sequence in *seq_pos, then break
+	// (can't slide it over)
+	const float change = col->change_in_expected_score (*seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs);
+	if (change == INVALID_EDGE)
+	  break;
+
+	// if an improvement, then record it
+	if (change > best_score_change) {
+	  best_score_change = change;
+	  best_j = j;
+	}
+
+      }
+
+      // search left
+      for (int j = i - 1; j >= 0; --j) {
+
+	// get the column
+	Column* col = tmp_columns[j];
+	assert (!col->is_dead());
+	while (col != col->get_merged_into())
+	  col = col->get_merged_into();
+
+	// if col contains a character from the sequence in *seq_pos, then break
+	// (can't slide it over)
+	const float change = col->change_in_expected_score (*seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs);
+	if (change == INVALID_EDGE)
+	  break;
+
+	if (change > best_score_change) {
+	  best_score_change = change;
+	  best_j = j;
+	}
+
+      }
+
+      // if we've found a better position, then record it
+      if (best_j != i) {
+	const Shift shift (*seq_pos, std::pair<size_t, size_t> (i, best_j));
+	shifts.push (std::pair<float, Shift> (best_score_change, shift));
+      }
+
+    }
+  }
+
+  // now shift the (seq, pos) according to the corresponding
+  // change in expected score
+  // for each candidate shift, check that it's still a valid shift; 
+  // also check whether there's a new, better shift
+  std::pair<float, Shift> score_shift;
+  while (!shifts.empty()) {
+
+    // get the top candidate shift
+    score_shift = shifts.top();
+    shifts.pop();
+    const Shift& shift = score_shift.second;
+    const Seq_pos& seq_pos = shift.first;
+
+    // get the original column holding seq_pos
+    const size_t orig_j = (shift.second).first;
+
+    // initialize best column to original column
+    size_t best_j = orig_j;
+    // best change in expected accuracy from adding *seq_pos to another column
+    float best_score_change;
+
+    // initialize best_score_change to change in score corresponding to original column
+    // (corresponding to removing *seq_pos from curr_col, calculating expected change and then re-adding)
+    // Note that this is different from Sudeep's original method,
+    // which initialized the scores to 0 rather than the score associated with
+    // the current column (and so, I believe, was biased towards shifting)
+    best_score_change = tmp_columns[orig_j]->change_in_expected_score (seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs, true); // skip_seq_pos = true
+
+    // search right
+    for (size_t j = orig_j + 1; j < tmp_columns.size(); ++j) {
+
+      // get the column
+      Column* col = tmp_columns[j];
+      assert (!col->is_dead());
+      while (col != col->get_merged_into())
+	col = col->get_merged_into();
+
+      // if col contains a character from the sequence in *seq_pos, then break
+      // (can't slide it over)
+      const float change = col->change_in_expected_score (seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs);
+      if (change == INVALID_EDGE)
+	break;
+
+      // if an improvement, then record it
+      if (change > best_score_change) {
+	best_score_change = change;
+	best_j = j;
+      }
+
+    }
+
+    // search left
+    for (int j = orig_j - 1; j >= 0; --j) {
+
+      // get the column
+      Column* col = tmp_columns[j];
+      assert (!col->is_dead());
+      while (col != col->get_merged_into())
+	col = col->get_merged_into();
+
+      // if col contains a character from the sequence in *seq_pos, then break
+      // (can't slide it over)
+      const float change = col->change_in_expected_score (seq_pos, sparse_matrices, tree_weights, gap_factor, num_seqs);
+      if (change == INVALID_EDGE)
+	break;
+
+      // if an improvement, then record it
+      if (change > best_score_change) {
+	best_score_change = change;
+	best_j = j;
+      }
+
+    }
+
+    // if wrong order on priority queue (if lower expected change in score than next shift on queue)
+    if (best_score_change < (shifts.top()).first) {
+      shifts.push (std::pair<float, Shift> (best_score_change, shift));
+      continue;
+    }
+
+    // if we've found an improvement, then make the change and move seq_pos!
+    if (best_j != orig_j) {
+      if (CTAGGING(-1,REFINEMENT)) {
+	CL << "Converting " << endl
+	   << "  " << *tmp_columns[orig_j] << endl
+	   << "  " << *tmp_columns[best_j] << endl;
+      }
+      tmp_columns[orig_j]->erase_seq_pos (seq_pos.first);
+      tmp_columns[best_j]->add_seq_pos (seq_pos);
+      set_seq_pos_col (seq_pos, tmp_columns[best_j]);
+      if (CTAGGING(-1,REFINEMENT)) {
+	CL << "to " << endl
+	   << "  " << *tmp_columns[orig_j] << endl
+	   << "  " << *tmp_columns[best_j] << endl;
+      }
+    }
+
+  }
+
+  // we're done, so create new columns object
+  columns.clear();
+  size_t idx = 0;
+  for (size_t i = 0; i < tmp_columns.size(); ++i) {
+    Column* col = tmp_columns[i];
+    // if empty, then skip
+    if (col->get_seq_pos_map().empty())
+      continue;
+    columns.push_back (col);     // store
+    col->set_index (idx++);      // update index
+  }
+  num_columns = columns.size();
+
+}
+
+std::pair<float, std::string> Alignment_DAG::get_accuracy_annotation_normalized (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights) const {
+
+  float overall_acc = 0.;
+  float overall_denom = 0.;
+  std::string annot;
+  for (std::vector<Column*>::const_iterator column = columns.begin(); column != columns.end(); ++column) {
+
+    // skip dead columns
+    if ((*column)->is_dead())
+      continue;
+
+    // If normalizing, then convert to per-pair accuracy as:
+    // Divide by 2 * (n choose 2 = 1/2*n*(n-1)) + ((num_seqs - n) * n),
+    // where the first part is the (sum-of-pairs) number of matched characters
+    // and the second part the number of characters aligned to gaps.
+    // The factor of 10.0 here is because accuracy as calculated during annealing is <= 1,
+    // and we want to map it to the interval [0-10].
+    const std::pair<float, float> accuracy_pair = (*column)->get_accuracy_normalized (sparse_matrices, tree_weights, num_seqs);
+
+    // cover case of no information for the column (can occur when a sequence is empty in pairwise inference)
+    if (accuracy_pair.second == 0.) {
+      annot += '0';
+      continue;
+    }
+
+    // else perform calculation as usual
+    const float acc_norm = accuracy_pair.first / accuracy_pair.second;
+    assert ((acc_norm >= 0.) && (acc_norm <= 1.00001)); // prevent rounding error for the case of 1.0 (yes, it happens!)
+    annot += static_cast<char> ((acc_norm > 0) ? "0123456789"[ std::min (static_cast<int> (std::floor (acc_norm * 10.0)), 9) ] : '0'); // normalize to 0-9 (0 if expected accuracy < 0)
+
+    // increment for overall calculation
+    overall_acc += accuracy_pair.first;
+    overall_denom += accuracy_pair.second;
+
+  }
+
+  // cover case of no information for the alignment
+  if (overall_denom == 0.)
+    return std::make_pair (0., annot);
+
+  // normalize by number of (non-dead) columns
+  overall_acc /= overall_denom;
+  assert ((overall_acc >= 0.) && (overall_acc <= 1.00001));
+
+  return std::make_pair (overall_acc, annot);
+
+}
+
+float Alignment_DAG::expected_score (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, const float gap_factor) const {
+
+  float score = 0;
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+    if ((*col)->is_dead())
+      continue;
+    score += (*col)->expected_score (sparse_matrices, tree_weights, gap_factor, num_seqs);
+  }
+
+  return score;
+}
diff --git a/src/annealing/alignment_DAG.h b/src/annealing/alignment_DAG.h
new file mode 100644
index 0000000..d479467
--- /dev/null
+++ b/src/annealing/alignment_DAG.h
@@ -0,0 +1,742 @@
+
+/**
+ * \file alignment_DAG.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Ariel Schwartz and Robert Bradley.
+ * Sudeep Juvekar wrote the iterative refinement code do_lateral_refinement.
+ * Jaeyoung Do wrote the parallelization and database code.
+ */
+
+
+
+// to do:
+
+// - try converting dfs_f and dfs_b to a true postorder dfs
+//    in order to return R_{forward,backward} in topological order
+//    => avoid two sorts in reorder() ?
+
+
+
+/* Notes */
+
+// I have empirically observed that using the sort algorithm on a vector<Column*>
+//  is *much* faster than using list<Column*>::sort.  I have no idea why,
+//  but it means that R_forward and R_backward had better be vectors!
+
+// If I decide that I want to keep track of ppv as well as ama (expected accuracy),
+//  then add a member to Column and have update_weight_{tgf,maxstep} return a pair<p_match,p_gap>
+//  so that I can update those on the fly.
+
+
+#ifndef ALIGNMENT_DAG_INCLUDED
+#define ALIGNMENT_DAG_INCLUDED
+
+#define ACCURACY_ANNOT "Accuracy"
+#define GUI_FILENAME_DAG_SUFFIX ".gui"
+#define GUI_FILENAME_PROB_SUFFIX ".probs"
+#define INVALID_EDGE -1e10 // to do: this could be fragile; replace with negative return value and test for that?
+
+#include <stack>
+#include <list>
+#include <map>
+#include <queue>
+#include <iostream>
+#include <algorithm>
+
+#include "config.h"
+#ifdef HAVE_TR1_UNORDERED_MAP
+#include <tr1/unordered_map>
+#endif
+
+#ifdef HAVE_TR1_UNORDERED_SET
+#include <tr1/unordered_set>
+#endif
+
+#include "util/hash_fcn.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+#include "annealing/SparseMatrix.h"
+#include "annealing/tree_weights.h"
+
+#include "manager/manager.h"
+
+namespace fsa {
+
+  // Note:
+  // All indexing of sequence data is 0-based here,
+  // but SparseMatrix uses 1-based indexing.
+
+  /**
+   * \brief (sequence, position) duple
+   */
+  typedef std::pair<size_t, unsigned> Seq_pos;
+
+  /**
+   * \brief Map of sequences to positions.
+   *
+   * I have experimented with using a hash_map instead,
+   * but observed better performance in practice with a standard map.
+   */
+  typedef std::map<size_t, unsigned> Seq_pos_map;
+
+
+  /**
+   * \brief Column of the alignment.
+   *
+   * These are the nodes of the DAG.
+   */
+  class Column {
+
+  private:
+
+    size_t index;               ///< the position of the column in the alignment (0-based)
+    size_t orig_index;          ///< the original index (when DAG first initialized)
+    Seq_pos_map seq_pos_map;    ///< map of (seq_id,pos) pairs in the column
+    Column* merged_into;        ///< the Column which this column has merged into
+    bool marked;                ///< indicates if the column has been visited by the dfs 
+    bool dead;                  ///< mark a column as dead (dropped from the DAG)
+
+  public:
+
+    static Manager* manager;   ///< manager for database and MW
+
+    /**
+     * \brief Constructor.
+     *
+     * \param index the initial index of the column
+     */
+    Column (size_t index)
+      : index (index), orig_index (index),
+      merged_into (this), marked (false), dead (false)
+      { }
+
+    /**
+     * \brief Compares two columns based on their current indices.
+     *
+     */
+    bool operator< (Column const &r) const {
+      return (index < r.index);
+    }
+
+    /**
+     * \brief Compares two columns based on their current indices.
+     *
+     */
+    bool operator== (Column const &r) const {
+      return (index == r.index);
+    }
+
+    /**
+     * \brief Number of sequences in column.
+     *
+     */
+    inline size_t size() const {
+      return seq_pos_map.size();
+    }
+
+    /**
+     * \brief Has the column has been marked as visited?
+     *
+     */
+    inline bool is_marked() const {
+      return marked;
+    }
+
+    /**
+     * \brief Mark the column as visited.
+     *
+     */
+    inline void mark() {
+      marked = true;
+    }
+
+    /**
+     * \brief Unmark the column as visited.
+     *
+     */
+    inline void unmark() {
+      marked = false;
+    }
+
+    /**
+     * \brief Is the column dead?
+     *
+     */
+    inline bool is_dead() const {
+      return dead;
+    }
+
+    /**
+     * \brief Mark the column as dead.
+     *
+     * Columns are marked as dead when they have been merged into another column
+     * (ie, the node which they represent is no longer present in the DAG).
+     */
+    inline void set_dead() {
+      dead = true;
+    }
+
+    /**
+     * \brief Returns the current index of the column.
+     *
+     * The index of the column is its position in the total order specified by the alignment.
+     * 0-based.
+     */
+    inline size_t get_index() const {
+      return index;
+    }
+
+    /**
+     * \brief Set the index.
+     *
+     */
+    inline void set_index (const size_t idx) {
+      index = idx;
+    }
+
+    /**
+     * \brief Returns the original index of the column.
+     *
+     */
+    inline const size_t get_orig_index() const {
+      return orig_index;
+    }
+
+    /**
+     * \brief Get the Column* which this column has been merged into.
+     *
+     */
+    inline Column* get_merged_into() const {
+      return merged_into;
+    }
+
+    /**
+     * \brief Set the Column* which this column has been merged into.
+     *
+     */
+    inline void set_merged_into (Column* col) {
+      merged_into = col;
+    }
+
+    /**
+     * \brief Get the sequence positions represented by this column.
+     *
+     */
+    inline const Seq_pos_map& get_seq_pos_map() const {
+      return seq_pos_map;
+    }
+
+    /**
+     * \brief Does this column contain a particular sequence?
+     */
+    inline bool contains_seq (const size_t i) const {
+      return seq_pos_map.find (i) != seq_pos_map.end();
+    }
+
+    /**
+     * \brief Add a sequence position.
+     *
+     */
+    inline void add_seq_pos (const Seq_pos& seq_pos) {
+      seq_pos_map.insert (seq_pos);
+    }
+
+    /**
+     * \brief Remove the entry for a particular sequence.
+     */
+    inline void erase_seq_pos (const size_t seq) {
+      if (seq_pos_map.erase (seq) != 1)
+	THROWEXPR ("Invalid attempt to erase a (sequence, position) pair.");
+    }
+
+    /**
+     * \brief Get the expected accuracy of the column.
+     *
+     * Normalization is by the sum-of-pairs number of characters in the column
+     * (but only if we have posterior information available for a pair).
+     * Note that the denominator has to be a float due to the weights.
+     * \param tree_weights weights for sequence pairs during annealing
+     * \return (numerator, denominator)
+     */
+    std::pair<float, float> get_accuracy_normalized (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, const size_t num_seqs) const;
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Column& col) {
+
+      o << "column " << col.index << ": ";
+
+      const Seq_pos_map seqs = col.seq_pos_map;
+      // catch case of empty (all gaps) column
+      if (seqs.begin() == seqs.end()) {
+	return o;
+      }
+      // else display aligned characters
+      Seq_pos_map::const_iterator iter = seqs.begin();
+      o << "(" << iter->first << ", " << iter->second << ")";
+      for (++iter; iter != seqs.end(); ++iter)
+	o << " ~ (" << iter->first << ", " << iter->second << ")";
+
+      return o;
+    }
+
+    /**
+     * \brief Get the expected sum-of-pairs score of this column.
+     *
+     * Calculates the value of the objective function
+     * (accuracy modified by the gap factor) for this column.
+     * \param tree_weights weights for sequence pairs during annealing
+     * \param gap_factor gap factor
+     * @see change_in_expected_score
+     */
+    float expected_score (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, size_t num_seqs) const;
+
+    /**
+     * \brief Get the change in expected sum-of-pairs score from aligning a character here.
+     *
+     * Given a character (sequence and position seq_pos) which is not aligned in this column,
+     * returns the /change/ in expected value of the objective function (accuracy modified by gap factor) 
+     * associated with aligning the character as part of this column.
+     * Note that we can use this function to calculate the expected change resulting from
+     * removing seq_pos from this column, calculating the expected change, and re-adding,
+     * even when seq_pos already is aligned in this column, by setting skip_seq_pos = true.
+     * \param seq_pos a character (sequence, position) which isn't aligned in this column
+     * \param tree_weights weights for sequence pairs during annealing
+     * \param gap_factor gap factor
+     * \param skip_seq_pos if false, then return INVALID_EDGE if the character is already present in the column; else ignore
+     * \return INVALID_EDGE if there already is a character from the sequence in seq_pos aligned here
+     */
+    float change_in_expected_score (const Seq_pos& seq_pos, std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, size_t num_seqs, bool skip_seq_pos = false) const;
+
+  };
+
+  /**
+   * \brief Edge between two columns.
+   *
+   * Store information about a candidate edge (between columns, i.e., nodes of the DAG).
+   * Calculates edge weights.
+   */
+  class Edge {
+
+  public:
+
+    Column* source;              ///< source column (outgoing edge)
+    Column* dest;                ///< destination column (incoming edge)
+    float weight;                ///< column weight
+
+    unsigned short weight_size;  ///< size of source and dest when the weight was last calculated
+
+    static Manager* manager;     ///< manager for database and MW
+
+    /**
+     * \brief Constructor.
+     *
+     * \param source source column
+     * \param dest dest column
+     * \param weight weight of the edge
+     */
+    Edge (Column* source, Column* dest,
+	  float weight, unsigned short weight_size)
+      : source (source), dest (dest),
+      weight (weight), weight_size (weight_size)
+    { }
+
+    /**
+     * \brief If requested, updates weight based on tgf.
+     *
+     * Updates change in expected sum-of-pairs score (accuracy modified by gap factor)
+     * from adding the edge.
+     * Note that while annealing with tgf weights is a true steepest ascent algorithm,
+     * the updated weights can increase iff the edge is inconsistent
+     * (in this case the steepest ascent condition doesn't apply, since it's only
+     * a guarantee for accepted edges).
+     * \param tree_weights weights for sequence pairs during annealing
+     * \param update_weight update weight of the edge
+     * \return true if inconsistent edge
+     */
+    bool update_weight_tgf (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, bool update_weight = true);
+
+    /**
+     * \brief If requested, updates weight based on maxstep.
+     *
+     * Updates change in expected sum-of-pairs score (accuracy modified by gap factor)
+     * from adding the edge.
+     * \param tree_weights weights for sequence pairs during annealing
+     * \param update_weight update weight of the edge
+     * \return true if inconsistent edge
+     */
+    bool update_weight_maxstep (std::vector<std::vector<SparseMatrix *> >& sparse_matrices, const Tree_weights& tree_weights, float gap_factor, bool update_weight = true);
+
+    /**
+     * \brief Compare two edges based on their weights.
+     */
+    bool operator< (Edge const e2) const {
+      return weight < e2.weight;
+    }
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<<(std::ostream& o,const Edge& edge) {
+      o << *edge.source << " -> " << *edge.dest << "; weight = " << edge.weight;
+      return o;
+    }
+
+    /**
+     * \brief Does the weight need to be updated?
+     * \return true if the source or dest column has changed size since the weight was last calculated
+     */
+    inline bool weight_outdated() const {
+      return (weight_size != (source->size() + dest->size()));
+    }
+
+    /**
+     * \brief Output for GUI.
+     *
+     * Only for use after calling add_edge();
+     * assumes that source and dest of this edge have been reset with get_merged_into().
+     */
+    inline void write_gui_output (std::ostream& o) {
+      assert (source->get_merged_into() == source);
+      assert (dest->get_merged_into() == source);
+      o << source->get_orig_index() << " -> " << dest->get_orig_index() << endl;
+    }
+
+  };
+
+
+  /**
+   * \brief Function object for defining a binary comparison operator for column pointers.
+   *
+   * Comparison is based on the corresponding columns' indices.
+   * @see Column::operator<().
+   */
+  class greater_index : std::binary_function<Column*, Column*, bool> {
+  public:
+    bool operator() (Column* x, Column* y) const { return (*y  < *x); }
+  };
+
+  /**
+   * \brief Function object for defining a binary comparison operator for column pointers.
+   *
+   * Comparison is based on the corresponding columns' indices.
+   * @see Column::operator<().
+   */
+  class smaller_index : std::binary_function<Column*, Column*, bool> {
+  public:
+    bool operator() (Column* x, Column* y) const { return (*x  < *y); }
+  };
+
+  /**
+   * \brief Function object for defining a binary comparison operator for column pointers.
+   *
+   * Comparison is based on the corresponding edges' weights.
+   */
+  class smaller_weight : std::binary_function<Edge*, Edge*, bool> {
+  public:
+    bool operator() (Edge* x, Edge* y) const { return (x->weight < y->weight); }
+  };
+
+  /**
+   * \brief Function object for hashing pairs of columns.
+   *
+   * Cast to 64-bit representation (even though may actually be a 32-bit representation
+   * on many systems) for safety.
+   */
+  class column_pair_hash : std::unary_function<std::pair<Column*, Column*>, bit64_t> {
+  public:
+    bit64_t operator() (std::pair<Column*, Column*> col_pair) const {
+      return Hash_functions::bit64_t_pair_hash (reinterpret_cast<bit64_t> (col_pair.first), reinterpret_cast<bit64_t> (col_pair.second));
+    }
+  };
+
+  /**
+   * \brief Map a position in a sequence to the containing Column*.
+   */
+  typedef std::vector<Column*> Seq_pos_col_map;
+
+  /**
+   * \brief Map a sequence position to the containing Column*.
+   *
+   * Indexed by [sequence][position].
+   */
+  typedef std::vector<Seq_pos_col_map > Seq_pos_col_maps;
+
+  /**
+   * \brief Store a multiple alignment as a DAG and perform sequence annealing.
+   *
+   * Imposes a total order on the DAG at all times with 
+   * an explicit vector representation of the columns.
+   */
+  class Alignment_DAG {
+
+  private:
+
+    std::vector<Column*> columns;                  ///< the current columns of the alignment
+    Seq_pos_col_maps seq_pos_col_maps;             ///< mapping from sequence positions pair<seq, pos> to the containing Column*
+
+    const Sequence_database& seq_db;               ///< sequence data
+    size_t num_seqs;                               ///< number of sequences in the alignment
+    size_t num_columns;                            ///< number of columns in the alignment
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * Initialize alignment DAG to the null alignment.
+     * Initializes to the "maximal chain decomposition" null alignment,
+     * which imposes the total order corresponding to a chain decomposition
+     * where the number of chains is maximized.
+     * This also corresponds to maximizing the possible number of gap-opens.
+     */
+    Alignment_DAG (const Sequence_database& seq_db);
+
+    /**
+     * \brief Constructor.
+     *
+     * Initialize alignment DAG to the passed Stockholm alignment.
+     */
+    Alignment_DAG (const Sequence_database& seq_db, const Stockholm& stock);
+
+    /**
+     * \brief Destructor.
+     */
+    ~Alignment_DAG();
+
+    /**
+     * \brief Get the columns of the alignment.
+     */
+    const std::vector<Column*>& get_columns() const {
+      return (*this).columns;
+    }
+
+    /**
+     * \brief Drop all-gaps columns of the alignment.
+     */
+    void drop_all_gaps_columns();
+
+    /**
+     * \brief Depth-first search for toplogical sorting a la Tarjan.
+     *
+     * Computes the Dilworth chain decomposition for the graph.
+     * Uses a non-recursive (external stack-based) implementation of a postorder traversal of the graph.
+     * Pretty tricky.
+     */
+    void dfs_topological_sort();
+
+    /**
+     * \brief Perform sequence annealing with an equidistant star phylogeny.
+     *
+     * All sequence pairs are weighted equally.
+     * \param sparse_matrices pairwise posterior probabilities
+     * \param manager database manager
+     * \param use_tgf use tgf instead of maxstep weighting
+     * \param gap_factor gap factor
+     * \param enable_dynamic_weights re-weight edges after merges 
+     * \param edge_weight_threshold the threshold for accepting edges
+     * \param output_for_gui write GUI-formatted output to disk
+     * \param gui_prefix prefix for GUI filename
+     */
+    void anneal (std::vector<std::vector<SparseMatrix*> >& sparse_matrices,
+		 Manager& manager,
+		 const bool use_tgf,
+		 const float gap_factor, const bool enable_dynamic_weights, const float edge_weight_threshold,
+		 const size_t num_refinement_steps,
+		 const bool output_for_gui, const std::string gui_prefix);
+
+
+    /**
+     * \brief Perform sequence annealing using sequence pair weights.
+     *
+     * \param sparse_matrices pairwise posterior probabilities
+     * \param tree_weights weights for sequence pairs during annealing
+     * \param manager database manager
+     * \param use_tgf use tgf instead of maxstep weighting
+     * \param gap_factor gap factor
+     * \param enable_dynamic_weights re-weight edges after merges 
+     * \param edge_weight_threshold the threshold for accepting edges
+     * \param output_for_gui write GUI-formatted output to disk
+     * \param gui_prefix prefix for GUI filename
+     */
+    void anneal (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights,
+		 Manager& manager,
+		 const bool use_tgf,
+		 const float gap_factor, const bool enable_dynamic_weights, const float edge_weight_threshold,
+		 const size_t num_refinement_steps,
+		 const bool output_for_gui, const std::string gui_prefix);
+
+    /**
+     * \brief Display the DAG in human-readable format.
+     *
+     * Show the current total order.
+     * If aligned_only, then only show columns with aligned characters.
+     */
+    void show (std::ostream& o, bool aligned_only = false) const;
+
+    /**
+     * \brief Get the Stockholm object corresponding to the current alignment.
+     *
+     * Mark up with unnormalized column accuracy scores.
+     * \param dilworth_resort impose a total order corresponding to a minimal chain decompostion of the DAG
+     */
+    Stockholm get_stockholm() const;
+
+    /**
+     * \brief Get the Stockholm object corresponding to the current alignment.
+     *
+     * Mark up with normalized column accuracy scores.
+     * \param tree_weights weights for sequence pairs during annealing
+     */
+    Stockholm get_stockholm (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights) const;
+
+
+  private:
+
+    /**
+     * \brief Get the Column* specified by seq_pos.
+     */
+    inline Column* get_seq_pos_col (const Seq_pos& seq_pos) const {
+      assert ((seq_pos.first >= 0) && (seq_pos.first < seq_pos_col_maps.size()));
+      assert ((seq_pos.second >= 0) && (seq_pos.second < seq_pos_col_maps[seq_pos.first].size()));
+      assert (seq_pos_col_maps[seq_pos.first][seq_pos.second] != 0);
+
+      return seq_pos_col_maps[seq_pos.first][seq_pos.second];
+    }
+
+    /**
+     * \brief Set the Column* specified by seq_pos.
+     */
+    inline void set_seq_pos_col (const Seq_pos& seq_pos, Column* col) {
+      assert ((seq_pos.first >= 0) && (seq_pos.first < seq_pos_col_maps.size()));
+      assert ((seq_pos.second >= 0) && (seq_pos.second < seq_pos_col_maps[seq_pos.first].size()));
+
+      seq_pos_col_maps[seq_pos.first][seq_pos.second] = col;
+    }
+
+    /**
+     * \brief Output for GUI.
+     *
+     * Should only be called before annealing begins.
+     * \param show_edges show edges of the DAG
+     */
+    void write_gui_output (std::ostream& o, const bool show_edges = false) const;
+
+    /**
+     * \brief Forward depth-first search of the Pearce-Kelly algorithm.
+     *
+     * Search forwards, ie in the direction from l_bound to upper bound.
+     * Look for cycles in the graph, ie a path l_bound ~> u_bound.
+     * Store visited nodes (columns) in R_forward.
+     * Non-recursive (external stack-based) implementation of DFS.
+     * Note that the traversal is neither preorder nor postorder, but rather something arbitrary
+     * (because the columns reached by the iteration over sequence positions
+     * won't be sorted w.r.t. the total order of the DAG).
+     * \param l_bound lower bound of the DFS
+     * \param u_bound upper bound of the DFS
+     * \param R_forward visited nodes
+     */
+    bool dfs_f (Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward);
+
+    /**
+     * \brief Backward depth-first search of the Pearce-Kelly algorithm.
+     *
+     * Searches backwards, ie in the direction from u_bound to u_bound.
+     * Store visited nodes (columns) in R_backward.
+     * Non-recursive (external stack-based) implementation of DFS.
+     * Note that the traversal is neither preorder nor postorder, but rather something arbitrary
+     * (because the columns reached by the iteration over sequence positions
+     * won't be sorted w.r.t. the total order of the DAG).
+     * \param l_bound lower bound of the (backward) DFS
+     * \param u_bound upper bound of the (backward) DFS
+     * \param R_backward visited nodes
+     */
+    void dfs_b (Column* u_bound, Column* l_bound, std::vector<Column*>& R_backward);
+
+    /**
+     * \brief Reorder procedure of the Pearce-Kelly algorithm.
+     *
+     * \param R_forward nodes reached by a forward DFS
+     * \param R_backward nodes reached by a backward DFS
+     */
+    void reorder (std::vector<Column*>& R_forward, std::vector<Column*>& R_backward);
+
+    /**
+     * \brief Unmark all columns in the vector.
+     *
+     * \param cols columns to unmark
+     */
+    void unmark (std::vector<Column*>& cols);
+
+    /**
+     * \brief Check whether a candidate edge induces a cycle.
+     *
+     * Performs cycle-checking with a forward DFS from the destination node.
+     * Stores nodes reached by the forward DFS in R_forward for
+     * later use by add_edge.
+     * \param edge edge to add
+     * \param l_bound lower bound on DFS
+     * \param u_bound upper bound on DFS
+     * \param R_forward nodes reached by forward DFS
+     * \see dfs_f
+     */
+    bool induces_cycle (Edge* edge, Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward);
+
+    /**
+     * \brief Merge the source and dest columns of the edge into the source column.
+     *
+     * \param edge edge to merge
+     */
+    void merge (Edge* edge);
+
+    /**
+     * \brief Add a new edge to the alignment DAG.
+     *
+     * \param edge edge to add
+     * \param l_bound lower bound on DFS
+     * \param u_bound upper bound on DFS
+     * \param R_forward nodes reached by forward DFS
+     */
+    void add_edge (Edge* edge, Column* l_bound, Column* u_bound, std::vector<Column*>& R_forward);
+
+    /**
+     * \brief Perform one iteration of lateral refinement.
+     *
+     * Iterate through all columns of the alignment, re-aligning characters 
+     * according to the per-column change in expected accuracy.
+     * \param tree_weights weights for sequence pairs during annealing
+     */
+    void do_lateral_refinement (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, const float gap_factor);
+
+    /**
+     * \brief Get the overall and per-column normalized expected accuracy (formatted as a string for #=GC annotation).
+     *
+     * The sparse matrices are necessary for calculating the denominator for normalization.
+     * \param tree_weights weights for sequence pairs during annealing
+     */
+    std::pair<float, std::string> get_accuracy_annotation_normalized (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights) const;
+
+    /**
+     * \brief Get the expected sum-of-pairs score of the alignment.
+     *
+     * Calculates the value of the objective function (accuracy modified by the gap factor)
+     * over all columns.
+     * \param tree_weights weights for sequence pairs during annealing
+     */
+    float expected_score (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const Tree_weights& tree_weights, const float gap_factor) const;
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o,const Alignment_DAG& dag) {
+      for (std::vector<Column*>::const_iterator iter = dag.columns.begin(); iter != dag.columns.end(); ++iter)
+	o << **iter << endl;
+      return o;
+    }
+
+  };
+
+}
+
+#endif /* ALIGNMENT_DAG_INCLUDED */
diff --git a/src/annealing/dotplot.cc b/src/annealing/dotplot.cc
new file mode 100644
index 0000000..d9fcb9f
--- /dev/null
+++ b/src/annealing/dotplot.cc
@@ -0,0 +1,53 @@
+
+/**
+ * \file dotplot.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Ian Holmes, Lars Barquist and Robert Bradley.
+ */
+
+#include "dotplot.h"
+
+using namespace fsa;
+
+Dotplot::Dotplot (const Sequence& x, const Sequence& y)
+  : array2d<double> (x.length(), y.length(), 0.), xseq (x.name), yseq (y.name)
+{ }
+
+void Dotplot::write_dotplot (const std::string& filename, const double cutoff /* = PROB_DISPLAY_CUTOFF */) const
+{
+  std::ofstream file (filename.c_str());
+  if (!file)
+    THROWEXPR ("ERROR: Couldn't create dotplot file with name '" << filename << "'.");
+  // print horizontal sequence axis labels
+  file << ".";
+  for (unsigned x = 0; x < xseq.size(); ++x)
+    file << ' ' << xseq[x];
+  file << '\n';
+  // print rows
+  for (unsigned y = 0; y < yseq.size(); ++y) {
+    file << yseq[y];
+    for (unsigned x = 0; x < xseq.size(); ++x) {
+      const double& p = (*this) (x, y);
+      file << ' ' << (p < cutoff ? '0' : p);
+    }
+    file << '\n';
+  }
+	
+  file.close();
+}
+
+
+void Dotplot::write_dotplot (const std::string& prefix, const std::string& seqname, const double cutoff /* = PROB_DISPLAY_CUTOFF */) const
+{
+  std::string filename;
+  filename += prefix + '-' + seqname;
+  write_dotplot (filename, cutoff);
+}
+
+void Dotplot::write_dotplot (const std::string& prefix, const std::string& xseqname, const std::string& yseqname, const double cutoff /* = PROB_DISPLAY_CUTOFF */) const
+{
+  std::string filename;
+  filename += prefix + '-' + xseqname + '-' + yseqname;
+  write_dotplot (filename, cutoff);
+}
+
diff --git a/src/annealing/dotplot.h b/src/annealing/dotplot.h
new file mode 100644
index 0000000..2a9c430
--- /dev/null
+++ b/src/annealing/dotplot.h
@@ -0,0 +1,62 @@
+
+/**
+ * \file dotplot.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Ian Holmes, Lars Barquist and Robert Bradley.
+ */
+
+#ifndef DOTPLOT_INCLUDED
+#define DOTPLOT_INCLUDED
+
+#define PROB_DISPLAY_CUTOFF 0.01
+
+#include "util/misc.h"
+#include "util/array2d.h"
+#include "seq/sequence.h"
+
+namespace fsa {
+
+  /**
+   * \brief Base class for probability matrices.
+   *
+   * Both alignment and fold (for e.g. Pair SCFGs) dotplots inherit from this class.
+   */
+  struct Dotplot : array2d<double> {
+
+    std::string xseq; ///< x axis label
+    std::string yseq; ///< y axis label
+
+    Dotplot (size_t x, size_t y)
+      : array2d<double> (x, y, 0.) { }
+
+    /**
+     * \brief Constructor.
+     */
+    Dotplot (const Sequence& x, const Sequence& y);
+
+    /**
+     * \brief Output method.
+     *
+     * For e.g. alignment dotplots, output is formatted as:
+     * <cruft>
+     * .   x1   x2   x3
+     * y1  .2   .2   .2
+     * y2  .2   .2   .2
+     */
+    void write_dotplot (const std::string& filename, const double cutoff = PROB_DISPLAY_CUTOFF) const;
+
+    /**
+     * \brief Output method for fold dotplots.
+     */
+    void write_dotplot (const std::string& prefix, const std::string& seqname, const double cutoff = PROB_DISPLAY_CUTOFF) const;
+
+    /**
+     * \brief Output method for alignment dotplots.
+     */
+    void write_dotplot (const std::string& prefix, const std::string& xseqname, const std::string& yseqname, const double cutoff = PROB_DISPLAY_CUTOFF) const;
+
+  };
+
+}
+
+#endif /*DOTPLOT_INCLUDED*/	
diff --git a/src/annealing/tree_weights.cc b/src/annealing/tree_weights.cc
new file mode 100644
index 0000000..6da396c
--- /dev/null
+++ b/src/annealing/tree_weights.cc
@@ -0,0 +1,100 @@
+
+/**
+ * \file tree_weights.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "util/logfile.h"
+#include "annealing/tree_weights.h"
+
+using namespace fsa;
+
+const double Tree_weights::min_sequence_weight = 0.000001;
+
+void Tree_weights::from_file (const Sequence_database& seq_db, const std::string& filename) {
+
+  // mark populated
+  __populated = true;
+
+  // initialize all weights to 0.0
+  __weights.assign (seq_db.size(), std::vector<float> (seq_db.size(), 0.0));
+
+  // read in weights from file
+  std::ifstream filestream (filename.c_str(), std::ifstream::in);
+  if (!filestream.is_open())
+    THROWEXPR ("ERROR: Couldn't open file '" << filename << "'.");
+
+  std::string line;
+  while (!filestream.eof()) {
+    getline (filestream, line);
+    Util::chomp (line);
+    if (!line.length())
+      continue;
+
+    // log
+    if (CTAGGING(-1,TREE_WEIGHTS))
+      CL << line;
+    std::string buffer;
+    // skip comments and sequence names
+    std::stringstream ss (line);
+    std::vector<std::string> tokens; // vector to hold whitespace-separated tokens (words)
+    while (ss >> buffer)
+      tokens.push_back (buffer);
+
+    // skip lines which we don't understand
+    if (tokens.size() != 3) {
+      CTAG(8,ANNEALING) << "WARNING: I'm skipping unparseable line '" << line << "'" << endl;
+      continue;
+    }
+    else if (tokens[0] == tokens[1])
+      THROWEXPR ("ERROR: A sequence can't have a weight with itself!" << endl << line << endl);
+
+    // format is:
+    //   seqX seqY weight
+    // symmetrize as we go
+    if (!seq_db.exists_seq (tokens[0]) || !seq_db.exists_seq (tokens[1]))
+      THROWEXPR ("ERROR: No sequence pair '" << tokens[0] << "' and '" << tokens[1] << "' in sequence file.");
+    const size_t i = seq_db.get_seq_index (tokens[0]);
+    const size_t j = seq_db.get_seq_index (tokens[1]);
+    __weights[i][j] = __weights[j][i] = static_cast<float> (atof (tokens[2].c_str()));
+
+  }
+
+  // normalize weights
+  normalize();
+
+  CTAG(9,ANNEALING) << "Read sequence pair weights from file '" << filename << "'." << endl;
+
+}
+
+void Tree_weights::normalize() {
+
+  const size_t num_seqs = __weights.size();
+  const size_t num_seq_pairs = num_seqs * (num_seqs - 1) / 2;
+
+  std::vector<double> seqtotal (num_seqs, 0.0); // total for single sequences
+  double total = 0.0;                           // total for all sequence pairs
+  for (size_t i = 0; i < num_seqs; ++i) {
+    for (size_t j = i + 1; j < num_seqs; ++j) {
+      seqtotal[i] += __weights[i][j];
+      seqtotal[j] += __weights[i][j];
+      total += __weights[i][j];
+    }
+  }
+  for (size_t i = 0; i < num_seqs; ++i) {
+    if (seqtotal[i] < Tree_weights::min_sequence_weight)
+      THROWEXPR ("ERROR: Weights for sequence " << i << " are too small; the sequence will be left unaligned.");
+  }
+
+  if (total < num_seqs * Tree_weights::min_sequence_weight)
+    THROWEXPR ("ERROR: Sequence pair weights are too small for reliable use.");
+
+  const double scaling = num_seq_pairs / total;
+  for (size_t i = 0; i < num_seqs; ++i) {
+    for (size_t j = i + 1; j < num_seqs; ++j)
+      __weights[i][j] *= scaling;
+  }
+  
+}
+
diff --git a/src/annealing/tree_weights.h b/src/annealing/tree_weights.h
new file mode 100644
index 0000000..8ade11c
--- /dev/null
+++ b/src/annealing/tree_weights.h
@@ -0,0 +1,96 @@
+
+/**
+ * \file tree_weights.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+// to do:
+// - 
+
+#ifndef ANNEALING_TREE_WEIGHTS_INCLUDED
+#define ANNEALING_TREE_WEIGHTS_INCLUDED
+
+#include <iostream>
+#include <map>
+
+#include "util/hash_fcn.h"
+#include "seq/sequence.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a set of (symmetric) weights for sequence pairs.
+   * 
+   * Generally these weights will be derived using a tree relating
+   * the sequences.
+   * If used as an "empty class," without calling the method from_file
+   * to populate the data structures, then the weights will all be set to 1.
+   * This allows the method get_weight to be used transparently both when
+   * weights are given and when they are not.
+   */
+  struct Tree_weights {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * Returns all weights as 1 until populated with from_file.
+     */
+    Tree_weights()
+    : __populated (false)
+    { }
+
+    /**
+     * \brief Read weights from a file.
+     *
+     * Unless particular weights are present in the file,
+     * sets them to 0.  Assumes that weights are symmetric,
+     * i.e., that weight (i, j) == weight (j, i).
+     */
+    void from_file (const Sequence_database& seq_db, const std::string& filename);
+
+    /**
+     * \brief Normalize the weights such that they sum to (N choose 2).
+     *
+     * (N choose 2) is the number of iterations in a sum-of-pairs
+     * operation over N sequences.
+     */
+    void normalize();
+
+    /**
+     * \brief Get the weight for a particular sequence pair.
+     *
+     * This function can be called on an empty instance of this class,
+     * i.e., one for which the data structures have not been populated.
+     * If they have not been, then all weights returned will be 1.
+     * \param i index of first sequence
+     * \param j index of second sequence
+     * \return weight of pair, or 0 if undefined (or always 1 if used as an empty class)
+     */
+    inline float operator() (const size_t i, const size_t j) const;
+
+    static const double min_sequence_weight;           ///< minimum weight for a sequence (summed over pairs)
+
+
+  private:
+
+    bool __populated;                            ///< have we read input data? (all weights = 1 unless true)
+    std::vector<std::vector<float> > __weights;  ///< weights for each sequence pair
+    
+  };
+
+  inline float Tree_weights::operator() (const size_t i, const size_t j) const {
+    // return 1 if we haven't populated the weights
+    if (!__populated)
+      return 1.0;
+    // else look up the appropriate weighta
+    assert (i < __weights.size());
+    assert (j < __weights[i].size());
+    return __weights[i][j];
+  }
+
+}
+
+#endif /* ANNEALING_TREE_WEIGHTS_INCLUDED */
diff --git a/src/fsa/Makefile.am b/src/fsa/Makefile.am
new file mode 100644
index 0000000..91ae267
--- /dev/null
+++ b/src/fsa/Makefile.am
@@ -0,0 +1,37 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src -Wno-deprecated
+
+# AM_CXXFLAGS = -finline-limit=10000 --param inline-unit-growth=70
+# Commented out b/c was causing bugs on some older compilers.
+#  --RKB & CD 4/14/09
+
+if HAVE_CONDOR
+AM_CPPFLAGS += -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+endif
+
+noinst_LIBRARIES = libfsa.a
+
+libfsa_a_SOURCES = \
+	algebras.cc \
+	aminoacid_indel2dp.cc \
+	aminoaciddp.cc \
+	anchors.cc \
+	constraints.cc \
+	fsa.cc \
+	model.cc \
+	nucleotide_indel2dp.cc \
+	nucleotidedp.cc \
+	sequence_pair_selector.cc
+
+noinst_HEADERS = \
+	algebras.h \
+	aminoacid_indel2dp.h \
+	aminoaciddp.h \
+	anchors.h \
+	constraints.h \
+	dptables.h \
+	fsa.h \
+	model.h \
+	mybanding.h \
+	nucleotide_indel2dp.h \
+	nucleotidedp.h \
+	sequence_pair_selector.h
diff --git a/src/fsa/Makefile.in b/src/fsa/Makefile.in
new file mode 100644
index 0000000..fc1c872
--- /dev/null
+++ b/src/fsa/Makefile.in
@@ -0,0 +1,583 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+
+# AM_CXXFLAGS = -finline-limit=10000 --param inline-unit-growth=70
+# Commented out b/c was causing bugs on some older compilers.
+#  --RKB & CD 4/14/09
+ at HAVE_CONDOR_TRUE@am__append_1 = -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+subdir = src/fsa
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libfsa_a_AR = $(AR) $(ARFLAGS)
+libfsa_a_LIBADD =
+am_libfsa_a_OBJECTS = algebras.$(OBJEXT) aminoacid_indel2dp.$(OBJEXT) \
+	aminoaciddp.$(OBJEXT) anchors.$(OBJEXT) constraints.$(OBJEXT) \
+	fsa.$(OBJEXT) model.$(OBJEXT) nucleotide_indel2dp.$(OBJEXT) \
+	nucleotidedp.$(OBJEXT) sequence_pair_selector.$(OBJEXT)
+libfsa_a_OBJECTS = $(am_libfsa_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libfsa_a_SOURCES)
+DIST_SOURCES = $(libfsa_a_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src -Wno-deprecated $(am__append_1)
+noinst_LIBRARIES = libfsa.a
+libfsa_a_SOURCES = \
+	algebras.cc \
+	aminoacid_indel2dp.cc \
+	aminoaciddp.cc \
+	anchors.cc \
+	constraints.cc \
+	fsa.cc \
+	model.cc \
+	nucleotide_indel2dp.cc \
+	nucleotidedp.cc \
+	sequence_pair_selector.cc
+
+noinst_HEADERS = \
+	algebras.h \
+	aminoacid_indel2dp.h \
+	aminoaciddp.h \
+	anchors.h \
+	constraints.h \
+	dptables.h \
+	fsa.h \
+	model.h \
+	mybanding.h \
+	nucleotide_indel2dp.h \
+	nucleotidedp.h \
+	sequence_pair_selector.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/fsa/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/fsa/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libfsa.a: $(libfsa_a_OBJECTS) $(libfsa_a_DEPENDENCIES) $(EXTRA_libfsa_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libfsa.a
+	$(AM_V_AR)$(libfsa_a_AR) libfsa.a $(libfsa_a_OBJECTS) $(libfsa_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libfsa.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/algebras.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/aminoacid_indel2dp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/aminoaciddp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/anchors.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/constraints.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/fsa.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/model.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nucleotide_indel2dp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nucleotidedp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sequence_pair_selector.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/fsa/algebras.cc b/src/fsa/algebras.cc
new file mode 100644
index 0000000..202b2e8
--- /dev/null
+++ b/src/fsa/algebras.cc
@@ -0,0 +1,52 @@
+/*
+ *    This file is part of HMMoC 1.3, a hidden Markov model compiler.
+ *    Copyright (C) 2007 by Gerton Lunter, Oxford University.
+ *
+ *    HMMoC is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    HMMOC is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with HMMoC; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+\*/
+//
+// algebras.cc - extended real types
+//
+// Gerton Lunter, 27/8/04
+//
+//
+
+
+#include "algebras.h"
+
+
+BFMantissa *BFloat::aConversionLookup;           // Actual location of the static members of BFloat class
+double *BFloat::aDoubleConversionLookup;
+
+
+_BFloatInitialize _dummyInitializer;             // This initializes aConversionLookup and aDoubleConversionLookup
+
+
+_BFloatInitialize::_BFloatInitialize() {
+
+  BFloat::aConversionLookup = new BFMantissa[cBFloatConvTableSize];
+  BFloat::aDoubleConversionLookup = new double[cBFloatDoubleConvTableSize];
+
+  BFMantissa iBFM = 1.0;
+  for (int i = 0; i < cBFloatConvTableSize; i++) {
+    BFloat::aConversionLookup[ i ] = iBFM;
+    iBFM *= cBFloatRangeInv;
+  }
+
+  for (int i = 0; i < cBFloatDoubleConvTableSize; i++) {
+    BFloat::aDoubleConversionLookup[ i ] = exp( (i-cBFloatDoubleConvTableSize/2) * logcBFloatRange );
+  }
+
+}
diff --git a/src/fsa/algebras.h b/src/fsa/algebras.h
new file mode 100644
index 0000000..9fe5723
--- /dev/null
+++ b/src/fsa/algebras.h
@@ -0,0 +1,554 @@
+/*
+ *    This file is part of HMMoC 1.3, a hidden Markov model compiler.
+ *    Copyright (C) 2007 by Gerton Lunter, Oxford University.
+ *
+ *    HMMoC is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    HMMOC is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with HMMoC; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+\*/
+//
+// algebras.h - extended real types
+//
+// Gerton Lunter, 27/8/04
+//
+
+#ifndef _algebras_h_
+#define _algebras_h_
+
+#include <ctype.h>
+#include <cstdlib>
+#include <cmath>
+#include <iostream>
+#include <limits>
+#include <string>
+#include <vector>
+
+// below changed to avoid polluting the global namespace
+// -- RKB 12/20/08
+//using namespace std;
+using std::cerr;
+using std::cout;
+using std::endl;
+using std::string;
+using std::vector;
+
+// typedefs
+typedef float BFMantissa;
+const BFMantissa cBFloatRange = 20282409603651670423947251286016.0;  // 2.03e+31; 2^104
+const BFMantissa cBFloatRangeInv = 1.0/cBFloatRange;
+// Aaron E. Darling 6/7/7: need to typecast to avoid compiler warnings about imprecise FP representations
+const BFMantissa cBFloatRangeSqrt    = (BFMantissa)1.0e+18;          // Value between square root of the exponent, and the exponent
+const BFMantissa cBFloatRangeInvSqrt = (BFMantissa)1.0e-18;          // Square of this should still be representable, with full mantissa!
+const BFMantissa logcBFloatRange     = log(cBFloatRange);
+const int cBFloatDigits              = 7;                 // Number of significant digits for printing (7 for floats, 16 for doubles?)
+const int cBFloatInfinity            = 1000000000;        // Tiniest number representable is cBFloatRangeInv ^ BFloatInfinity
+const int cBFloatConvTableSize       = 100;               // This includes many zero entries, it makes additions a bit faster
+const int cBFloatDoubleConvTableSize = 50;                // Table size for bfloat -> double conversion; cBFloatRange^(-size/2) is double 0
+//#define BFLOAT_CHECK_UOFLOW                             // Don't bother with under- and overflow checking.
+
+
+//
+// BFloats: more buoyant floats.
+//
+// struct{ float + int } is 8 bytes; nice size makes noticable speed difference
+//
+class BFloat {                   
+ public:
+  static BFMantissa* aConversionLookup;              // used by addition
+  static double* aDoubleConversionLookup;            // used by Value()
+  BFMantissa f;
+  int e;
+ public:
+  BFloat(BFMantissa iF, int iE) : f(iF), e(iE) {};
+  BFloat() {};
+  ~BFloat() {};
+  inline double Value() const { 
+    if (abs(e) < cBFloatDoubleConvTableSize/2) {
+      return (double)f * aDoubleConversionLookup[ e + cBFloatDoubleConvTableSize/2 ];
+    } else if (e < cBFloatDoubleConvTableSize/2) {
+      return 0.0;
+    } else {
+      return (double)f * exp((double)e * logcBFloatRange);
+    }
+  }
+  void clear() { f=0; e=-cBFloatInfinity; }
+};
+
+
+//
+// dummy class to initialise BFloat lookup table
+//
+class _BFloatInitialize {
+public:
+  _BFloatInitialize();
+};
+
+
+//
+// implementations of BFloat calculations
+//
+
+
+// Normalization of BFloat result of a single operation
+#ifdef BFLOAT_CHECK_UOFLOW
+static inline void BFloatNormalise(BFloat& a)
+     //#define BFloatNormalise(a)
+{\
+  if (a.f > cBFloatRangeSqrt) {\
+    a.f *= cBFloatRangeInv;\
+    a.e++;\
+  } else if (a.f < cBFloatRangeInvSqrt) {\
+    if (a.f == 0.0) {\
+      a.e = -cBFloatInfinity;\
+    } else {\
+      a.f *= cBFloatRange;\
+      a.e--;\
+    }\
+  }\
+  if (a.e > cBFloatInfinity) {\
+    cerr << "BFloat: Overflow" << endl;\
+    a.e = cBFloatInfinity;\
+  } else if (a.e < -cBFloatInfinity) {\
+    cerr << "BFloat: Underflow" << endl;\
+    a.e = -cBFloatInfinity;\
+    a.f = 0.0;\
+  }\
+};
+#else
+static inline void BFloatNormDown(BFloat& a) { 
+  a.f *= cBFloatRangeInv;
+  a.e++;
+}
+static inline void BFloatNormUp(BFloat& a) { 
+  if (a.f == 0.0) {
+    a.e = -cBFloatInfinity;
+  } else {
+    a.f *= cBFloatRange;
+    a.e--;
+  }
+}
+static inline void BFloatNormalise(BFloat& a)
+     //#define BFloatNormalise(a) 
+{
+  if (a.f > cBFloatRangeSqrt) {
+    BFloatNormDown(a);
+  } else if (a.f < cBFloatRangeInvSqrt) {
+    BFloatNormUp(a);
+  }
+};
+#endif
+
+static inline void DoubleNormalise(double& f, int& e)
+{
+  // comparing to 0.0 here fails, because the comparison is done
+  // using higher-precision doubles, but the subsequent while-loop
+  // uses true doubles, resulting in an infinite loop. (G.L. 3/9/07)
+  if (f < std::numeric_limits<double>::min()) {
+    if (f < 0.0) cerr << "BFloat: Negative number: " << f << endl;
+    f = 0.0; 
+    e=-cBFloatInfinity;
+  } else {
+    while (f > (double)cBFloatRangeSqrt) {
+      f *= (double)cBFloatRangeInv;
+      e++;
+    }
+    while (f < (double)cBFloatRangeInvSqrt) {
+      f *= (double)cBFloatRange;
+      e--;
+    }
+  }
+};
+
+// Logarithm of a BFloat
+static inline double bfloat_doublelog( const BFloat& a ) { return a.e*logcBFloatRange+log(a.f); }
+
+// BFloat exp of a double
+static inline BFloat bfloat_doubleexp( double iA ) 
+{
+  int iE = (int)std::floor( iA / log(cBFloatRange) );
+  iA -= iE * log(cBFloatRange);
+  BFloat iX( exp(iA), iE );
+  BFloatNormalise( iX );
+  return iX;
+}
+
+// Returns a double value - or underflow/overflow if it does not fit.
+static inline double bfloat2double( const BFloat bfloat) { return bfloat.Value(); }
+
+// Simplistic double-to-BFloat conversion - can be slow if 'standard' numbers get very large/small
+static inline BFloat double2bfloat( double prob) { 
+  if (prob < std::numeric_limits<double>::min()) {
+    if (prob < 0.0)
+      cerr << "BFloat: Negative number: " << prob << endl;
+    return BFloat (0.0, -cBFloatInfinity );
+  } else {
+    register BFloat a( 0.0, 0 );
+    while (prob > cBFloatRangeSqrt) {
+      prob *= cBFloatRangeInv;
+      a.e++;
+    }
+    while ((prob < cBFloatRangeInvSqrt)) {
+      prob *= cBFloatRange;
+      a.e--;
+    }
+    a.f = prob; 
+    return a;
+  }
+}
+
+static inline BFloat bfloat_pr_product (const BFloat& a, const BFloat& b) 
+{ 
+  register BFloat sf(a.f*b.f,a.e+b.e); 
+  BFloatNormalise(sf); 
+  return sf; 
+}
+
+static inline BFloat bfloat_pr_double_product (const BFloat& a, double b) 
+{ 
+  register double mantisse = a.f*b;
+  int exponent = a.e;
+  DoubleNormalise(mantisse, exponent);
+  return BFloat(mantisse, exponent);
+}
+
+static inline void bfloat_pr_product_accum( BFloat& a, const BFloat& b) { 
+  a.f *= b.f; a.e += b.e; 
+  BFloatNormalise( a ); 
+}
+
+static inline void bfloat_pr_double_product_accum (BFloat& a, double b) 
+{ 
+  register double mantisse = a.f*b;
+  DoubleNormalise(mantisse, a.e);
+  a.f = mantisse;
+}
+
+static inline BFloat bfloat_pr_quotient( const BFloat& a, const BFloat& b) 
+{ 
+  register BFloat sf(a.f/b.f, a.e-b.e); 
+  BFloatNormalise(sf); 
+  return sf;
+}
+  
+static inline void bfloat_pr_quotient_accum( BFloat& a, const BFloat& b) 
+{ 
+  a.f /= b.f; 
+  a.e -= b.e; 
+  BFloatNormalise( a ); 
+}
+
+static inline BFloat bfloat_pr_sum(const BFloat& a, const BFloat& b) 
+{
+  if (a.e > b.e) {
+    if (a.e >= b.e + cBFloatConvTableSize)
+      return a;
+    else
+      return BFloat( a.f + b.f * BFloat::aConversionLookup[ a.e - b.e ], a.e );
+  } else {
+    if (a.e <= b.e - cBFloatConvTableSize)
+      return b;
+    else
+      return BFloat( b.f + a.f * BFloat::aConversionLookup[ b.e - a.e ], b.e );
+  }
+}
+ 
+static inline void bfloat_pr_sum_accum( BFloat& a, const BFloat& b) 
+{
+  if (a.e >= b.e) {
+    if (a.e < b.e + cBFloatConvTableSize)
+      a.f += b.f * BFloat::aConversionLookup[ a.e - b.e ];
+  } else {
+    if (a.e > b.e - cBFloatConvTableSize) {
+      a.f = b.f + a.f * BFloat::aConversionLookup[ b.e - a.e ];
+      a.e = b.e;
+    } else {
+      a = b;
+    }
+  }
+}
+
+static inline bool bfloat_less( const BFloat& a, const BFloat& b) 
+{
+  if (a.e > b.e) {
+    if (a.e >= b.e + cBFloatConvTableSize)
+      return false;
+    else
+      return a.f < b.f * BFloat::aConversionLookup[ a.e - b.e ];
+  }
+  if (a.e <= b.e - cBFloatConvTableSize)
+    return true;
+  else
+    return a.f * BFloat::aConversionLookup[ b.e - a.e ] < b.f;
+};
+  
+static inline bool bfloat_equal( const BFloat& a, const BFloat& b) 
+{
+  if (a.e > b.e) {
+    if (a.e >= b.e + cBFloatConvTableSize)
+      return false;
+    else
+      return a.f == b.f * BFloat::aConversionLookup[ a.e - b.e ];
+  }
+  if (a.e <= b.e - cBFloatConvTableSize)
+    return false;
+  else
+    return a.f * BFloat::aConversionLookup[ b.e - a.e ] == b.f;
+};
+
+static inline bool bfloat_lessequal( const BFloat& a, const BFloat& b) 
+{
+  if (a.e > b.e) {
+    if (a.e >= b.e + cBFloatConvTableSize)
+      return false;
+    else
+      return a.f <= b.f * BFloat::aConversionLookup[ a.e - b.e ];
+  }
+  if (a.e <= b.e - cBFloatConvTableSize)
+    return true;
+  else
+    return a.f * BFloat::aConversionLookup[ b.e - a.e ] <= b.f;
+};
+
+static inline std::ostream& bfloat_print( std::ostream& out, const BFloat& x ) 
+{
+  static const double log10 = log(10.0);
+  static const double maxmantisse = 10.0 * (1.0 - 0.55 * exp(-cBFloatDigits * log10));
+  //out.setf(ios::fixed,ios::floatfield);
+  out.precision( cBFloatDigits );
+  if (x.e == cBFloatInfinity) {
+    out << 1.0 << "e+Inf";
+  }
+  if (x.e == -cBFloatInfinity) {
+    out << 1.0 << "e-Inf";
+  } else {
+    double iM = (log(x.f) + log(cBFloatRange)*(double)x.e) / log10;
+    long iExp = long(std::floor(iM));
+    iM = exp((iM - iExp) * log10);
+    if (iM > maxmantisse) {
+      iExp += 1;
+      iM = 1.0;
+    }
+    out << iM << ( iExp<0 ? "e" : "e+" ) << iExp;
+  }
+  //out.setf(ios::fixed,ios::floatfield);  // default
+  out.precision( 6 );           // default
+  return out;
+}
+
+
+//
+// Wrapper to allow BFloats to be used by Algebra template
+//
+struct BFloatMethods
+{
+  typedef BFloat Value;
+  static inline double to_prob (BFloat iX) { return bfloat2double(iX); }
+  static inline BFloat from_prob (double iP) { return double2bfloat(iP); }
+  static inline BFloat pmul( BFloat iX, BFloat iY) { return bfloat_pr_product(iX,iY); }
+  static inline BFloat pmuldouble( BFloat iX, double iY) { return bfloat_pr_double_product(iX,iY); }
+  static inline BFloat pdiv( BFloat iX, BFloat iY) { return bfloat_pr_quotient(iX,iY); }
+  static inline BFloat psum( BFloat iX, BFloat iY) { return bfloat_pr_sum(iX,iY); }
+  static inline BFloat pdiff( BFloat iX, BFloat iY) { cerr << "Bfloat pdiff: Not implemented." << endl; return BFloat(0,0); }
+  static inline BFloat doubleexp( double iX) { return bfloat_doubleexp(iX); }
+  static inline double doublelog( BFloat iX) { return bfloat_doublelog(iX); }
+  static inline void pmulacc( BFloat& iX, BFloat iY) { bfloat_pr_product_accum(iX,iY); }
+  static inline void pmulaccdouble( BFloat& iX, double iY) { bfloat_pr_double_product_accum(iX,iY); }
+  static inline void pdivacc( BFloat& iX, BFloat iY) { bfloat_pr_quotient_accum(iX,iY); }
+  static inline void psumacc( BFloat& iX, BFloat iY) { bfloat_pr_sum_accum(iX,iY); }
+  static inline void pdiffacc( BFloat& iX, BFloat iY) { cerr << "Bfloat pdiffacc: Not implemented." << endl; }
+  static inline bool less( BFloat iX, BFloat iY) { return bfloat_less(iX,iY); }
+  static inline bool equal( BFloat iX, BFloat iY) { return bfloat_equal(iX,iY); }
+  static inline bool lessequal( BFloat iX, BFloat iY) { return bfloat_lessequal(iX,iY); }
+  static inline std::ostream& print( std::ostream& iOut, BFloat iX ) { return bfloat_print( iOut, iX ); }
+};
+
+
+//
+// Simple log-space numbers - don't use, except possibly for Viterbi
+//
+class Logspace {
+  double x;
+ public:
+  Logspace( double x ) : x(x) {}
+  Logspace() {}
+  operator double&(){ return x; }
+  void clear() {x=-1.0e+300;}
+};
+
+inline Logspace logspace_addsmall( Logspace iX, Logspace iY ) {
+  if (iX - iY > 36.7) return iX;
+  return iX + log(1.0+exp(iY-iX));
+}
+
+inline Logspace logspace_add( Logspace iX, Logspace iY ) {
+  if (iX>iY) return logspace_addsmall(iX,iY); else return logspace_addsmall(iY,iX);
+}
+
+struct LogspaceMethods
+{
+  typedef Logspace Value;
+  static inline double to_prob (Value iX) { return exp(iX); }
+  static inline Value from_prob (double iP) { return Value(log(iP)); }
+  static inline Value pmul( Value iX, Value iY) { return iX+iY; }
+  static inline Value pmuldouble( Value iX, double iY) { return iX+log(iY); }
+  static inline Value pdiv( Value iX, Value iY) { return iX-iY; }
+  static inline Value psum( Value iX, Value iY) { return logspace_add(iX,iY); }
+  static inline Value pdiff( Value iX, Value iY) { cerr << "Logspace pdiff: Not implemented." << endl; return 0.0; }
+  static inline Value doubleexp( double iX) { return iX; }
+  static inline double doublelog( Value iX) { return iX; }
+  static inline void pmulacc( Value& iX, Value iY) { iX+=iY; }
+  static inline void pmulaccdouble( Value& iX, double iY) { iX+=log(iY); }
+  static inline void pdivacc( Value& iX, Value iY) { iX -= iY; }
+  static inline void psumacc( Value& iX, Value iY) { iX = logspace_add(iX,iY); }
+  static inline void pdiffacc( Value& iX, Value iY) { cerr << "Logspace pdiffacc: Not implemented." << endl; }
+  static inline bool less( Value iX, Value iY) { return iX<iY; }
+  static inline bool equal( Value iX, Value iY) { return iX==iY; }
+  static inline bool lessequal( Value iX, Value iY) { return iX<=iY; }
+  static inline std::ostream& print( std::ostream& iOut, Value iX ) { return bfloat_print( iOut, bfloat_doubleexp(iX) ); }
+};
+
+
+//
+// Algebra class - Wrapper for overloading all arithmetic operators to use a different algebra.
+//
+// Gerton Lunter, 19/3/03
+// Based on logprob.h by by Ian Holmes.
+//
+
+template <class AlgebraMethods>
+class Algebra {
+public:
+  // typedef
+  typedef typename AlgebraMethods::Value Value;
+
+  // value
+  Value val;
+
+public:
+  // constructors
+  Algebra() { }  // no initialisation, for speed
+  Algebra (double px) : val(from_prob(px)) { }
+  Algebra (const Algebra& lx) : val(lx.val) { }
+  Algebra (const BFloat v) : val(v) { }
+
+  // fast initialization
+  void clear() { val.clear(); }
+
+  // assignment operators
+  inline Algebra& operator= (const Algebra& lx) { val = lx.val; return *this; }
+  inline Algebra& operator= (double px) { val = from_prob(px); return *this; }
+
+  // arithmetic operators; all combinations of Algebra and double are covered
+  inline friend Algebra operator+ (const Algebra& lx, const Algebra& ly) { return from_log (psum (lx.val, ly.val)); }
+  inline friend Algebra operator+ (const Algebra& lx, double py) { return from_log (psum (lx.val, from_prob(py))); }
+  inline friend Algebra operator+ (double px, const Algebra& ly) { return from_log (psum (from_prob(px), ly.val)); }
+  inline Algebra& operator+= (const Algebra& lx) { psumacc (val, lx.val); return *this; }
+  inline Algebra& operator+= (double px) { psumacc (val, from_prob(px)); return *this; }
+
+  inline friend Algebra operator- (const Algebra& lx, const Algebra& ly) { return from_log (pdiff (lx.val, ly.val)); }
+  inline friend Algebra operator- (const Algebra& lx, double py) { return from_log (pdiff (lx.val, from_prob(py))); }
+  inline friend Algebra operator- (double px, const Algebra& ly) { return from_log (pdiff (from_prob(px), ly.val)); }
+  inline Algebra& operator-= (const Algebra& lx) { pdiffacc (val, lx.val); return *this; }
+  inline Algebra& operator-= (double px) { pdiffacc (val, from_prob(px)); return *this; }
+
+  inline friend Algebra operator* (const Algebra& lx, const Algebra& ly) { return from_log (pmul (lx.val, ly.val)); }
+  inline friend Algebra operator* (const Algebra& lx, double py) { return from_log (pmuldouble (lx.val, py)); }
+  inline friend Algebra operator* (double px, const Algebra& ly) { return from_log (pmuldouble (ly.val, px)); }
+  inline Algebra& operator*= (const Algebra& lx) { pmulacc (val, lx.val); return *this; }
+  inline Algebra& operator*= (double px) { pmulaccdouble (val, px); return *this; }
+
+  inline friend Algebra operator/ (const Algebra& lx, const Algebra& ly) { return from_log (pdiv (lx.val, ly.val)); }
+  inline friend Algebra operator/ (const Algebra& lx, double py) { return from_log (pdiv (lx.val, from_prob(py))); }
+  inline friend Algebra operator/ (double px, const Algebra& ly) { return from_log (pdiv (from_prob(px), ly.val)); }
+  inline Algebra& operator/= (const Algebra& lx) { pdivacc (val, lx.val); return *this; }
+  inline Algebra& operator/= (double px) { pdivacc (val, from_prob(px)); return *this; }
+
+  // miscellaneous operators
+  inline friend double log( const Algebra& lx ) { return doublelog( lx.val ); }
+  inline friend Algebra exp( const Algebra& px ) { return doubleexp( to_prob(px) ); }
+  
+  // increment & decremement
+  Algebra& operator++() { *this += 1.; return *this; }
+  Algebra operator++(int) { Algebra tmp (*this); ++(*this); return tmp; }
+
+  Algebra& operator--() { *this -= 1.; return *this; }
+  Algebra operator--(int) { Algebra tmp (*this); --(*this); return tmp; }
+
+  // relational operators
+  inline friend int operator== (const Algebra& lx, const Algebra& ly) { return equal(lx.val, ly.val); }
+  inline friend int operator== (const Algebra& lx, const double py) { return equal(lx.val, from_prob(py)); }
+  inline friend int operator== (const double px, const Algebra& ly) { return equal(from_prob(px), ly.val); }
+
+  inline friend int operator!= (const Algebra& lx, const Algebra& ly) { return !equal(lx.val, ly.val); }
+  inline friend int operator!= (const Algebra& lx, const double py) { return !equal(lx.val, from_prob(py)); }
+  inline friend int operator!= (const double px, const Algebra& ly) { return !equal(from_prob(px), ly.val); }
+
+  inline friend int operator< (const Algebra& lx, const Algebra& ly) { return less(lx.val, ly.val); }
+  inline friend int operator< (const Algebra& lx, const double py) { return less(lx.val, from_prob(py)); }
+  inline friend int operator< (const double px, const Algebra& ly) { return less(from_prob(px), ly.val); }
+
+  inline friend int operator> (const Algebra& lx, const Algebra& ly) { return less(ly.val, lx.val); }
+  inline friend int operator> (const Algebra& lx, const double py) { return less(from_prob(py), lx.val); }
+  inline friend int operator> (const double px, const Algebra& ly) { return less(ly.val, from_prob(px)); }
+
+  inline friend int operator<= (const Algebra& lx, const Algebra& ly) { return lessequal(lx.val, ly.val); }
+  inline friend int operator<= (const Algebra& lx, const double py) { return lessequal( lx.val, from_prob(py) ); }
+  inline friend int operator<= (const double px, const Algebra& ly) { return lessequal( from_prob(px), ly.val); }
+
+  inline friend int operator>= (const Algebra& lx, const Algebra& ly) { return lessequal( ly.val, lx.val); }
+  inline friend int operator>= (const Algebra& lx, const double py) { return lessequal( from_prob(py), lx.val ); }
+  inline friend int operator>= (const double px, const Algebra& ly) { return lessequal( ly.val, from_prob(px) ); }
+
+  // stream operators
+  inline friend std::ostream& operator<< (std::ostream& out, const Algebra& lx) { return AlgebraMethods::print(out, lx.val); }
+  inline friend std::istream& operator>> (std::istream& in, const Algebra& lx) { double px; in >> px; lx.val = px; return in; }
+
+  // cast operators
+  inline double prob() const { return to_prob (val); }
+  inline operator double() const { return to_prob (val); }
+
+private:
+  // private AlgebraMethods method wrappers
+  static inline double to_prob (Value X) { return AlgebraMethods::to_prob (X); }
+  static inline Value from_prob (double P) { return AlgebraMethods::from_prob (P); }
+  static inline Value pmul (Value X, Value Y) { return AlgebraMethods::pmul (X, Y); }
+  static inline Value pmuldouble (Value X, double Y) { return AlgebraMethods::pmuldouble (X, Y); }
+  static inline Value pdiv (Value X, Value Y) { return AlgebraMethods::pdiv( X, Y); }
+  static inline Value psum (Value X, Value Y) { return AlgebraMethods::psum (X, Y); }
+  static inline Value pdiff (Value X, Value Y) { return AlgebraMethods::pdiff (X, Y); }
+  static inline Value doubleexp (double X) { return AlgebraMethods::doubleexp( X ); }
+  static inline double doublelog (Value X) { return AlgebraMethods::doublelog( X ); }
+  static inline void pmulacc (Value& X, Value Y) { AlgebraMethods::pmulacc (X, Y); }
+  static inline void pmulaccdouble (Value& X, double Y) { AlgebraMethods::pmulaccdouble (X, Y); }
+  static inline void pdivacc( Value& X, Value Y) { AlgebraMethods::pdivacc( X, Y); }
+  static inline void psumacc (Value& X, Value Y) { AlgebraMethods::psumacc (X, Y); }
+  static inline void pdiffacc (Value& X, Value Y) { AlgebraMethods::pdiffacc (X, Y); }
+  static inline bool less (Value X, Value Y ) { return AlgebraMethods::less( X, Y ); }
+  static inline bool equal (Value X, Value Y ) { return AlgebraMethods::equal( X, Y ); }
+  static inline bool lessequal( Value X, Value Y ) { return AlgebraMethods::lessequal( X, Y ); }
+
+public:
+  // static constructor from logspace value
+  static inline Algebra from_log (Value X) { Algebra lx; lx.val = X; return lx; }
+};
+
+
+//
+// and these are the the things that we'll use:
+//
+
+#define bfloat Algebra<BFloatMethods>
+
+#define logspace Algebra<LogspaceMethods>
+
+#endif
diff --git a/src/fsa/aminoacid_indel2dp.cc b/src/fsa/aminoacid_indel2dp.cc
new file mode 100644
index 0000000..a817f93
--- /dev/null
+++ b/src/fsa/aminoacid_indel2dp.cc
@@ -0,0 +1,2445 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file aminoacid_indel2.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:18 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include "aminoacid_indel2dp.h"
+
+#include "mybanding.h"
+
+const extern string _AminoAcidIndel2AlignstateId[];
+const extern string _AminoAcidIndel2AlignemissionId[];
+const extern string _AminoAcidIndel2AligntransitionId[];
+const extern string _AminoAcidIndel2AligntransF[];
+const extern string _AminoAcidIndel2AligntransT[];
+const extern string _AminoAcidIndel2AligntransP[];
+const extern string _AminoAcidIndel2AligntransE[];
+const extern string _AminoAcidIndel2AlignoutputId[];
+const extern string _AminoAcidIndel2Alignempty;
+const extern int _AminoAcidIndel2AlignstateNum;
+const extern int _AminoAcidIndel2AlignemitNum;
+const extern int _AminoAcidIndel2AligntransNum;
+const extern int _AminoAcidIndel2AlignoutputNum;
+
+AminoAcidIndel2AlignDPTable::AminoAcidIndel2AlignDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidIndel2AlignstateId), emissionId(_AminoAcidIndel2AlignemissionId), transitionId(_AminoAcidIndel2AligntransitionId), transitionFrom(_AminoAcidIndel2AligntransF), transitionTo(_AminoAcidIndel2AligntransT), transitionProb(_AminoAcidIndel2AligntransP), transitionEmit(_AminoAcidIndel2AligntransE), outputId(_AminoAcidIndel2AlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaIndel2Block2.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaIndel2Block1.allocate();
+    StateMemoryaaIndel2Block3.allocate();
+}
+
+
+AminoAcidIndel2AlignDPTable::~AminoAcidIndel2AlignDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaIndel2Block2.absolve();
+        StateMemoryaaIndel2Block1.absolve();
+        StateMemoryaaIndel2Block3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidIndel2AlignDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidIndel2AligntransNum ? _AminoAcidIndel2AligntransitionId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignemitNum ? _AminoAcidIndel2AlignemissionId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidIndel2AlignstateNum ? _AminoAcidIndel2AlignstateId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidIndel2AlignoutputNum ? _AminoAcidIndel2AlignoutputId[id] : _AminoAcidIndel2Alignempty; }
+int AminoAcidIndel2AlignDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidIndel2AlignstateNum;i++) {
+            (*pmId)[_AminoAcidIndel2AlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignemitNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AligntransNum; i++) {  
+            (*pmId)[_AminoAcidIndel2AligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignoutputNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidIndel2AlignDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidIndel2AlignDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidIndel2AlignDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block2Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaIndel2Block1Secondary = this->StateMemoryaaIndel2Block1.read();
+            return CurStateMemoryaaIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block2Secondary = this->StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaIndel2Block2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block3Secondary = this->StateMemoryaaIndel2Block3.read();
+            return CurStateMemoryaaIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _AminoAcidIndel2AlignstateId[];
+const extern string _AminoAcidIndel2AlignemissionId[];
+const extern string _AminoAcidIndel2AligntransitionId[];
+const extern string _AminoAcidIndel2AligntransF[];
+const extern string _AminoAcidIndel2AligntransT[];
+const extern string _AminoAcidIndel2AligntransP[];
+const extern string _AminoAcidIndel2AligntransE[];
+const extern string _AminoAcidIndel2AlignoutputId[];
+const extern string _AminoAcidIndel2Alignempty;
+const extern int _AminoAcidIndel2AlignstateNum;
+const extern int _AminoAcidIndel2AlignemitNum;
+const extern int _AminoAcidIndel2AligntransNum;
+const extern int _AminoAcidIndel2AlignoutputNum;
+
+AminoAcidIndel2AlignFoldedDPTable::AminoAcidIndel2AlignFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidIndel2AlignstateId), emissionId(_AminoAcidIndel2AlignemissionId), transitionId(_AminoAcidIndel2AligntransitionId), transitionFrom(_AminoAcidIndel2AligntransF), transitionTo(_AminoAcidIndel2AligntransT), transitionProb(_AminoAcidIndel2AligntransP), transitionEmit(_AminoAcidIndel2AligntransE), outputId(_AminoAcidIndel2AlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaIndel2Block2.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaIndel2Block3.allocate();
+    StateMemoryaaIndel2Block1.allocate();
+}
+
+
+AminoAcidIndel2AlignFoldedDPTable::~AminoAcidIndel2AlignFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaIndel2Block2.absolve();
+        StateMemoryaaIndel2Block3.absolve();
+        StateMemoryaaIndel2Block1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidIndel2AlignFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidIndel2AligntransNum ? _AminoAcidIndel2AligntransitionId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignemitNum ? _AminoAcidIndel2AlignemissionId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignFoldedDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidIndel2AlignstateNum ? _AminoAcidIndel2AlignstateId[id] : _AminoAcidIndel2Alignempty; }
+const string& AminoAcidIndel2AlignFoldedDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidIndel2AlignoutputNum ? _AminoAcidIndel2AlignoutputId[id] : _AminoAcidIndel2Alignempty; }
+int AminoAcidIndel2AlignFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidIndel2AlignstateNum;i++) {
+            (*pmId)[_AminoAcidIndel2AlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignemitNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AligntransNum; i++) {  
+            (*pmId)[_AminoAcidIndel2AligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignoutputNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidIndel2AlignFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidIndel2AlignFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidIndel2AlignFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block2Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaIndel2Block1Secondary = this->StateMemoryaaIndel2Block1.read();
+            return CurStateMemoryaaIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block2Secondary = this->StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaIndel2Block2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block3Secondary = this->StateMemoryaaIndel2Block3.read();
+            return CurStateMemoryaaIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int AminoAcidIndel2AlignBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidIndel2AlignBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int AminoAcidIndel2AlignBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidIndel2AlignBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void AminoAcidIndel2AlignBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
+        for (int i=0; i<23; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AligntransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int AminoAcidIndel2AlignBaumWelch::transitionIdentifier00[];
+int AminoAcidIndel2AlignBaumWelch::emissionIdentifier00[];
+int AminoAcidIndel2AlignBaumWelch::emissionIdentifier01[];
+int AminoAcidIndel2AlignBaumWelch::emissionIdentifier10[];
+int AminoAcidIndel2AlignBaumWelch::emissionIdentifier11[];
+
+void AminoAcidIndel2AlignBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> AminoAcidIndel2AlignBaumWelch::mId;
+int AminoAcidIndel2AlignBaumWelch::atransitionIdx[];
+int AminoAcidIndel2AlignBaumWelch::aemissionIdx[];
+
+const extern string _AminoAcidIndel2AlignWithBandingstateId[];
+const extern string _AminoAcidIndel2AlignWithBandingemissionId[];
+const extern string _AminoAcidIndel2AlignWithBandingtransitionId[];
+const extern string _AminoAcidIndel2AlignWithBandingtransF[];
+const extern string _AminoAcidIndel2AlignWithBandingtransT[];
+const extern string _AminoAcidIndel2AlignWithBandingtransP[];
+const extern string _AminoAcidIndel2AlignWithBandingtransE[];
+const extern string _AminoAcidIndel2AlignWithBandingoutputId[];
+const extern string _AminoAcidIndel2AlignWithBandingempty;
+const extern int _AminoAcidIndel2AlignWithBandingstateNum;
+const extern int _AminoAcidIndel2AlignWithBandingemitNum;
+const extern int _AminoAcidIndel2AlignWithBandingtransNum;
+const extern int _AminoAcidIndel2AlignWithBandingoutputNum;
+
+AminoAcidIndel2AlignWithBandingDPTable::AminoAcidIndel2AlignWithBandingDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidIndel2AlignWithBandingstateId), emissionId(_AminoAcidIndel2AlignWithBandingemissionId), transitionId(_AminoAcidIndel2AlignWithBandingtransitionId), transitionFrom(_AminoAcidIndel2AlignWithBandingtransF), transitionTo(_AminoAcidIndel2AlignWithBandingtransT), transitionProb(_AminoAcidIndel2AlignWithBandingtransP), transitionEmit(_AminoAcidIndel2AlignWith [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaIndel2Block1.allocate();
+    StateMemoryaaIndel2Block3.allocate();
+}
+
+
+AminoAcidIndel2AlignWithBandingDPTable::~AminoAcidIndel2AlignWithBandingDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaIndel2Block2withbanding.absolve();
+        StateMemoryaaIndel2Block1.absolve();
+        StateMemoryaaIndel2Block3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidIndel2AlignWithBandingDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingtransNum ? _AminoAcidIndel2AlignWithBandingtransitionId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingemitNum ? _AminoAcidIndel2AlignWithBandingemissionId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingstateNum ? _AminoAcidIndel2AlignWithBandingstateId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingoutputNum ? _AminoAcidIndel2AlignWithBandingoutputId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+int AminoAcidIndel2AlignWithBandingDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidIndel2AlignWithBandingstateNum;i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingemitNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingtransNum; i++) {  
+            (*pmId)[_AminoAcidIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingoutputNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidIndel2AlignWithBandingDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidIndel2AlignWithBandingDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidIndel2AlignWithBandingDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaIndel2Block1Secondary = this->StateMemoryaaIndel2Block1.read();
+            return CurStateMemoryaaIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block2withbandingSecondary = this->StateMemoryaaIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaIndel2Block2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block3Secondary = this->StateMemoryaaIndel2Block3.read();
+            return CurStateMemoryaaIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _AminoAcidIndel2AlignWithBandingstateId[];
+const extern string _AminoAcidIndel2AlignWithBandingemissionId[];
+const extern string _AminoAcidIndel2AlignWithBandingtransitionId[];
+const extern string _AminoAcidIndel2AlignWithBandingtransF[];
+const extern string _AminoAcidIndel2AlignWithBandingtransT[];
+const extern string _AminoAcidIndel2AlignWithBandingtransP[];
+const extern string _AminoAcidIndel2AlignWithBandingtransE[];
+const extern string _AminoAcidIndel2AlignWithBandingoutputId[];
+const extern string _AminoAcidIndel2AlignWithBandingempty;
+const extern int _AminoAcidIndel2AlignWithBandingstateNum;
+const extern int _AminoAcidIndel2AlignWithBandingemitNum;
+const extern int _AminoAcidIndel2AlignWithBandingtransNum;
+const extern int _AminoAcidIndel2AlignWithBandingoutputNum;
+
+AminoAcidIndel2AlignWithBandingFoldedDPTable::AminoAcidIndel2AlignWithBandingFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidIndel2AlignWithBandingstateId), emissionId(_AminoAcidIndel2AlignWithBandingemissionId), transitionId(_AminoAcidIndel2AlignWithBandingtransitionId), transitionFrom(_AminoAcidIndel2AlignWithBandingtransF), transitionTo(_AminoAcidIndel2AlignWithBandingtransT), transitionProb(_AminoAcidIndel2AlignWithBandingtransP), transitionEmit(_AminoAcidInd [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaIndel2Block3.allocate();
+    StateMemoryaaIndel2Block1.allocate();
+}
+
+
+AminoAcidIndel2AlignWithBandingFoldedDPTable::~AminoAcidIndel2AlignWithBandingFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaIndel2Block2withbanding.absolve();
+        StateMemoryaaIndel2Block3.absolve();
+        StateMemoryaaIndel2Block1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidIndel2AlignWithBandingFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingtransNum ? _AminoAcidIndel2AlignWithBandingtransitionId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingemitNum ? _AminoAcidIndel2AlignWithBandingemissionId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingFoldedDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingstateNum ? _AminoAcidIndel2AlignWithBandingstateId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+const string& AminoAcidIndel2AlignWithBandingFoldedDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidIndel2AlignWithBandingoutputNum ? _AminoAcidIndel2AlignWithBandingoutputId[id] : _AminoAcidIndel2AlignWithBandingempty; }
+int AminoAcidIndel2AlignWithBandingFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidIndel2AlignWithBandingstateNum;i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingemitNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingtransNum; i++) {  
+            (*pmId)[_AminoAcidIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidIndel2AlignWithBandingoutputNum; i++) {
+            (*pmId)[_AminoAcidIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidIndel2AlignWithBandingFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidIndel2AlignWithBandingFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidIndel2AlignWithBandingFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaIndel2Block1Secondary = this->StateMemoryaaIndel2Block1.read();
+            return CurStateMemoryaaIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block2withbandingSecondary = this->StateMemoryaaIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaIndel2Block2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaIndel2Block3Secondary = this->StateMemoryaaIndel2Block3.read();
+            return CurStateMemoryaaIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int AminoAcidIndel2AlignWithBandingBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidIndel2AlignWithBandingBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int AminoAcidIndel2AlignWithBandingBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidIndel2AlignWithBandingBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void AminoAcidIndel2AlignWithBandingBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
+        for (int i=0; i<23; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignWithBandingtransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int AminoAcidIndel2AlignWithBandingBaumWelch::transitionIdentifier00[];
+int AminoAcidIndel2AlignWithBandingBaumWelch::emissionIdentifier00[];
+int AminoAcidIndel2AlignWithBandingBaumWelch::emissionIdentifier01[];
+int AminoAcidIndel2AlignWithBandingBaumWelch::emissionIdentifier10[];
+int AminoAcidIndel2AlignWithBandingBaumWelch::emissionIdentifier11[];
+
+void AminoAcidIndel2AlignWithBandingBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> AminoAcidIndel2AlignWithBandingBaumWelch::mId;
+int AminoAcidIndel2AlignWithBandingBaumWelch::atransitionIdx[];
+int AminoAcidIndel2AlignWithBandingBaumWelch::aemissionIdx[];
+
+const string _AminoAcidIndel2AlignstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
+const string _AminoAcidIndel2AlignemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _AminoAcidIndel2AligntransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
+const string _AminoAcidIndel2AligntransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
+const string _AminoAcidIndel2AligntransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
+const string _AminoAcidIndel2AligntransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
+const string _AminoAcidIndel2AligntransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _AminoAcidIndel2AlignoutputId[] = {"sequence1","sequence2"};
+const string _AminoAcidIndel2Alignempty = "";
+const int _AminoAcidIndel2AlignstateNum = 7;
+const int _AminoAcidIndel2AlignemitNum = 4;
+const int _AminoAcidIndel2AligntransNum = 23;
+const int _AminoAcidIndel2AlignoutputNum = 2;
+
+
+
+
+bfloat Forward(AminoAcidIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2To;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    const bfloat *CurStateMemoryaaIndel2Block2From;
+    bfloat *CurStateMemoryaaIndel2Block3To;
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidIndel2AlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemoryaaIndel2Block1.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block1.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=0; iPos1<iLen2+1; ++iPos1) {
+        for (int iPos0=0; iPos0<iLen1+1; ++iPos0) {
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+            }
+            if (1) {
+                if ((iPos1+-1>=0)) {
+                    iSymbol[0] = iSequence2[iPos1+-1];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+-1>=0)) {
+                    iSymbol[1] = iSequence1[iPos0+-1];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block2To = dp.StateMemoryaaIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+0<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                    CurStateMemoryaaIndel2Block2To[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                    CurStateMemoryaaIndel2Block2To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                }
+                if ((iPos1+-1>=0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(1))-(0));
+                    CurStateMemoryaaIndel2Block2To[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    CurStateMemoryaaIndel2Block2To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+0<=0)) {
+                    CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                    CurStateMemoryaaIndel2Block2To[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                    CurStateMemoryaaIndel2Block2To[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                }
+                if ((iPos0+-1>=0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block2To[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block2To[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                    CurStateMemoryaaIndel2Block2To[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                }
+                if ((iPos0+-1>=0)&&(iPos1+-1>=0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(1))-(0), (iPos1-(1))-(0));
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                }
+                dp.StateMemoryaaIndel2Block2.written();
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                CurStateMemoryaaIndel2Block3To = dp.StateMemoryaaIndel2Block3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block3To[0] = ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                }
+                dp.StateMemoryaaIndel2Block3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block3From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidIndel2AlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelch(AminoAcidIndel2AlignBaumWelch& bw,AminoAcidIndel2AlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2To;
+    const bfloat *CurStateMemoryaaIndel2Block2Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block2From;
+    unsigned char alphaSymbolaminoacid[20] = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'};
+    unsigned char alphaIndexaminoacid[256];
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    bfloat *CurStateMemoryaaIndel2Block1To;
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    AminoAcidIndel2AlignFoldedDPTable dp(iLen1,2);
+    AminoAcidIndel2AlignDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexaminoacid[i]=0;
+    }
+
+//    for (int i=0; i<20; i++) {
+//        alphaIndexaminoacid[alphaSymbolaminoacid[i]]=i;
+//    }
+    for (int i=0; i<20; i++) {
+      alphaIndexaminoacid[tolower (alphaSymbolaminoacid[i])] = i;
+      alphaIndexaminoacid[toupper (alphaSymbolaminoacid[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemoryaaIndel2Block3.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block3Secondary = dp2.StateMemoryaaIndel2Block3.read();
+            iTempProb[2] = CurStateMemoryaaIndel2Block3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if (iPrevSlowCoord != -1 && iPrevSlowCoord != iPos1) {
+                dp.StateMemoryaaIndel2Block2.clear(iPos1);
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block2To = dp.StateMemoryaaIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                CurStateMemoryaaIndel2Block2Secondary = dp2.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block2To[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[15] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[21] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block2To[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[18] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block2To[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[14] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[17] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[20] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+                    CurStateMemoryaaIndel2Block2To[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[13] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[16] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[19] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[22] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block2To[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                }
+                dp.StateMemoryaaIndel2Block2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block1To = dp.StateMemoryaaIndel2Block1.write();
+                CurStateMemoryaaIndel2Block1Secondary = dp2.StateMemoryaaIndel2Block1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemoryaaIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat Backward(AminoAcidIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2To;
+    const bfloat *CurStateMemoryaaIndel2Block2From;
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    bfloat *CurStateMemoryaaIndel2Block1To;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidIndel2AlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemoryaaIndel2Block3.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block2To = dp.StateMemoryaaIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block2To[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    CurStateMemoryaaIndel2Block2To[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                    CurStateMemoryaaIndel2Block2To[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block2To[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                    CurStateMemoryaaIndel2Block2To[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block2To[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                    CurStateMemoryaaIndel2Block2To[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+                    CurStateMemoryaaIndel2Block2To[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    CurStateMemoryaaIndel2Block2To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    CurStateMemoryaaIndel2Block2To[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    CurStateMemoryaaIndel2Block2To[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    CurStateMemoryaaIndel2Block2To[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                }
+                dp.StateMemoryaaIndel2Block2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block1To = dp.StateMemoryaaIndel2Block1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[0];
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[2];
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2From = dp.StateMemoryaaIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block2From[3];
+                }
+                dp.StateMemoryaaIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block1From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidIndel2AlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+const string _AminoAcidIndel2AlignWithBandingstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
+const string _AminoAcidIndel2AlignWithBandingemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _AminoAcidIndel2AlignWithBandingtransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
+const string _AminoAcidIndel2AlignWithBandingtransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
+const string _AminoAcidIndel2AlignWithBandingtransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
+const string _AminoAcidIndel2AlignWithBandingtransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
+const string _AminoAcidIndel2AlignWithBandingtransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _AminoAcidIndel2AlignWithBandingoutputId[] = {"sequence1","sequence2"};
+const string _AminoAcidIndel2AlignWithBandingempty = "";
+const int _AminoAcidIndel2AlignWithBandingstateNum = 7;
+const int _AminoAcidIndel2AlignWithBandingemitNum = 4;
+const int _AminoAcidIndel2AlignWithBandingtransNum = 23;
+const int _AminoAcidIndel2AlignWithBandingoutputNum = 2;
+
+
+
+
+bfloat ForwardBanding(AminoAcidIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2withbandingTo;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingFrom;
+    bfloat *CurStateMemoryaaIndel2Block3To;
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemoryaaIndel2Block1.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block1.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.forwardIterator();
+        bool bLastSlowCoordInited = false;
+        int iLastSlowCoord = -1;  
+        do {
+            if (bLastSlowCoordInited) {
+                if (iLastSlowCoord > position[1]) {
+                    cout << "WARNING: Banding (forward): Slowest coordinate should be nondecreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+                }
+                } else {
+                bLastSlowCoordInited = true;
+            }
+            iLastSlowCoord = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+-1>=0)) {
+                        iSymbol[0] = iSequence2[position[1]+-1];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+-1>=0)) {
+                        iSymbol[1] = iSequence1[position[0]+-1];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaIndel2Block2withbandingTo = dp.StateMemoryaaIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+0<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                    }
+                    if ((position[1]+-1>=0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+0<=0)) {
+                        CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                    }
+                    if ((position[0]+-1>=0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block1From[0];
+                    }
+                    if ((position[0]+-1>=0)&&(position[1]+-1>=0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                    }
+                    dp.StateMemoryaaIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextForward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                CurStateMemoryaaIndel2Block3To = dp.StateMemoryaaIndel2Block3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block3To[0] = ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                    CurStateMemoryaaIndel2Block3To[0] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                }
+                dp.StateMemoryaaIndel2Block3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block3From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidIndel2AlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelchBanding(AminoAcidIndel2AlignWithBandingBaumWelch& bw,AminoAcidIndel2AlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    const bfloat *CurStateMemoryaaIndel2Block3Secondary;
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2withbandingTo;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingFrom;
+    unsigned char alphaSymbolaminoacid[20] = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'};
+    unsigned char alphaIndexaminoacid[256];
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    bfloat *CurStateMemoryaaIndel2Block1To;
+    const bfloat *CurStateMemoryaaIndel2Block1Secondary;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    AminoAcidIndel2AlignWithBandingFoldedDPTable dp(iLen1,2);
+    AminoAcidIndel2AlignWithBandingDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexaminoacid[i]=0;
+    }
+
+//    for (int i=0; i<20; i++) {
+//        alphaIndexaminoacid[alphaSymbolaminoacid[i]]=i;
+//    }
+    for (int i=0; i<20; i++) {
+      alphaIndexaminoacid[tolower (alphaSymbolaminoacid[i])] = i;
+      alphaIndexaminoacid[toupper (alphaSymbolaminoacid[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemoryaaIndel2Block3.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block3Secondary = dp2.StateMemoryaaIndel2Block3.read();
+            iTempProb[2] = CurStateMemoryaaIndel2Block3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (iPrevSlowCoord != -1 && iPrevSlowCoord != position[1]) {
+                    dp.StateMemoryaaIndel2Block2withbanding.clear(position[1]);
+                }
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaIndel2Block2withbandingTo = dp.StateMemoryaaIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    CurStateMemoryaaIndel2Block2withbandingSecondary = dp2.StateMemoryaaIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[21] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[15] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[18] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[20] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[14] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[17] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[22] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[16] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[13] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemoryaaIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[19] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    }
+                    dp.StateMemoryaaIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block1To = dp.StateMemoryaaIndel2Block1.write();
+                CurStateMemoryaaIndel2Block1Secondary = dp2.StateMemoryaaIndel2Block1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                    iTempProb[1] *= CurStateMemoryaaIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemoryaaIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBanding(AminoAcidIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemoryaaIndel2Block2withbandingTo;
+    const bfloat *CurStateMemoryaaIndel2Block2withbandingFrom;
+    const bfloat *CurStateMemoryaaIndel2Block3From;
+    bfloat *CurStateMemoryaaIndel2Block1To;
+    const bfloat *CurStateMemoryaaIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemoryaaIndel2Block3.write()[0] = 1.0;
+    dp.StateMemoryaaIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaIndel2Block2withbandingTo = dp.StateMemoryaaIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemoryaaIndel2Block3From = dp.StateMemoryaaIndel2Block3.read();
+                        CurStateMemoryaaIndel2Block2withbandingTo[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                        CurStateMemoryaaIndel2Block2withbandingTo[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemoryaaIndel2Block3From[0];
+                    }
+                    dp.StateMemoryaaIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaIndel2Block1To = dp.StateMemoryaaIndel2Block1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[0];
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[2];
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaIndel2Block2withbandingFrom = dp.StateMemoryaaIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaIndel2Block2withbandingFrom[3];
+                }
+                dp.StateMemoryaaIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaIndel2Block1From = dp.StateMemoryaaIndel2Block1.read();
+            iTempProb[0] = CurStateMemoryaaIndel2Block1From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidIndel2AlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/aminoacid_indel2dp.h b/src/fsa/aminoacid_indel2dp.h
new file mode 100644
index 0000000..84bae41
--- /dev/null
+++ b/src/fsa/aminoacid_indel2dp.h
@@ -0,0 +1,315 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file aminoacid_indel2.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:18 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _aminoacid_indel2dp_h_
+#define _aminoacid_indel2dp_h_
+
+
+#include "dptables.h"
+#include "algebras.h"
+#include <string>
+
+#include <map>
+
+using std::map;
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesaaIndel2Block2;
+typedef States<bfloat,1> StatesaaIndel2Block1;
+typedef States<bfloat,1> StatesaaIndel2Block3;
+
+class AminoAcidIndel2AlignDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesaaIndel2Block2,2> StateMemoryaaIndel2Block2;
+    DPTable<StatesaaIndel2Block1,0> StateMemoryaaIndel2Block1;
+    DPTable<StatesaaIndel2Block3,0> StateMemoryaaIndel2Block3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidIndel2AlignDPTable(int iLen1,int iLen2);
+    ~AminoAcidIndel2AlignDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat AminoAcidIndel2AlignReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double AminoAcidIndel2AlignShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesaaIndel2Block2;
+typedef States<bfloat,1> StatesaaIndel2Block3;
+typedef States<bfloat,1> StatesaaIndel2Block1;
+
+class AminoAcidIndel2AlignFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesaaIndel2Block2,2> StateMemoryaaIndel2Block2;
+    DPTable<StatesaaIndel2Block3,0> StateMemoryaaIndel2Block3;
+    DPTable<StatesaaIndel2Block1,0> StateMemoryaaIndel2Block1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidIndel2AlignFoldedDPTable(int iLen1,int iLen2);
+    ~AminoAcidIndel2AlignFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class AminoAcidIndel2AlignBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    AminoAcidIndel2AlignBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[23];
+    static int transitionIdentifier00[23];   
+    static const int transitionDimension00 = 23;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[20][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[20][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[20][20][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[23];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesaaIndel2Block2withbanding;
+typedef States<bfloat,1> StatesaaIndel2Block1;
+typedef States<bfloat,1> StatesaaIndel2Block3;
+
+class AminoAcidIndel2AlignWithBandingDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesaaIndel2Block2withbanding,2> StateMemoryaaIndel2Block2withbanding;
+    DPTable<StatesaaIndel2Block1,0> StateMemoryaaIndel2Block1;
+    DPTable<StatesaaIndel2Block3,0> StateMemoryaaIndel2Block3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidIndel2AlignWithBandingDPTable(int iLen1,int iLen2);
+    ~AminoAcidIndel2AlignWithBandingDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat AminoAcidIndel2AlignWithBandingReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double AminoAcidIndel2AlignWithBandingShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesaaIndel2Block2withbanding;
+typedef States<bfloat,1> StatesaaIndel2Block3;
+typedef States<bfloat,1> StatesaaIndel2Block1;
+
+class AminoAcidIndel2AlignWithBandingFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesaaIndel2Block2withbanding,2> StateMemoryaaIndel2Block2withbanding;
+    DPTable<StatesaaIndel2Block3,0> StateMemoryaaIndel2Block3;
+    DPTable<StatesaaIndel2Block1,0> StateMemoryaaIndel2Block1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidIndel2AlignWithBandingFoldedDPTable(int iLen1,int iLen2);
+    ~AminoAcidIndel2AlignWithBandingFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class AminoAcidIndel2AlignWithBandingBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    AminoAcidIndel2AlignWithBandingBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[23];
+    static int transitionIdentifier00[23];   
+    static const int transitionDimension00 = 23;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[20][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[20][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[20][20][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[23];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+bfloat Forward(AminoAcidIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat BackwardBaumWelch(AminoAcidIndel2AlignBaumWelch& bw,AminoAcidIndel2AlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat Backward(AminoAcidIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat ForwardBanding(AminoAcidIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBaumWelchBanding(AminoAcidIndel2AlignWithBandingBaumWelch& bw,AminoAcidIndel2AlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBanding(AminoAcidIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+#endif // _aminoacid_indel2dp_h_
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/aminoaciddp.cc b/src/fsa/aminoaciddp.cc
new file mode 100644
index 0000000..ff4863a
--- /dev/null
+++ b/src/fsa/aminoaciddp.cc
@@ -0,0 +1,2205 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file aminoacid.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:18 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include "aminoaciddp.h"
+
+#include "mybanding.h"
+
+const extern string _AminoAcidAlignstateId[];
+const extern string _AminoAcidAlignemissionId[];
+const extern string _AminoAcidAligntransitionId[];
+const extern string _AminoAcidAligntransF[];
+const extern string _AminoAcidAligntransT[];
+const extern string _AminoAcidAligntransP[];
+const extern string _AminoAcidAligntransE[];
+const extern string _AminoAcidAlignoutputId[];
+const extern string _AminoAcidAlignempty;
+const extern int _AminoAcidAlignstateNum;
+const extern int _AminoAcidAlignemitNum;
+const extern int _AminoAcidAligntransNum;
+const extern int _AminoAcidAlignoutputNum;
+
+AminoAcidAlignDPTable::AminoAcidAlignDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidAlignstateId), emissionId(_AminoAcidAlignemissionId), transitionId(_AminoAcidAligntransitionId), transitionFrom(_AminoAcidAligntransF), transitionTo(_AminoAcidAligntransT), transitionProb(_AminoAcidAligntransP), transitionEmit(_AminoAcidAligntransE), outputId(_AminoAcidAlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaBlock2.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaBlock1.allocate();
+    StateMemoryaaBlock3.allocate();
+}
+
+
+AminoAcidAlignDPTable::~AminoAcidAlignDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaBlock2.absolve();
+        StateMemoryaaBlock1.absolve();
+        StateMemoryaaBlock3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidAlignDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidAligntransNum ? _AminoAcidAligntransitionId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidAlignemitNum ? _AminoAcidAlignemissionId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidAlignstateNum ? _AminoAcidAlignstateId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidAlignoutputNum ? _AminoAcidAlignoutputId[id] : _AminoAcidAlignempty; }
+int AminoAcidAlignDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidAlignstateNum;i++) {
+            (*pmId)[_AminoAcidAlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignemitNum; i++) {
+            (*pmId)[_AminoAcidAlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidAligntransNum; i++) {  
+            (*pmId)[_AminoAcidAligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignoutputNum; i++) {
+            (*pmId)[_AminoAcidAlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidAlignDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidAlignDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidAlignDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock2Secondary;
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaBlock1Secondary = this->StateMemoryaaBlock1.read();
+            return CurStateMemoryaaBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock2Secondary = this->StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaBlock2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock3Secondary = this->StateMemoryaaBlock3.read();
+            return CurStateMemoryaaBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _AminoAcidAlignstateId[];
+const extern string _AminoAcidAlignemissionId[];
+const extern string _AminoAcidAligntransitionId[];
+const extern string _AminoAcidAligntransF[];
+const extern string _AminoAcidAligntransT[];
+const extern string _AminoAcidAligntransP[];
+const extern string _AminoAcidAligntransE[];
+const extern string _AminoAcidAlignoutputId[];
+const extern string _AminoAcidAlignempty;
+const extern int _AminoAcidAlignstateNum;
+const extern int _AminoAcidAlignemitNum;
+const extern int _AminoAcidAligntransNum;
+const extern int _AminoAcidAlignoutputNum;
+
+AminoAcidAlignFoldedDPTable::AminoAcidAlignFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidAlignstateId), emissionId(_AminoAcidAlignemissionId), transitionId(_AminoAcidAligntransitionId), transitionFrom(_AminoAcidAligntransF), transitionTo(_AminoAcidAligntransT), transitionProb(_AminoAcidAligntransP), transitionEmit(_AminoAcidAligntransE), outputId(_AminoAcidAlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaBlock2.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaBlock3.allocate();
+    StateMemoryaaBlock1.allocate();
+}
+
+
+AminoAcidAlignFoldedDPTable::~AminoAcidAlignFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaBlock2.absolve();
+        StateMemoryaaBlock3.absolve();
+        StateMemoryaaBlock1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidAlignFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidAligntransNum ? _AminoAcidAligntransitionId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidAlignemitNum ? _AminoAcidAlignemissionId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignFoldedDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidAlignstateNum ? _AminoAcidAlignstateId[id] : _AminoAcidAlignempty; }
+const string& AminoAcidAlignFoldedDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidAlignoutputNum ? _AminoAcidAlignoutputId[id] : _AminoAcidAlignempty; }
+int AminoAcidAlignFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidAlignstateNum;i++) {
+            (*pmId)[_AminoAcidAlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignemitNum; i++) {
+            (*pmId)[_AminoAcidAlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidAligntransNum; i++) {  
+            (*pmId)[_AminoAcidAligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignoutputNum; i++) {
+            (*pmId)[_AminoAcidAlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidAlignFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidAlignFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidAlignFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock2Secondary;
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaBlock1Secondary = this->StateMemoryaaBlock1.read();
+            return CurStateMemoryaaBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock2Secondary = this->StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaBlock2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock3Secondary = this->StateMemoryaaBlock3.read();
+            return CurStateMemoryaaBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int AminoAcidAlignBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidAlignBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int AminoAcidAlignBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidAlignBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void AminoAcidAlignBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+        for (int i=0; i<13; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAligntransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int AminoAcidAlignBaumWelch::transitionIdentifier00[];
+int AminoAcidAlignBaumWelch::emissionIdentifier00[];
+int AminoAcidAlignBaumWelch::emissionIdentifier01[];
+int AminoAcidAlignBaumWelch::emissionIdentifier10[];
+int AminoAcidAlignBaumWelch::emissionIdentifier11[];
+
+void AminoAcidAlignBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> AminoAcidAlignBaumWelch::mId;
+int AminoAcidAlignBaumWelch::atransitionIdx[];
+int AminoAcidAlignBaumWelch::aemissionIdx[];
+
+const extern string _AminoAcidAlignWithBandingstateId[];
+const extern string _AminoAcidAlignWithBandingemissionId[];
+const extern string _AminoAcidAlignWithBandingtransitionId[];
+const extern string _AminoAcidAlignWithBandingtransF[];
+const extern string _AminoAcidAlignWithBandingtransT[];
+const extern string _AminoAcidAlignWithBandingtransP[];
+const extern string _AminoAcidAlignWithBandingtransE[];
+const extern string _AminoAcidAlignWithBandingoutputId[];
+const extern string _AminoAcidAlignWithBandingempty;
+const extern int _AminoAcidAlignWithBandingstateNum;
+const extern int _AminoAcidAlignWithBandingemitNum;
+const extern int _AminoAcidAlignWithBandingtransNum;
+const extern int _AminoAcidAlignWithBandingoutputNum;
+
+AminoAcidAlignWithBandingDPTable::AminoAcidAlignWithBandingDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidAlignWithBandingstateId), emissionId(_AminoAcidAlignWithBandingemissionId), transitionId(_AminoAcidAlignWithBandingtransitionId), transitionFrom(_AminoAcidAlignWithBandingtransF), transitionTo(_AminoAcidAlignWithBandingtransT), transitionProb(_AminoAcidAlignWithBandingtransP), transitionEmit(_AminoAcidAlignWithBandingtransE), outputId(_AminoAcidAlignWithBandingout [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaBlock2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaBlock1.allocate();
+    StateMemoryaaBlock3.allocate();
+}
+
+
+AminoAcidAlignWithBandingDPTable::~AminoAcidAlignWithBandingDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaBlock2withbanding.absolve();
+        StateMemoryaaBlock1.absolve();
+        StateMemoryaaBlock3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidAlignWithBandingDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingtransNum ? _AminoAcidAlignWithBandingtransitionId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingemitNum ? _AminoAcidAlignWithBandingemissionId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingstateNum ? _AminoAcidAlignWithBandingstateId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingoutputNum ? _AminoAcidAlignWithBandingoutputId[id] : _AminoAcidAlignWithBandingempty; }
+int AminoAcidAlignWithBandingDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidAlignWithBandingstateNum;i++) {
+            (*pmId)[_AminoAcidAlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingemitNum; i++) {
+            (*pmId)[_AminoAcidAlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingtransNum; i++) {  
+            (*pmId)[_AminoAcidAlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingoutputNum; i++) {
+            (*pmId)[_AminoAcidAlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidAlignWithBandingDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidAlignWithBandingDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidAlignWithBandingDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock2withbandingSecondary;
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaBlock1Secondary = this->StateMemoryaaBlock1.read();
+            return CurStateMemoryaaBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock2withbandingSecondary = this->StateMemoryaaBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaBlock2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock3Secondary = this->StateMemoryaaBlock3.read();
+            return CurStateMemoryaaBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _AminoAcidAlignWithBandingstateId[];
+const extern string _AminoAcidAlignWithBandingemissionId[];
+const extern string _AminoAcidAlignWithBandingtransitionId[];
+const extern string _AminoAcidAlignWithBandingtransF[];
+const extern string _AminoAcidAlignWithBandingtransT[];
+const extern string _AminoAcidAlignWithBandingtransP[];
+const extern string _AminoAcidAlignWithBandingtransE[];
+const extern string _AminoAcidAlignWithBandingoutputId[];
+const extern string _AminoAcidAlignWithBandingempty;
+const extern int _AminoAcidAlignWithBandingstateNum;
+const extern int _AminoAcidAlignWithBandingemitNum;
+const extern int _AminoAcidAlignWithBandingtransNum;
+const extern int _AminoAcidAlignWithBandingoutputNum;
+
+AminoAcidAlignWithBandingFoldedDPTable::AminoAcidAlignWithBandingFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_AminoAcidAlignWithBandingstateId), emissionId(_AminoAcidAlignWithBandingemissionId), transitionId(_AminoAcidAlignWithBandingtransitionId), transitionFrom(_AminoAcidAlignWithBandingtransF), transitionTo(_AminoAcidAlignWithBandingtransT), transitionProb(_AminoAcidAlignWithBandingtransP), transitionEmit(_AminoAcidAlignWithBandingtransE), outputId(_AminoAcidAlignWi [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemoryaaBlock2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemoryaaBlock3.allocate();
+    StateMemoryaaBlock1.allocate();
+}
+
+
+AminoAcidAlignWithBandingFoldedDPTable::~AminoAcidAlignWithBandingFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemoryaaBlock2withbanding.absolve();
+        StateMemoryaaBlock3.absolve();
+        StateMemoryaaBlock1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& AminoAcidAlignWithBandingFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingtransNum ? _AminoAcidAlignWithBandingtransitionId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingemitNum ? _AminoAcidAlignWithBandingemissionId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingFoldedDPTable::getStateId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingstateNum ? _AminoAcidAlignWithBandingstateId[id] : _AminoAcidAlignWithBandingempty; }
+const string& AminoAcidAlignWithBandingFoldedDPTable::getOutputId(int id) { return id>=0 && id<_AminoAcidAlignWithBandingoutputNum ? _AminoAcidAlignWithBandingoutputId[id] : _AminoAcidAlignWithBandingempty; }
+int AminoAcidAlignWithBandingFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_AminoAcidAlignWithBandingstateNum;i++) {
+            (*pmId)[_AminoAcidAlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingemitNum; i++) {
+            (*pmId)[_AminoAcidAlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingtransNum; i++) {  
+            (*pmId)[_AminoAcidAlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_AminoAcidAlignWithBandingoutputNum; i++) {
+            (*pmId)[_AminoAcidAlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "AminoAcidAlignWithBandingFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat AminoAcidAlignWithBandingFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat AminoAcidAlignWithBandingFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock2withbandingSecondary;
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemoryaaBlock1Secondary = this->StateMemoryaaBlock1.read();
+            return CurStateMemoryaaBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock2withbandingSecondary = this->StateMemoryaaBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemoryaaBlock2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemoryaaBlock3Secondary = this->StateMemoryaaBlock3.read();
+            return CurStateMemoryaaBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int AminoAcidAlignWithBandingBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidAlignWithBandingBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int AminoAcidAlignWithBandingBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "AminoAcidAlignWithBandingBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void AminoAcidAlignWithBandingBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+        for (int i=0; i<13; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignWithBandingtransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_AminoAcidAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int AminoAcidAlignWithBandingBaumWelch::transitionIdentifier00[];
+int AminoAcidAlignWithBandingBaumWelch::emissionIdentifier00[];
+int AminoAcidAlignWithBandingBaumWelch::emissionIdentifier01[];
+int AminoAcidAlignWithBandingBaumWelch::emissionIdentifier10[];
+int AminoAcidAlignWithBandingBaumWelch::emissionIdentifier11[];
+
+void AminoAcidAlignWithBandingBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<20;v00++)for(int v10=0;v10<20;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> AminoAcidAlignWithBandingBaumWelch::mId;
+int AminoAcidAlignWithBandingBaumWelch::atransitionIdx[];
+int AminoAcidAlignWithBandingBaumWelch::aemissionIdx[];
+
+const string _AminoAcidAlignstateId[] = {"start","insert1","match","delete1","end"};
+const string _AminoAcidAlignemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _AminoAcidAligntransitionId[] = {"trSM","trSI1","trSD1","trMM","trMI1","trMD1","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E"};
+const string _AminoAcidAligntransF[] = {"start","start","start","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1"};
+const string _AminoAcidAligntransT[] = {"match","insert1","delete1","match","insert1","delete1","end","match","insert1","end","match","delete1","end"};
+const string _AminoAcidAligntransP[] = {"probSM","probSI1","probSD1","probMM","probMI1","probMD1","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E"};
+const string _AminoAcidAligntransE[] = {"emit12","emit1","emit2","emit12","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _AminoAcidAlignoutputId[] = {"sequence1","sequence2"};
+const string _AminoAcidAlignempty = "";
+const int _AminoAcidAlignstateNum = 5;
+const int _AminoAcidAlignemitNum = 4;
+const int _AminoAcidAligntransNum = 13;
+const int _AminoAcidAlignoutputNum = 2;
+
+
+
+
+bfloat Forward(AminoAcidAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2To;
+    const bfloat *CurStateMemoryaaBlock1From;
+    const bfloat *CurStateMemoryaaBlock2From;
+    bfloat *CurStateMemoryaaBlock3To;
+    const bfloat *CurStateMemoryaaBlock3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidAlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemoryaaBlock1.write()[0] = 1.0;
+    dp.StateMemoryaaBlock1.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=0; iPos1<iLen2+1; ++iPos1) {
+        for (int iPos0=0; iPos0<iLen1+1; ++iPos0) {
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+            }
+            if (1) {
+                if ((iPos1+-1>=0)) {
+                    iSymbol[0] = iSequence2[iPos1+-1];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+-1>=0)) {
+                    iSymbol[1] = iSequence1[iPos0+-1];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock2To = dp.StateMemoryaaBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+0<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                    CurStateMemoryaaBlock2To[2] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                }
+                if ((iPos1+-1>=0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(1))-(0));
+                    CurStateMemoryaaBlock2To[2] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock2To[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+0<=0)) {
+                    CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                    CurStateMemoryaaBlock2To[0] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                }
+                if ((iPos0+-1>=0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock2To[0] += ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock2To[0] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                    CurStateMemoryaaBlock2To[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                }
+                if ((iPos0+-1>=0)&&(iPos1+-1>=0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(1))-(0), (iPos1-(1))-(0));
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                }
+                dp.StateMemoryaaBlock2.written();
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                CurStateMemoryaaBlock3To = dp.StateMemoryaaBlock3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock3To[0] = ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock3To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    CurStateMemoryaaBlock3To[0] += ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                }
+                dp.StateMemoryaaBlock3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+            iTempProb[0] = CurStateMemoryaaBlock3From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidAlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelch(AminoAcidAlignBaumWelch& bw,AminoAcidAlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2To;
+    const bfloat *CurStateMemoryaaBlock2Secondary;
+    const bfloat *CurStateMemoryaaBlock2From;
+    unsigned char alphaSymbolaminoacid[20] = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'};
+    unsigned char alphaIndexaminoacid[256];
+    const bfloat *CurStateMemoryaaBlock3From;
+    bfloat *CurStateMemoryaaBlock1To;
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    AminoAcidAlignFoldedDPTable dp(iLen1,2);
+    AminoAcidAlignDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexaminoacid[i]=0;
+    }
+
+//    for (int i=0; i<20; i++) {
+//        alphaIndexaminoacid[alphaSymbolaminoacid[i]]=i;
+//    }
+    for (int i=0; i<20; i++) {
+      alphaIndexaminoacid[tolower (alphaSymbolaminoacid[i])] = i;
+      alphaIndexaminoacid[toupper (alphaSymbolaminoacid[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemoryaaBlock3.write()[0] = 1.0;
+    dp.StateMemoryaaBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock3Secondary = dp2.StateMemoryaaBlock3.read();
+            iTempProb[2] = CurStateMemoryaaBlock3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if (iPrevSlowCoord != -1 && iPrevSlowCoord != iPos1) {
+                dp.StateMemoryaaBlock2.clear(iPos1);
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock2To = dp.StateMemoryaaBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                CurStateMemoryaaBlock2Secondary = dp2.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock2To[2] = iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[1] = iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock2To[0] = iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[1] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock2To[2] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[0] += iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[1] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+                    CurStateMemoryaaBlock2To[2] += iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[0] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemoryaaBlock2To[1] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                }
+                dp.StateMemoryaaBlock2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock1To = dp.StateMemoryaaBlock1.write();
+                CurStateMemoryaaBlock1Secondary = dp2.StateMemoryaaBlock1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemoryaaBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+            iTempProb[0] = CurStateMemoryaaBlock1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat Backward(AminoAcidAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2To;
+    const bfloat *CurStateMemoryaaBlock2From;
+    const bfloat *CurStateMemoryaaBlock3From;
+    bfloat *CurStateMemoryaaBlock1To;
+    const bfloat *CurStateMemoryaaBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidAlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemoryaaBlock3.write()[0] = 1.0;
+    dp.StateMemoryaaBlock3.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock2To = dp.StateMemoryaaBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock2To[2] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                    CurStateMemoryaaBlock2To[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock2To[0] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock2To[2] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock2To[0] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+                    CurStateMemoryaaBlock2To[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    CurStateMemoryaaBlock2To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    CurStateMemoryaaBlock2To[1] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                }
+                dp.StateMemoryaaBlock2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock1To = dp.StateMemoryaaBlock1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2From = dp.StateMemoryaaBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock2From[1];
+                }
+                dp.StateMemoryaaBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+            iTempProb[0] = CurStateMemoryaaBlock1From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidAlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+const string _AminoAcidAlignWithBandingstateId[] = {"start","insert1","match","delete1","end"};
+const string _AminoAcidAlignWithBandingemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _AminoAcidAlignWithBandingtransitionId[] = {"trSM","trSI1","trSD1","trMM","trMI1","trMD1","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E"};
+const string _AminoAcidAlignWithBandingtransF[] = {"start","start","start","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1"};
+const string _AminoAcidAlignWithBandingtransT[] = {"match","insert1","delete1","match","insert1","delete1","end","match","insert1","end","match","delete1","end"};
+const string _AminoAcidAlignWithBandingtransP[] = {"probSM","probSI1","probSD1","probMM","probMI1","probMD1","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E"};
+const string _AminoAcidAlignWithBandingtransE[] = {"emit12","emit1","emit2","emit12","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _AminoAcidAlignWithBandingoutputId[] = {"sequence1","sequence2"};
+const string _AminoAcidAlignWithBandingempty = "";
+const int _AminoAcidAlignWithBandingstateNum = 5;
+const int _AminoAcidAlignWithBandingemitNum = 4;
+const int _AminoAcidAlignWithBandingtransNum = 13;
+const int _AminoAcidAlignWithBandingoutputNum = 2;
+
+
+
+
+bfloat ForwardBanding(AminoAcidAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2withbandingTo;
+    const bfloat *CurStateMemoryaaBlock1From;
+    const bfloat *CurStateMemoryaaBlock2withbandingFrom;
+    bfloat *CurStateMemoryaaBlock3To;
+    const bfloat *CurStateMemoryaaBlock3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidAlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemoryaaBlock1.write()[0] = 1.0;
+    dp.StateMemoryaaBlock1.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.forwardIterator();
+        bool bLastSlowCoordInited = false;
+        int iLastSlowCoord = -1;  
+        do {
+            if (bLastSlowCoordInited) {
+                if (iLastSlowCoord > position[1]) {
+                    cout << "WARNING: Banding (forward): Slowest coordinate should be nondecreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+                }
+                } else {
+                bLastSlowCoordInited = true;
+            }
+            iLastSlowCoord = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+-1>=0)) {
+                        iSymbol[0] = iSequence2[position[1]+-1];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+-1>=0)) {
+                        iSymbol[1] = iSequence1[position[0]+-1];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaBlock2withbandingTo = dp.StateMemoryaaBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+0<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                        CurStateMemoryaaBlock2withbandingTo[2] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                    }
+                    if ((position[1]+-1>=0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                        CurStateMemoryaaBlock2withbandingTo[2] += ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+0<=0)) {
+                        CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                        CurStateMemoryaaBlock2withbandingTo[0] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                    }
+                    if ((position[0]+-1>=0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[0] += ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        CurStateMemoryaaBlock2withbandingTo[0] += ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+                        CurStateMemoryaaBlock2withbandingTo[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock1From[0];
+                    }
+                    if ((position[0]+-1>=0)&&(position[1]+-1>=0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(1))-(0), (position[1]-(1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                    }
+                    dp.StateMemoryaaBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextForward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                CurStateMemoryaaBlock3To = dp.StateMemoryaaBlock3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock3To[0] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                    CurStateMemoryaaBlock3To[0] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                    CurStateMemoryaaBlock3To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                }
+                dp.StateMemoryaaBlock3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+            iTempProb[0] = CurStateMemoryaaBlock3From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidAlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelchBanding(AminoAcidAlignWithBandingBaumWelch& bw,AminoAcidAlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    const bfloat *CurStateMemoryaaBlock3Secondary;
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2withbandingTo;
+    const bfloat *CurStateMemoryaaBlock2withbandingSecondary;
+    const bfloat *CurStateMemoryaaBlock2withbandingFrom;
+    unsigned char alphaSymbolaminoacid[20] = {'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y'};
+    unsigned char alphaIndexaminoacid[256];
+    const bfloat *CurStateMemoryaaBlock3From;
+    bfloat *CurStateMemoryaaBlock1To;
+    const bfloat *CurStateMemoryaaBlock1Secondary;
+    const bfloat *CurStateMemoryaaBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    AminoAcidAlignWithBandingFoldedDPTable dp(iLen1,2);
+    AminoAcidAlignWithBandingDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexaminoacid[i]=0;
+    }
+
+//    for (int i=0; i<20; i++) {
+//        alphaIndexaminoacid[alphaSymbolaminoacid[i]]=i;
+//    }
+    for (int i=0; i<20; i++) {
+      alphaIndexaminoacid[tolower (alphaSymbolaminoacid[i])] = i;
+      alphaIndexaminoacid[toupper (alphaSymbolaminoacid[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemoryaaBlock3.write()[0] = 1.0;
+    dp.StateMemoryaaBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock3Secondary = dp2.StateMemoryaaBlock3.read();
+            iTempProb[2] = CurStateMemoryaaBlock3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (iPrevSlowCoord != -1 && iPrevSlowCoord != position[1]) {
+                    dp.StateMemoryaaBlock2withbanding.clear(position[1]);
+                }
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaBlock2withbandingTo = dp.StateMemoryaaBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    CurStateMemoryaaBlock2withbandingSecondary = dp2.StateMemoryaaBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[2] = iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[1] = iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[0] = iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[2] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[0] += iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+                        CurStateMemoryaaBlock2withbandingTo[2] += iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemoryaaBlock2withbandingTo[0] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                        iTempProb[1] *= CurStateMemoryaaBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    }
+                    dp.StateMemoryaaBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock1To = dp.StateMemoryaaBlock1.write();
+                CurStateMemoryaaBlock1Secondary = dp2.StateMemoryaaBlock1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexaminoacid[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                    iTempProb[1] *= CurStateMemoryaaBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexaminoacid[iSymbol[1]]][alphaIndexaminoacid[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemoryaaBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+            iTempProb[0] = CurStateMemoryaaBlock1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBanding(AminoAcidAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemoryaaBlock2withbandingTo;
+    const bfloat *CurStateMemoryaaBlock2withbandingFrom;
+    const bfloat *CurStateMemoryaaBlock3From;
+    bfloat *CurStateMemoryaaBlock1To;
+    const bfloat *CurStateMemoryaaBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'D'] = 2;
+    iTranslate[(unsigned)'d'] = 2;
+    iTranslate[(unsigned)'E'] = 3;
+    iTranslate[(unsigned)'e'] = 3;
+    iTranslate[(unsigned)'F'] = 4;
+    iTranslate[(unsigned)'f'] = 4;
+    iTranslate[(unsigned)'G'] = 5;
+    iTranslate[(unsigned)'g'] = 5;
+    iTranslate[(unsigned)'H'] = 6;
+    iTranslate[(unsigned)'h'] = 6;
+    iTranslate[(unsigned)'I'] = 7;
+    iTranslate[(unsigned)'i'] = 7;
+    iTranslate[(unsigned)'K'] = 8;
+    iTranslate[(unsigned)'k'] = 8;
+    iTranslate[(unsigned)'L'] = 9;
+    iTranslate[(unsigned)'l'] = 9;
+    iTranslate[(unsigned)'M'] = 10;
+    iTranslate[(unsigned)'m'] = 10;
+    iTranslate[(unsigned)'N'] = 11;
+    iTranslate[(unsigned)'n'] = 11;
+    iTranslate[(unsigned)'P'] = 12;
+    iTranslate[(unsigned)'p'] = 12;
+    iTranslate[(unsigned)'Q'] = 13;
+    iTranslate[(unsigned)'q'] = 13;
+    iTranslate[(unsigned)'R'] = 14;
+    iTranslate[(unsigned)'r'] = 14;
+    iTranslate[(unsigned)'S'] = 15;
+    iTranslate[(unsigned)'s'] = 15;
+    iTranslate[(unsigned)'T'] = 16;
+    iTranslate[(unsigned)'t'] = 16;
+    iTranslate[(unsigned)'V'] = 17;
+    iTranslate[(unsigned)'v'] = 17;
+    iTranslate[(unsigned)'W'] = 18;
+    iTranslate[(unsigned)'w'] = 18;
+    iTranslate[(unsigned)'Y'] = 19;
+    iTranslate[(unsigned)'y'] = 19;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    AminoAcidAlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemoryaaBlock3.write()[0] = 1.0;
+    dp.StateMemoryaaBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemoryaaBlock2withbandingTo = dp.StateMemoryaaBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                        CurStateMemoryaaBlock2withbandingTo[2] = ((iTransition[11])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[4])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                        CurStateMemoryaaBlock2withbandingTo[0] = ((iTransition[8])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemoryaaBlock2withbandingTo[2] += ((iTransition[10])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                        CurStateMemoryaaBlock2withbandingTo[0] += ((iTransition[7])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemoryaaBlock3From = dp.StateMemoryaaBlock3.read();
+                        CurStateMemoryaaBlock2withbandingTo[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                        CurStateMemoryaaBlock2withbandingTo[1] += ((iTransition[6])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                        CurStateMemoryaaBlock2withbandingTo[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemoryaaBlock3From[0];
+                    }
+                    dp.StateMemoryaaBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemoryaaBlock1To = dp.StateMemoryaaBlock1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] = ((iTransition[2])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemoryaaBlock1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemoryaaBlock2withbandingFrom = dp.StateMemoryaaBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemoryaaBlock1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemoryaaBlock2withbandingFrom[1];
+                }
+                dp.StateMemoryaaBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemoryaaBlock1From = dp.StateMemoryaaBlock1.read();
+            iTempProb[0] = CurStateMemoryaaBlock1From[0];
+        }
+    }
+    *ppOutTable = new AminoAcidAlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/aminoaciddp.h b/src/fsa/aminoaciddp.h
new file mode 100644
index 0000000..c3f641b
--- /dev/null
+++ b/src/fsa/aminoaciddp.h
@@ -0,0 +1,315 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file aminoacid.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:18 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _aminoaciddp_h_
+#define _aminoaciddp_h_
+
+
+#include "dptables.h"
+#include "algebras.h"
+#include <string>
+
+#include <map>
+
+using std::map;
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesaaBlock2;
+typedef States<bfloat,1> StatesaaBlock1;
+typedef States<bfloat,1> StatesaaBlock3;
+
+class AminoAcidAlignDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesaaBlock2,2> StateMemoryaaBlock2;
+    DPTable<StatesaaBlock1,0> StateMemoryaaBlock1;
+    DPTable<StatesaaBlock3,0> StateMemoryaaBlock3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidAlignDPTable(int iLen1,int iLen2);
+    ~AminoAcidAlignDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat AminoAcidAlignReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double AminoAcidAlignShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesaaBlock2;
+typedef States<bfloat,1> StatesaaBlock3;
+typedef States<bfloat,1> StatesaaBlock1;
+
+class AminoAcidAlignFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesaaBlock2,2> StateMemoryaaBlock2;
+    DPTable<StatesaaBlock3,0> StateMemoryaaBlock3;
+    DPTable<StatesaaBlock1,0> StateMemoryaaBlock1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidAlignFoldedDPTable(int iLen1,int iLen2);
+    ~AminoAcidAlignFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class AminoAcidAlignBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    AminoAcidAlignBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[13];
+    static int transitionIdentifier00[13];   
+    static const int transitionDimension00 = 13;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[20][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[20][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[20][20][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[13];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesaaBlock2withbanding;
+typedef States<bfloat,1> StatesaaBlock1;
+typedef States<bfloat,1> StatesaaBlock3;
+
+class AminoAcidAlignWithBandingDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesaaBlock2withbanding,2> StateMemoryaaBlock2withbanding;
+    DPTable<StatesaaBlock1,0> StateMemoryaaBlock1;
+    DPTable<StatesaaBlock3,0> StateMemoryaaBlock3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidAlignWithBandingDPTable(int iLen1,int iLen2);
+    ~AminoAcidAlignWithBandingDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat AminoAcidAlignWithBandingReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double AminoAcidAlignWithBandingShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesaaBlock2withbanding;
+typedef States<bfloat,1> StatesaaBlock3;
+typedef States<bfloat,1> StatesaaBlock1;
+
+class AminoAcidAlignWithBandingFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesaaBlock2withbanding,2> StateMemoryaaBlock2withbanding;
+    DPTable<StatesaaBlock3,0> StateMemoryaaBlock3;
+    DPTable<StatesaaBlock1,0> StateMemoryaaBlock1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    AminoAcidAlignWithBandingFoldedDPTable(int iLen1,int iLen2);
+    ~AminoAcidAlignWithBandingFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class AminoAcidAlignWithBandingBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    AminoAcidAlignWithBandingBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[13];
+    static int transitionIdentifier00[13];   
+    static const int transitionDimension00 = 13;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[20][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[20][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[20][20][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[13];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+bfloat Forward(AminoAcidAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat BackwardBaumWelch(AminoAcidAlignBaumWelch& bw,AminoAcidAlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat Backward(AminoAcidAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat ForwardBanding(AminoAcidAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBaumWelchBanding(AminoAcidAlignWithBandingBaumWelch& bw,AminoAcidAlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBanding(AminoAcidAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+#endif // _aminoaciddp_h_
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/anchors.cc b/src/fsa/anchors.cc
new file mode 100644
index 0000000..8505db8
--- /dev/null
+++ b/src/fsa/anchors.cc
@@ -0,0 +1,1536 @@
+
+/**
+ * \file anchors.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <unistd.h>
+#include <cstdio>
+#include <iostream>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <algorithm>
+
+#include "seq/alignment.h"
+#include "fsa/anchors.h"
+
+#define FILENAME_PREFIX "fsa_tmp_seq"
+#define TMP_DIR "/tmp"
+
+#define GUI_FILENAME_ANCHORS_SUFFIX ".anchors"
+
+using namespace fsa;
+
+// Note that unless specified otherwise, we use a 0-based coordinate system.
+// The SparseMatrix code uses a 1-based system, but its constructor expects
+// 0-based coordinates as input and the conversion happens behind the scenes.
+
+// constructor
+Anchor::Anchor (Interval xcoords, Interval ycoords)
+  : xcoords (xcoords), ycoords (ycoords),
+    __score (-1.),
+    __external_scoring (false),
+    __immutable (false) {
+
+  update();
+
+}
+
+// constructor
+Anchor::Anchor (Interval xcoords, Interval ycoords, double score)
+  : xcoords (xcoords), ycoords (ycoords),
+    __score (score),
+    __external_scoring (false),
+    __immutable (false) {
+
+  update();
+
+}
+
+void Anchor::update() {
+
+  // ensure valid coordinates
+  assert ((xcoords.start >= 0) && (xcoords.end >= xcoords.start));
+  assert ((ycoords.start >= 0) && (ycoords.end >= ycoords.start));
+  assert ((xcoords.end - xcoords.start) == (ycoords.end - ycoords.start));
+
+  x = static_cast<unsigned> (std::floor (0.5 * (xcoords.end + xcoords.start)));
+  y = static_cast<unsigned> (std::floor (0.5 * (ycoords.end + ycoords.start)));
+
+  assert (x - y == xcoords.end - ycoords.end);
+
+  length = xcoords.end - xcoords.start + 1;
+  assert (length > 0);
+
+}
+
+double Anchor::p_value (const std::string& xseq, const std::string& yseq) const {
+  return p_value (&xseq, &yseq);
+}
+
+double Anchor::p_value (const std::string* xseq, const std::string* yseq) const {
+
+  // extract anchored subseqs
+  const std::string& xsubseq = xseq->substr (xcoords.start, length);
+  const std::string& ysubseq = yseq->substr (ycoords.start, length);
+
+  // calculate hamming distance (# of mismatches)
+  size_t h = 0;
+  for (size_t i = 0; i < length; ++i) {
+    if (xsubseq[i] != ysubseq[i])
+      ++h;
+  }
+
+  // get p-value (normalize to [0,1])
+  const double pval =  1.0 - static_cast<double> (length) / static_cast<double> (std::max (xseq->length(), yseq->length()));
+  assert ((pval >= 0.) && (pval <= 1.0));
+
+  return pval;
+}
+
+void Anchors::show (std::ostream& o) const {
+  for (std::vector<Anchor>::const_iterator anchor = begin(); anchor != end(); ++anchor)
+    o << *anchor << endl;
+}
+
+void Anchors::write_gui_output (std::ostream& o, const size_t xidx, const size_t yidx) const {
+  for (std::vector<Anchor>::const_iterator anchor = this->begin(); anchor != this->end(); ++anchor)
+    o << "(" << xidx << " ~ " << yidx << ") == " << *anchor << endl;
+}
+
+Anchors Anchors::convert_constraints_to_anchors (const Constraints& constraints, const Sequence& xseq_orig, const Sequence& yseq_orig, const bool hardmasked) {
+
+  Anchors anchors;
+  for (std::vector<Constraint>::const_iterator constraint = constraints.begin(); constraint != constraints.end(); ++constraint) {
+
+    // left end
+    Anchor left (Interval (constraint->xcoords.start, constraint->xcoords.start),
+		 Interval (constraint->ycoords.start, constraint->ycoords.start));
+    left.set_immutable();
+
+    // right end
+    Anchor right (Interval (constraint->xcoords.end, constraint->xcoords.end),
+		  Interval (constraint->ycoords.end, constraint->ycoords.end));
+    right.set_immutable();
+
+    // move anchors if necessary to get out of hardmasked region
+    bool is_anchor_entirely_hardmasked = false;
+    if (hardmasked) {
+
+      // if necessary, increment left boundary along the sequences until it doesn't fall in a hardmasked region
+      bool shifted = false; // for logging
+      while (xseq_orig.is_pos_hardmasked (left.x) || yseq_orig.is_pos_hardmasked (left.y)) {
+	shifted = true;
+	left.xcoords.start = left.xcoords.end = (left.x + 1);
+	left.ycoords.start = left.ycoords.end = (left.y + 1);
+	left.update();
+	// check whether the increment boundary is valid
+	// (falls within sequence limits and not past right-hand boundary)
+	if ((left.x >= xseq_orig.length()) || (left.x >= right.x)) {
+	  is_anchor_entirely_hardmasked = true;
+	  break;
+	}
+      }
+
+      if (shifted && !is_anchor_entirely_hardmasked)
+	CTAG(6,ANCHORING) << "WARNING: Shifted Mercator constraint boundary which fell in hardmasked region; new left-hand boundary is: " << left << endl;
+
+      // if necessary, decrement right boundary along the sequences until doesn't fall in a hardmasked region
+      shifted = false;
+      while (xseq_orig.is_pos_hardmasked (right.x) || yseq_orig.is_pos_hardmasked (right.y)) {
+	shifted = true;
+	right.xcoords.start = right.xcoords.end = (right.x - 1);
+	right.ycoords.start = right.ycoords.end = (right.y - 1);
+	right.update();
+	if ((right.x >= xseq_orig.length()) || (left.x >= right.x)) {
+	  is_anchor_entirely_hardmasked = true;
+	  break;
+	}
+      }
+
+      if (shifted && !is_anchor_entirely_hardmasked)
+	CTAG(6,ANCHORING) << "WARNING: Shifted Mercator constraint boundary which fell in hardmasked region; new right-hand boundary is: " << right << endl;
+
+    }
+
+    // if anchor is entirely hardmasked in one sequence, then ignore it
+    if (is_anchor_entirely_hardmasked) {
+      CTAG(6,ANCHORING) << "WARNING: Mercator constraint fell entirely within a hardmasked region; ignoring it entirely." << endl;
+      continue;
+    }
+
+    // store anchors
+    anchors.store (left);
+    anchors.store (right);
+
+  }
+
+  // if hardmasking, map Mercator coordinates to stripped sequence
+  if (hardmasked) {
+    for (std::vector<Anchor>::iterator anchor = anchors.begin(); anchor != anchors.end(); ++anchor) {
+      anchor->xcoords.start = xseq_orig.map_orig_to_stripped (anchor->xcoords.start);
+      anchor->xcoords.end = xseq_orig.map_orig_to_stripped (anchor->xcoords.end);
+      anchor->ycoords.start = yseq_orig.map_orig_to_stripped (anchor->ycoords.start);
+      anchor->ycoords.end = yseq_orig.map_orig_to_stripped (anchor->ycoords.end);
+      anchor->update();
+      // sanity check
+      if ((anchor->xcoords.end == xseq_orig.length()) || (anchor->ycoords.end == yseq_orig.length())) {
+	THROWEXPR ("ERROR: Mercator constraint falls in a hardmasked interval:" << endl << *anchor);
+      }
+    }
+  }
+
+  return anchors;
+
+}
+
+const Post_probs Anchors::convert_to_post_probs() const {
+
+  // store each Anchor as an entry
+  Post_probs post_probs;
+  for (std::vector<Anchor>::const_iterator anchor = begin(); anchor != end(); ++anchor)
+    post_probs.push_back (Post_prob (anchor->x, anchor->y, anchor->get_score()));
+
+  // now enforce lexical ordering on centroids
+  // (required by SparseMatrix constructor)
+  // forgetting this step caused me BIG PAIN!
+  std::sort (post_probs.begin(), post_probs.end());
+
+  return post_probs;
+}
+
+bool Anchors::create_spanning_map() {
+
+  __spanning_map.clear();
+
+  bool nondegen = true;
+  for (size_t i = 0; i < this->size(); ++i)
+    nondegen = __spanning_map.insert (std::make_pair (std::make_pair ((*this)[i].x, (*this)[i].y), i)).second;
+
+  return nondegen;
+}
+
+size_t Anchors::exists_spanning_anchor (const unsigned x, const unsigned y) const {
+
+  if (__spanning_map.find (std::make_pair (x, y)) != __spanning_map.end())
+    return (*__spanning_map.find (std::make_pair (x, y))).second;
+
+  return size();
+
+}
+
+const Anchor Anchors::get_spanning_anchor (const unsigned x, const unsigned y) {
+
+  const size_t idx = exists_spanning_anchor (x, y);
+  assert (idx < this->size());
+  assert (((*this)[idx].xcoords.start <= x) && ((*this)[idx].xcoords.end >= x));
+  assert (((*this)[idx].ycoords.start <= y) && ((*this)[idx].ycoords.end >= y));
+  return (*this)[idx];
+
+}
+
+bool Anchors::resolve_parallel (const size_t max_join_distance /* = 0 */, const bool concatenate_immutable /* = false */) {
+
+  CTAG (6,ANCHORING ANCHORING_VERBOSE) << "Resolving parallel anchors." << endl;
+
+  // catch case of no anchors (very important!)
+  if (size() == 0)
+    return true;
+
+  // lexical sort in x coordinate (essential)
+  // we get this automatically from MUMmer if not using translated anchors,
+  // but must do it by hand if using translated anchors
+  std::sort (begin(), end(), Anchor::lexical_comparison_x);
+
+  // first deal with overlapping degenerate parallel anchors
+  Anchors resolved (this->xseq, this->yseq);
+  std::vector<bool> processed (size(), false);
+  for (size_t i = 0; i < this->size(); ++i) {
+
+    // if we've already dealt with this anchor, ignore it and go to the next
+    if (processed[i])
+      continue;
+    // else mark as processed
+    else
+      processed[i] = true;   // this actually isn't necessary but it makes me happy
+
+    Anchor& curr = (*this)[i];
+
+    // don't concatenate immutable anchors unless so requested; leave them disjoint
+    // this is crucial when concatenating parallel anchors prior to performing anchor annealing:
+    // if two original immutable anchors abut and one is concatenated so
+    // as to give a centroid overlapping the centroid of the other immutable anchor,
+    // then we will get negative gap posterior errors
+    // => very very bad
+    // So: just store current (immutable) anchor
+    if (curr.is_immutable() && !concatenate_immutable) {
+      resolved.store (curr);
+      continue;
+    }
+
+    // right-hand x boundary of the current anchor
+    unsigned currright = curr.xcoords.end;
+
+    // look for overlapping parallel anchors
+    for (size_t j = i + 1; j < this->size(); ++j) { // i + 1 because lexical sorting
+
+      const Anchor& overlap = (*this)[j];
+
+      // don't concatenate immutable anchors unless so requested; leave them disjoint
+      if (overlap.is_immutable() && !concatenate_immutable)
+	continue;
+
+      // does this anchor overlap or is it within max_join_distance of the previous?
+      unsigned overlapleft = overlap.xcoords.start;
+      unsigned overlapright = overlap.xcoords.end;
+      if (static_cast<int> (overlapleft - currright) > static_cast<int> (max_join_distance)) // if not, then stop;
+	break;                                         // lexical ordering means there can be no other overlaps or acceptably adjacent anchors
+
+      // is this anchor parallel with the current anchor?
+      if (!curr.is_parallel (overlap))  // if not, then go on to the next
+	continue;
+      else
+	processed[j] = true;            // else mark as processed and deal with it
+
+      // if this overlapping anchor is completely degenerate (contained within anchor curr),
+      // then just ignore it (conveys no new information) 
+      // (although handle special cases of immutable anchors)
+      if (overlapright <= currright) {
+
+	// handle case of immutable anchor
+	// deal with it by marking the containing anchor as immutable
+	// and ignoring (implicitly dropping) the original immutable anchor
+	if (overlap.is_immutable() && concatenate_immutable) {
+	  curr.set_immutable();
+	  // log
+	  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	    CL << "Marking anchor containing immutable anchor as immutable itself:" << endl
+	       << curr << endl;
+	  }
+	}
+
+	// handle case of external_scoring anchor
+	// deal with it by marking the containing anchor as external_scoring
+	// and ignoring (implicitly dropping) the original external_scoring anchor
+	if (overlap.is_external_scoring()) {
+	  curr.set_external_scoring();
+	  curr.set_score (overlap.get_score()); // won't affect immutable anchors
+	  // log
+	  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	    CL << "Marking anchor containing externally-scored anchor as externally-scored itself:" << endl
+	       << curr << endl;
+	  }
+	}
+
+	// else ignore (implicitly drop) the degenerate anchor
+	else {
+	  // log
+	  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	    CL << "Dropping degenerate first anchor in favor of second:" << endl
+	       << overlap << endl
+	       << curr << endl;
+	  }
+	}
+
+	continue;
+      }
+
+      // else increment boundaries of current anchor as appropriate
+      // (although handle special cases of immutable anchors)
+      else {
+
+	// log
+	if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	  CL << "Concatenating these two parallel anchors:" << endl
+	     << curr << endl
+	     << overlap << endl;
+	}
+
+	// increment coordinates for current anchor
+	curr.xcoords.end = overlap.xcoords.end;
+	curr.ycoords.end = overlap.ycoords.end;
+	currright = curr.xcoords.end;
+
+	// handle case of immutable anchor
+	// deal with it by marking the current anchor as immutable
+	if (overlap.is_immutable() && concatenate_immutable) {
+	  curr.set_immutable();
+	  // log
+	  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	    CL << "Marking anchor containing immutable anchor as immutable itself:" << endl
+	       << curr << endl;
+	  }
+	}
+
+	// handle case of external_scoring anchor
+	// deal with it by marking the current anchor as external_scoring
+	if (overlap.is_external_scoring()) {
+	  curr.set_external_scoring();
+	  curr.set_score (overlap.get_score()); // won't affect immutable anchors
+	  // log
+	  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	    CL << "Marking anchor containing externally-scored anchor as externally-scored itself:" << endl
+	       << curr << endl;
+	  }
+	}
+
+      }
+
+    }
+
+    // update and store current anchor
+    curr.update();
+    resolved.store (curr);
+    resolved.update_score (resolved.size() - 1);
+
+  }
+
+  // store the results
+  __anchors.assign (resolved.begin(), resolved.end());
+
+  // enforce immutable unique
+  // (we can't call create_spanning_map directly before enforce_immutable_unique
+  // because we need to ensure that the immutable anchors are nondegenerate first)
+  enforce_immutable_unique();
+
+  // now re-create the spanning_map
+  return create_spanning_map();
+
+}
+
+void Anchors::enforce_immutable_unique() {
+
+  std::set<unsigned> immutable_x;
+  std::set<unsigned> immutable_y;
+
+  // get immutable coordinates
+  const Anchors immutable_anchors;
+  for (std::vector<Anchor>::const_iterator anchor = begin(); anchor != end(); ++anchor) {
+    if (anchor->is_immutable()) {
+      immutable_x.insert (anchor->x);
+      immutable_y.insert (anchor->y);
+    }
+  }
+
+  // if there are no immutable anchors, then we're done!
+  if (!immutable_x.size())
+    return;
+  
+  Anchors passed;
+  for (std::vector<Anchor>::const_iterator anchor = begin(); anchor != end(); ++anchor) {
+
+    // if immutable, store and continue    
+    if (anchor->is_immutable()) {
+      passed.store (*anchor);
+      continue;
+    }
+
+    // else see if it overlaps an immutable anchor
+    else {
+
+      // drop it if overlaps with immutable
+      if ((immutable_x.find (anchor->x) != immutable_x.end()) || (immutable_y.find (anchor->y) != immutable_y.end())) {
+	if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE)) {
+	  CL << "Dropping anchor which overlaps an immutable anchor:" << endl
+	     << *anchor << endl;
+	}
+	continue;
+      }
+
+      // else keep it
+      else {
+	passed.store (*anchor);
+      }
+
+    }
+
+  }
+
+  __anchors.assign (passed.begin(), passed.end());
+
+}
+
+void Anchors::remove_overlaps (const size_t minlen /* = ANCHOR_NUC_MINLEN_DEFAULT */) {
+
+  // the x and y coordinates are handled separately in the hope of greater efficiency
+  // (since pruning x means pruning y as well => fewer possiblities for overlapping anchors)
+
+  // sort by x, prune by x
+  std::sort (begin(), end(), Anchor::lexical_comparison_x);
+  remove_overlaps (minlen, 0);
+
+  // sort by x, prune by y
+  std::sort (begin(), end(), Anchor::lexical_comparison_x);
+  remove_overlaps (minlen, 1);
+
+  // sort by y, prune by x
+  std::sort (begin(), end(), Anchor::lexical_comparison_y);
+  remove_overlaps (minlen, 0);
+
+  // sort by y, prune by y
+  std::sort (begin(), end(), Anchor::lexical_comparison_y);
+  remove_overlaps (minlen, 1);
+
+}
+
+void Anchors::remove_overlaps (const size_t minlen, const unsigned which) {
+
+  // loop over all anchors:
+  // for each anchor i
+  //   find all overlapping anchors
+  //   for each overlapping anchor j
+  //      if anchor j scores below the current anchor i, then prune the left-hand boundary of j
+  //      if anchor j scores above the current anchor i, then prune the right-hand boundary of i; break
+  //       (break because the lexical sorting means that anchor j will be the lefthand-most overlapping anchor)
+
+  // We require both lexical ordering and consistency of anchors.
+  // Lexical ordering guarantees that the anchors are sorted by increasing left-hand x coordinate.
+
+  std::vector<bool> is_dead (size(), false);
+  for (size_t i = 0; i < size(); ++i) {
+
+    // skip if dead
+    if (is_dead[i])
+      continue;
+
+    Anchor& curr = (*this)[i]; // must be a reference so that we aren't just modifying a copy!
+
+    // right-hand x boundary of the current anchor
+    unsigned xright = (which == 0) ? curr.xcoords.end : curr.ycoords.end;
+
+     // assemble list of overlapping anchors
+    std::list<size_t> xoverlaps;
+    unsigned xleftmost = xright;  // leftmost boundary of overlaps
+    for (size_t j = i + 1; j < size(); ++j) { // i + 1 because lexical sorting
+
+      // ignore dead anchors
+      if (is_dead[j])
+	continue;
+
+      // does this anchor overlap with the previous?
+      unsigned jxleft = (which == 0) ? (*this)[j].xcoords.start : (*this)[j].ycoords.start;
+      if (jxleft > xright) // if it doesn't overlap, then stop;
+	break;             // lexical ordering means there can be no other overlaps
+
+      // store and increment boundaries
+      xoverlaps.push_back (j);
+      if (jxleft < xleftmost)
+	xleftmost = jxleft;
+
+    }
+
+    // if there are overlaps, make sure that coordinate boundaries are sane
+    if (xoverlaps.size())
+      assert (xleftmost <= xright);
+    // if no overlaps, go to the next anchor
+    else
+      continue;
+
+    // go through the list of overlapping coordinates:
+    //  at each overlapping anchor, choose in favor of either current anchor i or overlapping anchor *overlap
+    //  prune anchors as appropriate
+    assert (xright >= xleftmost);
+    for (unsigned s = 0; s <= xright - xleftmost; ++s) { // s is the distance "within" anchor i
+      unsigned x = xleftmost + s;                        // x is the actual x coordinate
+      
+      assert (x <= ((which == 0) ? curr.xcoords.end : curr.ycoords.end));
+
+      std::list<size_t>::iterator overlapidx = xoverlaps.begin(); // use STL erase-remove idiom
+      while (overlapidx != xoverlaps.end()) { // *overlapidx is index of overlapping anchor in (*this)
+
+	Anchor& overlap = (*this)[*overlapidx]; // must be a reference so that we aren't just modifying a copy!
+
+	// does this anchor overlap at coordinate x?
+	// if not, then go on to the next
+	if (((which == 0) && overlap.xcoords.start > x) || (!(which == 0) && overlap.ycoords.start > x)) {
+	  ++overlapidx;
+	  continue;
+	}
+
+	// log before
+	if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+	  if (which == 0)
+	    CL << "Overlapping anchors (x = " << x << "):" << endl
+	       << curr << endl
+	       << overlap << endl;
+	  else
+	    CL << "Overlapping anchors (y = " << x << "):" << endl
+	       << curr << endl
+	       << overlap << endl;
+
+	}
+
+	// if anchor overlap is a new best, 
+	// then prune the right-hand boundary of current anchor i here
+	// and end loop over coordinates (because we're done with anchor i)
+	if (overlap.get_score() > curr.get_score()) {
+
+	  // calculate distance to prune anchor
+#ifndef NDEBUG
+	  if (which == 0)
+	    assert (static_cast<int> (curr.xcoords.end) - (x - 1) >= 0);
+	  else
+	    assert (static_cast<int> (curr.ycoords.end) - (x - 1) >= 0);
+#endif // NDEBUG
+	  const unsigned delta = ((which == 0) ? curr.xcoords.end : curr.ycoords.end) - (x - 1);
+
+	  // catch case of current anchor being shorter than the distance to prune
+	  // or new length shorter than minlen
+	  // (note that this always includes the case of length-1 (transitive) anchors)
+	  // if so, then mark it as dead
+	  if ((curr.length <= delta) || ((curr.length - delta) < minlen)) {
+	    assert (!curr.is_immutable() || overlap.is_immutable()); // sanity check: either the current anchor must not be immutable,
+	    is_dead[i] = true;                                       // or the better overlapping anchor must be
+	    if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE))
+	      CL << "Pruned by removing first anchor." << endl;
+	  }
+	  // else prune the current anchor *iter
+	  else {
+	    curr.xcoords.end -= delta;
+	    curr.ycoords.end -= delta;
+	    curr.update();
+	    update_score (i);
+	    // log after
+	    if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+	      CL << "Pruned as:" << endl
+		 << curr << endl
+		 << overlap << endl;
+	    }
+	  }
+	  // if we found a better overlapping anchor, then stop the loop over overlaps
+	  // as well as coordinates
+	  // (because we've already pruned and are done with the current anchor)
+	  goto FOUND_BETTER;
+
+	}
+
+	// otherwise overlapping anchor overlap isn't as good,
+	// so prune its left-hand boundary and drop it from the list of overlaps
+	else {
+
+	  // calculate distance to prune anchor
+#ifndef NDEBUG
+	  if (which == 0)
+	    assert (static_cast<int> (curr.xcoords.end + 1) - overlap.xcoords.start);
+	  else
+	    assert (static_cast<int> (curr.ycoords.end + 1) - overlap.ycoords.start);
+#endif // NDEBUG
+	  const unsigned delta = (which == 0) ? ((curr.xcoords.end + 1) - overlap.xcoords.start) : ((curr.ycoords.end + 1) - overlap.ycoords.start);
+
+	  // catch case of *overlap being shorter than the distance to prune
+	  // or new length shorter than minlen
+	  // (note that this always includes the case of length-1 (transitive) anchors)
+	  // if so, then erase *overlap entirely
+	  if ((overlap.length <= delta) || ((overlap.length - delta) < minlen)) {
+	    assert (!overlap.is_immutable() || curr.is_immutable()); // sanity check: either the current anchor must not be immutable,
+	    is_dead[*overlapidx] = true;                             // or the better overlapping anchor must be
+	    if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE))
+	      CL << "Pruned by removing second anchor." << endl;
+	  }
+	  // else prune overlap
+	  else {
+	    overlap.ycoords.start += delta;
+	    overlap.xcoords.start += delta;
+	    overlap.update();
+	    update_score (*overlapidx);
+	    // log after
+	    if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+	      CL << "Pruned as:" << endl
+		 << curr << endl
+		 << overlap << endl;
+	    }
+	  }
+	  // we're done with anchor *overlap; drop it from the list
+	  overlapidx = xoverlaps.erase (overlapidx);
+
+	}
+
+	// Note that we don't need to explicitly increment overlapidx here at all:
+	// If *overlap is better than the curren anchor *iter, then we break out of
+	// the overlapidx loop with an explicit goto FOUND_BETTER.
+	// If *overlap is worse, then we prune it, remove it from the list of overlaps
+	// and reset overlapidx when using erase.
+
+      } // end loop over overlapping anchors
+
+    } // end loop over coordinates
+
+  FOUND_BETTER:
+    ; // hack to get around requirement of a statement post-label
+
+  }
+
+  // assemble and store list of pruned anchors
+  Anchors pruned (this->xseq, this->yseq);
+  for (size_t i = 0; i < size(); ++i) {
+    if (!is_dead[i])
+      pruned.store ((*this)[i]);
+  }
+
+  // store list of pruned anchors
+  __anchors.assign (pruned.begin(), pruned.end());
+
+}
+
+
+// to do: fix this for proper scoring
+// pull out the anchored subseqs, get hamming distance (mismatches)
+// and use BLAST theory / forward approximation
+void Anchors::update_score (const size_t idx) {
+
+  assert ((idx >= 0) && (idx < size()));
+
+  Anchor& anchor = (*this)[idx];
+
+  // compute anchor score as (1 - p_value)
+  if (!anchor.is_external_scoring()) {
+    anchor.set_score (1.0 - anchor.p_value (this->xseq, this->yseq));
+    assert ((anchor.get_score() >= 0.0) && (anchor.get_score() <= 1.0));
+  }
+
+}
+
+void Anchors::impose_normalized_probability_distribution() {
+
+  // sum of scores of anchors with particular coordinates
+  std::vector<double> sum_scorex (xseq->length(), 0.);
+  std::vector<double> sum_scorey (yseq->length(), 0.);
+
+  // max of scores of anchors with particular coordinates
+  std::vector<double> max_scorex (xseq->length(), 0.);
+  std::vector<double> max_scorey (yseq->length(), 0.);
+
+  // accumulate counts for normalization
+  for (size_t i = 0; i < size(); ++i) {
+
+    // update score
+    update_score (i);
+
+    const Anchor& anchor = (*this)[i];
+
+    // check sane
+    assert ((anchor.get_score() >= 0.0) && (anchor.get_score() <= 1.0));
+
+    // accumulate counts for normalization
+    sum_scorex[anchor.x] += anchor.get_score();
+    sum_scorey[anchor.y] += anchor.get_score();
+
+    max_scorex[anchor.x] = max (anchor.get_score(), max_scorex[anchor.x]);
+    max_scorey[anchor.y] = max (anchor.get_score(), max_scorey[anchor.y]);
+
+  }
+
+  for (size_t i = 0; i < size(); ++i) {
+
+    Anchor& anchor = (*this)[i];
+
+    if (anchor.is_immutable())
+      continue;
+
+    // sanity check for finiteness
+    assert ((sum_scorex[anchor.x] > 0) && (sum_scorey[anchor.y] > 0));
+
+    // reweight scores
+    anchor.set_score (max_scorex[anchor.x] * (anchor.get_score() / sum_scorex[anchor.x]));
+    anchor.set_score (max_scorey[anchor.y] * (anchor.get_score() / sum_scorey[anchor.y]));
+
+    // check sane
+    assert ((anchor.get_score() >= 0.0) && (anchor.get_score() <= 1.0));
+
+  }
+
+}
+
+Anchors Cabbage_adapter::get_candidate_anchors() const {
+
+  CTAG (6,ANCHORING ANCHORING_VERBOSE) << "Getting candidate anchors for sequence pair '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+
+  Anchors anchors (xseq.seq, yseq.seq);
+  
+  // (90,110)  -- (190,210) => 100 -- 200; 0.1
+  // (140,160) -- (170,190) => 150 -- 180; 0.2
+  // (240,260) -- (290,310) => 250 -- 300; 0.3
+  // Because we use a 0-based coordinate system,
+  // these anchor the first "different" nucleotides starting a new sequence
+  // (rather than the last "same" ending the old sequence).
+
+  Anchor one (Interval (90, 110), Interval (190, 210), .1);
+  Anchor two (Interval (140, 160), Interval (170, 190), .2);
+  Anchor three (Interval (240, 260), Interval (290, 310), .3);
+
+  anchors.store (one);
+  anchors.store (two);
+  anchors.store (three);
+
+  if (!anchors.create_spanning_map())
+    THROWEXPR ("ERROR: Degenerate anchors.");
+
+  return anchors;
+}
+
+// Wrapper for call_exonerate.
+Anchors Exonerate_adapter::get_candidate_anchors (const int minscore /* = EXONERATE_MINSCORE_DEFAULT */) const {
+
+  CTAG (8,ANCHORING ANCHORING_VERBOSE) << "Getting candidate anchors (with exonerate) for sequence pair '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+
+  Anchors anchors = call_exonerate (xseq.seq, yseq.seq, minscore);
+  return anchors;
+
+}
+
+Anchors Exonerate_adapter::call_exonerate (const std::string& xseq, const std::string& yseq, const int minscore /* = EXONERATE_MINSCORE_DEFAULT */) const {
+
+  // check that exonerate executable is properly defined;
+  // if not, then die
+#ifndef EXONERATE_EXEC
+  THROWEXPR ("ERROR: exonerate executable isn't defined; try recompiling and specifying the exonerate path.");
+  // else call exonerate!
+#else
+
+  // get pid of current process for unique filenames
+  pid_t curr_pid = getpid();
+
+  // write sequence files to scratch directory
+  std::string xfile = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_x.fa";
+  std::string yfile = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_y.fa";
+  // X
+  std::ofstream filestream;
+  filestream.open (xfile.c_str());
+  if (!filestream.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << xfile << "'.");
+  filestream << ">X" << endl;
+  filestream << xseq << endl;
+  filestream.close();
+  // Y
+  filestream.open (yfile.c_str());
+  if (!filestream.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << yfile << "'.");
+  filestream << ">Y" << endl;
+  filestream << yseq << endl;
+  filestream.close();
+
+  // create exonerate executable string
+  // prepare for use with execv()
+  // (which requires null-terminated string)
+  std::string exec;
+  exec = std::string (EXONERATE_EXEC)
+    + " " + xfile + " " + yfile
+    + " --querytype dna --targettype dna "
+    + " --score " + Util::to_string (minscore) + " --gappedextension false "
+    + " --saturatethreshold 5 "
+    + " --bigseq true "
+    + " --showvulgar false --showalignment false ";
+  if (__softmasked)
+    exec += " --softmaskquery true --softmasktarget true ";
+  if (__use_translated)
+    exec += " --model ungapped:trans --proteinsubmat blosum62 ";
+  else
+    exec += " --model ungapped ";
+
+  std::vector<std::string> exonerate_args = Util::split (exec);
+  exonerate_args.push_back (static_cast<std::string> ("--ryo")); // this hack is necessary to prevent splitting the --ryo args
+  exonerate_args.push_back (static_cast<std::string> ("%qab %qae %qS %tab %tae %tS %s\\n")); // note that this is NOT enclosed in double quotes
+                                                                                         // these are only necessary for command-line usage
+                                                                                         // (to prevent the shell from splitting the argument)
+
+  char* exonerate_argv [exonerate_args.size() + 1];
+  for (size_t i = 0; i < exonerate_args.size(); ++i)
+    exonerate_argv[i] = static_cast<char*> (const_cast<char*> (exonerate_args[i].c_str()));
+  exonerate_argv[exonerate_args.size()] = static_cast<char*> (0);
+  if (CTAGGING(6,ANCHORING ANCHORING_VERBOSE)) {
+    std::string exec_line;
+    for (std::vector<std::string>::iterator iter = exonerate_args.begin(); iter != exonerate_args.end(); ++iter)
+      exec_line += ' ' + *iter;
+    CTAG (6,ANCHORING ANCHORING_VERBOSE) << "Calling exonerate as '" << exec_line << "'" << endl;
+  }
+
+  // run exonerate
+  pid_t exonerate_pid;
+
+  // clear cin
+  std::cin.clear();
+
+  // tmp file to hold exonerate output
+  std::string output_file = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_output";
+
+  // fork and call exonerate
+  int exonerate_status = 0;
+  if ((exonerate_pid = fork()) < 0) {  // a negative PID indicates failure
+    THROWEXPR ("ERROR: Couldn't start fork; exiting.");
+  }
+  else if (exonerate_pid == 0) {       // a 0 PID indicates the child process
+    freopen (output_file.c_str(), "w", stdout);    // capture stdout (send to file output_file) to store exonerate results
+    freopen ("/dev/null", "a", stderr);            // capture stderr (send to trash) so that it doesn't mess up our logging
+    if (execv (exonerate_argv[0], exonerate_argv) == -1) // replace child fork with a new process
+      THROWEXPR ("ERROR: Couldn't run exonerate (execv problem).");
+    fclose (stdout);
+    fclose (stderr);
+  }
+  else {                               // a positive PID indicates the parent process
+    waitpid (exonerate_pid, &exonerate_status, 0);  // wait for child process to end
+    if (exonerate_status)                           // did it work?
+      THROWEXPR ("ERROR: Running exonerate failed with exit code " << exonerate_status << ".");
+  }
+
+  // read output_file and parse results to get anchors
+  // exonerate output format is:
+  //    564000 563704 - 243683 243386 - 168
+  //    xstart xend xstrand ystart yend ystrand raw_score
+  // NB exonerate uses 0-based, half-open coordinates [start, end);
+  // we convert from this format to our 0-based, closed interval coordinates
+  Anchors anchors (xseq, yseq);
+  std::ifstream output_stream (output_file.c_str(), std::ifstream::in);
+  std::string line;
+  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE_VERBOSE))
+    CL << "exonerate output:" << endl;
+
+  while (!output_stream.eof()) {
+
+    getline (output_stream, line);
+    if (line.length() == 0) // skip empty lines
+      continue;
+
+    // log
+    if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE_VERBOSE))
+      CL << line;
+    std::string buffer;
+    std::stringstream ss (line);
+    std::vector<std::string> tokens; // vector to hold whitespace-separated tokens (words)
+    while (ss >> buffer)
+      tokens.push_back (buffer);
+
+    // skip exonerate's progress messages
+    if ((tokens.size() > 0) && ((tokens[0] == "Command") || (tokens[0] == "Hostname:") || (tokens[0] == "Message:") || (tokens[0] == "--")))
+      continue;
+
+    // now parse tokens into anchors
+    if (tokens.size() == 7) {
+
+      // parse output
+      const unsigned xstart = atoi (tokens[0].c_str());   // 0-based, half-open coordinates [start, end)
+      const unsigned xend = atoi (tokens[1].c_str()) - 1;
+      assert (tokens[2].length() == 1);        // assert single character indicating strand
+      const char xstrand = (tokens[2])[0];
+      const unsigned ystart = atoi (tokens[3].c_str());
+      const unsigned yend = atoi (tokens[4].c_str()) - 1;
+      assert (tokens[5].length() == 1);        // assert single character indicating strand
+      const char ystrand = (tokens[5])[0];
+      const double raw_score = static_cast<double> (atoi (tokens[6].c_str()));
+
+      // only consider collinear hits on forward strand
+      if ((xstrand != '+') || (ystrand != '+'))
+	continue;
+
+      // check sane
+      assert (xstart <= xend);
+      assert (ystart <= yend);
+      assert (raw_score >= minscore - DOUBLE_TINY);
+
+      // create anchor for ungapped aligned intervalval
+      anchors.store (Anchor (Interval (xstart, xend),
+			     Interval (ystart, yend),
+			     raw_score));
+
+      // mark the anchor as scored externally (no score updating later on)
+      anchors.back().set_external_scoring();
+
+    } else if (tokens.size() == 0) {
+      continue;
+    } else {
+      if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE))
+	CL << "WARNING: I don't know how to parse exonerate output line: " << line;
+      continue;
+    }
+  }
+
+  output_stream.close();
+
+  // clean up temporary files
+  if (remove (xfile.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << xfile << "'." << endl;
+  if (remove (yfile.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << yfile << "'." << endl;
+  if (remove (output_file.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << output_file << "'." << endl;
+
+  return anchors;
+
+#endif /* EXONERATE_EXEC */
+
+}
+
+
+// Wrapper for call_mummer.
+Anchors Mummer_adapter::get_candidate_anchors (size_t minlen /* = ANCHOR_NUC_MINLEN_DEFAULT */) const {
+
+  CTAG (8,ANCHORING ANCHORING_VERBOSE) << "Getting candidate anchors (with MUMmer) for sequence pair '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+
+  Anchors anchors (xseq.seq, yseq.seq);
+
+  // anchoring on translated sequences in protein space
+  if (__use_translated) {
+
+    // get translated sequences
+    const Translated_sequence tr_x (xseq);
+    const Translated_sequence tr_y (yseq);
+    
+    // forward strand for all frame combinations
+    for (size_t fx = 0; fx < 3; ++fx) {
+      for (size_t fy = 0; fy < 3; ++fy) {
+
+	// get anchors
+	Anchors tr_anchors = call_mummer (tr_x.get_forward (fx).seq, tr_y.get_forward (fy).seq, minlen);
+
+	// map anchor coordinates back to nucleotide sequence
+	for (std::vector<Anchor>::iterator anchor = tr_anchors.begin(); anchor != tr_anchors.end(); ++anchor) {
+	  anchor->xcoords = tr_x.map_interval_to_orig (true, fx, anchor->xcoords);
+	  anchor->ycoords = tr_y.map_interval_to_orig (true, fy, anchor->ycoords);
+	  anchor->update();
+	  // sanity check on mapping
+	  assert (anchor->xcoords.end < xseq.length());
+	  assert (anchor->ycoords.end < yseq.length());
+	  // store anchor
+	  anchors.store (*anchor);
+	  anchors.update_score (anchors.size() - 1);
+	}
+
+      }
+    }
+
+//    // reverse strand for all frame combinations
+//    for (size_t fx = 0; fx < 3; ++fx) {
+//      for (size_t fy = 0; fy < 3; ++fy) {
+//
+//	// get anchors
+//	Anchors tr_anchors = call_mummer (tr_x.reverse[fx], tr_y.reverse[fy], minlen);
+//
+//	// map anchor coordinates back to nucleotide sequence
+//	for (std::vector<Anchor>::iterator anchor = tr_anchors.begin(); anchor != tr_anchors.end(); ++anchor) {
+//	  anchor->xcoords = tr_x.map_interval_to_orig (false, fx, anchor->xcoords);
+//	  anchor->ycoords = tr_y.map_interval_to_orig (false, fy, anchor->ycoords);
+//	  anchor->update();
+//	  // store anchor
+//	  anchors.store (*anchor);
+//	  anchors.update_score (anchors.size() - 1);
+//	}
+//
+//      }
+//    }
+// reverse strand doesn't convey much more information
+//   -- RKB 10/11/08
+
+  }
+
+  // anchoring on nucleotide sequence
+  else {
+    anchors = call_mummer (xseq.seq, yseq.seq, minlen);
+  }
+
+  return anchors;
+
+}
+
+// I originally wrote this function using pipes to redirect the child process (mummer) stdout
+// to the parent process stdin.  For some inscrutable reason, it only worked the first
+// time it was called; subsequent calls had nothing in cin.
+// This was very weird; I was saving and restoring the original stdin and stdout, but
+// it happened anyways.
+// Hence the current way, where I redirect stdout of the child process to a file.
+Anchors Mummer_adapter::call_mummer (const std::string& xseq, const std::string& yseq, size_t minlen /* = ANCHOR_NUC_MINLEN_DEFAULT */) const {
+
+  // check that MUMmer executable is properly defined;
+  // if not, then die
+#ifndef MUMMER_EXEC
+  THROWEXPR ("ERROR: MUMmer executable isn't defined; try recompiling and specifying the MUMmer path.");
+  // else call MUMmer!
+#else
+
+  // get pid of current process for unique filenames
+  const pid_t curr_pid = getpid();
+
+  // write sequence files to scratch directory
+  std::string xfile = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_x.fa";
+  std::string yfile = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_y.fa";
+  // X
+  std::ofstream filestream;
+  filestream.open (xfile.c_str());
+  if (!filestream.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << xfile << "'.");
+  filestream << ">X" << endl;
+  filestream << xseq << endl;
+  filestream.close();
+  // Y
+  filestream.open (yfile.c_str());
+  if (!filestream.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << yfile << "'.");
+  filestream << ">Y" << endl;
+  filestream << yseq << endl;
+  filestream.close();
+
+  // create mummer executable string
+  // prepare for use with execv()
+  // (which requires null-terminated string)
+  std::string exec = std::string (MUMMER_EXEC)
+    + " -mum -l " + Util::to_string (minlen)
+    + " " + xfile + " " + yfile;
+  const std::vector<std::string> mummer_args = Util::split (exec);
+  char* mummer_argv [mummer_args.size() + 1];
+  for (size_t i = 0; i < mummer_args.size(); ++i)
+    mummer_argv[i] = static_cast<char*> (const_cast<char*> (mummer_args[i].c_str()));
+  mummer_argv[mummer_args.size()] = static_cast<char*> (0);
+  if (CTAGGING(6,ANCHORING ANCHORING_VERBOSE))
+    CTAG (6,ANCHORING ANCHORING_VERBOSE) << "Calling MUMmer as '" << exec << "'" << endl;
+  
+  // run mummer
+  pid_t mummer_pid;
+
+  // clear cin
+  std::cin.clear();
+
+  // tmp file to hold mummer output
+  std::string output_file = std::string (TMP_DIR) + "/" + FILENAME_PREFIX + "_" + Util::to_string (curr_pid) + "_output";
+
+  // fork and call mummer
+  int mummer_status = 0;
+  if ((mummer_pid = fork()) < 0) {  // a negative PID indicates failure
+    THROWEXPR ("ERROR: Couldn't start fork; exiting.");
+  }
+  else if (mummer_pid == 0) {       // a 0 PID indicates the child process
+    freopen (output_file.c_str(), "w", stdout);    // capture stdout (send to file output_file) to store mummer results
+    freopen ("/dev/null", "a", stderr);            // capture stderr (send to trash) so that it doesn't mess up our logging
+    if (execv (mummer_argv[0], mummer_argv) == -1) // replace child fork with a new process
+      THROWEXPR ("ERROR: Couldn't run MUMmer (execv problem).");
+    fclose (stdout);
+    fclose (stderr);
+  }
+  else {                            // a positive PID indicates the parent process
+    waitpid (mummer_pid, &mummer_status, 0);  // wait for child process to end
+    if (mummer_status)                        // did it work?
+      THROWEXPR ("ERROR: Running MUMmer failed with exit code " << mummer_status << ".");
+  }
+
+  // read output_file and parse results to get anchors
+  // mummer output format is:
+  // >seqname
+  //             xpos                         ypos                      match_length
+  // (position in reference sequence /t position in query sequence /t length of match)
+  // Note that we convert from 1-based (MUMmer's output) to 0-based coordinates here
+  Anchors anchors (xseq, yseq);
+  std::ifstream output_stream (output_file.c_str(), std::ifstream::in);
+  std::string line;
+  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE_VERBOSE))
+    CL << "MUMmer output:" << endl;
+  while (!output_stream.eof()) {
+    getline (output_stream, line);
+    // log
+    if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE_VERBOSE))
+      CL << line;
+    std::string buffer;
+    // skip comments and sequence names
+    if ((line.length() > 0) && ((line[0] == '#') || (line[0] == '>')))
+      continue;
+    std::stringstream ss (line);
+    std::vector<std::string> tokens; // vector to hold whitespace-separated tokens (words)
+    while (ss >> buffer)
+      tokens.push_back (buffer);
+
+    // now parse tokens into anchors
+    if (tokens.size() == 3) {
+      unsigned xstart = atoi (tokens[0].c_str()) - 1; // convert from 1-based to 0-based coordinates
+      unsigned ystart = atoi (tokens[1].c_str()) - 1;
+      size_t length = atoi (tokens[2].c_str());
+      assert (length >= minlen);
+      anchors.store (Anchor (Interval (xstart, xstart + length - 1),
+			     Interval (ystart, ystart + length - 1))); // -1 because closed interval
+      anchors.update_score (anchors.size() - 1);
+    } else if (tokens.size() == 0) {
+      continue;
+    } else {
+      if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE))
+	CL << "WARNING: I don't know how to parse MUMmer output line: " << line;
+      continue;
+    }
+  }
+
+  output_stream.close();
+  
+  // clean up temporary files
+  if (remove (xfile.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << xfile << "'." << endl;
+  if (remove (yfile.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << yfile << "'." << endl;
+  if (remove (output_file.c_str()) != 0)
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "WARNING: Couldn't delete temporary file '" << output_file << "'." << endl;
+
+  return anchors;
+
+#endif /* MUMMER_EXEC */
+
+}
+
+void Anchor_resolver::add_mercator_constraints (const std::string& filename) {
+
+  // read Mercator file
+  __constraints_set.read_mercator (filename);
+ 
+}
+
+const std::vector<Anchors> Anchor_resolver::get_resolved_anchors (const size_t minlen /* = ANCHOR_NUC_MINLEN_DEFAULT */, const size_t max_join_distance /* = 0 */, bool const use_translated /* = false */,
+								  const bool use_exonerate /* = false */, const int minscore /* = EXONERATE_MINSCORE_DEFAULT */, const bool softmasked /* = false */,
+								  const bool hardmasked /* = true */,
+								  const size_t num_refinement_steps /* = 0 */,
+								  const bool output_for_gui /* = false */, const std::string gui_prefix /* = "" */) const {
+
+  // initialize dummy Tree_weights (returns all weights as 1.0)
+  Tree_weights tree_weights;
+  return get_resolved_anchors (tree_weights,
+			       minlen, max_join_distance, use_translated,
+			       use_exonerate, minscore, softmasked,
+			       hardmasked,
+			       num_refinement_steps,
+			       output_for_gui, gui_prefix);
+
+}
+
+const std::vector<Anchors> Anchor_resolver::get_resolved_anchors (const Tree_weights& tree_weights,
+								  const size_t minlen /* = ANCHOR_NUC_MINLEN_DEFAULT */, const size_t max_join_distance /* = 0 */, const bool use_translated /* false */,
+								  const bool use_exonerate /* = false */, const int minscore /* = EXONERATE_MINSCORE_DEFAULT */, const bool softmasked /* = false */,
+								  const bool hardmasked /* = true */,
+								  const size_t num_refinement_steps /* = 0 */,
+								  const bool output_for_gui /* = false */, std::string gui_prefix /* = "" */) const {
+
+  // store all candidate anchors for later recovery
+  std::vector<Anchors> candidate_anchors_list (seq_pairs.size());
+
+  // This proceeds as:
+  // - get candidate anchors for all sequence pairs we're considering
+  // - create and store Post_probs objects for each sequence pair
+  // - create "reduced" sequences, where a reduced sequence is obtained from
+  //    the original sequence by taking only positions corresponding to the
+  //    centroids of candidate anchors
+  // - perform anchor annealing on the reduced sequences
+  // - map the resolved anchors back to the original sequence coordinates
+
+  // information to build reduced sequences:
+  //  set of positions within the sequence which correspond to candidate anchors
+  std::vector<std::set<unsigned> > anchored_positions (seq_db.size());
+
+  // get list of candidate anchors
+  // list of Post_probs for each sequence pair
+  std::vector<Post_probs> post_probs_list (seq_pairs.size());
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+
+    // get sequence indices for this sequence pair
+    const size_t i = seq_pairs[cnt].first;
+    const size_t j = seq_pairs[cnt].second;
+
+    const Sequence& xseq = seq_db_internal.get_seq (i);
+    const Sequence& yseq = seq_db_internal.get_seq (j);
+
+    // if one of the seqs is empty, don't try to find anchors
+    // (MUMmer doesn't handle empty sequences gracefully)
+    if (!xseq.length() || !yseq.length())
+      continue;
+
+    // get candidate anchors
+    const Mummer_adapter mummer_adapter (xseq, yseq, use_translated);            // find in protein space if requested
+    candidate_anchors_list[cnt] = mummer_adapter.get_candidate_anchors (minlen);
+
+    // if present, add Mercator constraint information as anchors
+    if (__constraints_set.size()) {
+      const Sequence& xseq_orig = seq_db.get_seq (i);
+      const Sequence& yseq_orig = seq_db.get_seq (j);
+      const Anchors constraints_anchors = Anchors::convert_constraints_to_anchors (__constraints_set.get_constraints (i, j), xseq_orig, yseq_orig, hardmasked);
+      // store constraints as anchors
+      candidate_anchors_list[cnt].store (constraints_anchors);
+    }
+
+    // get exonerate anchors if so requested
+    if (use_exonerate) {
+      const Exonerate_adapter exonerate_adapter (xseq, yseq, use_translated, softmasked);
+      const Anchors exonerate_anchors = exonerate_adapter.get_candidate_anchors (minscore);
+      candidate_anchors_list[cnt].store (exonerate_anchors);
+    }
+
+    // enforce immutable unique
+    // important that we do this before any other manipulations
+    // (otherwise, e.g., resolve_parallel might fail)
+    candidate_anchors_list[cnt].enforce_immutable_unique();
+
+    // resolve parallel anchors:
+    // remove degenerate anchors, merge overlapping anchors and concatenate adjacent anchors if requested
+    // essential if using translated anchors
+    if (!candidate_anchors_list[cnt].resolve_parallel (max_join_distance, false)) // don't concatenate immutable anchors
+      THROWEXPR ("ERROR: Couldn't resolve parallel anchors.");
+
+    // record the centroids of the candidate anchors to later build the reduced sequences
+    for (std::vector<Anchor>::const_iterator anchor = candidate_anchors_list[cnt].begin(); anchor != candidate_anchors_list[cnt].end(); ++anchor) {
+      anchored_positions[i].insert (anchor->x);
+      anchored_positions[j].insert (anchor->y);
+    }
+
+  }
+
+  // now properly normalize the scores of externally-scored anchors:
+  // first get the maximum score for an externally-scored anchor
+  // over the anchors for /all/ sequence pairs
+  double max_external_score = 0;
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+    for (std::vector<Anchor>::const_iterator anchor = candidate_anchors_list[cnt].begin(); anchor != candidate_anchors_list[cnt].end(); ++anchor) {
+      if (anchor->is_external_scoring() && (anchor->get_score() > max_external_score))
+	max_external_score = anchor->get_score();
+    }
+  }
+
+  // then use this max score as a normalization constant
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+    for (std::vector<Anchor>::iterator anchor = candidate_anchors_list[cnt].begin(); anchor != candidate_anchors_list[cnt].end(); ++anchor) {
+      if (anchor->is_external_scoring())
+	anchor->set_score ((anchor->get_score() / max_external_score) - DOUBLE_TINY); // (ensure all scores < 1.0)
+      // check sane after normalization to [0,1]
+      assert ((anchor->get_score() >= 0.0) && (anchor->get_score() <= 1.0));
+    }
+  }
+
+  // now finish pre-processing the anchors prior to anchor annealing and log them
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+
+    // convert score distribution over anchors to a normalized probability distribution
+    candidate_anchors_list[cnt].impose_normalized_probability_distribution();
+
+    // convert candidate anchors to Post_probs format
+    post_probs_list[cnt] = candidate_anchors_list[cnt].convert_to_post_probs();
+
+    // get sequence indices for this sequence pair
+    const size_t i = seq_pairs[cnt].first;
+    const size_t j = seq_pairs[cnt].second;
+
+    const Sequence& xseq = seq_db_internal.get_seq (i);
+    const Sequence& yseq = seq_db_internal.get_seq (j);
+
+    // log candidate anchors
+    if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+      CL << "Sequences '" << xseq.name << "' and '" << yseq.name << "' have candidate anchors:" << endl;
+      candidate_anchors_list[cnt].show (CL);
+    }
+
+    // log
+    size_t num_anchors = candidate_anchors_list[cnt].size();
+    CTAG (7,ANCHORING ANCHORING_VERBOSE) << "Found " << num_anchors << " candidate anchors for sequence pair '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+
+  }
+
+  // create reduced_seq_db to hold actual reduced sequences
+  Sequence_database reduced_seq_db;
+  for (size_t i = 0; i < seq_db.size(); ++i) {
+    const Sequence& sequence = seq_db.get_seq (i);
+    std::string seq (anchored_positions[i].size(), 'R'); // R for Rob!
+    reduced_seq_db.add_seq (Sequence (sequence.name, seq));
+  }
+
+  // create map from positions in "reduced" sequences to positions in actual sequences
+  // note that the anchor positions in anchored_positions[i] are already sorted because it's a set
+  std::vector<std::map<unsigned, unsigned> > reduced_position_map (seq_db.size());            // map reduced -> original
+  std::vector<std::map<unsigned, unsigned> > reduced_position_reverse_map (seq_db.size());    // map original -> reduced
+  if (CTAGGING(-1,ANCHORING_VERBOSE))
+    CL << "reduced_position_map:" << endl;
+  for (size_t i = 0; i < seq_db.size(); ++i) {
+    unsigned ii = 0;
+    for (std::set<unsigned>::iterator x = anchored_positions[i].begin(); x != anchored_positions[i].end(); ++x, ++ii) { // ii is the position within the reduced sequence
+      reduced_position_map[i].insert (std::make_pair (ii, *x));                                                                // x is the position within the original sequence
+      reduced_position_reverse_map[i].insert (std::make_pair (*x, ii));
+      if (CTAGGING(-1,ANCHORING_VERBOSE))
+	CL << "(" << i << ", " << *x << ") == " << ii << endl;
+    }
+  }
+
+  // store sparse matrices on reduced sequences for anchor annealing
+  std::vector<std::vector<SparseMatrix*> > sparse_matrices (seq_db.size(), std::vector<SparseMatrix*> (seq_db.size(), reinterpret_cast<SparseMatrix*> (NULL)));
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+
+    // get sequence indices for this sequence pair
+    const size_t i = seq_pairs[cnt].first;
+    const size_t j = seq_pairs[cnt].second;
+
+    // map the original sequence positions to the new reduced ones
+    for (Post_probs::iterator post = post_probs_list[cnt].begin(); post != post_probs_list[cnt].end(); ++post) {
+      (*post).x = reduced_position_reverse_map[i][(*post).x];
+      (*post).y = reduced_position_reverse_map[j][(*post).y];
+    }
+
+    // if reduced seqs are length 0, then leave null
+    if ((anchored_positions[i].size() == 0) || (anchored_positions[j].size() == 0))
+      continue;
+
+    // else create corresponding sparse matrix and store transpose
+    sparse_matrices[i][j] = new SparseMatrix (i, j,
+					      anchored_positions[i].size(), anchored_positions[j].size(), post_probs_list[cnt]);
+    sparse_matrices[j][i] = sparse_matrices[i][j]->ComputeTranspose();
+
+  }
+
+  // do database stuff
+  // create empty database manager 
+  Manager manager;
+
+  // now resolve anchors
+  CTAG (9,ANCHORING ANCHORING_VERBOSE) << "Performing anchor annealing to resolve anchors." << endl;
+
+  // do anchor annealing
+  // It's important to perform use gap-factor 0;
+  // otherwise the result will depend heavily on how we scale the scores for the HSPs.
+  // This way will give the maximal set (well, a greedy version thereof) of consistent anchors.
+  Alignment_DAG dag (reduced_seq_db);
+  dag.anneal (sparse_matrices, tree_weights,
+	      manager,
+	      false,                    // use_tgf = false
+	      0, true, 0,               // gap_factor = 0, enable_dynamic_weights = true, edge_weight_threshold = 0
+	      num_refinement_steps,
+	      false, "");               // output_for_gui = false, gui_prefix = ""
+  dag.dfs_topological_sort();  // this isn't really necessary but it does force removal of dead columns, which is nice
+
+  // convert the annealed alignment into a set of pairwise anchors
+  // initialize them with sequence lengths for score calculation
+  std::vector<Anchors> resolved_anchors_list;
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt)
+    resolved_anchors_list.push_back (Anchors (seq_db_internal.get_seq (seq_pairs[cnt].first).seq, seq_db_internal.get_seq (seq_pairs[cnt].second).seq));
+
+  // we need a mapping from sequence pairs to the corresponding index in seq_pairs
+  // -1 means not present; otherwise is the index 
+  std::map<std::pair<size_t, size_t>, size_t> seq_pair_lookup;
+  for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt)
+    seq_pair_lookup.insert (std::make_pair (std::make_pair (seq_pairs[cnt].first, seq_pairs[cnt].second), cnt));
+
+  // loop over columns of the alignment,
+  // interpreting aligned characters as constituting a resolved anchor
+
+  // don't store an anchor more than once:
+  // candidate_anchors_added[cnt][a] = true indicates that candidate_anchors_list[cnt][a]
+  // has already been added as a resolved anchor
+  std::vector<std::vector<bool> > candidate_anchors_added (candidate_anchors_list.size(), std::vector<bool> ());
+  for (size_t cnt = 0; cnt < candidate_anchors_list.size(); ++cnt)
+    candidate_anchors_added[cnt].assign (candidate_anchors_list[cnt].size(), false);
+
+  // now loop over columns of the DAG to look for aligned positions
+  const std::vector<Column*>& columns = dag.get_columns();
+  for (std::vector<Column*>::const_iterator col = columns.begin(); col != columns.end(); ++col) {
+    
+    // there shouldn't be any dead columns here
+    assert (!(*col)->is_dead());
+
+    const Seq_pos_map seq_pos_map = (*col)->get_seq_pos_map();
+
+    // if no aligned positions, continue on to the next column
+    if (seq_pos_map.size() < 2)
+      continue;
+
+    // create a pairwise anchor for each pair of aligned characters
+    for (Seq_pos_map::const_iterator seq_pos1 = seq_pos_map.begin(); seq_pos1 != seq_pos_map.end(); ++seq_pos1) {
+      for (Seq_pos_map::const_iterator seq_pos2 = seq_pos_map.begin(); seq_pos2 != seq_pos_map.end(); ++seq_pos2) {
+
+	// sequence indices
+	const size_t i = seq_pos1->first;
+	const size_t j = seq_pos2->first;
+	assert ((i < seq_db.size()) && (j < seq_db.size()));
+
+	// require i < j to prevent duplicates
+	if (i >= j)
+	  continue;
+
+	// make sure that the sequence pair (i, j) is in the list seq_pairs of sequence pairs to process;
+	// if not, then continue on to the next pair
+	if (seq_pair_lookup.find (std::make_pair (i, j)) == seq_pair_lookup.end())
+	  continue;
+	const size_t cnt = seq_pair_lookup[std::make_pair (i, j)];
+
+	const unsigned x = (reduced_position_map[i])[(*seq_pos1).second]; // map from positions within the reduced sequences to the original sequences
+	const unsigned y = (reduced_position_map[j])[(*seq_pos2).second]; //     (*seq_pos1).second   ->     reduced_position_map[j][(*seq_pos1).second]
+	assert ((x < seq_db.get_seq (i).length()) && (y < seq_db.get_seq (j).length()));
+
+	// here "transitive anchoring" comes into play:
+	// If it's a "transitive anchor" then we won't have information stored for it
+	// (ie no entry in candidate_anchors[cnt]), but we don't want to discard the transitive information either.
+	// We therefore should do a lookup to see if a candidate anchor (x,y) exists for seq. pair cnt;
+	// if not, then just create an anchor of length one with midpoints (x,y) and store it.
+	const size_t candidate_index = candidate_anchors_list[cnt].exists_spanning_anchor (x, y);
+	if (candidate_index != candidate_anchors_list[cnt].size()) {                                // if there is a spanning candidate anchor
+	  if (!candidate_anchors_added[cnt][candidate_index]) {    // if it hasn't already been added, then add it
+	    resolved_anchors_list[cnt].store (candidate_anchors_list[cnt].get_spanning_anchor (x, y));
+	    candidate_anchors_added[cnt][candidate_index] = true;
+	  } else                                                   // else we've already added it, so just continue
+	    continue;
+	} else {                                                   // if there is no spanning candidate anchor
+	  resolved_anchors_list[cnt].store (Anchor (Interval (x, x), Interval (y, y)));
+	  resolved_anchors_list[cnt].update_score (resolved_anchors_list[cnt].size() - 1);
+	}
+
+      }
+    }
+
+  }
+
+  // log resolved anchors
+  if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+    for (size_t cnt = 0; cnt < resolved_anchors_list.size(); ++cnt) {
+      CL << "Resolved anchors after anchor annealing for '" << seq_db_internal.get_seq (seq_pairs[cnt].first).name << "' and '" << seq_db_internal.get_seq (seq_pairs[cnt].second).name << "':" << endl;
+      resolved_anchors_list[cnt].show (CL);
+    }
+  }
+
+  // perform various administrative tasks:
+  // - resolve adjacent parallel anchors
+  // - enforce immutable anchors unique
+  // - prune overlapping anchors
+  // because we have already resolved candidate parallel anchors before anchor annealing,
+  // this should be relevant only for catching adjacent parallel anchors which arise due to transitive anchoring
+  // also sort lexically
+  for (size_t cnt = 0; cnt < resolved_anchors_list.size(); ++cnt) {
+    resolved_anchors_list[cnt].enforce_immutable_unique();
+    if (!resolved_anchors_list[cnt].resolve_parallel (max_join_distance, true)) // concatenate immutable anchors
+      THROWEXPR ("ERROR: Couldn't resolve parallel anchors.");
+    resolved_anchors_list[cnt].remove_overlaps (use_translated ? 3 * minlen : minlen); // remove pruned anchors which are shorter than minlen
+  }
+
+  // debugging
+  if (CTAGGING(-1,ANCHORING ANCHORING_VERBOSE_VERBOSE)) {
+    dag.get_stockholm().write_stockholm (CL);
+  }
+
+  // log resolved anchors
+  if (CTAGGING(4,ANCHORING ANCHORING_VERBOSE)) {
+    for (size_t cnt = 0; cnt < resolved_anchors_list.size(); ++cnt) {
+      CL << "Resolved anchors for '" << seq_db_internal.get_seq (seq_pairs[cnt].first).name << "' and '" << seq_db_internal.get_seq (seq_pairs[cnt].second).name << "':" << endl;
+      resolved_anchors_list[cnt].show (CL);
+    }
+  }
+
+  // write GUI output if requested
+  if (output_for_gui) {
+    std::string gui_filename = std::string (gui_prefix) + GUI_FILENAME_ANCHORS_SUFFIX;
+    std::ofstream gui_file;
+    gui_file.open (gui_filename.c_str());
+    if (!gui_file.is_open())
+      THROWEXPR ("ERROR: Couldn't create file with name '" << gui_filename << "'.");
+    for (size_t cnt = 0; cnt < resolved_anchors_list.size(); ++cnt) {
+      gui_file << "; Resolved anchors after concatenation for '" << seq_db_internal.get_seq (seq_pairs[cnt].first).name << "' and '" << seq_db_internal.get_seq (seq_pairs[cnt].second).name << "'." << endl
+	       << "; Format is " << endl
+	       << ";   (0 ~ 1) == [1,6] ~ [3,8] => 0.9" << endl
+	       << ";   meaning that sequences 0 and 1 have an ungapped anchor " << endl
+	       << ";   which spans [1,6] in sequence 0 and [3,8] in sequence 1" << endl
+	       << ";   and has a score of 0.9." << endl
+	       << "; sequence is 0-based and position is 0-based" << endl
+	       << endl;
+      resolved_anchors_list[cnt].write_gui_output (gui_file, seq_pairs[cnt].first, seq_pairs[cnt].second);
+      gui_file << endl;
+    }
+    gui_file.close();
+    CTAG (9,ANCHORING ANCHORING_VERBOSE) << "Created GUI output file '" << gui_filename << "'" << endl;
+  }
+
+  // impose normalized probability distribution
+  for (size_t cnt = 0; cnt < resolved_anchors_list.size(); ++cnt)
+    resolved_anchors_list[cnt].impose_normalized_probability_distribution();
+
+  return resolved_anchors_list;
+}
diff --git a/src/fsa/anchors.h b/src/fsa/anchors.h
new file mode 100644
index 0000000..85ad22e
--- /dev/null
+++ b/src/fsa/anchors.h
@@ -0,0 +1,818 @@
+
+/**
+ * \file anchors.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef FSA_ANCHORS_INCLUDED
+#define FSA_ANCHORS_INCLUDED
+
+#include <iostream>
+#include <fstream>
+
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+#include "annealing/dotplot.h"
+#include "annealing/SparseMatrix.h"
+#include "annealing/alignment_DAG.h"
+#include "fsa/constraints.h"
+#include "fsa/model.h"
+#include "fsa/sequence_pair_selector.h"
+
+#define MEGABYTE 1048576
+
+#define ANCHOR_NUC_MINLEN_DEFAULT 10
+#define ANCHOR_AA_MINLEN_DEFAULT 7
+
+#define EXONERATE_MINSCORE_DEFAULT 100
+
+namespace fsa {
+
+  /**
+   * \brief Represent a single ungapped anchor.
+   *
+   * Assumes a 0-based coordinate system and a fully-closed interval.
+   */
+  struct Anchor {
+
+  public:
+
+    Interval xcoords;           ///< interval of the anchor in sequence X
+    Interval ycoords;           ///< interval of the anchor in sequence Y
+    unsigned x;                 ///< center of the interval xcoords
+    unsigned y;                 ///< center of the interval ycoords
+    size_t length;              ///< length of the (ungapped) matched sequence
+
+  private:
+
+    double __score;             ///< score of the anchor (higher is better)
+    bool __external_scoring;    ///< was the anchor scored according to some external measure?
+    bool __immutable;           ///< an anchor which should never be pruned or re-scored
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    Anchor() { }
+
+    /**
+     * \brief Constructor.
+     */
+    Anchor (Interval xcoords, Interval ycoords);
+
+    /**
+     * \brief Constructor.
+     */
+    Anchor (Interval xcoords, Interval ycoords, double score);
+
+    /**
+     * \brief Set score.
+     *
+     * Immutable anchors cannot be rescored.
+     * \param score new score
+     */
+    inline void set_score (const double score) {
+      if (!is_immutable())
+	__score = score;
+    }
+
+    /**
+     * \brief Get score.
+     */
+    inline double get_score() const {
+      return __score;
+    }
+
+    /**
+     * \brief Was the anchor scored according to some external measure?
+     *
+     * If so, then it shouldn't be updated according to length.
+     */
+    inline bool is_external_scoring() const {
+      return __external_scoring;
+    }
+
+    /**
+     * \brief Mark the score as external.
+     */
+    inline void set_external_scoring() {
+      __external_scoring = true;
+    }
+
+    /**
+     * \brief Mark anchor as immutable.
+     *
+     * Immutable anchors should never be pruned or rescored.
+     * Useful primarily for constraints which we want to force
+     * (we assume that they are consistent,
+     * although nothing will break if they are not).
+     * Sets anchor score to 1.0 - DOUBLE_VERY_TINY.
+     */
+    inline void set_immutable() {
+      __score = 1.0 - DOUBLE_VERY_TINY;
+      __immutable = true;
+    }
+
+    /**
+     * \brief Is the anchor score immutable?
+     */
+    inline bool is_immutable() const {
+      return __immutable;
+    }
+
+    /**
+     * \brief Is it parallel to another anchor?
+     */
+    inline bool is_parallel (const Anchor& a) const {
+      return (xcoords.start - a.xcoords.start == ycoords.start - a.ycoords.start);
+    }
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Anchor& anchor)  {
+      o << "[" << anchor.xcoords.start << ", " << anchor.xcoords.end << "] ~ ["
+	<< anchor.ycoords.start << ", " << anchor.ycoords.end << "]"
+	<< " : " << anchor.x << " ~ " << anchor.y
+	<< " => " << std::setprecision (PRECISION_DEFAULT) << anchor.get_score();
+      if (anchor.is_external_scoring())
+	o << " (external_scoring)";
+      if (anchor.is_immutable())
+	o << " (immutable)";
+      return o;
+    }
+
+    /**
+     * \brief Re-calculate x, y and length.
+     */
+    void update();
+
+    /**
+     * \brief Map score to a high probability.
+     *
+     * Linear map from a score in the interval [0,1] to a 
+     * high probability in [1 - 0.01, 1].
+     * The point of this is: When performing anchor annealing, we want an actual
+     * score/probability distribution on candidate anchors.
+     * However, post-anchor annealing, the probability distribution over anchored
+     * characters is a series of step functions, ie all the mass is concentrated
+     * in single aligned pairs.  We therefore no longer want the 'score'
+     * but rather a probability near 1, where the mapping preserves
+     * the ordering of the scores.
+     * \return probability of anchor
+     * \see FSA::build_anchored_multiple_alignment
+     */
+    inline double score_to_prob() const {
+      return ((1.0 - DOUBLE_TINY) + DOUBLE_TINY * get_score());
+    }
+
+    /**
+     * \brief Compute the p-value associated with two anchored subsequences.
+     *
+     * Computed p-value is that associated with the null model,
+     * so a lower p-value is more significant.
+     * \param xseq complete sequence X
+     * \param yseq complete sequence Y
+     * \return p-value of anchored subseqs under a null model
+     */
+    double p_value (const std::string& xseq, const std::string& yseq) const;
+
+    /**
+     * \brief Compute the p-value associated with two anchored subsequences.
+     *
+     * Computed p-value is that associated with the null model,
+     * so a lower p-value is more significant.
+     * \param xseq complete sequence X
+     * \param yseq complete sequence Y
+     * \return p-value of anchored subseqs under a null model
+     */
+    double p_value (const std::string* xseq, const std::string* yseq) const;
+
+    /**
+     * \brief Lexical order, preferring x coordinate, on the left-hand boundaries.
+     *
+     * Sorted first by the left-hand x coordinate,
+     * then the left-hand y coordinate.
+     */
+    bool operator< (const Anchor& r) const {
+      return lexical_comparison_x (*this, r);
+    }
+
+    /**
+     * \brief Equality.
+     */
+    bool operator== (const Anchor& r) const {
+      if ((xcoords.start == r.xcoords.start) && (xcoords.end == r.xcoords.end) && (ycoords.start == r.ycoords.start) && (ycoords.end == r.ycoords.end))
+	return true;
+      else
+	return false;
+    }
+
+    /**
+     * \brief Lexical order on x coordinate.
+     */
+    static bool lexical_comparison_x (const Anchor& l, const Anchor& r) {
+      if (l.xcoords.start == r.xcoords.start)
+	return (l.xcoords.end < r.xcoords.end);
+      else
+	return (l.xcoords.start < r.xcoords.start);
+    }
+
+    /**
+     * \brief Lexical order on y coordinate.
+     */
+    static bool lexical_comparison_y (const Anchor& l, const Anchor& r) {
+      if (l.ycoords.start == r.ycoords.start)
+	return (l.ycoords.end < r.ycoords.end);
+      else
+	return (l.ycoords.start < r.ycoords.start);
+    }
+
+    /**
+     * \brief Lexical order, preferring x, then y, on the left-hand boundaries.
+     */
+    static bool lexical_comparison_x_y (const Anchor& l, const Anchor& r) {
+      if (l.xcoords.start == r.xcoords.start)
+	return (l.ycoords.start < r.ycoords.start);
+      else
+	return (l.xcoords.start < r.xcoords.start);
+    }
+
+    /**
+     * \brief Lexical order, preferring y coordinate, then x, on the left-hand boundaries.
+     */
+    static bool lexical_comparison_y_x (const Anchor& l, const Anchor& r) {
+      if (l.ycoords.start == r.ycoords.start)
+	return (l.xcoords.start < r.xcoords.start);
+      else
+	return (l.ycoords.start < r.ycoords.start);
+    }
+
+    /**
+     * \brief Lexical order, preferring x, then y, on the centroids.
+     */
+    static bool lexical_comparison_x_y_centroid (const Anchor& l, const Anchor& r) {
+      if (l.x == r.x)
+	return (l.y < r.y);
+      else
+	return (l.x < r.x);
+    }
+
+  };
+
+
+  /**
+   * \brief A vector of anchors for two sequences.
+   */
+  struct Anchors {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    Anchors()
+    : xseq (NULL), yseq (NULL) { }
+
+    /**
+     * \brief Constructor.
+     * \param xseq sequence X
+     * \param yseq sequence Y
+     */
+    Anchors (const std::string& xseq, const std::string& yseq)
+    : xseq (&xseq), yseq (&yseq) { }
+
+    /**
+     * \brief Constructor.
+     * \param xseq sequence X
+     * \param yseq sequence Y
+     */
+    Anchors (const std::string* xseq, const std::string* yseq)
+    : xseq (xseq), yseq (yseq) { }
+
+    /**
+     * \brief Convert constraints to anchors.
+     *
+     * For every constraint, creates an anchor for each end of the constraint.
+     * If sequence is hardmasked, then constraints whose ends fall in 
+     * hardmasked regions are pruned until they don't.
+     * Sequences are for hardmasking.
+     * \param xseq_orig Sequence for sequence X
+     * \param yseq_orig Sequence for sequence Y
+     * \param hardmasked sequence is hardmasked
+     */
+    static Anchors convert_constraints_to_anchors (const Constraints& constraints,
+						   const Sequence& xseq_orig, const Sequence& yseq_orig,
+						   const bool hardmasked);
+
+    /**
+     * Display.
+     */
+    void show (std::ostream& o) const;
+
+    /**
+     * \brief Output formatted for GUI.
+     *
+     * Format is 
+     * (0 ~ 1) == [1,6] ~ [3,8] => 0.9
+     * meaning that sequences 0 and 1 have an anchor which
+     * spans [1,6] in sequence 0 (X) and [3,8] in sequence 1 (Y)
+     * and has a score of 0.9.
+     * \param xidx index of sequence X
+     * \param yidx index of sequence Y
+     */
+    void write_gui_output (std::ostream& o, const size_t xidx, const size_t yidx) const;
+
+    /**
+     * \brief Convert these anchors to a Post_probs format.
+     *
+     * Enforces lexical ordering, preferring x coordinate, on centroids of anchors.
+     * For subsequent conversion to a SparseMatrix object.
+     * Recommended function; memory-efficient.
+     */
+    const Post_probs convert_to_post_probs() const;
+
+    /**
+     * \brief Creates a map from centroid coordinates x and y specified by an anchor to the anchor index in (*this).
+     *
+     * A set of anchors is nondegenerate if the centroids x and y
+     * of anchors uniquely specify the containing anchor.
+     * \return false if the set of anchors is degenerate (more than one spanning anchor in (*this)).
+     */
+    bool create_spanning_map();
+
+    /**
+     * \brief Returns the anchor index if an anchor which anchors coordinates x and y exists; returns this->size() otherwise.
+     *
+     * \param x coordinate anchored in first sequence X
+     * \param y coordinate anchored in second sequence Y
+     */
+    size_t exists_spanning_anchor (const unsigned x, const unsigned y) const;
+
+    /**
+     * \brief Returns the anchor which anchors coordinates x and y.
+     *
+     * Assumes that exists_spanning_anchor (x, y) has been used
+     * to check that such an anchor does exist.
+     * Calls exists_spanning_anchor (x, y).
+     * \param x coordinate anchored in first sequence X
+     * \param y coordinate anchored in second sequence Y
+     * \return anchor which anchors coordinates x and y
+     */
+    const Anchor get_spanning_anchor (const unsigned x, const unsigned y);
+
+    /**
+     * \brief Resolve parallel degenerate, overlapping and adjacent anchors.
+     *
+     * Drop degenerate anchors which are entirely spanned by a larger parallel anchor.
+     * Merge overlapping parallel anchors.
+     * Concatenate nearby (semi-adjacent) parallel anchors which are separated by <= max_join_distance (ungapped).
+     * If degenerate anchors are immutable,
+     * then the degenerate anchor is kept and the containing anchor discarded
+     * (the presumption being that immutable anchors are "special").
+     * Calls enforce_immutable_unique and rebuilds the spanning_map.
+     * \param max_join_distance maximum separation between parallel anchors to concatenate
+     * \return true if non-degenerate spanning map created successfully
+     * \see enforce_immutable_unique
+     */
+    bool resolve_parallel (const size_t max_join_distance = 0, const bool concatenate_immutable = false);
+
+    /**
+     * \brief Remove anchors whose centroids overlap with the immutable anchors.
+     *
+     * This must be called before impose_normalized_probability_distribution
+     * in order to make sure that the distribution can be normalized.
+     * Does not rebuild the spanning_map.
+     */
+    void enforce_immutable_unique();
+
+    /**
+     * \brief Remove overlaps between anchors.
+     *
+     * Resolve overlapping anchors favor of the highest-scoring one.
+     * Internally enforces lexical ordering of anchors.
+     * This is absolutely crucial for efficient DP on unanchored regions.
+     * Does not rebuild the spanning_map!
+     * \param minlen minimum anchor length
+     */
+    void remove_overlaps (const size_t minlen = ANCHOR_NUC_MINLEN_DEFAULT);
+
+    /**
+     * \brief Remove overlaps in X coordinate between anchors.
+     *
+     * Assumes that the anchors are already properly sorted.
+     * This is the responsibility of the calling function.
+     * \param minlen minimum anchor length
+     * \param which 0 for X, 1 for Y
+     */
+    void remove_overlaps (const size_t minlen, const unsigned which);
+
+    /**
+     * \brief Update score of an anchor and map to [0,1].
+     *
+     * Updates the score of the anchor (*this)[idx].
+     * Scores are computed as (1 - p_value) of the anchor.
+     * They therefore fall in the interval [0,1] and can be interpreted as probabilities, 
+     * but do NOT generally form a probability distribution over anchored positions.
+     * The scores for a particular sequence position aren't required to be normalized to sum to <= 1.
+     * \param idx index of the anchor in (*this)
+     * \see impose_normalized_probability_distribution()
+     */
+    void update_score (const size_t idx);
+
+    /**
+     * \brief Convert scores to a normalized probability distribution.
+     *
+     * Calls update_score() on all anchors.
+     * Guarantees that the distribution over anchor centroids is normalized, ie
+     *   sum_j P(x_i ~ y_j) <= 1 for every i
+     *   sum_i P(x_i ~ y_j) <= 1 for every j
+     * where x_i and y_j are centroids of anchored intervals.
+     * This normalization is accomplished as follows:
+     * If we have candidate anchors A ~ A1 and A ~ A2,
+     *   X .....A.......
+     *   Y ..A1.....A2..
+     * then P(A ~ A1) and P(A ~ A2) as reported by update_score()
+     * are scaled by their fractional respective weights.
+     * More precisely, an anchor with score P(x_i ~ y_k) becomes
+     *    max_j P(x_i ~ y_j) * ( P(x_i ~ y_k) / sum_j P(x_i ~ y_j) )
+     * This transformation has the properties:
+     * - if there is no overlap, then the score is unchanged
+     * - if one anchor has a much higher score than overlapping ones,
+     *    then its score is only reduced a little bit, whereas the scores
+     *    of the others are drastically reduced
+     * - it maps to [0, 1] (assuming that the scores are originally in [0, 1])
+     * Because each can be individually interpreted as probabilities (<= 1),
+     * this guarantees a normalized distribution.
+     * This transformation penalizes non-unique (overlapping) anchors while
+     * maintaining their relative ordering.
+     * IMPORTANT: The scores of immutable anchors cannot be changed,
+     * so this will NOT give a normalized distribution if immutable anchors
+     * overlap other anchors.  enforce_immutable_unique must be called first.
+     * \see ensure_immutable_unique
+     */
+    void impose_normalized_probability_distribution();
+
+    /**
+     * \brief Number of anchors.
+     */
+    size_t size() const { return __anchors.size(); }
+
+    /**
+     * \brief Store an anchor.
+     */
+    void store (const Anchor& a) {
+      __anchors.push_back (a);
+    }
+
+    /**
+     * \brief Store anchors.
+     */
+    void store (const Anchors& new_anchors) {
+      __anchors.insert (__anchors.end(),
+			new_anchors.begin(), new_anchors.end());
+    }
+
+    /**
+     * \brief Data access operator.
+     */
+    const Anchor& operator[] (const size_t i) const {
+      assert (i < __anchors.size());
+      return __anchors[i];
+    }
+
+    /**
+     * \brief Data access operator.
+     */
+    Anchor& operator[] (const size_t i) {
+      assert (i < __anchors.size());
+      return __anchors[i];
+    }
+
+    /**
+     * \brief Get reference to last anchor.
+     */
+    Anchor& back() {
+      return __anchors.back();
+    }
+    
+    /**
+     * \brief Get iterator to start of __anchors.
+     */
+    std::vector<Anchor>::iterator begin() {
+      return __anchors.begin();
+    }
+
+    /**
+     * \brief Get iterator to start of __anchors.
+     */
+    std::vector<Anchor>::const_iterator begin() const {
+      return __anchors.begin();
+    }
+
+    /**
+     * \brief Get iterator to end of __anchors.
+     */
+    std::vector<Anchor>::iterator end() {
+      return __anchors.end();
+    }
+
+    /**
+     * \brief Get iterator to end of __anchors.
+     */
+    std::vector<Anchor>::const_iterator end() const {
+      return __anchors.end();
+    }
+
+
+  private:
+
+    // pointers are ugly but necessary to have an assignment operator :(
+    const std::string* xseq;        ///< first sequence X
+    const std::string* yseq;        ///< second sequence Y
+
+    std::vector<Anchor> __anchors;  ///< hold Anchor objects
+    /**
+     * \brief Map from the anchored coordinates x and y specified by an anchor to the anchor index in (*this).
+     *
+     * If coordinates x and y are anchored by an anchor A, then we
+     * say that anchor A "spans" x and y.
+     */
+    std::map<std::pair<unsigned, unsigned>, size_t, Util::Duple_less<unsigned, unsigned> > __spanning_map;
+
+  };
+
+
+  /**
+   * \brief Toy anchoring.
+   *
+   * Use with toy file anchors_cabbage.fasta.
+   */
+  struct Cabbage_adapter {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    Cabbage_adapter (const Sequence& xseq, const Sequence& yseq)
+    : xseq (xseq), yseq (yseq) { }
+
+    /**
+     * \brief Get a set of anchors.
+     */
+    Anchors get_candidate_anchors() const;
+
+  private:
+
+    /**
+     * \brief Named sequences.
+     */
+    const Sequence& xseq;
+    const Sequence& yseq;
+
+  };
+
+
+  /**
+   * \brief Anchoring with MUMmer.
+   *
+   * Called as 'mummer -mum'.
+   */
+  struct Mummer_adapter {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * \param xseq sequence X
+     * \param yseq sequence Y
+     */
+    Mummer_adapter (const Sequence& xseq, const Sequence& yseq,
+		    bool use_translated = false)
+    : xseq (xseq), yseq (yseq),
+      __use_translated (use_translated) { }
+
+    /**
+     * \brief Get a set of anchors.
+     *
+     * Wrapper function for call_mummer();
+     * needed to handle case of using translated anchors.
+     * Anchors may be degenerate, overlapping, etc.
+     * Does NOT call create_spanning_map() before returning list of anchors.
+     * \param minlen minimum length of an exact match
+     */
+    Anchors get_candidate_anchors (const size_t minlen = ANCHOR_NUC_MINLEN_DEFAULT) const;
+
+  private:
+
+    /**
+     * \brief Actually call MUMmer and parse output.
+     *
+     * Forks a MUMmer process and reads from STDOUT via a pipe.
+     * Note that the parameters xseq and yseq are NOT necessarily the same
+     * as the member variables xseq and yseq.
+     * \param xseq sequence X to run on
+     * \param yseq sequence Y to run on
+     * \return Anchors found by MUMmer
+     */
+    Anchors call_mummer (const std::string& xseq, const std::string& yseq, const size_t minlen = ANCHOR_NUC_MINLEN_DEFAULT) const;
+
+    const Sequence& xseq; ///< Sequence X
+    const Sequence& yseq; ///< Sequence Y
+
+    /**
+     * \brief find anchors in protein space
+     *
+     * This should only be set if the sequences are nucleotide sequence!
+     * Otherwise results will be meaningless.
+     */
+    const bool __use_translated;
+
+  };
+
+  /**
+   * \brief Anchoring with exonerate.
+   *
+   * Called as '--querytype dna --targettype dna --gappedextension false
+   * --saturatethreshold 5 --bigseq true --showvulger false --showalignment false
+   * --ryo "%qab %qae %qS %tab %tae %tS %s\n"'.
+   */
+  struct Exonerate_adapter {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * \param xseq sequence X
+     * \param yseq sequence Y
+     */
+    Exonerate_adapter (const Sequence& xseq, const Sequence& yseq,
+		       bool use_translated = false, bool softmasked = false)
+    : xseq (xseq), yseq (yseq),
+      __use_translated (use_translated), __softmasked (softmasked) { }
+
+    /**
+     * \brief Get a set of anchors.
+     *
+     * Wrapper function for call_exonerate.
+     * Anchors may be degenerate, overlapping, etc.
+     * Does NOT call create_spanning_map before returning list of anchors.
+     * \param minscore minimum score of an alignment
+     */
+    Anchors get_candidate_anchors (const int minscore = EXONERATE_MINSCORE_DEFAULT) const;
+
+  private:
+
+    /**
+     * \brief Actually call exonerate and parse output.
+     *
+     * Forks an exonerate process and reads from STDOUT via a pipe.
+     * Note that the parameters xseq and yseq are NOT necessarily the same
+     * as the member variables xseq and yseq.
+     * \param xseq sequence X to run on
+     * \param yseq sequence Y to run on
+     * \return alignments found by exonerate
+     */
+    Anchors call_exonerate (const std::string& xseq, const std::string& yseq,
+			    const int minscore = EXONERATE_MINSCORE_DEFAULT) const;
+
+    const Sequence& xseq; ///< Sequence X
+    const Sequence& yseq; ///< Sequence Y
+
+    /**
+     * \brief find anchors in protein space
+     *
+     * This should only be called if the sequences are nucleotide sequence!
+     * Otherwise results will be meaningless.
+     */
+    const bool __use_translated;
+
+    /**
+     * \brief is the sequence softmasked?
+     *
+     * exonerate uses softmasking information if present.
+     */
+    const bool __softmasked;
+
+  };
+
+
+  /**
+   * \brief Adapter class to perform anchor annealing.
+   *
+   * Note that the sequence information containers
+   * hold sequences with the case preserved.
+   * This is ok for MUMmer, since it is case-insensitive,
+   * and is essential for preserving softmasking for exonerate.
+   */
+  struct Anchor_resolver {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * \param seq_db sequence data
+     * \param seq_db_internal sequence data (hardmasked, nondegenerate)
+     * \param seq_pairs sequence pairs in seq_db and seq_db_internal to consider
+     */
+    Anchor_resolver (const Sequence_database& seq_db, const Sequence_database& seq_db_internal,
+		     const Sequence_pairs& seq_pairs)
+    : seq_db (seq_db), seq_db_internal (seq_db_internal),
+      seq_pairs (seq_pairs),
+      __constraints_set (Constraints_set (seq_db))
+    { }
+
+    /**
+     * \brief Add Mercator constraints.
+     *
+     * \param filename filename of Mercator constraint file
+     */
+    void add_mercator_constraints (const std::string& filename);
+
+    /**
+     * \brief Perform anchor annealing using sequence pair weights to get a set of consistent anchors.
+     *
+     * Each entry in std::vector<Anchors> corresponds to a set of pairwise anchors;
+     * all anchors in the corresponding complete "multiple anchoring" are consistent.
+     * Anchor annealing is performed on the "reduced" sequences obtained by
+     * storing only the positions corresponding to the centroids of candidate anchors
+     * (this dramatically speeds up depth-first search on the sequences).
+     * While the same algorithm is used, anchor annealing is qualitatively different
+     * from sequence annealing.  The reason is this: Sequence annealing is designed
+     * for the case where we have information P (x ~ y) that characters are aligned.
+     * In anchor annealing, in contrast, we have p-values of anchors occuring
+     * under a null model rather than an actual probability distribution over
+     * anchored positions.  We therefore want to greedily call anchors with the smallest
+     * p-values and ignore "gap" information entirely (which isn't well-defined
+     * for anchors).  We can do exactly this by using the maxstep weighting scheme 
+     * with a gap factor of 0 (yes, it's a bit of a hack).
+     * Note that we always call Anchors::impose_normalized_probability_distribution
+     * before performing anchor annealing in order to heuristically reduce
+     * the p-values associated with non-unique anchors.
+     * \param tree_weights weights for sequence pairs during anchor annealing
+     * \param minlen minimum length of anchor
+     * \param max_join_distance maximum separation between parallel anchors to concatenate
+     * \param use_translated find anchors in protein space
+     * \param use_exonerate call exonerate to find anchors
+     * \param softmasked sequence is softmasked (used by exonerate)
+     * \param hardmasked sequence is hardmasked (used for Mercator coord mapping)
+     * \param num_refinement_steps number of iterative refinement steps
+     * \param output_for_gui output anchoring information for MAD GUI
+     * \param gui_prefix prefix for GUI output filename
+     * \return set of resolved anchors
+     * \see Anchors::impose_normalized_probability_distribution()
+     */
+    const std::vector<Anchors> get_resolved_anchors (const Tree_weights& tree_weights,
+						     const size_t minlen = ANCHOR_NUC_MINLEN_DEFAULT, const size_t max_join_distance = 0, bool const use_translated = false,
+						     const bool use_exonerate = false, const int minscore = EXONERATE_MINSCORE_DEFAULT, const bool softmasked = false,
+						     const bool hardmasked = true,
+						     const size_t num_refinement_steps = 0,
+						     const bool output_for_gui = false, const std::string gui_prefix = "") const;
+    /**
+     * \brief Perform anchor annealing on an equidistant star phylogeny to get a set of consistent anchors.
+     *
+     * All sequence pairs are weighted equally.
+     */
+    const std::vector<Anchors> get_resolved_anchors (const size_t minlen = ANCHOR_NUC_MINLEN_DEFAULT, const size_t max_join_distance = 0, bool const use_translated = false,
+						     const bool use_exonerate = false, const int minscore = EXONERATE_MINSCORE_DEFAULT, const bool softmasked = false,
+						     const bool hardmasked = true,
+						     const size_t num_refinement_steps = 0,
+						     const bool output_for_gui = false, const std::string gui_prefix = "") const;
+
+
+  private:
+
+    /**
+     * \brief Hold all input sequence data.
+     */
+    const Sequence_database& seq_db;
+
+    /**
+     * \brief Hold all input sequence data (hardmasked & nondegenerate).
+     */
+    const Sequence_database& seq_db_internal;
+
+    /**
+     * \brief Hold sequence pairs to find pairwise anchors for.
+     * 
+     * Indices refer to sequences in seq_db and seq_db_internal
+     * (they are indexed identically).
+     */
+    const Sequence_pairs& seq_pairs;
+
+    /**
+     * \brief Constraint information.
+     */
+    Constraints_set __constraints_set;
+
+  };
+
+}
+
+#endif /* FSA_ANCHORS_INCLUDED */
diff --git a/src/fsa/constraints.cc b/src/fsa/constraints.cc
new file mode 100644
index 0000000..e2f1e71
--- /dev/null
+++ b/src/fsa/constraints.cc
@@ -0,0 +1,101 @@
+
+/**
+ * \file constraints.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "util/logfile.h"
+#include "fsa/constraints.h"
+
+using namespace fsa;
+
+void Constraints::write_mercator (std::ostream& o) const {
+
+  for (std::vector<Constraint>::const_iterator constraint = begin(); constraint != end(); ++constraint)
+    constraint->write_mercator (__xname, __yname, o);
+
+}
+
+
+Constraints_set::Constraints_set (const Sequence_database& seq_db)
+  : seq_db (seq_db)
+{ }
+
+void Constraints_set::read_mercator (const std::string& filename) {
+
+  std::ifstream filestream (filename.c_str(), std::ifstream::in);
+  if (!filestream.is_open())
+    THROWEXPR ("ERROR: Couldn't open file '" << filename << "'.");
+
+  std::string line;
+  while (!filestream.eof()) {
+    getline (filestream, line);
+    // log
+    if (CTAGGING(-1,CONSTRAINTS_VERBOSE))
+      CL << line;
+    std::string buffer;
+    // skip comments and sequence names
+    std::stringstream ss (line);
+    std::vector<std::string> tokens; // vector to hold whitespace-separated tokens (words)
+    while (ss >> buffer)
+      tokens.push_back (buffer);
+
+    // now parse tokens into constraints
+    // sample line:
+    //   drosophila_melanogaster-5.0 30 1344 drosophila_yakuba-2.0 413 1727
+    // Note that Mercator constraints are 0-based half-open [start, end).
+    if (tokens.size() == 6) {
+      std::string xname = tokens[0];
+      unsigned xstart = atoi (tokens[1].c_str()); // [start, end)
+      unsigned xend = atoi (tokens[2].c_str()) - 1;
+      std::string yname = tokens[3];
+      unsigned ystart = atoi (tokens[4].c_str());
+      unsigned yend = atoi (tokens[5].c_str()) - 1;
+
+      // sanity checks on sequence names
+      if (!seq_db.exists_seq (xname) || !seq_db.exists_seq (yname))
+	THROWEXPR ("ERROR: I don't recognize the sequence names '" << xname << "' and '" << yname << "' in constraint file '" << filename << "'.");
+
+      // map sequence names to indices
+      size_t i = seq_db.get_seq_index (xname);
+      size_t j = seq_db.get_seq_index (yname);
+
+      // be consistent
+      if (i > j) {
+	std::swap (i, j);
+	std::swap (xname, yname);
+	std::swap (xstart, ystart);
+	std::swap (xend, yend);
+      }
+
+      // if no constraint information for this sequence pair,
+      // create a new Constraints object
+      if (constraints_list.find (std::make_pair (i, j)) == constraints_list.end())
+	constraints_list.insert (std::make_pair (std::make_pair (i, j), Constraints (xname, yname)));
+
+      // store constraint
+      (constraints_list.find (std::make_pair (i, j)))->second.store (Constraint (Interval (xstart, xend), Interval (ystart, yend)));
+
+    } else if (tokens.size() == 0) {
+      continue;
+    } else {
+      if (CTAGGING(4,CONSTRAINTS))
+	CL << "WARNING: I don't know how to parse Mercator output line " << line << "; skipping it." << endl;
+      continue;
+    }
+  }
+
+  filestream.close();
+
+  // log
+  CTAG(8,CONSTRAINTS) << "Read Mercator constraints file '" << filename << "'." << endl;
+
+}
+
+void Constraints_set::write_mercator (std::ostream& o) const {
+
+  for (std::map<std::pair<size_t, size_t>, Constraints>::const_iterator iter = constraints_list.begin(); iter != constraints_list.end(); ++iter)
+    iter->second.write_mercator (o);
+
+}
diff --git a/src/fsa/constraints.h b/src/fsa/constraints.h
new file mode 100644
index 0000000..647589f
--- /dev/null
+++ b/src/fsa/constraints.h
@@ -0,0 +1,195 @@
+
+/**
+ * \file constraints.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef FSA_CONSTRAINTS_INCLUDED
+#define FSA_CONSTRAINTS_INCLUDED
+
+#include <iostream>
+#include <fstream>
+
+#include <map>
+
+#include "util/misc.h"
+#include "seq/sequence.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represents a single constraint.
+   *
+   * Assumes a 0-based coordinate system and a fully-closed interval.
+   * Constraints are like Anchors, but they are assumed to already be consistent.
+   */
+  struct Constraint {
+
+    Interval xcoords;  ///< interval of the constraint in sequence X
+    Interval ycoords;  ///< interval of the constraint in sequence Y
+
+    /**
+     * \brief Constructor.
+     */
+    Constraint (const Interval& xcoords, const Interval& ycoords)
+    : xcoords (xcoords), ycoords (ycoords) { }
+  
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Constraint& constraint)  {
+      o << "[" << constraint.xcoords.start << ", " << constraint.xcoords.end << "] ~ ["
+	<< constraint.ycoords.start << ", " << constraint.ycoords.end << "]";
+      return o;
+    }
+
+    /**
+     * \brief Write constraint in Mercator format.
+     *
+     * Note that Mercator constraints are 0-based half-open [start, end),
+     * whereas we represent them as [start, end].
+     */
+    inline void write_mercator (const std::string& xname, const std::string& yname, std::ostream& o) const {
+      o << xname << ' ' << xcoords.start << ' ' << xcoords.end + 1 << ' '
+	<< yname << ' ' << ycoords.start << ' ' << ycoords.end + 1 << endl;
+    }
+
+  };
+
+  /**
+   * \brief Hold a vector of constraints for two sequences.
+   */
+  struct Constraints {
+
+    /**
+     * \brief Constructor.
+     */
+    Constraints() { }
+
+    /**
+     * Constructor.
+     *
+     * \param xname name of sequence X
+     * \param yname name of sequence X
+     */
+    Constraints (const std::string& xname, const std::string& yname)
+      : __xname (xname), __yname (yname) { }
+
+    /**
+     * \brief Write constraint file in Mercator format.
+     */
+    void write_mercator (std::ostream& o) const;
+
+    /**
+     * \brief Number of constraints.
+     */
+    size_t size() const { return __constraints.size(); }
+
+    /**
+     * \brief Store a constraint.
+     */
+    void store (const Constraint& c) {
+      __constraints.push_back (c);
+    }
+
+    /**
+     * \brief Get iterator to start of __constraints.
+     */
+    std::vector<Constraint>::iterator begin() {
+      return __constraints.begin();
+    }
+
+    /**
+     * \brief Get iterator to start of __constraints.
+     */
+    std::vector<Constraint>::const_iterator begin() const {
+      return __constraints.begin();
+    }
+
+    /**
+     * \brief Get iterator to end of __constraints.
+     */
+    std::vector<Constraint>::iterator end() {
+      return __constraints.end();
+    }
+
+    /**
+     * \brief Get iterator to end of __constraints.
+     */
+    std::vector<Constraint>::const_iterator end() const {
+      return __constraints.end();
+    }
+
+
+  private:
+  
+    const std::string __xname;               ///< name of sequence X
+    const std::string __yname;               ///< name of sequence Y
+
+    std::vector<Constraint> __constraints;   ///< Contraint objects
+
+  };
+
+  /**
+   * \brief Represent a set of contraints for many sequences.
+   */
+  struct Constraints_set {
+
+    /**
+     * \brief Constructor.
+     *
+     * \param seq_db input sequence data
+     */
+    Constraints_set (const Sequence_database& seq_db);
+
+    /**
+     * \brief Read constraints from a Mercator file.
+     *
+     * Note that Mercator constraints are 0-based half-open [start, end).
+     */
+    void read_mercator (const std::string& filename);
+
+    /**
+     * \brief Write constraints to a Mercator-format file.
+     *
+     * Note that Mercator constraints are 0-based half-open [start, end).
+     */
+    void write_mercator (std::ostream& o) const;
+
+    /**
+     * \brief Get constraints for a particular sequence std::pair.
+     *
+     * \param i index for first sequence
+     * \param j index for second sequence
+     */
+    inline Constraints get_constraints (unsigned i, unsigned j) const {
+      if (constraints_list.find (std::make_pair (i, j)) == constraints_list.end())
+	return Constraints();
+      return (*constraints_list.find (std::make_pair (i, j))).second;
+    }
+
+    /**
+     * \brief Number of sequence std::pairs which we have constraints for.
+     */
+    inline size_t size() const {
+      return constraints_list.size();
+    }
+
+  private:
+
+    /**
+     * \brief Hold all input sequence data.
+     */
+    const Sequence_database& seq_db;
+
+    /**
+     * \brief constraints for sequence std::pairs
+     */
+    std::map<std::pair<size_t, size_t>, Constraints> constraints_list;
+
+  };
+
+}
+
+#endif /* FSA_CONSTRAINTS_INCLUDED */
diff --git a/src/fsa/dptables.h b/src/fsa/dptables.h
new file mode 100644
index 0000000..cabc25c
--- /dev/null
+++ b/src/fsa/dptables.h
@@ -0,0 +1,438 @@
+/*
+ *    This file is part of HMMoC 1.3, a hidden Markov model compiler.
+ *    Copyright (C) 2007 by Gerton Lunter, Oxford University.
+ *
+ *    HMMoC is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    HMMOC is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with HMMoC; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+\*/
+/*
+ *
+ * dptables.h -- ordinary and sparse dynamic programming tables
+ *
+ * Gerton Lunter, 1 Oct 2006
+ *
+ * Modified for GCC 4.0.2 and Microsoft Visual Studio 2005 by Aaron Darling, 2007
+ *
+ */
+
+#ifndef __dptable_h_
+#define __dptable_h_
+
+
+#include <map>
+#include <cassert>
+
+
+#ifdef __GNUC__
+ #define HAVE_HASH_MAP
+ #if __GNUC__ < 3
+  #include <hash_map.h>
+  namespace Sgi { using ::hash_map; }; // inherit globals
+ #else
+  #include <ext/hash_map>
+  #if __GNUC_MINOR__ + __GNUC__ == 3
+   namespace Sgi = std;               // GCC 3.0
+  #else
+   namespace Sgi = ::__gnu_cxx;       // GCC 3.1 and later
+  #endif
+ #endif
+#else      // ...there are other compilers, right?
+#ifdef _MSC_VER
+// visual studio 2005 has no hash map.  older versions did.
+#else
+// default for all other compilers
+#define HAVE_HASH_MAP
+namespace Sgi = std;
+#endif
+#endif
+
+
+using std::map;
+#ifdef HAVE_HASH_MAP
+using Sgi::hash_map;
+#endif
+
+// Define aliases for two maps: red-black trees, and hashes
+// (GNU C++ does not define a hash function for long long int, so we have to define our own)
+
+template<class key>
+struct _hash {
+  size_t operator()(long long x) const { return x; }
+};
+
+// typedefs can't be templated
+
+template<class key, class value>
+class treemap : public map<key,value> {};
+
+#ifdef HAVE_HASH_MAP
+template<class key, class value>
+class hashmap : public hash_map<key,value,_hash<key> > {};
+#endif
+
+// select one of the maps (the hash map is faster and appears to use less memory)
+
+#ifdef HAVE_HASH_MAP
+#define _mymap hashmap
+#else
+#define _mymap treemap
+#endif
+
+//
+// Public interface for the banding iterator
+// 
+// Not strictly part of the DP table definitions, but cannot be made part of the 
+// main .h file either, because of circular inclusions in case DP tables 
+// refer to this class
+//
+
+template < int dim >
+class Banding {
+
+public:
+  typedef int Position[dim];
+
+  virtual ~Banding() {};
+  virtual Position& forwardIterator() = 0;    // Initializes the position for forward iteration, and returns a reference to it
+  virtual Position& backwardIterator() = 0;   // Same for backward iteration
+
+  virtual bool hasNextForward() = 0;          // Advances the position, and returns true if successful
+  virtual bool hasNextBackward() = 0;         // Same for backward iteration
+
+  virtual bool lastColumnEntry() = 0;         // true if next call to hasNext[FW/BW] advances the slow coordinate
+
+  virtual void warning() {};                  // gets called when iterator loops out of range
+
+  // Traversals must be such that when  v  is visited, all positions of the form  v-e  either have already been
+  // visited, or will not be.  Here,  e  is any nonzero vector with all entries nonnegative (forward iteration)
+  // or nonpositive (backward iteration).
+  //
+  // It is crucial that the forwardIterator and backwardIterator visit identical sets of states (although the order
+  // in which they're visited need not be their precise mirror image).  If not, the basic assumption that the forward
+  // and backward iterations yield the same total likelihood is not satifsfied, and BaumWelch will not work properly.
+  //
+};
+
+
+
+
+// States are stored in a self-initializing array
+
+template<class Real,int size> class States;
+
+template<int size>
+class States<double,size> {
+private:
+  double data[size];
+public:
+  enum { length = size };                                      // to know the size, just in case
+  States() { for (int i=0; i<size; i++) data[i]=0; }           // initialization
+  operator double* () { return data; }                         // cast to actual array
+  operator const double* () const { return data; }
+};
+
+template<class Real, int size>
+class States {
+private:
+  Real data[size];
+public:
+  enum { length = size };                                      // to know the size, just in case
+  States() { for (int i=0; i<size; i++) data[i].clear(); }      // initialization
+  operator Real* () { return data; }                           // cast to actual array
+  operator const Real* () const { return data; }
+};
+
+
+
+// Define index types to serve as keys to the DP table position
+
+template<int dim> class _index {};
+template<> class _index<1> { public: typedef unsigned int t; };
+template<> class _index<2> { public: typedef unsigned long t; };
+template<> class _index<3> { public: typedef unsigned long long t; };
+template<> class _index<4> { public: typedef unsigned long long t; };
+
+
+//
+// Base classes for a dynamic programming table
+//
+// DP tables provide the following methods:
+//
+// const States& read(...)   :   read access to state array
+// States& write(...)        :   write access to state array
+// void written()            :   signal that write access is finished
+// void allocate(...)        :   inform table about its dimensions; must be called before read/write access
+// void clear()              :   empties the table; keeps its dimensions
+// void clear(int)           :   empties one column of a (folded) DP table
+// void absolve()            :   ensures that table does not delete its data; another table with reference to the data,
+//                               which is created by the default copy constructor, is now responsible.  Not allowed for
+//                               folded tables
+//
+
+template<class States>
+class _DPT {                            // base class, keeps track of the responsibility for the data
+ private:
+  void clear(int i) {}                  // placeholder, to allow dummy definition for non-folded tables
+ protected:
+  bool isInCharge;                      // true if this class' destructor destroys the data
+ public:
+  typedef States states_type;
+  _DPT() : isInCharge(true) {}
+  void absolve() { isInCharge=false; }  // take away the responsibility of destroying the data
+  void written() {}                     // signal that we're done writing -- used by extensions
+};
+
+template<template<typename,int> class DPTable, class States, int dim>     // Wrapper for memory-efficient Fw/Bw/Baum-Welch
+class _FoldedTable : public _DPT<States> {
+ protected:
+  DPTable<States,dim-1>* aTables[2];
+ public:
+  _FoldedTable() { aTables[0] = new DPTable<States,dim-1>(); aTables[1] = new DPTable<States,dim-1>(); }
+  ~_FoldedTable() { assert(_DPT<States>::isInCharge); delete aTables[0]; delete aTables[1]; }        // do not allow data to be retained
+  void clear(int i) { aTables[i%2]->clear(); }
+};
+
+template<class States, int dim>
+class DPTable {};
+
+template<class States, int dim>
+class SparseDPTable {};
+
+template<template<typename,int> class DPTable, class States, int dim>
+class FoldedTable {};
+
+
+
+// Explicit partial specializations for up to 4 spatial dimensions
+
+
+template<template<typename,int> class DPTable, class States>
+class FoldedTable<DPTable, States, 0> : public _FoldedTable<DPTable, States, 1> {
+ public:
+  void allocate() { this->aTables[0]->allocate(); };
+  const States& read() const { return this->aTables[0]->read(); }
+  States& write() { return this->aTables[0]->write(); }
+  void written() { this->aTables[0]->written(); }
+};
+
+
+template<template<typename,int> class DPTable, class States>
+class FoldedTable<DPTable, States, 1> : public _FoldedTable<DPTable, States, 1> {
+  int z;
+ public:
+  void allocate(int a) { this->aTables[0]->allocate(); this->aTables[1]->allocate(); };
+  const States& read(int a) const { return this->aTables[a%2]->read(); }
+  States& write(int a) { return this->aTables[z=a%2]->write(); }
+  void written() { this->aTables[z]->written(); }
+};
+
+
+template<template<typename,int> class DPTable, class States>
+class FoldedTable<DPTable, States, 2> : public _FoldedTable<DPTable, States, 2> {
+  int z;
+ public:
+  void allocate(int a, int b) { this->aTables[0]->allocate(a); this->aTables[1]->allocate(a); };
+  const States& read(int a, int b) const { return this->aTables[b%2]->read(a); }
+  States& write(int a, int b) { return this->aTables[z=b%2]->write(a); }
+  void written() { this->aTables[z]->written(); }
+};
+
+
+template<template<typename,int> class DPTable, class States>
+class FoldedTable<DPTable, States, 3> : public _FoldedTable<DPTable, States, 3> {
+  int z;
+ public:
+  void allocate(int a, int b, int c) { this->aTables[0]->allocate(a,b); this->aTables[1]->allocate(a,b); };
+  const States& read(int a, int b, int c) const { return this->aTables[c%2]->read(a,b); }
+  States& write(int a, int b, int c) { return this->aTables[z=c%2]->write(a,b); }
+  void written() { this->aTables[z]->written(); }
+};
+
+
+template<template<typename,int> class DPTable, class States>
+class FoldedTable<DPTable, States, 4> : public _FoldedTable<DPTable, States, 4> {
+  int z;
+ public:
+  void allocate(int a, int b, int c, int d) { this->aTables[0]->allocate(a,b,c); this->aTables[1]->allocate(a,b,c); };
+  const States& read(int a, int b, int c, int d) const { return this->aTables[d%2]->read(a,b,c); }
+  States& write(int a, int b, int c, int d) { return this->aTables[z=d%2]->write(a,b,c); }
+  void written() { this->aTables[z]->written(); }
+};
+
+
+template<class States>
+class DPTable<States,0> : public _DPT<States> {
+private:
+  States *pTable;
+public:
+  DPTable() { pTable = 0; };
+  ~DPTable() { if (pTable && _DPT<States>::isInCharge) delete pTable; };
+  void allocate() { pTable = new States(); };
+  void clear() { delete pTable; allocate(); };
+  const States& read() const { return *pTable; }
+  States& write() { return *pTable; }
+};
+
+
+template<class States>
+class DPTable<States,1> : public _DPT<States> {
+private:
+  States *pTable;
+  int maxa;
+public:
+  DPTable() { pTable = 0; }
+  ~DPTable() { if (pTable && _DPT<States>::isInCharge ) { delete[] pTable; } }
+  void allocate(int a) { maxa = a; pTable = new States[a]; }
+  void clear() { delete[] pTable; allocate(maxa); };
+  const States& read(int a) const { return pTable[a]; }
+  States& write(int a) { return pTable[a]; }
+};
+
+
+template<class States>
+class DPTable<States,2> : public _DPT<States> {
+private:
+  States *pTable;
+  int maxa, maxb;
+public:
+  DPTable() { pTable = 0; }
+  ~DPTable() { if (pTable && _DPT<States>::isInCharge ) { delete[] pTable; } }
+  void allocate(int a, int b) { maxa = a; maxb = b; pTable = new States[a*b]; }
+  void clear() { delete[] pTable; allocate(maxa,maxb); };
+  const States& read(int a, int b) const { return pTable[a+maxa*b]; }
+  States& write(int a, int b) { return pTable[a+maxa*b]; }
+};
+
+
+template<class States>
+class DPTable<States,3> : public _DPT<States> {
+private:
+  States *pTable;
+  int maxa, maxb, maxc;
+public:
+  DPTable() { pTable = 0; }
+  ~DPTable() { if (pTable && _DPT<States>::isInCharge ) { delete[] pTable; } }
+  void allocate(int a, int b, int c) { maxa = a; maxb = b; maxc = c; pTable = new States[a*b*c]; }
+  void clear() { delete[] pTable; allocate(maxa,maxb,maxc); };
+  const States& read(int a, int b, int c) const { return pTable[a+maxa*(b+maxb*c)]; }
+  States& write(int a, int b, int c) { return pTable[a+maxa*(b+maxb*c)]; }
+};
+
+
+template<class States>
+class DPTable<States,4> : public _DPT<States> {
+private:
+  States *pTable;
+  int maxa, maxb, maxc, maxd;
+public:
+  DPTable() { pTable = 0; }
+  ~DPTable() { if (pTable && _DPT<States>::isInCharge ) { delete[] pTable; } }
+  void allocate(int a, int b, int c, int d) { maxa = a; maxb = b; maxc = c; maxd = d; pTable = new States[a*b*c*d]; }
+  void clear() { delete[] pTable; allocate(maxa,maxb,maxc,maxd); };
+  const States& read(int a, int b, int c, int d) const { return pTable[a+maxa*(b+maxb*(c+maxc*d))]; }
+  States& write(int a, int b, int c, int d) { return pTable[a+maxa*(b+maxb*(c+maxc*d))]; }
+};
+
+
+template<class States>
+class SparseDPTable<States,0> : public DPTable<States,0> {};
+
+
+template<class States>
+class SparseDPTable<States,1> : public _DPT<States> {
+private:
+  typedef _index<1>::t idx;
+  _mymap<idx,States> &table;
+  const States zero;
+public:
+  SparseDPTable() : table(*new _mymap<_index<1>::t,States>), zero() {};
+  ~SparseDPTable() { if (_DPT<States>::isInCharge) delete &table; };
+  void allocate(int a) {};
+  void clear() { table.clear(); }
+  States& write(int a) { return table[idx(a)]; }
+  const States& read(int a) const {
+    _mymap<_index<1>::t,char>::iterator iter2;
+    typename _mymap<idx,States>::const_iterator iter = table.find(idx(a));
+    if (iter == table.end()) return zero;
+    return iter->second;
+  }
+};
+
+
+template<class States>
+class SparseDPTable<States,2> : public _DPT<States> {
+private:
+  typedef _index<2>::t idx;
+  _mymap<idx,States> &table;
+  idx maxa;
+  const States zero;
+public:
+  SparseDPTable() : table(*new _mymap<idx,States>), zero() {};
+  ~SparseDPTable() { if (_DPT<States>::isInCharge) delete &table; };
+  void allocate(int a, int b) { maxa = a; };
+  void clear() { table.clear(); }
+  States& write(int a, int b) { return table[idx(a)+maxa*idx(b)]; }
+  const States& read(int a, int b) const {
+    typename _mymap<idx,States>::const_iterator iter = table.find(unsigned(a)+maxa*unsigned(b));
+    if (iter == table.end()) return zero;
+    return iter->second;
+  }
+};
+
+
+template<class States>
+class SparseDPTable<States,3> : public _DPT<States> {
+
+private:
+  typedef _index<3>::t idx;
+  _mymap<idx,States> &table;
+  idx maxa, maxb;
+  const States zero;
+public:
+  SparseDPTable() : table(*new _mymap<idx,States>), zero() {};
+  ~SparseDPTable() { if (_DPT<States>::isInCharge) delete &table; };
+  void allocate(int a, int b, int c) { maxa = a; maxb = b; };
+  void clear() { table.clear(); }
+  States& write(int a, int b, int c) { return table[idx(a)+maxa*(idx(b)+maxb*idx(c))]; }
+  const States& read(int a, int b, int c) const {
+    typename _mymap<idx,States>::const_iterator iter = table.find(unsigned(a)+maxa*(unsigned(b)+maxb*unsigned(c)));
+    if (iter == table.end()) return zero;
+    return iter->second;
+  }
+};
+
+
+template<class States>
+class SparseDPTable<States,4> : public _DPT<States> {
+private:
+  typedef _index<4>::t idx;
+  _mymap<idx,States> &table;
+  idx maxa, maxb, maxc;
+  const States zero;
+public:
+  SparseDPTable() : table(*new _mymap<idx,States>), zero() {};
+  ~SparseDPTable() { if (_DPT<States>::isInCharge) delete &table; };
+  void allocate(int a, int b, int c, int d) { maxa=a; maxb=b; maxc=c; }
+  void clear() { table.clear(); }
+  States& write(int a, int b, int c, int d) { return table[unsigned(a)+maxa*(unsigned(b)+maxb*(unsigned(c)+maxc*unsigned(d)))]; }
+  const States& read(int a, int b, int c, int d) const {
+    typename _mymap<idx,States>::const_iterator iter = table.find(unsigned(a)+maxa*(unsigned(b)+maxb*(unsigned(c)+maxc*unsigned(d))));
+    if (iter == table.end()) return zero;
+    return iter->second;
+  }
+};
+
+
+#endif
+
diff --git a/src/fsa/fsa.cc b/src/fsa/fsa.cc
new file mode 100644
index 0000000..0fe6c2f
--- /dev/null
+++ b/src/fsa/fsa.cc
@@ -0,0 +1,1887 @@
+
+/**
+ * \file fsa.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ * Jaeyoung Do wrote the parallelization and database code.
+ */
+
+#include "math/mst.h"
+#include "seq/similarity_matrix.h"
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+FSA::FSA (int argc, char** argv) :
+  opts (argc, argv),
+  alphabet (DNA_alphabet()),
+  tree_weights (Tree_weights()), // default constructor sets all weights to 1.0
+  w_worker (false)
+{ }
+
+void FSA::init_opts() {
+
+  opts.newline();
+  INIT_CONSTRUCTED_OPTS_LIST (opts, -1, "[options] <sequence file(s)>", "Distance-based alignment of DNA, RNA and proteins.");
+
+  opts.print_title ("Output options");
+  opts.add ("-stockholm", write_stockholm = false, "output Stockholm alignments (default is multi-FASTA format)", false);
+  opts.add ("-gui", output_for_gui = false, "record alignment & statistical model for interactive Java GUI", false);
+  opts.add ("-write-params", write_params = false, "write learned emission distributions (substitution matrices) to disk", false);
+  opts.add ("-write-posteriors", write_dotplots = false, "write learned pairwise posterior alignment probability matrices to disk", false);
+  // --write-divergences option disabled for now (9/14/08)
+  //  opts.add ("-write-divergences", write_divergences = false, "write pairwise divergences using log-det transform on learned substitution matrices to disk", false);
+  write_divergences = false;
+  opts.newline();
+
+  opts.print_title ("Parallelization options");
+#if defined(HAVE_CONDOR)
+  opts.add ("-parallelize", num_parallelized_jobs = 0, "collect pairwise posterior probabilities and candidate edges simultaneously", false);
+  opts.add ("-noannealing", noannealing = false, "disable annealing", false);
+  opts.print ("      Note that --parallelize is only relevant when database connection options are given;"); opts.newline();
+  opts.print ("      similarly, --noannealing is only relevant when --parallelize is set."); opts.newline();
+#else
+  opts.print ("(Parallelization not available; please see the manual for more information.)");
+  opts.newline();
+  num_parallelized_jobs = 0;
+  noannealing = false;
+#endif
+  opts.newline();
+
+  opts.print_title ("Database options");
+#if defined(HAVE_POSTGRES)
+  opts.add ("-db-maxram", db_max_ram = 0, "maximum RAM to use when the database mode (in megabytes)", true); 
+  opts.add ("-hostname", db_hostname = "", "database server host name", false);
+  opts.add ("-hostaddr", db_hostaddr = "", "database server host IP address", false);
+  opts.add ("-dbname", db_name = "", "database name", false);
+  opts.add ("-port", db_port = 0, "database server port", false);
+  opts.add ("-user", db_user = "", "database username", false);
+  opts.add ("-password", db_password = "", "database password", false);
+  opts.add ("-noposteriors", read_posteriors_from_db = false, "do not compute posteriors; instead read them from database", false);
+  opts.print ("      Note that to access the database server, you must provide at least --hostname and --dbname.");
+  opts.newline();
+#else
+  opts.print ("(Database not available; please see the manual for more information.)");
+  opts.newline();
+#endif
+  opts.newline();
+
+  opts.print_title ("Pair HMM model options");
+  opts.add ("-nucprot", nucprot = false, "align input nucleotide sequences (must all be nucleotide) in protein space", false);
+  opts.add ("-indel2", is_indel2 = true, "(default) use two sets of indel states in Pair HMM (use --noindel2 to use 1 set only)", false);
+  opts.add ("-gapopen1", gap_open1 = 0., "initial gap-open probability (for set 1 of indel states)", false);       // the command-line values, if passed, are used in init_indel()
+  opts.add ("-gapextend1", gap_extend1 = 0., "initial gap-extend probability (for set 1 of indel states)", false);
+  opts.add ("-gapopen2", gap_open2 = 0., "initial gap-open probability (for set 2 of indel states)", false);
+  opts.add ("-gapextend2", gap_extend2 = 0., "initial gap-extend probability (for set 2 of indel states)", false);
+  // --raggedends option disabled for now (8/6/08)
+  //  opts.add ("-raggedends", ragged_ends = false, "favor padding indels at starts and ends of sequences", true);
+  ragged_ends = false;
+  opts.add ("-model", model = MODEL_DEFAULT, "initial substitution model: 0 = Jukes-Cantor, 1 = Tamura-Nei / BLOSUM62-like (proteins)", true);
+  opts.add ("-time", time = TIME_DEFAULT, "Jukes-Cantor/Tamura-Nei evolutionary time parameter", true);
+  opts.add ("-alphar", alpha_R = ALPHA_R_DEFAULT, "Tamura-Nei rate alpha_R (transition: purine)", true);
+  opts.add ("-alphay", alpha_Y = ALPHA_Y_DEFAULT, "Tamura-Nei rate alpha_Y (transition: pyrimidine)", true);
+  opts.add ("-beta", beta = BETA_DEFAULT, "Tamura-Nei rate beta (transversion)", true);
+  opts.add ("-load-probs", load_probs_file = "", "load pairwise posterior probabilities from a file rather than performing inference with Pair HMM", false);
+  opts.newline();
+
+  opts.print_title ("Parameter estimation options");
+  opts.add ("-learngap", learn_gap, "estimate indel probabilities for each pair of sequences (--nolearngap to disable)", true);
+  opts.add ("-learnemit-bypair", learn_emit_bypair, "(default for DNA and RNA) estimate emission probabilities for each pair of sequences (--nolearnemit-bypair to disable)", false);
+  opts.add ("-learnemit-all", learn_emit_all, "(default for proteins) estimate emission probabilities averaged over all sequences (--nolearnemit-all to disable)", false);
+  opts.add ("-nolearn", nolearn = false, "disable ALL parameter learning (use ProbCons defaults)", false);
+  opts.add ("-regularize", regularize = true, "regularize learned emission and gap probabilities with Dirichlet prior", true);
+  opts.add ("-regularization-gapscale", regularization_transition_scale, "scaling factor for transition prior", false);
+  opts.add ("-regularization-emitscale", regularization_emission_scale, "scaling factor for emission Dirichlet prior", false);
+  opts.add ("-mininc", em_min_inc = EM_MIN_INC_DEFAULT, "minimum fractional increase in log-likelihood per round of EM", true);
+  opts.add ("-maxrounds", em_max_iter = EM_MAX_ITER_DEFAULT, "maximum number of iterations of EM", true);
+  opts.add ("-mingapdata", min_gap_training_data, "minimum amount of sequence data (# of aligned pairs of characters) for training gap probs", false);
+  opts.add ("-minemitdata", min_emit_training_data, "minimum amount of sequence data (# of aligned pairs of characters) for training emission probs", false);
+  opts.newline();
+
+  opts.print_title ("Multiple alignment options: sequence annealing");
+  opts.add ("-refinement", num_refinement_steps = -1, "number of iterative refinement steps (default is unlimited; 0 for none)", false);
+  opts.add ("-maxsn", maxsn = false, "maximum sensitivity (instead of highest accuracy)", false);
+  // hack to use #define directive
+  std::string opt_string_hack = "gap factor; 0 for highest sensitivity (the internal effective minimum is " + Util::to_string (DEFAULT_POSTERIOR_PROB_CUTOFF) + "); >1 for higher specificity";
+  opts.add ("-gapfactor", gap_factor = 1, opt_string_hack.c_str(), true);
+  opts.add ("-dynamicweights", enable_dynamic_weights = true, "enable dynamic edge re-weighting", true);
+  opts.add ("-treeweights", tree_weights_file = "", "weights for sequence pairs based on a tree", false);
+  opts.add ("-require-homology", require_homology = false, "require that there be some detectable homology between all input sequences", true);
+  opts.newline();
+
+  opts.print_title ("Alignment speedup options: many sequences");
+  opts.add ("-fast", fast_defaults = false, "fast alignment: use 5 * Erdos-Renyi threshold percent of sequence pairs for alignment and 2 * for learning", false);
+  opts.add ("-refalign", refalign = false, "alignment to a reference sequence only (reference must be first sequence in file)", false);
+  opts.add ("-mst-min", num_minimum_spanning_trees = 3, "build --mst-min minimum spanning trees on input sequences for pairwise comparisons", true);
+  opts.add ("-mst-max", num_maximum_spanning_trees = 0, "build --mst-max maximum spanning trees on input sequences for pairwise comparisons", true);
+  opts.add ("-mst-palm", num_minimum_spanning_palm_trees = 0, "build --mst-palm minimum spanning palm trees on input sequences for pairwise comparisons", true);
+  opts.add ("-degree", degree = 0, "use --degree number of pairwise comparisons between closest sequences", true);
+  opts.add ("-kmer", kmer_length = 0, "length of k-mers to use when determining sequence similarity", false);
+  opts.add ("-alignment-fraction", fraction_alignment_pairs = 1., "randomized fraction of all (n choose 2) pairs of sequences to consider during alignment inference", true);
+  opts.add ("-alignment-number", num_alignment_pairs = 0, "total number of (randomized) pairs of sequences to consider during alignment inference", false);
+  opts.newline();
+
+  opts.print_title ("Alignment speedup options: long sequences (MUMmer)");
+#ifdef MUMMER_EXEC
+  opts.add ("-anchored", anchored = false, "use anchoring (--noanchored to disable)", false);
+  opts.add ("-translated", use_translated = false, "perform anchoring in protein space", true);
+  opts.add ("-minlen", anchor_minlen, "minimum length of exact matches for anchoring", false);
+  opts.add ("-maxjoinlen", anchor_max_join_length = 2, "maximum ungapped separation of parallel adjacent anchors to join", true);
+  // hack to use #define directive
+  opt_string_hack.clear(); opt_string_hack = "leave hardmasked sequence >" + Util::to_string (MIN_HARDMASK_LENGTH) + " nt unaligned instead of randomizing it (default for long DNA)";
+  opts.add ("-hardmasked", hardmasked = false, opt_string_hack.c_str(), false);
+#else
+  anchored = false;
+  use_translated = false;
+  hardmasked = false;
+  opts.print ("(MUMmer not available; please see the manual for more information.)");
+  opts.newline();
+#endif
+  opts.newline();
+
+  opts.print_title ("Alignment speedup options: long sequences (exonerate)");
+#ifdef EXONERATE_EXEC
+  opts.add ("-exonerate", exonerate = false, "call exonerate to get anchors (implies --anchored)", false);
+  opts.add ("-minscore", exonerate_minscore = EXONERATE_MINSCORE_DEFAULT, "minimum score of alignments found by exonerate", true);
+  opts.add ("-softmasked", softmasked = false, "input sequences are softmasked", false);
+#else
+  exonerate = false;
+  softmasked = false;
+  opts.print ("(exonerate not available; please see the manual for more information.)");
+  opts.newline();
+#endif
+  opts.newline();
+
+  opts.print_title ("Alignment speedup options: long sequences (Mercator)");
+  opts.add ("-mercator", mercator_constraint_file = "", "input Mercator constraints", false);
+  opts.newline();
+
+  opts.print_title ("Memory savings");
+  opts.add ("-maxram", max_ram = (total_ram() > 0 ? static_cast<int> (0.8 * total_ram()) : -1), "maximum RAM to use (in megabytes)", true); // use 80% of max RAM by default
+  opts.add ("-bandwidth", bandwidth = 0, "banding (default is no banding)", false);
+  opts.add ("-minprob", minprob = DEFAULT_POSTERIOR_PROB_CUTOFF, "minimum posterior probability to store", true);
+  opts.newline();
+
+  opts.newline();
+  opts.print ("Input sequence file(s) must be in FASTA format."); opts.newline();
+  opts.newline();
+  opts.print ("FSA attempts to automatically figure out appropriate settings;"); opts.newline();
+  opts.print ("you can override its automated choices with the above options."); opts.newline();
+  opts.newline();
+
+  opts.print ("Please contact the FSA team at fsa at math.berkeley.edu with any questions or comments.");
+
+}
+
+void FSA::input_data() {
+
+  // get sequence filenames
+  const std::vector<sstring>& seq_filename = opts.get_not_opts();
+
+  // check for at least one sequence file
+  if (seq_filename.size() == 0) {
+    cerr << opts.short_help() << endl
+	 << "ERROR: Please specify at least one sequence file." << endl;
+    exit (1);
+  }
+  // read all files into a single Sequence_database
+  for (std::vector<sstring>::const_iterator sf = seq_filename.begin(); sf != seq_filename.end(); ++sf)
+    seq_db.read_fasta (*sf, &Alignment::is_gap_char,
+		       false, // strip_leading_chr
+		       true); // verbose
+
+  // calculate some statistics
+  num_seqs = seq_db.size();
+  num_seq_pairs = num_seqs * (num_seqs - 1) / 2;
+  if (num_seqs < 2)
+    THROWEXPR (opts.short_help() << "You must include at least 2 sequences to be aligned.");
+  CTAG(9,FSA) << "Read " << num_seqs << " sequences." << endl;
+
+  // figure out which alphabet we're using
+  if (seq_db.matches_alphabet (DNA_alphabet()) || seq_db.matches_alphabet (RNA_alphabet())) {
+    is_dna = true;
+    is_protein = false;
+    alphabet = DNA_alphabet();
+    // store alphabet as string
+    // NB can't use e.g. Alphabet::chars_uc because not alphabetical sorting (which we require).
+    alphabet_string = DNA_ALPHABET_STRING;
+  }
+  else if (seq_db.matches_alphabet (Protein_alphabet())) {
+    is_dna = false;
+    is_protein = true;
+    alphabet = Protein_alphabet();
+    alphabet_string = PROTEIN_ALPHABET_STRING;
+  }
+  else {
+    THROWEXPR ("ERROR: This doesn't seem to be nucleotide or amino acid sequence; I'm bailing.");
+  }
+
+  // get gui filename
+  gui_prefix = *(seq_filename.begin());
+
+}
+
+void FSA::set_up_defaults() {
+
+  // set regularization scales to defaults
+  regularization_transition_scale = is_dna ? REGULARIZATION_NUC_TRANSITION_SCALE_DEFAULT : REGULARIZATION_AA_TRANSITION_SCALE_DEFAULT;
+  regularization_emission_scale = is_dna ? REGULARIZATION_NUC_EMISSION_SCALE_DEFAULT : REGULARIZATION_AA_EMISSION_SCALE_DEFAULT;
+
+  // set training data cutoffs to defaults
+  min_emit_training_data = is_dna ? MIN_NUC_EMISSION_TRAINING_DATA : MIN_AA_EMISSION_TRAINING_DATA;
+  min_gap_training_data = is_dna ? MIN_NUC_TRANSITION_TRAINING_DATA : MIN_AA_TRANSITION_TRAINING_DATA;
+
+  // set up anchoring defaults
+  anchor_minlen = is_dna ? ANCHOR_NUC_MINLEN_DEFAULT : ANCHOR_AA_MINLEN_DEFAULT;
+
+  const size_t meanlen = static_cast<size_t> (std::floor (seq_db.meanlength()));
+
+  // model
+  const bool dna_defaults = (is_dna && (meanlen <= LONG_DNA_DEFAULT)) ? true : false;
+  const bool longdna_defaults = (is_dna && (meanlen > LONG_DNA_DEFAULT)) ? true : false;
+  const bool protein_defaults = (is_protein) ? true : false;
+
+  // It's best to set the minimal number of options here:
+  // Only set things which are /different/ from the initialization
+  // in init_opts.
+  //  - explicitly turn on anchoring if desired, but don't turn it off
+  // For example, I used to explicitly set
+  //  model = MODEL_DEFAULT
+  // but it's best to just leave this job to init_opts.
+
+  // small DNA
+  if (dna_defaults) {
+    learn_gap = true;
+    learn_emit_bypair = true;
+    learn_emit_all = false;
+    hardmasked = true;
+  }
+
+  // same as dna_defaults, but with anchoring
+  if (longdna_defaults) {
+    learn_gap = true;
+    learn_emit_bypair = true;
+    learn_emit_all = false;
+    anchored = true;
+    hardmasked = true;
+  }
+
+  // protein:
+  if (protein_defaults) {
+    learn_gap = (num_seq_pairs * meanlen > static_cast<size_t> (min_gap_training_data)) ? true : false;
+    learn_emit_bypair = false;
+    learn_emit_all = (num_seq_pairs * meanlen > static_cast<size_t> (min_emit_training_data)) ? true : false;
+  }
+
+  // warning about anchoring (MUMmer)
+#ifndef MUMMER_EXEC
+  if (meanlen > 5000) {
+    CTAG(9,FSA) << endl << "WARNING: MUMmer is not available, so we are running in unanchored mode; inference may be slow or even fail." << endl << endl;
+    anchored = false;
+  }
+#endif
+
+  // set up default word length to use for sequence similarity comparisons
+  kmer_length = Sequence_kmer_counts::choose_minimum_word_length (seq_db,
+								  alphabet);
+
+}
+
+void FSA::parse_opts() {
+
+  // parse command-line options
+  opts.parse_or_die();
+
+
+  /***********************************************
+   * Output options
+   ***********************************************/
+
+  // no point in writing divergences unless learning by pair
+  if (!learn_emit_bypair && write_divergences)
+    THROWEXPR ("ERROR: Writing divergences doesn't make sense unless --learnemit-bypair is set.");
+
+
+  /***********************************************
+   * Parallelization options
+   ***********************************************/
+
+  // ensure valid number of parallelized jobs
+  if ((static_cast<size_t> (num_parallelized_jobs) > num_seq_pairs) || (static_cast<size_t> (num_parallelized_jobs) > MAX_NUM_PARALLELIZED_JOBS)) {
+    CTAG(9,FSA) << "WARNING: Reducing --parallelize " << num_parallelized_jobs << " to ";
+    if (MAX_NUM_PARALLELIZED_JOBS < num_seq_pairs) {
+      CL << MAX_NUM_PARALLELIZED_JOBS <<", the maximum number of parallelized jobs" << endl;
+      num_parallelized_jobs = MAX_NUM_PARALLELIZED_JOBS;
+    } else {
+      CTAG(9,FSA) << num_seq_pairs  <<", the maximum possible number of unique sequence pairs." << endl;
+      num_parallelized_jobs = num_seq_pairs;
+    }
+  }
+  else if (num_parallelized_jobs != 0 && num_parallelized_jobs < MIN_NUM_PARALLELIZED_JOBS) {
+    CTAG(9,FSA) << "WARNING: Increasing --parallelize " << num_parallelized_jobs << " to " << MIN_NUM_PARALLELIZED_JOBS <<", the minimum number of parallelized jobs" << endl;
+    num_parallelized_jobs = MIN_NUM_PARALLELIZED_JOBS;
+  }
+  parallelizing = (num_parallelized_jobs > 0) ? true : false;
+
+  /***********************************************
+   * Database options
+   ***********************************************/
+
+  write_db = !read_posteriors_from_db && (db_name.length() > 0);
+
+  
+  /***********************************************
+   * Pair HMM model options
+   ***********************************************/
+
+  // handle nucprot option
+  if (nucprot) {
+
+    // sanity checks
+    if (!is_dna)
+      THROWEXPR ("ERROR: Input sequences must be nucleotide in order to use --nucprot option.");
+    if (output_for_gui)
+      THROWEXPR ("ERROR: You currently cannot view GUI output for --nucprot alignments.  Sorry!");
+    if (mercator_constraint_file != "")
+      THROWEXPR ("ERROR: You cannot specify Mercator constraints for --nucprot alignments.");
+    if (hardmasked) {
+      CTAG(9,FSA) << "WARNING: Hardmasking is not allowed for --nucprot alignments; I'm disabling hardmasking." << endl;
+      hardmasked = false;
+    }
+    if (anchored) {
+      CTAG(9,FSA) << "WARNING: Anchoring is not allowed for --nucprot alignments; I'm disabling anchoring." << endl;
+      anchored = false;
+    }
+
+    // fix the alphabet as appropriate
+    is_dna = false;
+    is_protein = true;
+    alphabet = Protein_alphabet();
+    alphabet_string = PROTEIN_ALPHABET_STRING;
+
+    // warn if learning strategy isn't acceptable.
+    if (learn_emit_bypair) {
+      CTAG(9,FSA) << "WARNING: You cannot use --learnemit-bypair with --nucprot; I'm disabling --learnemit-bypair and enabling --learnemit-all." << endl;
+      learn_emit_bypair = false;
+    }
+
+    // now set default options all over again (but for proteins)
+    // NB this prevent users from changing some options on the command line
+    set_up_defaults();
+
+  }
+
+  // sane parameters to Tamura-Nei
+  if ((time < 0) || (alpha_R < 0) || (alpha_Y < 0) || (beta < 0))
+    THROWEXPR ("ERROR: Jukes-Cantor and Tamura-Nei parameters --time, --alphar, --alphay and --beta must be positive.");
+
+
+  /***********************************************
+   * Parameter estimation options
+   ***********************************************/
+
+  // don't allow too many iterations of EM
+  if (em_max_iter > EM_MAX_ITER_DEFAULT) {
+    CL << "Reducing max rounds of EM to " << EM_MAX_ITER_DEFAULT << endl;
+    em_max_iter = EM_MAX_ITER_DEFAULT;
+  }
+
+  // enforce no learning if so requested
+  // initialize parameters to defaults which don't depend on the data:
+  // ProbCons defaults for RNA and BLOSUM62 for protein
+  if (nolearn) {
+    learn_emit_all = learn_emit_bypair = learn_gap = false;
+    model = 5;
+  }
+
+  // check learning strategy is consistent
+  if (learn_emit_all && learn_emit_bypair)
+    THROWEXPR ("ERROR: You cannot learn both across all sequences and by pairs of sequences.  Please tell me which to ignore with --nolearnemit-all or --nolearnemit-bypair.");
+
+  // check that regularization is sane
+  if ((regularization_transition_scale < 0) || (regularization_emission_scale < 0))
+    THROWEXPR ("ERROR: Regularization scales must be >= 0.");
+
+  // can't learn by all if anchored
+  if (learn_emit_all && anchored)
+    THROWEXPR ("ERROR: Only --learnemit-bypair is allowed for anchoring; try using --nolearnemit-all or --nolearn.");
+
+
+  /***********************************************
+   * Multiple alignment options: sequence annealing
+   ***********************************************/
+
+  // refinement
+  if (num_refinement_steps == -1)
+    num_refinement_steps = 99999999;
+
+  // warning about low gap factor
+  if (gap_factor < minprob)
+    CL << "A gap factor < " << minprob << " is not meaningful; " << minprob << " will be used internally instead." << endl;
+
+  // maximum sensitivity option
+  if (maxsn)
+    gap_factor = 0;
+  
+  // use tgf weighting always
+  // (originally the maxsn option triggered maxstep weighting,
+  // but empirically I found that tgf weighting gave essentially identical performance
+  // + is truly steepest-ascent => use tgf weighting, even for maxsn mode)
+  use_tgf = true;
+
+
+  /***********************************************
+   * Alignment speedup options: many sequences
+   ***********************************************/
+
+  // recommendation to use --fast
+  if (!fast_defaults && (num_seqs > 100))
+    CTAG(9,FSA) << endl << "WARNING: It is highly recommended that you invoke the --fast option when aligning many sequences.  If you do not, then inference may take a very long time or even fail." << endl << endl;
+
+  // k-mer length must be > 0
+  // (catch the case of k = 0, which occurs automatically if the median sequence length is 0)
+  if (kmer_length <= 0) {
+    if (seq_db.median_length() != 0)
+      THROWEXPR ("ERROR: k-mer word length must be > 0.");
+  }
+
+  // degree must be >= 0
+  if (degree < 0)
+    THROWEXPR ("ERROR: The requested --degree setting must be in 0, ..., (N - 1).");
+  // and less than N
+  if (degree > static_cast<int> (seq_db.size() - 1))
+    degree = seq_db.size() - 1;
+
+  // can't have both refalign and fast
+  if (refalign) {
+    if (fast_defaults)
+      THROWEXPR ("ERROR: You can't select both --fast and --refalign; please choose one or the other.");
+    num_minimum_spanning_trees = 0;
+    num_maximum_spanning_trees = 0;
+    num_minimum_spanning_palm_trees = 0;
+    degree = 0;
+  }
+
+  // fast options:
+  //  Scaled by 5 (so we do ~90% of all (10 choose 2) pairs for an alignment of 15 sequences)
+  if (fast_defaults)
+    fraction_alignment_pairs = 5 * Sequence_pair_selector::erdos_renyi_p_cutoff (num_seqs);
+
+  // if alignment to a reference, use minimal number of sequence pairs
+  if (refalign)
+    num_alignment_pairs = num_seqs - 1;
+
+  // convert from fraction to absolute number of pairs for inference
+  // if num_alignment_pairs not specified, then initialize with 
+  //  fraction_alignment_pairs if specified
+  //  all pairs if not
+  if (num_alignment_pairs < DOUBLE_TINY)
+    num_alignment_pairs = static_cast<int> (std::floor (num_seq_pairs * fraction_alignment_pairs));
+
+  // make sure that we can generate a spanning tree to get a complete alignment
+  if (static_cast<size_t> (num_alignment_pairs) < (num_seqs - 1)) {
+    CTAG(9,FSA) << "WARNING: Increasing --alignment-number to (N - 1) = " << num_seqs - 1 << " to ensure a complete alignment." << endl;
+    num_alignment_pairs = num_seqs - 1;
+  }
+
+  // make sure that a reasonable number of alignment pairs are requested
+  if (static_cast<size_t> (num_alignment_pairs) > num_seq_pairs) {
+    // only warn if --fast wasn't invoked
+    if (!fast_defaults)
+      CTAG(9,FSA) << "WARNING: Reducing --alignment-number " << num_alignment_pairs << " to " << num_seq_pairs << ", the maximum possible number of unique sequence pairs." << endl;
+    num_alignment_pairs = num_seq_pairs;
+  }
+
+  // now store fractions (used for logging)
+  fraction_alignment_pairs = static_cast<double> (num_alignment_pairs) / num_seq_pairs;
+
+
+
+  /***********************************************
+   * Alignment speedup options: long sequences (MUMmer)
+   ***********************************************/
+
+  // Exonerate implies anchoring
+  if (exonerate)
+    anchored = true;
+
+  // check sane
+#ifndef MUMMER_EXEC
+  if (anchored)
+    THROWEXPR ("ERROR: FSA was compiled without MUMmer support.  Please recompile with MUMmer if you wish to use anchoring.");
+#endif
+
+  // don't try to translate sequence if we're already in protein space
+  if (is_protein && use_translated)
+    use_translated = false;
+
+  // translated implies anchoring
+  if (use_translated)
+    anchored = true;
+
+  // set up proper minlen if doing translated anchoring
+  if (use_translated)
+    anchor_minlen = ANCHOR_AA_MINLEN_DEFAULT;
+  
+  // no hardmasking for protein sequence
+  if (!is_dna && hardmasked)
+    THROWEXPR ("ERROR: Hardmasking is only available for nucleotide sequence.");
+
+  /***********************************************
+   * Alignment speedup options: long sequences (exonerate)
+   ***********************************************/
+
+  // check sane
+#ifndef EXONERATE_EXEC
+  if (exonerate)
+    THROWEXPR ("ERROR: FSA was compiled without exonerate support.  Please recompile with exonerate if you wish to use exonerate for anchoring.");
+#endif
+
+  // recommend softmasking
+  if (exonerate && !softmasked)
+    CTAG(9,FSA) << endl << "WARNING: It is HIGHLY RECOMMENDED that you softmask sequence and use the --softmasked option when calling exonerate." << endl << endl;
+
+  // warning about anchoring (exonerate)
+  if ((seq_db.meanlength() > 50000) && !exonerate) {
+    CTAG(9,FSA) << endl << "WARNING: Unless you are aligning well-conserved sequences, it is highly recommend that you invoke the exonerate program (as well as MUMmer) when aligning very long sequences." << endl << endl;
+  }
+
+  /***********************************************
+   * Alignment speedup options: long sequences (Mercator)
+   ***********************************************/
+
+
+  /***********************************************
+   * Memory savings
+   ***********************************************/
+
+  // check that bandwidth is sane
+  if (bandwidth < 0)
+    THROWEXPR ("ERROR: Please specify a positive banding width.");
+
+}
+
+void FSA::init_indel_params (Params& params) {
+
+  params.is_indel2 = is_indel2;
+  params.to_end = DOUBLE_TINY;
+
+  // if nucleotide
+  if (is_dna) {
+    if (!is_indel2) {
+      params.gap_open1 = 0.02;
+      params.gap_extend1 = 0.3;
+      params.gap_open2 = 0;
+      params.gap_extend2 = 0;
+    } else {
+      params.gap_open1 = 0.012; // have mixture components still sum to gap_open prob of 0.02 as above
+      params.gap_extend1 = 0.4;
+      params.gap_open2 = 0.008;
+      params.gap_extend2 = 0.9;
+    }
+  }
+
+  // if amino acid (ProbCons defaults for these -- taken from probcons/Defaults.h)
+  else if (is_protein) {
+    if (!is_indel2) {
+      params.gap_open1 = 0.01993141696f;
+      params.gap_extend1 = 0.7943345308f;
+      params.gap_open2 = 0;
+      params.gap_extend2 = 0;
+    } else {
+      params.gap_open1 = 0.0119511066f;
+      params.gap_extend1 = 0.3965826333f;
+      params.gap_open2 = 0.008008334786f;
+      params.gap_extend2 = 0.8988758326f;
+    }
+  }
+
+  // unreachable code
+  else {
+    THROWEXPR ("ERROR: These don't seem to be nucleotide or amino acid sequences!  This message should never occur.");
+  }
+
+  // initialize indel params to command-line values if passed
+  if (gap_open1 > DOUBLE_TINY)
+    params.gap_open1 = gap_open1;
+  if (gap_extend1 > DOUBLE_TINY)
+    params.gap_extend1 = gap_extend1;
+  if (gap_open2 > DOUBLE_TINY)
+    params.gap_open2 = gap_open2;
+  if (gap_extend2 > DOUBLE_TINY)
+    params.gap_extend2 = gap_extend2;
+
+  // log seed params
+  if (CTAGGING(-1,FSAEM)) {
+    CL << "Seed indel parameters:" << endl;
+    params.show_transition_matrix (CL);
+  }
+
+}
+
+
+void FSA::init_subst_params (Params& params, const std::vector<double>& char_freq, const unsigned model /* = MODEL_DEFAULT */, const double time /* = TIME_DEFAULT */) {
+
+  // time parameter
+  params.time = time;
+
+  // alphabet_string
+  params.alphabet_string = alphabet_string;
+
+  // allocate memory
+  params.single_dist.resize (alphabet_string.length());
+  params.pair_dist.resize (alphabet_string.length());
+  for (size_t i = 0; i < alphabet_string.length(); i++)
+    params.pair_dist[i].resize (alphabet_string.length());
+
+  // init nuc models
+  if (is_dna) {
+
+    // ProbConsRNA defaults (taken from probconsRNA/Defaults.h)
+    const double probcons_single[4] = {
+      0.2270790040f, 0.2422080040f, 0.2839320004f, 0.2464679927f };
+    const double probcons_pair[4][4] = {
+      { 0.1487240046f, 0.0184142999f, 0.0361397006f, 0.0238473993f },
+      { 0.0184142999f, 0.1583919972f, 0.0275536999f, 0.0389291011f },
+      { 0.0361397006f, 0.0275536999f, 0.1979320049f, 0.0244289003f },
+      { 0.0238473993f, 0.0389291011f, 0.0244289003f, 0.1557479948f } };
+
+
+    // now set up the substitution model
+    switch (model) {
+
+    case 0: // Jukes-Cantor model
+      for (size_t i = 0; i < 4; i++) {
+	params.single_dist[i] = 1 / 4.0;
+	for (size_t j = 0; j < 4; j++) {
+	  if (i == j) {
+	    params.pair_dist[i][j] = params.single_dist[i] * (1/4.0 + (3/4.0) * std::exp (-4.0 * time / 3.0));
+	  } else {
+	    params.pair_dist[i][j] = params.single_dist[i] * (1/4.0 - (1/4.0) * std::exp (-4.0 * time / 3.0));
+	  }
+	}
+      }
+      break;
+
+    case 1: // Tamura-Nei model
+      // empirical char freqs
+      params.single_dist.assign (char_freq.begin(), char_freq.end());
+      for (size_t i = 0; i < 4; i++) {
+	for (size_t j = 0; j < 4; j++) {
+	  const double alphai = (i == 0 || i == 2) ? alpha_R : alpha_Y;
+	  const double pj = (j == 0 || j == 2) ? (char_freq[0] + char_freq[2]) : (char_freq[1] + char_freq[3]); // piR or piY, as appropriate for j
+	  assert (alphai > 0 && pj > 0);
+	  // if no change
+	  if (i == j) {
+	    params.pair_dist[i][j] = std::exp (-(alphai + beta) * time)
+	      + std::exp (-beta * time) * (1 - std::exp (-alphai * time)) * (char_freq[j] / pj)
+	      + (1 - std::exp (-beta * time)) * char_freq[j];
+	    params.pair_dist[i][j] *= char_freq[i]; // convert from subst. prob. to joint prob.
+	  }
+	  // else if transition
+	  //	  else if (std::abs (static_cast<int> (static_cast<int> (i) - j)) == 2) {
+	  else if (abs (static_cast<int> (static_cast<int> (i) - j)) == 2) {
+	    params.pair_dist[i][j] = 0.
+	      + std::exp (-beta * time) * (1 - std::exp (-alphai * time)) * (char_freq[j] / pj)
+	      + (1 - std::exp (-beta * time)) * char_freq[j];
+	    params.pair_dist[i][j] *= char_freq[i];
+	  }
+	  // else transversion
+	  else {
+	    params.pair_dist[i][j] = 0.
+	      + 0.
+	      + (1 - std::exp (-beta * time)) * char_freq[j];
+	    params.pair_dist[i][j] *= char_freq[i];
+	  }
+	}
+      }
+      break;
+
+    case 5: // ProbCons
+      for (size_t i = 0; i < 4; i++) {
+	params.single_dist[i] = probcons_single[i];
+	for (size_t j = 0; j < 4; j++) {
+	  params.pair_dist[i][j] = probcons_pair[i][j];
+	}
+      }
+      break;
+
+    default:
+      THROWEXPR ("ERROR: Model " << model << " does not exist.  Please choose a valid model." << endl);
+    }
+
+  }
+
+  // proteins
+  else {
+
+    // BLOSUM62 matrix (taken from probcons/Defaults.h and converted per my AA sorting)
+    double BLOSUM62_single[20] = {
+      0.07831005, 0.02189704, 0.05130349, 0.05615771, 0.04463228, 0.07783433, 0.02601093, 0.06511648, 0.05877077, 0.09716489, 0.02438117, 0.04433257, 0.03940142, 0.03585766, 0.05246024, 0.05849916, 0.05115306, 0.07343426, 0.01203523, 0.03124726 };
+    double BLOSUM62_pair[20][20] = {
+      { 0.02373072, 0.00145515, 0.00223549, 0.00332218, 0.00165004, 0.00597898, 0.00114353, 0.00318853, 0.00331693, 0.00449576, 0.00148878, 0.00210228, 0.00230618, 0.00219102, 0.00244502, 0.00631752, 0.00389995, 0.00533241, 0.00039119, 0.0013184 },
+      { 0.00145515, 0.0101347, 0.00036798, 0.00037956, 0.00052274, 0.00071206, 0.00026421, 0.0009404, 0.00046951, 0.00138494, 0.00037421, 0.00042479, 0.00034766, 0.00032102, 0.00044701, 0.00094867, 0.00073798, 0.00119152, 0.00010666, 0.00036626 },
+      { 0.00223549, 0.00036798, 0.01911178, 0.004968, 0.00069041, 0.00235249, 0.00097077, 0.00105355, 0.00252518, 0.00161966, 0.00047808, 0.0035354, 0.00125381, 0.00176784, 0.00161657, 0.00285226, 0.00180488, 0.00127915, 0.00016015, 0.00066005 },
+      { 0.00332218, 0.00037956, 0.004968, 0.01676565, 0.00078814, 0.0021486, 0.00131767, 0.00124207, 0.0042842, 0.00222063, 0.00076105, 0.00224738, 0.0015155, 0.00345128, 0.00268865, 0.00293898, 0.0021676, 0.00178697, 0.00023815, 0.00092548 },
+      { 0.00165004, 0.00052274, 0.00069041, 0.00078814, 0.01661038, 0.00115204, 0.00072545, 0.00279948, 0.00087222, 0.00533369, 0.00116111, 0.00084658, 0.00060701, 0.00059248, 0.00090768, 0.00119036, 0.00107595, 0.00256159, 0.00085751, 0.00368739 },
+      { 0.00597898, 0.00071206, 0.00235249, 0.0021486, 0.00115204, 0.04062876, 0.00103704, 0.0014252, 0.00259311, 0.00212853, 0.00066504, 0.00288882, 0.00155601, 0.00142432, 0.00194865, 0.00381962, 0.00214841, 0.00194579, 0.00038786, 0.00089301 },
+      { 0.00114353, 0.00026421, 0.00097077, 0.00131767, 0.00072545, 0.00103704, 0.00867996, 0.00059716, 0.00121376, 0.00111754, 0.00042237, 0.00141205, 0.00049078, 0.00113901, 0.00132105, 0.00116422, 0.00077747, 0.00071553, 0.00019097, 0.00131038 },
+      { 0.00318853, 0.0009404, 0.00105355, 0.00124207, 0.00279948, 0.0014252, 0.00059716, 0.01778263, 0.00157852, 0.01071834, 0.00224097, 0.00104273, 0.00103767, 0.00100883, 0.00138145, 0.00173565, 0.00248968, 0.01117956, 0.00039549, 0.00127857 },
+      { 0.00331693, 0.00046951, 0.00252518, 0.0042842, 0.00087222, 0.00259311, 0.00121376, 0.00157852, 0.01612228, 0.00259626, 0.0009612, 0.0025731, 0.00154836, 0.00312308, 0.0059565, 0.00312633, 0.00250862, 0.00210897, 0.00028448, 0.00100817 },
+      { 0.00449576, 0.00138494, 0.00161966, 0.00222063, 0.00533369, 0.00212853, 0.00111754, 0.01071834, 0.00259626, 0.03583921, 0.00461939, 0.00160275, 0.0015731, 0.00180553, 0.00246811, 0.00250962, 0.00302273, 0.0091446, 0.00076736, 0.00219713 },
+      { 0.00148878, 0.00037421, 0.00047808, 0.00076105, 0.00116111, 0.00066504, 0.00042237, 0.00224097, 0.0009612, 0.00461939, 0.00409522, 0.00063401, 0.00046718, 0.00075546, 0.00076734, 0.00087787, 0.00093371, 0.00197461, 0.00016253, 0.00054105 },
+      { 0.00210228, 0.00042479, 0.0035354, 0.00224738, 0.00084658, 0.00288882, 0.00141205, 0.00104273, 0.0025731, 0.00160275, 0.00063401, 0.01281864, 0.00100282, 0.00158223, 0.00207782, 0.00301397, 0.00220144, 0.00136609, 0.00021006, 0.0007496 },
+      { 0.00230618, 0.00034766, 0.00125381, 0.0015155, 0.00060701, 0.00155601, 0.00049078, 0.00103767, 0.00154836, 0.0015731, 0.00046718, 0.00100282, 0.01846071, 0.00090111, 0.00106268, 0.00180037, 0.00147982, 0.00135781, 0.00015674, 0.00047608 },
+      { 0.00219102, 0.00032102, 0.00176784, 0.00345128, 0.00059248, 0.00142432, 0.00113901, 0.00100883, 0.00312308, 0.00180553, 0.00075546, 0.00158223, 0.00090111, 0.00756604, 0.00253532, 0.00191155, 0.00154526, 0.00132844, 0.00020592, 0.00070192 },
+      { 0.00244502, 0.00044701, 0.00161657, 0.00268865, 0.00090768, 0.00194865, 0.00132105, 0.00138145, 0.0059565, 0.00246811, 0.00076734, 0.00207782, 0.00106268, 0.00253532, 0.01775118, 0.0022454, 0.00186053, 0.00169359, 0.00029139, 0.0009943 },
+      { 0.00631752, 0.00094867, 0.00285226, 0.00293898, 0.00119036, 0.00381962, 0.00116422, 0.00173565, 0.00312633, 0.00250962, 0.00087787, 0.00301397, 0.00180037, 0.00191155, 0.0022454, 0.01346609, 0.00487295, 0.00241601, 0.00026525, 0.00102648 },
+      { 0.00389995, 0.00073798, 0.00180488, 0.0021676, 0.00107595, 0.00214841, 0.00077747, 0.00248968, 0.00250862, 0.00302273, 0.00093371, 0.00220144, 0.00147982, 0.00154526, 0.00186053, 0.00487295, 0.01299436, 0.00343452, 0.00024961, 0.00094759 },
+      { 0.00533241, 0.00119152, 0.00127915, 0.00178697, 0.00256159, 0.00194579, 0.00071553, 0.01117956, 0.00210897, 0.0091446, 0.00197461, 0.00136609, 0.00135781, 0.00132844, 0.00169359, 0.00241601, 0.00343452, 0.02075171, 0.00038538, 0.00148001 },
+      { 0.00039119, 0.00010666, 0.00016015, 0.00023815, 0.00085751, 0.00038786, 0.00019097, 0.00039549, 0.00028448, 0.00076736, 0.00016253, 0.00021006, 0.00015674, 0.00020592, 0.00029139, 0.00026525, 0.00024961, 0.00038538, 0.00563625, 0.00069226 },
+      { 0.0013184, 0.00036626, 0.00066005, 0.00092548, 0.00368739, 0.00089301, 0.00131038, 0.00127857, 0.00100817, 0.00219713, 0.00054105, 0.0007496, 0.00047608, 0.00070192, 0.0009943, 0.00102648, 0.00094759, 0.00148001, 0.00069226, 0.00999315 } };
+
+
+    switch (model) {
+
+    case 1: // BLOSUM62, but converted to empirical target aa frequencies
+      params.single_dist.assign (char_freq.begin(), char_freq.end());
+      for (size_t i = 0; i < 20; i++) {
+	for (size_t j = 0; j < 20; j++) {
+	  params.pair_dist[i][j] = BLOSUM62_pair[i][j] * (char_freq[i] * char_freq[j]) / (BLOSUM62_single[i] * BLOSUM62_single[j]);
+	}
+      }
+      params.normalize();
+      break;
+
+    case 5: // BLOSUM62
+      for (size_t i = 0; i < 20; i++) {
+	params.single_dist[i] = BLOSUM62_single[i];
+	for (size_t j = 0; j < 20; j++) {
+	  params.pair_dist[i][j] = BLOSUM62_pair[i][j];
+	}
+      }
+      break;
+
+    default:
+      THROWEXPR ("ERROR: Model " << model << " does not exist.  Please choose a valid model." << endl);
+    }
+
+  }
+
+  params.assert_normalized();
+
+  // log seed params
+  if (CTAGGING(-1,FSAEM)) {
+    CL << "Seed emit parameters:" << endl;
+    params.show_emission (CL);
+  }
+
+  params.assert_normalized();
+
+}
+
+void FSA::init_pseudocounts (Params& pseudo, const Params& seed, double transition_scale, double emission_scale) {
+
+  if (CTAGGING(2,FSA))
+    CL << "Initializing pseudocounts." << endl;
+
+  // get seed distributions
+  pseudo.copy_all (seed);
+
+  // now scale to get counts
+  pseudo.gap_open1 *= transition_scale;
+  pseudo.gap_open2 *= transition_scale;
+  pseudo.gap_extend1 *= transition_scale;
+  pseudo.gap_extend2 *= transition_scale;
+  for (size_t i = 0; i < pseudo.pair_dist.size(); ++i) {
+    pseudo.single_dist[i] *= emission_scale;
+    for (size_t j = 0; j < pseudo.pair_dist.size(); ++j)
+      pseudo.pair_dist[i][j] *= emission_scale;
+  }
+
+}
+
+bool FSA::train_params (Params& params, const Sequence_database& seq_db_train, const Sequence_pairs& subset,
+			bool left_match, bool right_match, bool ragged_ends,
+			const Params& pseudocounts, bool learn_emit) {
+
+  // enforce max_ram cutoff
+  for (Sequence_pairs::const_iterator pair = subset.begin(); pair != subset.end(); ++pair) {
+    const size_t i = pair->first;
+    const size_t j = pair->second;
+    const size_t needed = estimate_ram_needed (seq_db_train.get_seq (i).seq.length(), seq_db_train.get_seq (j).seq.length());
+    if ((max_ram > 0) && (static_cast<int> (needed) > max_ram)) {
+      CTAG(9,FSAEM) << "WARNING: Skipping inference step because estimated memory usage (" << needed << " MB) "
+		    << "is greater than specified limit (" << max_ram << " MB)." << endl
+		    << "Offending sequences are '" << seq_db_train.get_seq (i).name << "' and '" << seq_db_train.get_seq (j).name << "'." << endl;
+      return false;
+    }
+  }
+
+  // without banding
+  if (bandwidth == 0) {
+    if (is_dna && !is_indel2)
+      return Model::train_params_engine<NucleotideWithoutBanding> (params, seq_db_train, subset,
+								   left_match, right_match, ragged_ends,
+								   learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (is_dna && is_indel2)
+      return Model::train_params_engine<NucleotideIndel2WithoutBanding> (params, seq_db_train, subset,
+									 left_match, right_match, ragged_ends,
+									 learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (!is_dna && !is_indel2)
+      return Model::train_params_engine<AminoAcidWithoutBanding> (params, seq_db_train, subset,
+								  left_match, right_match, ragged_ends,
+								  learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (!is_dna && is_indel2)
+      return Model::train_params_engine<AminoAcidIndel2WithoutBanding> (params, seq_db_train, subset,
+									left_match, right_match, ragged_ends,
+									learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+  // with banding
+  else {
+    if (is_dna && !is_indel2)
+      return Model::train_params_engine<NucleotideWithBanding> (params, seq_db_train, subset,
+								left_match, right_match, ragged_ends,
+								learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (is_dna && is_indel2)
+      return Model::train_params_engine<NucleotideIndel2WithBanding> (params, seq_db_train, subset,
+								      left_match, right_match, ragged_ends,
+								      learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (!is_dna && !is_indel2)
+      return Model::train_params_engine<AminoAcidWithBanding> (params, seq_db_train, subset,
+							       left_match, right_match, ragged_ends,
+							       learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else if (!is_dna && is_indel2)
+      return Model::train_params_engine<AminoAcidIndel2WithBanding> (params, seq_db_train, subset,
+								     left_match, right_match, ragged_ends,
+								     learn_gap, learn_emit, regularize, pseudocounts, em_max_iter, em_min_inc);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+
+}
+
+Dotplot FSA::get_pairwise_dotplot (Params& params, const Sequence& xseq, const Sequence& yseq,
+				   bool left_match, bool right_match, bool ragged_ends) {
+
+  // enforce max_ram cutoff
+  size_t needed = estimate_ram_needed (xseq.length(), yseq.length());
+  if ((max_ram > 0) && (static_cast<int> (needed) > max_ram)) {
+    CTAG(9,FSAEM) << "WARNING: Skipping inference step because estimated memory usage (" << needed << " MB) "
+		  << "is greater than specified limit (" << max_ram << " MB)." << endl
+		  << "Offending sequences are '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+    return Dotplot (xseq.length(), yseq.length());
+  }
+
+  // without banding
+  if (bandwidth == 0) {
+    if (is_dna && !is_indel2)
+      return Model::get_pairwise_dotplot_engine<NucleotideWithoutBanding> (params, xseq, yseq,
+									   left_match, right_match, ragged_ends);
+    else if (is_dna && is_indel2)
+      return Model::get_pairwise_dotplot_engine<NucleotideIndel2WithoutBanding> (params, xseq, yseq,
+										 left_match, right_match, ragged_ends);
+    else if (!is_dna && !is_indel2)
+      return Model::get_pairwise_dotplot_engine<AminoAcidWithoutBanding> (params, xseq, yseq,
+									  left_match, right_match, ragged_ends);
+    else if (!is_dna && is_indel2)
+      return Model::get_pairwise_dotplot_engine<AminoAcidIndel2WithoutBanding> (params, xseq, yseq,
+										left_match, right_match, ragged_ends);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+  // with banding
+  else {
+    if (is_dna && !is_indel2)
+      return Model::get_pairwise_dotplot_engine<NucleotideWithBanding> (params, xseq, yseq,
+									left_match, right_match, ragged_ends);
+    else if (is_dna && is_indel2)
+      return Model::get_pairwise_dotplot_engine<NucleotideIndel2WithBanding> (params, xseq, yseq,
+									      left_match, right_match, ragged_ends);
+    else if (!is_dna && !is_indel2)
+      return Model::get_pairwise_dotplot_engine<AminoAcidWithBanding> (params, xseq, yseq,
+								       left_match, right_match, ragged_ends);
+    else if (!is_dna && is_indel2)
+      return Model::get_pairwise_dotplot_engine<AminoAcidIndel2WithBanding> (params, xseq, yseq,
+									     left_match, right_match, ragged_ends);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+
+}
+
+Post_probs FSA::get_pairwise_post_probs (Params& params, const Sequence& xseq, const Sequence& yseq,
+					 bool left_match, bool right_match, bool ragged_ends) {
+
+  // enforce max_ram cutoff
+  const size_t needed = estimate_ram_needed (xseq.length(), yseq.length());
+  if ((max_ram > 0) && (needed > static_cast<size_t> (max_ram))) {
+    CTAG(9,FSAEM) << "WARNING: Skipping inference step because estimated memory usage (" << needed << " MB) "
+		  << "is greater than specified limit (" << max_ram << " MB)." << endl
+		  << "Offending sequences are '" << xseq.name << "' and '" << yseq.name << "'." << endl;
+    return Post_probs();
+  }
+
+  // without banding
+  if (bandwidth == 0) {
+    if (is_dna && !is_indel2)
+      return Model::get_pairwise_post_probs_engine<NucleotideWithoutBanding> (params, xseq, yseq,
+									      minprob,
+									      left_match, right_match, ragged_ends);
+    else if (is_dna && is_indel2)
+      return Model::get_pairwise_post_probs_engine<NucleotideIndel2WithoutBanding> (params, xseq, yseq,
+										    minprob,
+										    left_match, right_match, ragged_ends);  
+    else if (!is_dna && !is_indel2)
+      return Model::get_pairwise_post_probs_engine<AminoAcidWithoutBanding> (params, xseq, yseq,
+									     minprob,
+									     left_match, right_match, ragged_ends);
+    else if (!is_dna && is_indel2)
+      return Model::get_pairwise_post_probs_engine<AminoAcidIndel2WithoutBanding> (params, xseq, yseq,
+										   minprob,
+										   left_match, right_match, ragged_ends);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+  // with banding
+  else {
+    if (is_dna && !is_indel2)
+      return Model::get_pairwise_post_probs_engine<NucleotideWithBanding> (params, xseq, yseq,
+									   minprob,
+									   left_match, right_match, ragged_ends);
+    else if (is_dna && is_indel2)
+      return Model::get_pairwise_post_probs_engine<NucleotideIndel2WithBanding> (params, xseq, yseq,
+										 minprob,
+										 left_match, right_match, ragged_ends);
+    else if (!is_dna && !is_indel2)
+      return Model::get_pairwise_post_probs_engine<AminoAcidWithBanding> (params, xseq, yseq,
+									  minprob,
+									  left_match, right_match, ragged_ends);
+    else if (!is_dna && is_indel2)
+      return Model::get_pairwise_post_probs_engine<AminoAcidIndel2WithBanding> (params, xseq, yseq,
+										minprob,
+										left_match, right_match, ragged_ends);
+    else
+      THROWEXPR ("ERROR: Unreachable code.");
+  }
+
+}
+
+void FSA::show_divergences (std::ostream& o) const {
+
+  // first compute a matrix of divergences (-1 for no information)
+  std::vector<std::vector<double> > distmat (num_seqs, std::vector<double> (num_seqs, -1));
+  for (size_t cnt = 0; cnt < alignment_seq_pairs.size(); ++cnt) {
+    const size_t i = alignment_seq_pairs[cnt].first;
+    const size_t j = alignment_seq_pairs[cnt].second;
+    distmat[i][j] = alignment_params[cnt].branch_length (0);
+    distmat[j][i] = alignment_params[cnt].branch_length (1);
+  }
+
+  // now display: first get width
+  size_t width = 0;
+  for (size_t i = 0; i < seq_db_internal.size(); ++i)
+    width = max (width, seq_db_internal.get_seq (i).name.length());
+  width += 2;
+
+  // state label row
+  o.width (width); o << "";
+  for (size_t i = 0; i < num_seqs; ++i) {
+    o.width (width);
+    o << seq_db_internal.get_seq (i).name;
+  }
+  o << endl;
+  // divergences
+  for (size_t i = 0; i < num_seqs; ++i) {
+    o.width (width);
+    o << seq_db_internal.get_seq (i).name;
+    for (size_t j = 0; j < num_seqs; ++j) {
+      o.width (width);
+      if (i == j)
+	o << 0.;
+      else
+	o << std::setprecision (PRECISION_DEFAULT) << distmat[i][j];
+    }
+    o << endl;
+  }
+
+}
+
+size_t FSA::estimate_ram_needed (size_t xlen, size_t ylen) const {
+
+  size_t needed = static_cast<size_t> (std::floor (((xlen + 1.0) / (1.0 * MEGABYTE)) * (ylen + 1) * static_cast<double> (sizeof (bfloat))));
+  needed *= is_indel2 ? 5 : 3; // hardcode in size of Pair HMM state space (not counting state and end)
+  needed *= 2;                 // factor of 2 for when we store both forward and backward DP matrices (for posterior decoding)
+
+  return needed;
+}
+
+void FSA::assemble_sequence_data() {
+
+  // assemble clean sequence data
+  // (hardmasked sequence stripped if so requested and degenerate characters randomized)
+  for (size_t i = 0; i < num_seqs; ++i) {
+
+    // get original sequence data
+    Sequence& sequence = seq_db.get_seq (i);
+
+    // if hardmasked, keep track of hardmasking
+    if (hardmasked)
+      sequence.init_hardmasking (MIN_HARDMASK_LENGTH, DNA_alphabet::is_hardmask_char);
+
+    // if hardmasking, store stripped sequence
+    std::string orig_seq = hardmasked ? sequence.get_stripped_sequence().seq : sequence.seq;
+
+    // remove degenerate characters
+    std::string nondegen_seq;
+    if (nucprot)    // handle case of nucprot (store the translated sequence)
+      nondegen_seq = Protein_alphabet().get_nondegen ((Translated_sequence (Sequence (sequence.name, orig_seq))).get_forward (0).seq);
+    else
+      nondegen_seq = alphabet.get_nondegen (orig_seq);
+
+    // store
+    Sequence* nondegen_sequence = new Sequence (sequence.name, nondegen_seq);
+    seq_db_internal.add_seq (nondegen_sequence);
+  }
+
+}
+
+void FSA::choose_seq_pairs() {
+
+  // initialize Sequence_pair_selector
+  Sequence_pair_selector sequence_pair_selector (seq_db_internal,
+						 alphabet,
+						 kmer_length);
+
+  // refalign first
+  if (refalign) {
+
+    // first sequence lies at the center if --refalign is select
+    sequence_pair_selector.choose_palm_tree (seq_db_internal.get_seq (0).name);
+
+  }
+
+  // if all are requested, then go ahead and select all pairs
+  else if (static_cast<size_t> (num_alignment_pairs) == num_seq_pairs) {
+
+      sequence_pair_selector.choose_all();
+
+  }
+
+  // else select sequence pairs
+  // order as:
+  //  - minimum spanning tree
+  //  - maximum spanning tree
+  //  - minimum spanning palm tree
+  //  - degree per sequence
+  //  - randomly-chosen pairs
+  else {
+
+    // first add sequence pairs in a structured manner
+    if (num_minimum_spanning_trees > 0)
+      sequence_pair_selector.choose_minimum_spanning_tree (num_minimum_spanning_trees);
+    if (num_maximum_spanning_trees > 0)
+      sequence_pair_selector.choose_maximum_spanning_tree (num_maximum_spanning_trees);
+    if (num_minimum_spanning_palm_trees > 0)
+      sequence_pair_selector.choose_minimum_spanning_palm_tree (num_minimum_spanning_palm_trees);
+    if (degree > 0)
+      sequence_pair_selector.choose_kmer_similarity (degree);
+
+    // then add randomly until we hit the requested num_alignment_pairs target
+    const size_t num_selected = sequence_pair_selector.num_selected();
+    if (num_selected < static_cast<size_t> (num_alignment_pairs))
+      sequence_pair_selector.choose_random (num_alignment_pairs - num_selected);
+
+  }
+  
+  // now actually store the pairs
+  Sequence_pairs selected_sequence_pairs = sequence_pair_selector.get_chosen_sequence_pairs();
+  assert (selected_sequence_pairs.size() == static_cast<size_t> (num_alignment_pairs));
+  size_t num_added_alignment_pairs = 0;
+  for (Sequence_pairs::const_iterator sequence_pair = selected_sequence_pairs.begin(); sequence_pair != selected_sequence_pairs.end(); ++sequence_pair) {
+
+    const size_t i = sequence_pair->first;
+    const size_t j = sequence_pair->second;
+    assert (i < j);
+
+    // now actually store the sequence pair
+    // if a worker, do we store this seq pair?
+    if (w_worker) {
+      if (is_valid_worker_seq_pair (++num_added_alignment_pairs, i, j))
+	alignment_seq_pairs.push_back (*sequence_pair);
+    }
+
+    // if not parallelizing, just store it
+    else
+      alignment_seq_pairs.push_back (*sequence_pair);
+
+  }
+
+}
+
+bool FSA::is_valid_worker_seq_pair (const int cnt, const int i, const int j) const {
+
+  int start_pos = (int) (w_start_seq_pair.first * (2 * num_seqs - w_start_seq_pair.first - 1) / 2) + (w_start_seq_pair.second - w_start_seq_pair.first);
+  int input_pos = (int) (i * (2 * num_seqs - i - 1) / 2) + (j - i);
+
+  if (cnt != -1) {
+	if (w_prev_seq_pairs_sum <= cnt && cnt < (w_prev_seq_pairs_sum + w_num_seq_pairs))
+	  return true;
+  } else {
+    if (start_pos <= input_pos && input_pos < (start_pos + w_num_seq_pairs))
+      return true;
+  }
+  return false;
+}
+
+void FSA::init_for_mw_worker (const std::pair<int, int> start_seq_pair, const int prev_seq_pairs_sum, const int num_seq_pairs) {
+  w_start_seq_pair = start_seq_pair;
+  w_prev_seq_pairs_sum = prev_seq_pairs_sum;
+  w_num_seq_pairs = num_seq_pairs;
+  w_worker = true;
+}
+
+Post_probs FSA::perform_pairwise_inference (Params& params, const Sequence& xseq, const Sequence& yseq,
+					    const bool left_match, const bool right_match, const bool ragged_ends,
+					    const Params& pseudocounts) {
+
+  const size_t xlen = xseq.length();
+  const size_t ylen = yseq.length();
+
+  Sequence_database seq_db_pair;
+  seq_db_pair.add_seq (xseq);
+  seq_db_pair.add_seq (yseq);
+  Sequence_pairs both;
+  both.push_back (std::make_pair (0, 1));
+
+  // train params and get alignment posteriors:
+  // only train if there is enough sequence data
+  if (learn_gap || learn_emit_bypair) {
+    // 2 cases where we learn:
+    // 1) learn emit and possibly gap:
+    //     only learn emit if there's enough sequence data (which implies sufficient data for learning gap)
+    // 2) learn only gap
+    //     only learn gap if there's enough sequence data
+    if (learn_emit_bypair && ((0.5 * (xlen + ylen)) > min_emit_training_data))
+      train_params (params, seq_db_pair, both,
+		    left_match, right_match, ragged_ends,
+		    pseudocounts, learn_emit_bypair);
+    else if (learn_gap && ((0.5 * (xlen + ylen)) > min_gap_training_data))
+      train_params (params, seq_db_pair, both,
+		    left_match, right_match, ragged_ends,
+		    pseudocounts, false);
+  }
+
+  // perform inference
+  // note that we don't need to enforce lexical ordering here (it's guaranteed by get_pairwise_post_probs())
+  return get_pairwise_post_probs (params, xseq, yseq,
+				  left_match, right_match, ragged_ends);
+
+}
+
+Post_probs FSA::perform_anchored_pairwise_inference (const Params& params_seed, const Sequence& xseq, const Sequence& yseq,
+						     const Params& pseudocounts,
+						     const Anchors& anchors) {
+
+  const size_t xlen = xseq.length();
+  const size_t ylen = yseq.length();
+
+  // hold posterior information for this sequence pair
+  Post_probs post_probs;
+
+  // parameters for anchored subsequence pairs
+  // (modified for each pair)
+  Params params;
+
+  // loop through the anchors for this sequence pair:
+  // look at the subsequence from the previous to the current anchor
+  // This all relies on the list of anchors being properly sorted, but we guarantee this
+  // during our anchor resolution.
+  unsigned xprevright = 0; // right-hand X coordinate of previous anchor (closed interval)
+  unsigned yprevright = 0; // set to fake value before sequence start
+  for (size_t a = 0; a <= anchors.size(); ++a) { // we're going over the bound of Anchors anchors here
+                                                 // in order to catch the last anchored subsequence pair
+
+    // specify homology assumptions beyond (to left and right of) current subsequences
+    // note that this gives appropriate settings for the case of no anchors as well
+    bool left_match = true;          // for interior anchored pairs, homology is assumed to both left and right
+    bool right_match = true;
+    if (a == 0)                      // if first anchored pair, then no homology assumed to left
+      left_match = false;
+    if (a == anchors.size())         // if last anchored pair, then no homology assumed to right
+      right_match = false;
+
+    // to do:
+    // make concrete decision about whether to use {left,right}_match information
+    // for now don't force homology
+    left_match = right_match = false;
+
+    // calculate the minimum required subsequence length
+    // (left_match forces Start -> Match and right_match forces Match -> End)
+    const size_t minsublen = static_cast<size_t> (left_match) + static_cast<size_t> (right_match);
+
+    // get coordinates for current anchor, making sure to catch end case,
+    // for which we have no right-anchoring information
+    unsigned xcurrleft, xcurrright;  // current anchor is the closed interval [xcurrleft, xcurrright]
+    unsigned ycurrleft, ycurrright;
+    if (a == anchors.size()) {       // if last anchored pair,
+      xcurrleft = xlen;              // create a fake anchor which lies just beyond the sequence boundaries (0-based indexing)
+      xcurrright = xlen - 1;         // (fake value)
+      ycurrleft = ylen;
+      ycurrright = ylen - 1;
+    } else {
+      xcurrleft = anchors[a].xcoords.start;
+      xcurrright = anchors[a].xcoords.end;
+      ycurrleft = anchors[a].ycoords.start;
+      ycurrright = anchors[a].ycoords.end;
+    }
+
+    // catch the case of the last real anchor (a == anchors.size() - 1) ending at a sequence boundary
+    // (no need to perform inference since overhanging sequence will be left unaligned regardless)
+    if (a == anchors.size()
+	&& ((xprevright == xlen) || (yprevright == ylen)))
+      continue;
+
+    // assert that anchors are non-overlapping (at a pairwise level)
+    if (a != 0) {
+      if (xprevright >= xcurrleft)
+	THROWEXPR ("ERROR: Overlapping anchors: xprevright = " << xprevright << "; xcurrleft = " << xcurrleft << endl
+		   << anchors[a]);
+      if (yprevright >= ycurrleft)
+	THROWEXPR ("ERROR: Overlapping anchors: yprevright = " << yprevright << "; ycurrleft = " << ycurrleft << endl
+		   << anchors[a]);
+    }
+
+    // create subsequences (xsubleft + xsublen) and (ysubleft + ysublen)
+
+    unsigned xsubleft, ysubleft; // left coordinate of closed interval
+    unsigned xsublen, ysublen;   // length of closed interval
+
+    // if first anchored pair, then make sure to get first character in subseq
+    xsubleft = xprevright + (a != 0 ? 1 : 0); // this catches the case of an anchor beginning at the coordinate 0,
+    ysubleft = yprevright + (a != 0 ? 1 : 0); // since we initialize these to 0 before looping over anchors (so we don't want to increment the boundary)
+
+    // cover case of abutting (adjacent) anchors
+    xsubleft = (xsubleft > xcurrleft) ? xcurrleft : xsubleft;
+    ysubleft = (ysubleft > ycurrleft) ? ycurrleft : ysubleft;
+
+    xsublen = xcurrleft - xsubleft; // we don't include the anchors themselves
+    ysublen = ycurrleft - ysubleft; // the subseq [xsubleft + xsublen] is a closed interval (this is important to remember!)
+
+    // subsequence names and subsequences themselves
+    // cast to int to cover the case of 0-length subseqs at the beginning,
+    // in which case the second coordinate is negative
+    const Sequence xsubseq (xseq.name + "_[" + Util::to_string (xsubleft) + "-" + Util::to_string (static_cast<int> (xsubleft + xsublen) - 1) + "]", xseq.seq.substr (xsubleft, xsublen));
+    const Sequence ysubseq (yseq.name + "_[" + Util::to_string (ysubleft) + "-" + Util::to_string (static_cast<int> (ysubleft + ysublen) - 1) + "]", yseq.seq.substr (ysubleft, ysublen));
+
+    Sequence_database subseq_pair;
+    subseq_pair.add_seq (xsubseq);
+    subseq_pair.add_seq (ysubseq);
+    Sequence_pairs both;
+    both.push_back (std::make_pair (0, 1));
+
+    // cover case of empty subsequences:
+    //  (occur when anchors begin or end at sequence boundaries or are adjacent)
+    // store anchor indices and update posteriors,
+    // then continue to next anchor
+    if ((xsublen <= minsublen) || (ysublen <= minsublen)) {
+      // update posteriors to record current anchor info if not a fake anchor
+      if (a < anchors.size()) {
+	for (unsigned x = 0; x <= xcurrright - xcurrleft; ++x) // closed interval!
+	  post_probs.push_back (Post_prob (xcurrleft + x, ycurrleft + x, anchors[a].score_to_prob())); // force high probability for anchor
+      }
+      // increment the anchor indices
+      xprevright = xcurrright;
+      yprevright = ycurrright;
+      // log (but only if at least one sequence has length > 0)
+      if (xsublen + ysublen > 0) {
+	const double anchors_done = 100.0 * (a + 1) / (anchors.size() + 1);
+	if (CTAGGING(6,FSA))
+	  CTAG(6,FSA) << "Processed anchored subsequence pair '" << xsubseq.name << "' and '" << ysubseq.name << "'; "
+		      << std::floor (anchors_done + 0.5) << "% (" << a + 1 << "/" << anchors.size() + 1 << ") complete."
+		      << endl;
+      }
+      // skip inference step
+      continue;
+    }
+
+    // re-initialize params for this anchored pair of subseqs
+    params.copy_all (params_seed);
+
+    // train params and get alignment posteriors
+    // only train if there is enough sequence data
+    if (learn_gap || learn_emit_bypair) {
+      // 2 cases where we learn:
+      // 1) learn emit and possibly gap:
+      //     only learn emit if there's enough sequence data (which implies sufficient data for learning gap)
+      // 2) learn only gap
+      //     only learn gap if there's enough sequence data
+      if (learn_emit_bypair && ((0.5 * (xsublen + ysublen)) > min_emit_training_data))
+	train_params (params, subseq_pair, both,
+		      left_match, right_match, ragged_ends,
+		      pseudocounts, learn_emit_bypair);
+      else if (learn_gap && ((0.5 * (xsublen + ysublen)) > min_gap_training_data))
+	train_params (params, subseq_pair, both,
+		      left_match, right_match, ragged_ends,
+		      pseudocounts, false);
+    }
+
+    // perform inference
+    Post_probs subseq_post_probs = get_pairwise_post_probs (params, xsubseq, ysubseq,
+							    left_match, right_match, ragged_ends);
+
+    // store this subsequence information in the posterior maps for the entire sequence pair:
+    // first store the posteriors calculated for these subsequences
+    for (Post_probs::iterator iter = subseq_post_probs.begin(); iter != subseq_post_probs.end(); ++iter) {
+      const unsigned subx = iter->x;    // coordinates within the subseqs
+      const unsigned suby = iter->y;
+      const double& p = iter->prob;
+      const unsigned x = xsubleft + subx; // coordinates for the entire sequences
+      const unsigned y = ysubleft + suby;
+      assert (x < xlen);       // (0-based coordinates)
+      assert (y < ylen);
+      post_probs.push_back (Post_prob (x, y, p));
+    }
+
+    // then fix the current anchors
+    //  (unless we're at the end case, for which we've created a fake anchor beyond the sequence boundaries)
+    if (a < anchors.size()) {
+      for (unsigned x = 0; x <= xcurrright - xcurrleft; ++x) // closed interval!
+	post_probs.push_back (Post_prob (xcurrleft + x, ycurrleft + x, anchors[a].score_to_prob())); // force high probability for anchor
+    }
+
+    // log progress through anchors
+    const unsigned anchors_done = static_cast<unsigned> (std::floor ((100.0 * (a+1) / (anchors.size() + 1)) + 0.5));
+    if (CTAGGING(6,FSA))
+      CTAG(6,FSA) << "Processed anchored subsequence pair '" << xsubseq.name << "' and '" << ysubseq.name << "'; "
+		   << anchors_done << "% (" << a+1 << "/" << anchors.size() + 1 << ") complete."
+		   << endl;
+
+    // increment the anchor indices
+    xprevright = xcurrright;
+    yprevright = ycurrright;
+
+  }
+
+  // Enforce lexical ordering of post_probs:
+  // Unfortunately, storing anchor posteriors before subsequence posteriors isn't sufficient to preserve
+  // lexical ordering; overlapping anchors will still cause problems.  We therefore force a sort
+  // before constructing the SparseMatrix.  This costs O (n log n) time, but is unavoidable
+  // unless we deal more cleverly with overlapping anchors.
+  std::sort (post_probs.begin(), post_probs.end());
+
+  return post_probs;
+
+}
+
+void FSA::load_probabilities_from_file (const std::string& filename,
+					std::vector<std::vector<SparseMatrix*> >& sparse_matrices) {
+
+  CTAG(8,FSA) << "Reading posterior probabilities file '" << filename << "'." << endl;
+
+  // format is:
+  // ; match posteriors
+  // (0, 0) ~ (1, 0) => 0.999999
+  // ; gap posteriors
+  // (0, 0) ~ (1, -1) => 0.0001
+  Regexp re_probs ("^[ \t]*\\([ \t]*([0-9]+)[ \t]*,[ \t]*([0-9]+)[ \t]*\\)[ \t]*~[ \t]*\\([ \t]*([0-9]+)[ \t]*,[ \t]*([0-9]+)[ \t]*\\)[ \t]*=>[ \t]*(.*)$");
+
+  std::vector<std::vector<Post_probs> > post_probs_storage (num_seqs, std::vector<Post_probs> (num_seqs));
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open())
+    THROWEXPR ("ERROR: Couldn't open file '" << filename << "' for reading.")
+
+  std::string line;
+  while (!filestream.eof()) {
+
+    getline (filestream, line);
+    Util::chomp (line);
+    if (!line.length()) { continue; }
+
+    // are we at a match line?
+    if (re_probs.Match (line.c_str())) {
+
+      // check that format is correct
+      if (re_probs.SubStrings() != 5) {
+	CTAG(8,FSA) << "WARNING: Couldn't parse line: " << line << endl;
+	continue;
+      }
+
+      // pull out data
+      const size_t i = static_cast<size_t> (atoi (re_probs[1].c_str()));
+      const unsigned ii = static_cast<unsigned> (atoi (re_probs[2].c_str()));
+      const size_t j = static_cast<size_t> (atoi (re_probs[3].c_str()));
+      const unsigned jj = static_cast<unsigned> (atoi (re_probs[4].c_str()));
+      const float prob = atof (re_probs[5].c_str());
+
+      // check sane
+      if (i >= num_seqs || j >= num_seqs)
+	THROWEXPR ("ERROR: Invalid sequence indices i = " << i << ", j = " << j << ".");
+      if (ii >= seq_db.get_seq (i).length())
+	THROWEXPR ("ERROR: Sequence position out of bounds: (" << i << ", " << ii << ").");
+      if (jj >= seq_db.get_seq (j).length())
+	THROWEXPR ("ERROR: Sequence position out of bounds: (" << j << ", " << jj << ").");
+
+      // store
+      post_probs_storage[i][j].push_back (Post_prob (ii, jj, prob));
+
+    }
+
+  }
+  filestream.close();
+
+  // initialize SparseMatrix objects
+  for (size_t i = 0; i < num_seqs; ++i) {
+    for (size_t j = 0; j < num_seqs; ++j) {
+      Post_probs& post_probs = post_probs_storage[i][j];
+      // ensure we don't attempt to store empty data (potentially overwriting good data)
+      if (i == j || !post_probs.size())
+	continue;
+      // must sort before initializing SparseMatrix
+      std::sort (post_probs.begin(), post_probs.end());
+      sparse_matrices[i][j] = new SparseMatrix (i, j,
+						seq_db.get_seq (i).length(), seq_db.get_seq (j).length(),
+						post_probs);
+      // clean up as we go to save memory
+      post_probs.clear();
+      // get transpose too
+      sparse_matrices[j][i] = sparse_matrices[i][j]->ComputeTranspose();
+
+      // check that we've actually created a matrix!
+      if (!sparse_matrices[i][j]->size())
+	THROWEXPR ("ERROR: Failed to create sparse matrix of posterior probabilities.");
+
+    }
+  }
+
+}
+
+void FSA::build_multiple_alignment() {
+
+  // read in weights for sequence pairs if information present
+  if (tree_weights_file != "")
+    tree_weights.from_file (seq_db, tree_weights_file);
+
+  // set up model topology
+  bool left_match = false;  // do not require homology beyond sequence boundaries
+  bool right_match = false;
+
+  // initialize parameter seed
+  Params params_seed;
+  const std::vector<double> char_freq_total (Model::count_char_freq (seq_db_internal, this->alphabet_string, is_dna));
+  params_seed.bandwidth = bandwidth;
+  init_indel_params (params_seed);
+  init_subst_params (params_seed, char_freq_total, model, time);
+
+  // initialize pseudocounts (for regularization) according to the params_seed distribution
+  Params pseudocounts;
+  init_pseudocounts (pseudocounts, params_seed, regularization_transition_scale, regularization_emission_scale);
+
+  // if requested, learn params_seed over alignment_seq_pairs
+  if (learn_emit_all) {
+    train_params (params_seed, seq_db_internal, alignment_seq_pairs,
+		  left_match, right_match, ragged_ends,
+		  pseudocounts, learn_emit_all);
+  }
+
+  // store sparse matrices for annealing: store only sparse matrices for memory efficiency
+  std::vector<std::vector<SparseMatrix*> > sparse_matrices (num_seqs, std::vector<SparseMatrix*> (num_seqs, reinterpret_cast<SparseMatrix*> (NULL)));
+
+  // option list to be used for a database connection
+  DB_opts db_opts;
+  db_opts.copy_opts (this);
+
+  // create database manager 
+  Manager manager (seq_db_internal, db_opts);
+
+  if (parallelizing) 
+    manager.mw_master_run (opts.init_argc, opts.init_argv, params_seed, pseudocounts);
+  else if (write_db)
+    manager.mw_single_worker_run (params_seed, pseudocounts);
+
+  if (noannealing)
+    return;
+
+  // if available, get pairwise posterior probabilities from the database
+  if (manager.is_sparse_matrices_available()) {
+#if defined(HAVE_CONDOR) || defined(HAVE_POSTGRES)
+    CTAG(9,FSA) << "Getting pairwise posterior probabilities from database." << endl;
+    manager.get_sparse_matrices (sparse_matrices);
+    CTAG(8,FSA) << "Got pairwise posterior probabilities." << endl;
+#endif
+  }
+
+  // if requested, load pairwise probabilities from a file
+  // rather than re-estimating them with DP
+  else if (load_probs_file.length()) {
+
+    load_probabilities_from_file (load_probs_file,
+				  sparse_matrices);
+
+  }
+
+  // else perform alignment as usual
+  else {
+
+    // initialize params for each alignment_seq_pair
+    alignment_params.resize (alignment_seq_pairs.size());
+    for (size_t cnt = 0; cnt < alignment_seq_pairs.size(); ++cnt)
+      alignment_params[cnt].copy_all (params_seed);
+
+    // now do all-pairs comparison
+    CTAG(9,FSA) << "Collecting pairwise posterior probabilities." << endl;
+
+    // loop through sequence database
+    for (size_t cnt = 0; cnt < alignment_seq_pairs.size(); ++cnt) {
+
+      // get the sequence indices
+      const size_t i = alignment_seq_pairs[cnt].first;
+      const size_t j = alignment_seq_pairs[cnt].second;
+
+      // initialize all the sequence data
+      const Sequence& xseq = seq_db_internal.get_seq (i);
+      const Sequence& yseq = seq_db_internal.get_seq (j);
+
+      // if there is an empty sequence, then skip inference
+      if (!xseq.length() || !yseq.length())
+	continue;
+
+      // perform pairwise inference
+      Post_probs post_probs = perform_pairwise_inference (alignment_params[cnt], xseq, yseq,
+							  left_match, right_match, ragged_ends,
+							  pseudocounts);
+
+      // we need the original sequences in case we've been hardmasking
+      const Sequence& xseq_orig = seq_db.get_seq (i);
+      const Sequence& yseq_orig = seq_db.get_seq (j);
+
+      // if hardmasking, map coords back to original sequence
+      if (hardmasked) {
+	for (Post_probs::iterator p = post_probs.begin(); p != post_probs.end(); ++p) {
+	  p->x = xseq_orig.map_stripped_to_orig (p->x);
+	  p->y = yseq_orig.map_stripped_to_orig (p->y);
+	}
+      }
+
+      // create sparse matrix for sequence pair
+      sparse_matrices[i][j] = new SparseMatrix (i, j,
+						xseq_orig.length(), yseq_orig.length(),
+						post_probs);
+      sparse_matrices[j][i] = sparse_matrices[i][j]->ComputeTranspose(); // pre-compute the transpose for speed
+
+      // check for success (whether we hit max_ram limit)
+      // throw error if so
+      if (!sparse_matrices[i][j]->size() && xseq_orig.length() && yseq_orig.length()) {
+	CTAG(9,FSA) << "WARNING: Unable to detect any homology between sequences '" << xseq.name << "' and '" << yseq.name << "'."
+		    << " This may be due to RAM constraints; check --maxram or try using anchoring." << endl;
+	if (require_homology)
+	  THROWEXPR ("ERROR: Alignment failure.");
+      }
+
+      // log progress through sequence pairs
+      const unsigned percent_done = static_cast<unsigned> (std::floor ((100.0 * (cnt+1) / alignment_seq_pairs.size()) + 0.5));
+      if (CTAGGING(7,FSA))
+	CTAG(7,FSA) << "Processed sequence pair '" << xseq.name << "' and '" << yseq.name << "'; "
+		    << percent_done << "% (" << cnt+1 << "/" << alignment_seq_pairs.size() << ") complete."
+		    << endl;
+
+    } // end loop over sequences
+
+    // log
+    CTAG(8,FSA) << "Processed a total of " << std::floor ((100.0 * alignment_seq_pairs.size() / num_seq_pairs) + 0.5) << "% ("
+		<< alignment_seq_pairs.size() << "/" << num_seq_pairs << ") of all sequence pairs."
+		<< endl;
+
+  }
+
+  // write trained params and/or dotplots for all seq pairs if requested
+  if (write_params || write_dotplots) {
+    CTAG(8,FSA) << "Writing learned parameters and/or dotplots to disk." << endl;
+    std::string filename;
+
+    for (size_t cnt = 0; cnt < alignment_seq_pairs.size(); ++cnt) {
+      const Sequence& xseq = seq_db_internal.get_seq (alignment_seq_pairs[cnt].first);
+      const Sequence& yseq = seq_db_internal.get_seq (alignment_seq_pairs[cnt].second);
+
+      if (write_params) {
+	// emission in human-readable format
+	filename.clear();
+	filename = std::string ("params.emission.learned")
+	  + "." + xseq.name + "-" + yseq.name;
+	alignment_params[cnt].write_emission (filename);
+
+	// emission in .dat format
+	filename.clear();
+	filename = std::string ("params.emission.learned")
+	  + "." + xseq.name + "-" + yseq.name
+	  + ".dat";
+	alignment_params[cnt].write_emission_dat (filename);
+
+	// transition in human-readable format
+	filename.clear();
+	filename = std::string ("params.transition.learned")
+	  + "." + xseq.name + "-" + yseq.name;
+	alignment_params[cnt].write_transition (filename);
+      }
+
+      if (write_dotplots) {
+	filename.clear();
+	filename = std::string ("posterior.final.")
+	  + xseq.name + '-' + yseq.name;
+	get_pairwise_dotplot (alignment_params[cnt], xseq, yseq,
+			      left_match, right_match, ragged_ends).write_dotplot (filename);
+      }
+
+    }
+  }
+
+  // write pairwise distance estimates
+  if (write_divergences) {
+    CTAG(8,FSA) << "Writing distance matrix to disk." << endl;
+    const std::string filename = "divergences";
+    std::ofstream file (filename.c_str());
+    if (!file)
+      THROWEXPR ("ERROR: Couldn't create file with name '" << filename << "'.");
+    show_divergences (file);
+    file.close();
+  }
+
+  // now do sequence annealing
+  // handle case of nucprot
+  // who knows why, but I got weird memory errors when I didn't explicitly create
+  // a reference like this...
+  const Sequence_database& aa_db = nucprot
+    ? seq_db.translate()
+    : Sequence_database();
+
+  Alignment_DAG dag (nucprot ? aa_db : seq_db);
+  dag.anneal (sparse_matrices, tree_weights,
+	      manager,
+	      use_tgf,
+	      gap_factor, enable_dynamic_weights, 0,  // edge_weight_threshold = 0
+	      num_refinement_steps,
+	      output_for_gui, gui_prefix);
+  dag.dfs_topological_sort();
+
+  // we're done!
+  Stockholm stock = nucprot
+    ? dag.get_stockholm (sparse_matrices, tree_weights).get_codon_from_aa_alignment (seq_db)
+    : dag.get_stockholm (sparse_matrices, tree_weights);
+
+  if (write_stockholm)
+    stock.write_stockholm (cout);
+  else
+    stock.write_mfa (cout);
+
+}
+
+void FSA::build_anchored_multiple_alignment() {
+
+  // read in weights for sequence pairs if information present
+  if (tree_weights_file != "")
+    tree_weights.from_file (seq_db, tree_weights_file);
+
+  // initialize parameter seed
+  Params params_seed;
+  const std::vector<double> char_freq_total (Model::count_char_freq (seq_db_internal, this->alphabet_string, is_dna));
+  params_seed.bandwidth = bandwidth;
+  init_indel_params (params_seed);
+  init_subst_params (params_seed, char_freq_total, model, time);
+
+  // initialize pseudocounts (for regularization) according to the params_seed distribution
+  Params pseudocounts;
+  init_pseudocounts (pseudocounts, params_seed, regularization_transition_scale, regularization_emission_scale);
+
+  // store sparse matrices for annealing: store only sparse matrices for memory efficiency
+  std::vector<std::vector<SparseMatrix*> > sparse_matrices (num_seqs, std::vector<SparseMatrix*> (num_seqs, reinterpret_cast<SparseMatrix*> (NULL)));
+
+  // option list to be used for a database connection
+  DB_opts db_opts;
+  db_opts.copy_opts (this);
+
+  // create database manager 
+  Manager manager (seq_db_internal, db_opts);
+
+  if (parallelizing)
+    manager.mw_master_run (opts.init_argc, opts.init_argv, params_seed, pseudocounts);
+  else if (write_db)
+    manager.mw_single_worker_run (params_seed, pseudocounts);
+
+  if (noannealing)
+    return;
+
+  // if available, get pairwise posterior probabilities from the database
+  if (manager.is_sparse_matrices_available()) {
+#if defined(HAVE_CONDOR) || defined(HAVE_POSTGRES)
+    CTAG(9,FSA) << "Getting pairwise posterior probabilities from database." << endl;
+    manager.get_sparse_matrices (sparse_matrices);
+    CTAG(8,FSA) << "Got pairwise posterior probabilities." << endl;
+#endif
+  }
+
+  // if requested, load pairwise probabilities from a file
+  // rather than re-estimating them with DP
+  else if (load_probs_file.length()) {
+
+    load_probabilities_from_file (load_probs_file,
+				  sparse_matrices);
+
+  }
+
+  // else perform alignment as usual
+  else {
+
+    // no need to bother with alignment_params
+    // (different parameters are learned for each anchored subsequence pair)
+
+    // handle case of nucprot
+    const Sequence_database& aa_db = nucprot
+      ? seq_db.translate()
+      : Sequence_database();
+
+    // get resolved anchors for the sequence pairs which we're going use for alignment
+    Anchor_resolver anchor_resolver = nucprot
+      ? Anchor_resolver (aa_db, seq_db_internal, alignment_seq_pairs)
+      : Anchor_resolver (seq_db, seq_db_internal, alignment_seq_pairs);
+
+    // add Mercator constraints if present
+    if (mercator_constraint_file != "")
+      anchor_resolver.add_mercator_constraints (mercator_constraint_file);
+
+    // get resolved anchors
+    CTAG(9,FSA) << "Getting anchors for " << std::floor ((100.0 * alignment_seq_pairs.size() / num_seq_pairs) + 0.5)
+		<< "% (" << alignment_seq_pairs.size() << "/" << num_seq_pairs << ") of all sequence pairs."
+		<< endl;
+
+    // now actually get resolved anchors
+    std::vector<Anchors> resolved_anchors_list = anchor_resolver.get_resolved_anchors (tree_weights,
+										       anchor_minlen, anchor_max_join_length, use_translated,
+										       exonerate, exonerate_minscore, softmasked,
+										       hardmasked,
+										       num_refinement_steps,
+										       output_for_gui, gui_prefix);
+
+    // now align the subsequences between the anchors:
+    // do all-pairs comparison
+
+    // log
+    CTAG(9,FSA) << "Collecting pairwise posterior probabilities for each anchored subsequence pair." << endl;
+
+    // loop through sequence database
+    for (size_t cnt = 0; cnt < alignment_seq_pairs.size(); ++cnt) {
+
+      // initialize all the sequence data
+      const size_t i = alignment_seq_pairs[cnt].first;
+      const size_t j = alignment_seq_pairs[cnt].second;
+
+      const Sequence& xseq = seq_db_internal.get_seq (i);
+      const Sequence& yseq = seq_db_internal.get_seq (j);
+
+      // if there is an empty sequence, then skip inference
+      if (!xseq.length() || !yseq.length())
+	continue;
+
+      // perform anchored pairwise inference
+      Post_probs post_probs = perform_anchored_pairwise_inference (params_seed, xseq, yseq,
+								   pseudocounts,
+								   resolved_anchors_list[cnt]);
+
+      // we need the original sequences in case we've been hardmasking
+      const Sequence& xseq_orig = seq_db.get_seq (i);
+      const Sequence& yseq_orig = seq_db.get_seq (j);
+
+      // if hardmasking, map coords back to original sequence
+      if (hardmasked) {
+	for (Post_probs::iterator p = post_probs.begin(); p != post_probs.end(); ++p) {
+	  p->x = xseq_orig.map_stripped_to_orig (p->x);
+	  p->y = yseq_orig.map_stripped_to_orig (p->y);
+	}
+      }
+
+      // create sparse matrix for sequence pair
+      sparse_matrices[i][j] = new SparseMatrix (i, j,
+						xseq_orig.length(), yseq_orig.length(), post_probs);
+      sparse_matrices[j][i] = sparse_matrices[i][j]->ComputeTranspose();
+
+      // check for success (whether we hit max_ram limit)
+      // throw error if so
+      if (!sparse_matrices[i][j]->size() && xseq_orig.length() && yseq_orig.length()) {
+	CTAG(9,FSA) << "WARNING: Unable to detect any homology between sequences '" << xseq.name << "' and '" << yseq.name << "'."
+		    << " This may be due to RAM constraints; check --maxram or try using anchoring." << endl;
+	if (require_homology)
+	  THROWEXPR ("ERROR: Alignment failure.");
+      }
+
+      // log progress through sequence pairs
+      const unsigned percent_done = static_cast<unsigned> (std::floor ((100.0 * (cnt+1) / alignment_seq_pairs.size()) + 0.5));
+      if (CTAGGING(7,FSA))
+	CTAG(7,FSA) << "Processed sequence pair '" << xseq.name << "' and '" << yseq.name << "'; "
+		    << percent_done << "% (" << cnt+1 << "/" << alignment_seq_pairs.size() << ") complete."
+		    << endl;
+
+    } // end loop over sequences
+
+    // log
+    CTAG(8,FSA) << "Processed a total of " << std::floor ((100.0 * alignment_seq_pairs.size() / num_seq_pairs) + 0.5) << "% ("
+		<< alignment_seq_pairs.size() << "/" << num_seq_pairs << ") of all sequence pairs."
+		<< endl;
+  }
+
+  // now do sequence annealing
+  // handle case of nucprot
+  // who knows why, but I got weird memory errors when I didn't explicitly create
+  // a reference like this...
+  const Sequence_database& aa_db = nucprot
+    ? seq_db.translate()
+    : Sequence_database();
+
+  Alignment_DAG dag (nucprot ? aa_db : seq_db);
+  dag.anneal (sparse_matrices, tree_weights,
+	      manager,
+	      use_tgf,
+	      gap_factor, enable_dynamic_weights, 0,  // edge_weight_threshold = 0
+	      num_refinement_steps,
+	      output_for_gui, gui_prefix);
+  dag.dfs_topological_sort();
+
+  // we're done!
+  Stockholm stock = nucprot
+    ? dag.get_stockholm (sparse_matrices, tree_weights).get_codon_from_aa_alignment (seq_db)
+    : dag.get_stockholm (sparse_matrices, tree_weights);
+
+  if (write_stockholm)
+    stock.write_stockholm (cout);
+  else
+    stock.write_mfa (cout);
+
+}
+
+int FSA::run() {
+
+  try {
+    // It's important that we input the data /before/ parsing the command-line options.
+    // This allows us to set preset values for DNA, RNA and proteins and then let
+    // them be overriden by the command-line options.
+    init_opts();
+    input_data();
+    set_up_defaults();
+    parse_opts();
+    assemble_sequence_data();
+    choose_seq_pairs();
+    if (anchored)
+      build_anchored_multiple_alignment();
+    else
+      build_multiple_alignment();
+  }
+
+  catch (const Dart_exception& e) {
+    CLOGERR << e.what();
+    THROWEXPR ("ERROR: Exception thrown.");
+  }
+
+  return 0;
+}
diff --git a/src/fsa/fsa.h b/src/fsa/fsa.h
new file mode 100644
index 0000000..7d06bae
--- /dev/null
+++ b/src/fsa/fsa.h
@@ -0,0 +1,406 @@
+
+/**
+ * \file fsa.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ * Jaeyoung Do wrote the parallelization and database code.
+ *
+ * All nucleotide sequences are treated internally as DNA, meaning that 'U' gets converted to 'T'
+ * (this is done when degenerate characters are randomized in build_multiple_alignment).
+ * Messing this up will make bad things happen!
+ * NB: The case of the input sequences is preserved (in order to not destroy potential softmasking);
+ * however, the inference engines treat upper and lower-case characters identically.
+ *
+ * Dirichlet regularization scales:
+ * The emission regularization scales correspond precisely to the total number of
+ * pseudocount emissions because the seed distribution for pseudocount calculation
+ * is normalized to 1.
+ * The default values are (approximately) equal to the number of free parameters in a
+ * symmetric pair emission matrix
+ *   = 1/2 * n * (n - 1) + n
+ *   => 1/2 * 4 * 3 + 4 = 10 for nucleotides
+ *   => 1/2 * 20 * 19 + 20 = 210 for amino acids
+ * The transition regularization scale is chosen completely arbitrarily.
+ */
+
+#ifndef FSA_FSA_INCLUDED
+#define FSA_FSA_INCLUDED
+
+
+#define DNA_ALPHABET_STRING "ACGT"
+#define PROTEIN_ALPHABET_STRING "ACDEFGHIKLMNPQRSTVWY"
+
+#define MODEL_DEFAULT 1
+#define TIME_DEFAULT 0.4
+#define ALPHA_R_DEFAULT 1.3
+#define ALPHA_Y_DEFAULT 1.3
+#define BETA_DEFAULT 1.
+
+#define EM_MIN_INC_DEFAULT 0.1
+#define EM_MAX_ITER_DEFAULT 3
+#define REGULARIZATION_NUC_TRANSITION_SCALE_DEFAULT 3.
+#define REGULARIZATION_NUC_EMISSION_SCALE_DEFAULT 10.
+#define REGULARIZATION_AA_TRANSITION_SCALE_DEFAULT 3.
+#define REGULARIZATION_AA_EMISSION_SCALE_DEFAULT 210.
+
+#define MIN_NUC_EMISSION_TRAINING_DATA 60
+#define MIN_NUC_TRANSITION_TRAINING_DATA 60
+#define MIN_AA_EMISSION_TRAINING_DATA 1596
+#define MIN_AA_TRANSITION_TRAINING_DATA 60
+
+#define LONG_DNA_DEFAULT 500                ///< length to trigger anchoring
+
+#define DEFAULT_POSTERIOR_PROB_CUTOFF 0.01  ///< minimum posterior probability value that is maintained in the sparse matrix representation
+#define DEFAULT_DEGREE 5                    ///< default number of pairwise comparisons to use per sequence
+
+#define MAX_NUM_PARALLELIZED_JOBS 100
+#define MIN_NUM_PARALLELIZED_JOBS 1
+
+#define MIN_HARDMASK_LENGTH 10
+
+#include <iostream>
+#include <fstream>
+#include <algorithm>
+
+#include "util/misc.h"
+#include "util/opts_list.h"
+#include "util/memcheck.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+#include "fsa/anchors.h"
+#include "fsa/model.h"
+
+#include "annealing/alignment_DAG.h"
+#include "annealing/dotplot.h"
+#include "annealing/SparseMatrix.h"
+#include "annealing/tree_weights.h"
+
+#include "manager/manager.h"
+
+
+namespace fsa {
+
+  /**
+   * \brief Represent a running FSA program.
+   */
+  struct FSA {
+
+    // options
+    Opts_list opts;          ///< options list
+
+    // output
+    bool write_stockholm;    ///< output Stockholm instead of MFA
+    bool write_params;       ///< write bubbleplot-format files showing emission parameters during training
+    bool write_divergences;  ///< write divergences to file
+    bool write_dotplots;     ///< write dotplot-format files showing post. prob. matrices
+    bool output_for_gui;     ///< log intermediate alignments formatted for GUI displayer
+    std::string gui_prefix;  ///< prefix for gui output file
+
+    // model options
+    bool nucprot;            ///< align nucleotide sequence in protein space
+    bool is_indel2;          ///< 1 or 2 sets of indel states
+    double gap_open1;        ///< gap-open probability of set 1 of indel states
+    double gap_extend1;      ///< gap-extend probability of set 1 of indel states
+    double gap_open2;        ///< gap-open probability of set 2 of indel states
+    double gap_extend2;      ///< gap-extend probability of set 2 of indel states
+    bool ragged_ends;        ///< allow for easy insertions and deletions at ends of sequences
+    int model;               ///< substitution model (also used as seed for learning)
+    double time;             ///< Jukes-Cantor/Tamura-Nei evolutionary time parameter
+    double alpha_R;          ///< Tamura-Nei alpha_R parameter
+    double alpha_Y;          ///< Tamura-Nei alpha_Y parameter
+    double beta;             ///< Tamura-Nei beta parameter
+    sstring load_probs_file; ///< load pairwise posterior probabilities from file
+
+    // parameter estimation options
+    bool learn_gap;                           ///< learn indel parameters
+    bool learn_emit_all;                      ///< learn emit parameters over all sequences
+    bool learn_emit_bypair;                   ///< learn emit parameters for each pair
+    bool nolearn;                             ///< no learning (redundant but convenient)
+    bool regularize;                          ///< regularize learned parameters with Dirichlet distribution specified by model
+    double regularization_emission_scale;     ///< scaling factor (per sequence pair) for the Dirichlet pseudocounts for emissions (nuc or aa)
+    double regularization_transition_scale;   ///< scaling factor (per sequence pair) for the Dirichlet pseudocounts for transitions (nuc or aa)
+    double em_min_inc;                        ///< minimal fractional increase in log-likelihood per round EM
+    int em_max_iter;                          ///< max number of rounds of EM
+    int min_emit_training_data;               ///< minimum amount of sequence data for training emission probs
+    int min_gap_training_data;                ///< minimum amount of sequence data for training indel probs
+
+    // sequence annealing options
+    int num_refinement_steps;            ///< number of iterative refinement steps
+    bool maxsn;                          ///< maximum sensitivity
+    bool use_tgf;                        ///< use tgf or maxstep heuristic for weighting (no command-line control)
+    double gap_factor;                   ///< the gap factor
+    bool enable_dynamic_weights;         ///< dynamic edge-weight calculation
+    double minprob;                      ///< minimum posterior probability to store in sparse matrix
+    sstring tree_weights_file;           ///< weights for sequence pairs
+    bool require_homology;               ///< require some (potential) homology between all sequences considered
+
+    // alignment speedup options
+    int bandwidth;                       ///< banding width
+    bool fast_defaults;                  ///< only look at 10 * Erdos-Renyi threshold percent of sequence pairs for alignment
+    int num_minimum_spanning_trees;      ///< number of minimum spanning trees to use for alignment
+    int num_maximum_spanning_trees;      ///< number of maximum spanning trees to use for alignment
+    int num_minimum_spanning_palm_trees; ///< number of minimum spanning palm trees to use for alignment
+    int degree;                          ///< number of closest sequences to use for alignment
+    int kmer_length;                     ///< length of k-mers to use when determining sequence similarity
+    bool refalign;                       ///< minimal alignment (star)
+    double fraction_alignment_pairs;     ///< fraction of all (n choose 2) pairs to consider during alignment inference
+    int num_alignment_pairs;             ///< total number of all (n choose 2) pairs to consider during alignment inference
+    int max_ram;                         ///< maximum RAM (in megabytes) to use for DP
+
+    // anchoring options
+    bool anchored;                       ///< use anchor annealing
+    bool use_translated;                 ///< perform anchoring in protein space
+    int anchor_minlen;                   ///< minimum anchor length
+    int anchor_max_join_length;          ///< maximum separation of parallel, adjacent anchor to concatenate
+    bool hardmasked;                     ///< sequence is hardmasked
+    sstring mercator_constraint_file;    ///< input Mercator constraints
+    bool exonerate;                      ///< use exonerate
+    int exonerate_minscore;              ///< minimum score for exonerate anchors
+    bool softmasked;                     ///< sequence is softmasked
+
+    // parallelization options
+    bool parallelizing;                  ///< collect post. prob. matrices and cand. edges simutaneously
+    int num_parallelized_jobs;           ///< number of jobs to run simultaneously
+    bool noannealing;                    ///< false when the annealing step is not needed
+	
+    // database options
+    sstring db_hostname;                 ///< database server host name 
+    sstring db_hostaddr;                 ///< database server host IP address
+    sstring db_name;                     ///< database name
+    int db_port;                         ///< database server port
+    sstring db_user;                     ///< database user name
+    sstring db_password;                 ///< database password
+    bool read_posteriors_from_db;        ///< do not compute posteriors; instead read them from database
+    int db_max_ram;                      ///< maximum RAM (in megabytes) to use when the database mode
+    bool write_db;                       ///< write post. prob. matrices and candidate edges to database
+
+    // sequence composition
+    bool is_dna;                         ///< is it nucleotide sequence?
+    bool is_protein;                     ///< is it amino acid sequence?
+
+    // sequence alphabet
+    Alphabet alphabet;                   ///< store alphabet for randomizing degenerate characters, etc.
+    std::string alphabet_string;         ///< store alphabet in alphabetical order
+
+    // sequence data
+    Sequence_database seq_db;            ///< hold all input sequence data
+    Sequence_database seq_db_internal;   ///< hold all processed (nondegenerate, etc.) input sequence data (FSA's internal format)
+    Sequence_pairs alignment_seq_pairs;  ///< hold sequence pairs to be used for alignment
+    Tree_weights tree_weights;           ///< weights for sequence pairs during anchor and sequence annealing
+    size_t num_seqs;                     ///< total number of input sequences
+    size_t num_seq_pairs;                ///< total number of possible input sequence pairs
+
+    // parallelization
+    int w_num_seq_pairs;                 ///< the number of seq pairs to be considered
+    int w_prev_seq_pairs_sum;            ///< the number of seq pairs that have been considered by other workers
+    bool w_worker;                       ///< is this run by a worker?
+    std::pair<int, int> w_start_seq_pair;     ///< the first pair of sequences to be considered
+
+    // parameters
+    std::vector<Params> alignment_params;     ///< hold (trained) parameters for each alignment_seq_pair
+
+    /**
+     * \brief Constructor.
+     */
+    FSA (int argc, char** argv);
+
+    /**
+     * \brief Initialize command-line options.
+     */
+    void init_opts();
+
+    /**
+     * \brief Input sequence data.
+     *
+     * Detects whether nucleotide (DNA or RNA) or amino acid sequence.
+     * Also adjusts the default regularization scales as appropriate.
+     */
+    void input_data();
+
+    /**
+     * \brief Construct preset options for DNA, RNA and proteins.
+     *
+     * Sets up default HMM structure (1 or 2 sets of indel states),
+     * learning strategy and memory and speed usage before command-line
+     * options (which may override these values) are parsed.
+     */
+    void set_up_defaults();
+
+    /**
+     * \brief Parse options.
+     *
+     * Provides opportunity for command-line options to override defaults.
+     */
+    void parse_opts();
+
+    /**
+     * \brief Strip hardmasked sequence, randomize degenerate characters, etc.
+     */
+    void assemble_sequence_data();
+
+    /**
+     * \brief Choose sequence pairs to consider for inference and alignment.
+     * \see Sequence_pair_selector
+     */
+    void choose_seq_pairs();
+
+    /**
+     * \brief Build multiple alignment.
+     */
+    void build_multiple_alignment();
+
+    /**
+     * \brief Build anchored multiple alignment.
+     */
+    void build_anchored_multiple_alignment();
+
+    /**
+     * \brief Run FSA!
+     */
+    int run();
+
+    /**
+     * \brief Init indel parameters.
+     *
+     * This is a bit weird: It initializes the values to the defaults,
+     * then checks to see if command-line values were passed.  If so, 
+     * then it uses those instead.
+     */
+    void init_indel_params (Params& params);
+
+    /** 
+     * \brief Init substitution parameters (both nuc and amino acid).
+     *
+     * \param params parameters to initialize
+     * \param char_freq empirical character frequencies
+     * \param model substitution model to use
+     * \param time evolutionary time parameter of substitution model
+     */
+    void init_subst_params (Params& params, const std::vector<double>& char_freq, const unsigned model = MODEL_DEFAULT, const double time = TIME_DEFAULT);
+
+    /**
+     * \brief Init pseudocounts, scaled versions of the passed seed distribution.
+     *
+     * Pseudocounts for a single pairwise alignment.
+     * \param pseudo pseodocounts object
+     * \param seed seed distribution (scaled to get pseudocounts)
+     * \param transition_scale scaling factor for transition pseudocounts
+     * \param emission_scale scaling factor for emission pseudocounts
+     */
+    void init_pseudocounts (Params& pseudo, const Params& seed, const double transition_scale, const double emit_scale);
+
+    /**
+     * \brief Interface to Model::train_params_engine.
+     *
+     * Decides whether to learn gap parameters based on FSA::learn_gap.
+     * Doesn't learn if the estimated memory usage is greater than max_ram.
+     * \param params Params object to train
+     * \param seq_db_train sequence data
+     * \param subset sequence pairs to consider
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \param ragged_ends 
+     * \param pseudocounts pseudocounts
+     * \param learn_emit learn emission parameters
+     * \return whether training completed
+     * \see Model::train_params_engine
+     */
+    bool train_params (Params& params, const Sequence_database& seq_db_train, const Sequence_pairs& subset,
+		       const bool left_match, const bool right_match, const bool ragged_ends,
+		       const Params& pseudocounts, bool learn_emit);
+
+    /**
+     * \brief Interface to Model::get_alignment_post_probs_engine.
+     *
+     * \param params parameters
+     * \param xseq first sequence
+     * \param yseq second sequence
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \param ragged_ends 
+     * \return computed Post_probs object
+     * \see Model::get_pairwise_post_probs_engine
+     */
+    Post_probs get_pairwise_post_probs (Params& params, const Sequence& xseq, const Sequence& yseq,
+					const bool left_match, const bool right_match, const bool ragged_ends);
+
+    /**
+     * \brief Interface to Model::get_pairwise_dotplot_engine.
+     *
+     * \param params parameters
+     * \param xseq first sequence
+     * \param yseq second sequence
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \param ragged_ends 
+     * \return computed Dotplot object
+     * \see Model::get_pairwise_dotplot_engine
+     */
+    Dotplot get_pairwise_dotplot (Params& params, const Sequence& xseq, const Sequence& yseq,
+				  const bool left_match, const bool right_match, const bool ragged_ends);
+
+    /**
+     * \brief Perform pairwise inference.
+     *
+     * Train parameters and compute posterior alignment probabilities.
+     * \see train_params
+     * \see get_pairwise_post_probs
+     */
+    Post_probs perform_pairwise_inference (Params& params, const Sequence& xseq, const Sequence& yseq,
+					   const bool left_match, const bool right_match, const bool ragged_ends,
+					   const Params &pseudocounts);
+
+    /**
+     * \brief Perform anchored pairwise inference.
+     *
+     * Train parameters and compute posterior alignment probabilities for 
+     * all anchored subsequences.
+     * \see train_params
+     * \see get_pairwise_post_probs
+     */
+    Post_probs perform_anchored_pairwise_inference (const Params& params_seed, const Sequence& xseq, const Sequence& yseq,
+						    const Params& pseudocounts,
+						    const Anchors& anchors);
+
+    /**
+     * \brief Load pairwise probabilities of alignment from a file.
+     *
+     * File must be formatted as the .probs files created by FSA.
+     * \param sparse_matrices populate this object with SparseMatrix* read from file
+     */
+    void load_probabilities_from_file (const std::string& filename,
+				       std::vector<std::vector<SparseMatrix*> >& sparse_matrices);
+
+    /**
+     * \brief Show pairwise distance estimates.
+     *
+     * Reports a pairwise divergence of -1 if the calculation wasn't done 
+     * or the substitution matrix wasn't positive definite.
+     */
+    void show_divergences (std::ostream& o) const;
+
+    /**
+     * \brief Estimates the amount of RAM (in Mb) needed for DP.
+     *
+     * Size of state space is hard-coded in.
+     * \param xlen length of first sequence X
+     * \param ylen length of second second Y
+     * \return Estimated lower-bound on size of DP matrix in megabytes.
+     */
+    size_t estimate_ram_needed (size_t xlen, size_t ylen) const;
+
+    void init_for_mw_worker (const std::pair<int, int> start_seq_pair, const int prev_seq_pairs_sum, const int num_seq_pairs); 
+
+    /**
+     * \brief Do we store a sequence pair for alignment?
+     *
+     * Handles case of parallelization.
+     */
+    bool is_valid_worker_seq_pair (const int cnt, const int i, const int j) const; 
+
+  };
+
+}
+
+#endif /* FSA_FSA_INCLUDED */
diff --git a/src/fsa/model.cc b/src/fsa/model.cc
new file mode 100644
index 0000000..7fadbff
--- /dev/null
+++ b/src/fsa/model.cc
@@ -0,0 +1,392 @@
+
+/**
+ * \file model.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "fsa/model.h"
+
+using namespace fsa;
+
+Params::Params() {
+  
+  // initialize state names
+  states.resize (NUM_HMM_STATES);
+  states[0] = "Start"; states[1] = "Match"; states[2] = "Insert1"; states[3] = "Delete1"; states[4] = "Insert2"; states[5] = "Delete2"; states[6] = "End";
+
+  // initialize transition matrix
+  transition_matrix.assign (NUM_HMM_STATES, vector<double> (NUM_HMM_STATES, 0.));
+
+  // initialize stationary distribution
+  stat_dist.assign (NUM_HMM_STATES, 0.);
+
+}
+
+void Params::init_transition_matrix (bool left_match /* = false */, bool right_match /* = false */, bool ragged_ends /* = false */) {
+    
+  // these must manually be set to 0 because they are re-estimated
+  // by train_params even if the HMM only has 1 set of indel states
+  // (sanity checks against divide-by-zero errors give it a non-zero value)
+  if (!is_indel2)
+    gap_open2 = gap_extend2 = 0.;
+
+  // calculate stationary distribution of chain
+  stat_dist[1] = (1 - gap_extend1) * (1 -gap_extend2) / ((1 - gap_extend1) * (1 - gap_extend2) + (gap_open1 / 2) * (1 - gap_extend2) + (gap_open2 / 2) * (1 - gap_extend1));
+  stat_dist[2] = stat_dist[3] = ((gap_open1 / 2) / (2 * (1 - gap_extend1))) * stat_dist[1];
+  stat_dist[4] = stat_dist[5] = ((gap_open2 / 2) / (2 * (1 - gap_extend2))) * stat_dist[1];
+
+  // Start
+  transition_matrix[0][1] = left_match ? 1.0 : 1.0 - gap_open1 - gap_open2;             // Start -> Match
+  transition_matrix[0][2] = transition_matrix[0][3] = left_match ? 0. : gap_open1 / 2;  //       -> Insert1 | Delete1
+  transition_matrix[0][4] = transition_matrix[0][5] = left_match ? 0. : gap_open2 / 2;  //       -> Insert2 | Delete2
+
+  // Match
+  transition_matrix[1][1] = 1.0 - gap_open1 - gap_open2 - to_end;      // Match -> Match
+  transition_matrix[1][2] = transition_matrix[1][3] = gap_open1 / 2;   //       -> Insert1 | Delete1
+  transition_matrix[1][4] = transition_matrix[1][5] = gap_open2 / 2;   //       -> Insert2 | Delete2
+  transition_matrix[1][6] = to_end;                                    //       -> End
+
+  // Insert1 and Delete1
+  transition_matrix[2][2] = transition_matrix[3][3] = gap_extend1;                                                    // Insert1 -> Insert1
+  transition_matrix[2][1] = transition_matrix[3][1] = right_match ? 1.0 - gap_extend1 : 1.0 - gap_extend1 - to_end;   //         -> Match
+  transition_matrix[2][6] = transition_matrix[3][6] = right_match ? 0. : to_end;                                      //         -> End
+
+  // Insert2 and Delete2
+  transition_matrix[4][4] = transition_matrix[5][5] = gap_extend2;                                                    // Insert2 -> Insert2
+  transition_matrix[4][1] = transition_matrix[5][1] = right_match ? 1.0 - gap_extend2 : 1.0 - gap_extend2 - to_end;   //         -> Match
+  transition_matrix[4][6] = transition_matrix[5][6] = right_match ? 0. : to_end;                                      //         -> End
+
+  assert_transition_matrix_valid();
+
+}
+
+void Params::normalize_transition_matrix() {
+    
+  for (size_t i = 0; i < transition_matrix.size(); ++i) {
+    if (i == 6) // don't try to normalize transitions from End
+      continue;
+    double total = 0;
+    for (size_t j = 0; j < transition_matrix[i].size(); ++j) {
+      assert (transition_matrix[i][j] >= 0.);
+      total += transition_matrix[i][j];
+    }
+    for (size_t j = 0; j < transition_matrix[i].size(); ++j)
+      transition_matrix[i][j] /= total;
+  }
+
+}
+
+void Params::assert_transition_matrix_valid() {
+
+#ifndef NDEBUG
+  for (size_t i = 0; i < transition_matrix.size(); ++i)
+    for (size_t j = 0; j < transition_matrix.size(); ++j)
+      if (transition_matrix[i][j] < 0 || transition_matrix[i][j] > 1) {
+	show_transition_matrix (CL);
+	THROWEXPR ("ERROR: Invalid probabilities in transition matrix.");
+      }
+#endif
+
+}
+
+void Params::copy_all (const Params& from) {
+  copy_indel (from);
+  copy_subst (from);
+  bandwidth = from.bandwidth;
+}
+
+void Params::copy_indel (const Params& from) {
+  is_indel2 = from.is_indel2;
+  gap_open1 = from.gap_open1;
+  gap_open2 = from.gap_open2;
+  gap_extend1 = from.gap_extend1;
+  gap_extend2 = from.gap_extend2;
+  to_end = from.to_end;
+  transition_matrix.assign (from.transition_matrix.begin(), from.transition_matrix.end());
+}
+
+void Params::copy_subst (const Params& from) {
+  time = from.time;
+  single_dist.assign (from.single_dist.begin(), from.single_dist.end());
+  pair_dist.assign (from.pair_dist.begin(), from.pair_dist.end());
+  alphabet_string = from.alphabet_string;
+}
+
+void Params::show_transition_matrix (std::ostream& o) const {
+
+  // show raw params
+  o << "gap_open1 = " << gap_open1 << endl;
+  o << "gap_extend1 = " << gap_extend1 << endl;
+  o << "gap_open2 = " << gap_open2 << endl;
+  o << "gap_extend2 = " << gap_extend2 << endl;
+  o << "to_end = " << to_end << endl;
+  o << endl;
+
+  // now show transition matrix
+  const size_t width = 15;
+  // state label row
+  o.width (width); o << "";
+  for (size_t i = 0; i < states.size(); ++i) {
+    if (!is_indel2 && ((i == 4) || (i == 5)))
+      continue;
+    o.width (width);
+    o << states[i];
+  }
+  o << endl;
+  // transition matrix
+  for (size_t i = 0; i < states.size(); ++i) {
+    if (!is_indel2 && ((i == 4) || (i == 5)))
+      continue;
+    o.width (width);
+    o << states[i];
+    for (size_t j = 0; j < states.size(); ++j) {
+      if (!is_indel2 && ((j == 4) || (j == 5)))
+	continue;
+      o.width (width);
+      o << std::setprecision (PRECISION_DEFAULT) << transition_matrix[i][j];
+    }
+    o << endl;
+  }
+    
+}
+
+void Params::show_emission (std::ostream& o) const {
+
+  const size_t width = 10;
+
+  // single distribution
+  // character label row
+  o.width (width); o << "";
+  for (size_t i = 0; i < single_dist.size(); ++i) {
+    o.width (width);
+    o << alphabet_string[i];
+  }
+  o << endl;
+  // actual entries
+  o.width (width); o << "";
+  for (size_t i = 0; i < single_dist.size(); ++i) {
+    o.width (width);
+    const double p = (single_dist[i] > DOUBLE_VERY_TINY) ? single_dist[i] : DOUBLE_VERY_TINY;
+    o << std::setprecision (PRECISION_DEFAULT) << p;
+  }
+  o << endl; o << endl;
+
+  // pair distribution
+  // character label row
+  o.width (width); o << "";
+  for (size_t i = 0; i < single_dist.size(); ++i) {
+    o.width (width);
+    o << alphabet_string[i];
+  }
+  o << endl;
+  // actual entries
+  for (size_t i = 0; i < pair_dist.size(); ++i) {
+    o.width (width);
+    o << alphabet_string[i];
+    for (size_t j = 0; j < pair_dist.size(); ++j) {
+      o.width (width);
+      const double p = (pair_dist[i][j] > DOUBLE_VERY_TINY) ? pair_dist[i][j] : DOUBLE_VERY_TINY;
+      o << std::setprecision (PRECISION_DEFAULT) << p;
+    }
+    o << endl;
+  }
+    
+}
+
+void Params::show (std::ostream& o) const {
+  show_transition_matrix (o);
+  show_emission (o);
+}
+
+void Params::write_transition (const std::string& filename) const {
+  std::ofstream file (filename.c_str());
+  if (!file)
+    THROWEXPR ("ERROR: Couldn't create file with name '" << filename << "'.");
+  show_transition_matrix (file);
+  file.close();
+}
+
+void Params::write_emission (const std::string& filename) const {
+  std::ofstream file (filename.c_str());
+  if (!file)
+    THROWEXPR ("ERROR: Couldn't create file with name '" << filename << "'.");
+  show_emission (file);
+  file.close();
+}
+
+void Params::write_emission_dat (const std::string& filename) const {
+  std::ofstream file (filename.c_str());
+  if (!file)
+    THROWEXPR ("ERROR: Couldn't create file with name '" << filename << "'.");
+  // print single_dist
+  for (size_t i = 0; i < single_dist.size(); ++i)
+    file << i+1 << ' ' << single_dist[i] << endl; // viewParams.pl wants 1-based indexing
+  // print pair_dist
+  for (size_t i = 0; i < single_dist.size(); ++i)
+    for (size_t j = 0; j < single_dist.size(); ++j)
+      file << i+1 << ' ' << j+1 << ' ' << pair_dist[i][j] << endl;
+    
+  file.close();
+}
+
+bool Params::is_biological() const {
+  for (size_t i = 0; i < pair_dist.size(); ++i) {
+    const double match_odds = pair_dist[i][i] / (single_dist[i] * single_dist[i]);
+    for (size_t j = i + 1; j < pair_dist.size(); ++j) {
+      const double mismatch_odds = max (pair_dist[i][j] / (single_dist[i] * single_dist[j]), pair_dist[j][i] / (single_dist[i] * single_dist[j]));
+      if (match_odds < mismatch_odds)
+	return false;
+    }
+  }
+  return true;
+}
+
+double Params::branch_length (const unsigned which) const {
+  vector<double> freq (pair_dist.size(), 0.);
+  vector<vector<double> > submat (pair_dist.begin(), pair_dist.end());    
+
+  assert ((which == 0) || (which == 1));
+  if (which == 0) {
+    // assemble frequencies implied by pair_dist P(x,y):
+    // sum over second index to get frequency of first index P(x)
+    for (size_t i = 0; i < pair_dist.size(); ++i)
+      for (size_t j = 0; j < pair_dist.size(); ++j)
+	freq[i] += pair_dist[i][j];
+    // convert to conditional substitution matrix:
+    // divide each entry by frequency of first index => P(x,y) / P(x) = P(y|x)
+    // giving a distribution over the /second/ index 
+    // (yes, this is counter-intuitive, but it makes sense in terms of the Ps)
+    for (size_t i = 0; i < pair_dist.size(); ++i)
+      for (size_t j = 0; j < pair_dist.size(); ++j)
+	submat[i][j] /= freq[i];
+  } else {
+    for (size_t i = 0; i < pair_dist.size(); ++i)
+      for (size_t j = 0; j < pair_dist.size(); ++j)
+	freq[i] += pair_dist[j][i];
+    for (size_t i = 0; i < pair_dist.size(); ++i)
+      for (size_t j = 0; j < pair_dist.size(); ++j)
+	submat[i][j] /= freq[j];
+  }
+
+  // check that the probabilities sum appropriately, ie
+  // that we actually do have a stochastic matrix
+  if (which == 0) {
+    for (size_t i = 0; i < submat.size(); ++i) {
+      double sum = 0.;
+      for (size_t j = 0; j < submat.size(); ++j)
+	sum += submat[i][j];
+      assert (std::abs (1.0 - sum) < DOUBLE_VERY_TINY);
+    }
+  } else {
+    for (size_t i = 0; i < pair_dist.size(); ++i) {
+      double sum = 0;
+      for (size_t j = 0; j < pair_dist.size(); ++j)
+	sum += submat[j][i];
+      assert (std::abs (1.0 - sum) < DOUBLE_VERY_TINY);
+    }
+  }
+
+  return logdet (submat);
+}
+
+double Params::logdet (const vector<vector<double> >& matrix) {
+  const double det = determinant (matrix);
+  return (det > 0.) ? (-std::log (det)) : -1;
+}
+
+double Params::determinant (const vector<vector<double> >& matrix) {
+  double det = 0;
+  const size_t dim = matrix.size();
+  assert (dim >= 2);
+
+  if (dim == 2)
+    det = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0];
+  else {
+    for (size_t j1 = 0; j1 < dim; ++j1) {
+      vector<vector<double> > minor_mat (dim-1, vector<double> (dim-1));
+      for (size_t i = 1; i < dim; ++i) {
+	size_t j2 = 0;
+	for (size_t j = 0; j < dim; ++j) {
+	  if (j == j1)
+	    continue;
+	  minor_mat[i-1][j2] = matrix[i][j];
+	  ++j2;
+	}
+      }
+      det += ((j1 % 2 == 0) ? 1 : -1) * matrix[0][j1] * determinant (minor_mat);
+    }
+  }
+
+  return det;
+}
+
+void Params::assert_normalized() const {
+  double single_total = 0;
+  double pair_total = 0;
+  for (size_t i = 0; i < pair_dist.size(); ++i) {
+    assert (!(single_dist[i] < 0));
+    single_total += single_dist[i];
+    for (size_t j = 0; j < pair_dist.size(); ++j) {
+      assert (!(pair_dist[i][j] < 0));
+      pair_total += pair_dist[i][j];
+    }
+  }
+  assert (std::abs (1. - single_total ) < DOUBLE_TINY);
+  assert (std::abs (1. - pair_total ) < DOUBLE_TINY);
+}
+
+void Params::normalize() {
+  double single_total = 0;
+  double pair_total = 0;
+  for (size_t i = 0; i < pair_dist.size(); ++i) {
+    assert (!(single_dist[i] < 0));
+    single_total += single_dist[i];
+    for (size_t j = 0; j < pair_dist.size(); ++j) {
+      assert (!(pair_dist[i][j] < 0));
+      pair_total += pair_dist[i][j];
+    }
+  }
+  for (size_t i = 0; i < pair_dist.size(); ++i) {
+    single_dist[i] /= single_total;
+    for (size_t j = 0; j < pair_dist.size(); ++j) {
+      pair_dist[i][j] /= pair_total;
+    }
+  }
+  assert_normalized();
+}
+
+vector<double> Model::count_char_freq (const Sequence_database& seq_db, const std::string& alphabet_string, bool is_dna) {
+
+  if (CTAGGING(5,FSA))
+    CL << "Counting empirical character frequencies." << endl;
+
+  map<char, size_t> char_cnt;
+  for (size_t c = 0; c < alphabet_string.length(); ++c)
+    char_cnt[alphabet_string[c]] = 0;
+
+  double total = DOUBLE_TINY * alphabet_string.length(); // account for tiny values (ensure proper normalization)
+  for (size_t i = 0; i < seq_db.size(); ++i) {
+    const std::string& seq = seq_db.get_seq (i).seq;
+    for (size_t c = 0; c < seq.length(); ++c) {
+      char ch = toupper (seq[c]);   // ensure upper-case (alphabet_string is upper-case)
+      if (is_dna && (ch == 'U'))    // handle case of 'U'
+	ch = 'T';
+      ++char_cnt[ch];
+    }
+    total += seq.length();
+  }
+  vector<double> char_freq (alphabet_string.length(), 0.);
+  for (size_t c = 0; c < alphabet_string.length(); ++c)
+    char_freq[c] = (DOUBLE_TINY + char_cnt[alphabet_string[c]]) / total;
+
+  // log if requested
+  if (CTAGGING(-1,FSAEM)) {
+    CL << "Character frequencies:" << endl;
+    // character label row
+    for (size_t c = 0; c < alphabet_string.length(); ++c)
+      CL << "char_freq[" << alphabet_string[c] << "] = " << char_freq[c] << endl;
+  }
+
+  return char_freq;
+}
diff --git a/src/fsa/model.h b/src/fsa/model.h
new file mode 100644
index 0000000..3ba615f
--- /dev/null
+++ b/src/fsa/model.h
@@ -0,0 +1,915 @@
+
+/**
+ * \file model.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef FSA_MODEL_INCLUDED
+#define FSA_MODEL_INCLUDED
+
+#define NUM_HMM_STATES 7
+
+#include <iostream>
+#include <fstream>
+#include <cmath>
+#include <algorithm>
+
+#include "util/misc.h"
+#include "util/opts_list.h"
+#include "util/memcheck.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+#include "fsa/mybanding.h"
+#include "fsa/nucleotidedp.h"
+#include "fsa/aminoaciddp.h"
+#include "fsa/nucleotide_indel2dp.h"
+#include "fsa/aminoacid_indel2dp.h"
+#include "fsa/sequence_pair_selector.h"
+
+#include "annealing/dotplot.h"
+#include "annealing/SparseMatrix.h"
+#include "annealing/alignment_DAG.h"
+
+namespace fsa {
+
+  /**
+   * \param A struct to hold the alignment parameters and the DP bandwidth.
+   *
+   * Distributions aren't required to be normalized, so they can be used to hold pseudocounts as well.
+   */
+  struct Params {
+
+  public:
+    size_t bandwidth;     ///< banding width (of DP matrix)
+
+    double gap_open1;     ///< gap-open probability (set 1 of indel states)
+    double gap_extend1;   ///< gap-extend probability (set 1 of indel states)
+
+    double gap_open2;     ///< gap-open probability (set 2 of indel states)
+    double gap_extend2;   ///< gap-extend probability (set 2 of indel states)
+
+    double to_end;        ///< probability to transition to End state of HMM (basically irrelevant)
+
+    double time;                                 ///< evolutionary time parameter (for Jukes-Cantor & Tamura-Nei)
+    std::vector<double> single_dist;               ///< distribution over single nucleotides (for Insert and Delete states)
+    std::vector<std::vector<double> > pair_dist;   ///< distribution over pairs of aligned nucleotides (for Match state)
+
+    /**
+     * \brief Alphabet of the HMM.
+     *
+     * We must store the alphabet like this for sorting later on.
+     * (HMMoC-generated DP code demands alphabetical sorting.)
+     */
+    std::string alphabet_string;
+
+    bool is_indel2;  ///< one or two sets of indel states?
+
+    std::vector<std::string> states; ///< states of Pair HMM
+
+    /**
+     * \brief Transition probabilities of Pair HMM.
+     *
+     *     0     1       2       3       4       5   6
+     * Start Match Insert1 Delete1 Insert2 Delete2 End
+     */
+    std::vector<std::vector<double> > transition_matrix;
+
+    /**
+     * \brief Stationary distribution over states of the Pair HMM.
+     */
+    std::vector<double> stat_dist;
+
+    /**
+     * \brief Constructor.
+     */
+    Params();
+
+    /**
+     * \brief Initialize transition probabilities of Pair HMM.
+     *
+     * Initialize the transition matrix with the desired HMM structure.
+     * If left_match is set, then a transition Start -> Match is forced.
+     * This is appropriate if you know there is homology to the "left."
+     * If right_match is set, then only the {Insert, Delete} -> End transitions
+     * are disallowed.  This is appropriate if you know
+     * there is homology to the "right."
+     * Note that this transition matrix is NOT symmetric, but rather
+     * favors aligments which "begin" with homologous regions and end
+     * with possibly non-homologous regions.  This is intentional and reflects
+     * the implicit assumptions most people make when constructing alignments.
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     */
+    void init_transition_matrix (bool left_match = false, bool right_match = false, bool ragged_ends = false);
+
+    /**
+     * \brief Normalize transition matrix to be a (left) stochastic matrix.
+     */
+    void normalize_transition_matrix();
+
+    /**
+     * \brief Assert that entries in the transition matrix are valid probabilities.
+     */
+    void assert_transition_matrix_valid();
+
+    /**
+     * \brief Copy all parameters.
+     *
+     * \param from Params template
+     */
+    void copy_all (const Params& from);
+
+    /**
+     * \brief Copy indel parameters (for transition probabilities).
+     *
+     * \param from Params template
+     */
+    void copy_indel (const Params& from);
+
+    /**
+     * \brief Copy emission distributions.
+     *
+     * \param from Params template
+     */
+    void copy_subst (const Params& from);
+
+    /**
+     * \brief Show indel parameters and the corresponding transition matrix.
+     */
+    void show_transition_matrix (std::ostream& o) const;
+
+    /**
+     * \brief Show emit distributions in human-readable format.
+     */
+    void show_emission (std::ostream& o) const;
+
+    /**
+     * \brief Show all parameters.
+     */
+    void show (std::ostream& o) const;
+
+    /**
+     * \brief Write transition probs to disk.
+     * \param filename filename
+     */
+    void write_transition (const std::string& filename) const;
+
+    /**
+     * \brief Write emission probs to disk.
+     * \param filename filename
+     */
+    void write_emission (const std::string& filename) const;
+
+    /**
+     * \brief Write emission probs in .dat-format file to disk for viewParams.pl to use.
+     * \param filename filename
+     */
+    void write_emission_dat (const std::string& filename) const;
+
+    /**
+     * \brief Are the parameters biologically meaningful?
+     *
+     * Returns false if odds (match) < odds (mismatch),
+     * where odds (mismatch) = P (a ~ c) / (P (a) * P (c)), etc.
+     */
+    bool is_biological() const;
+
+    /**
+     * \brief Compute branch-length based on log-det transform.
+     *
+     * which specifies which index (0 = first => columns, 1 = second => rows) of pair_dist
+     * is the ancestral sequence.  It follows that
+     *  which = 0 gives a right stochastic matrix,
+     *     where summing over the second index (rows) of the conditional matrix submat gives 1.
+     *  which = 1 gives a left stochastic matrix,
+     *     where summing over the first index (columns) of the conditional matrix submat gives 1.
+     * \param which specifies which index is the ancestral sequence
+     */
+    double branch_length (unsigned which) const;
+
+    /**
+     * \brief Compute -log det.
+     *
+     * \return -1 if undefined (if determinant < 0).
+     */
+    static double logdet (const std::vector<std::vector<double> >& matrix);
+
+    /**
+     * \brief Compute the determinant of the substitution matrix.
+     * \param matrix matrix of interest
+     */
+    static double determinant (const std::vector<std::vector<double> >& matrix);
+
+    /**
+     * \brief Assert distributions normalized.
+     */
+    void assert_normalized() const;
+
+    /**
+     * \brief Normalize distributions.
+     */
+    void normalize();
+
+  };
+
+  /**
+   * \brief The statistical model.
+   */
+  struct Model {
+
+    /**
+     * \brief Create alignment dotplot from DP matrices.
+     *
+     * \param params parameters
+     * \param xseq first sequence X
+     * \param yseq second sequence Y
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \return Dotplot
+     */
+    template<class T>
+    static Dotplot get_pairwise_dotplot_engine (Params& params, const Sequence& xseq, const Sequence& yseq,
+						bool left_match, bool right_match, bool ragged_ends);
+
+    /**
+     * \brief Create an alignment posterior probability Post_probs from DP matrices.
+     *
+     * The construction of the Post_probs object guarantees proper lexical sorting.
+     * \param params parameters
+     * \param xseq first sequence X
+     * \param yseq second sequence Y
+     * \param minprob minimum posterior probability to store
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \return Post_probs (format expected by SparseMatrix constructor).
+     */
+    template<class T>
+    static Post_probs get_pairwise_post_probs_engine (Params& params, const Sequence& xseq, const Sequence& yseq,
+						      double minprob,
+						      bool left_match, bool right_match, bool ragged_ends);
+
+    /**
+     * \brief Use Baum-Welch training to estimate transition (indel) and emission parameters.
+     *
+     * Unsupervised training on the passed list of sequences.
+     * Returns the total forward likelihood.
+     * Dirichlet regularization according to the passed pseudocounts (held in a Params object, but not normalized).
+     * \param params parameters
+     * \param seq_db sequence data
+     * \param seq_pairs sequence pairs to consider
+     * \param left_match force homology at start of sequences
+     * \param right_match force homology at end of sequences
+     * \param learn_gap learn indel parameters
+     * \param learn_emit learn emit parameters
+     * \param regularize regularize parameters
+     * \param pseudocounts pseudocounts for emission regularization with a Dirichlet
+     * \param iterations maximum number of rounds of EM
+     * \param min_inc minimum fractional increase in log-likelihood before termination
+     */
+    template<class T>
+    static bool train_params_engine (Params& params, const Sequence_database& seq_db, const Sequence_pairs& seq_pairs,
+				     bool left_match, bool right_match, bool ragged_ends,
+				     bool learn_gap, bool learn_emit, bool regularize, const Params& pseudocounts, size_t iterations, double min_inc);
+
+    /**
+     * \brief Get character frequencies.
+     *
+     * Force tiny value for all characters, even if absent.
+     * NB: We CANNOT use seq_db.get_null_model (alphabet.size())
+     * because it will return an answer sorted non-alphabetically =>
+     * will give us WRONG results!
+     * Assumes that the alphabet is not case-sensitive and that the
+     * alphabet_string is upper-case.
+     * \param seq_db sequence data
+     * \param alphabet_string (ordered) characters in the alphabet
+     * \param is_dna is the alphabet DNA or protein
+     */
+    static std::vector<double> count_char_freq (const Sequence_database& seq_db, const std::string& alphabet_string, bool is_dna);
+
+  };
+
+  template<class T>
+    Dotplot Model::get_pairwise_dotplot_engine (Params& params, const Sequence& xseq, const Sequence& yseq,
+						bool left_match, bool right_match, bool ragged_ends) {
+
+    // print log message
+    if (CTAGGING(6,FSA))
+      CTAG(6,FSA) << "Summing over alignments of '" << xseq.name << "' and '" << yseq.name << "' to get posterior probs." << endl;
+
+    const size_t xlen = xseq.length();
+    const size_t ylen = yseq.length();
+
+    // initialize transition matrix
+    params.init_transition_matrix (left_match, right_match, ragged_ends);
+
+    // ensure that left_match and right_match are reasonable
+    assert (xlen >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+    assert (ylen >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+
+    // calculate the Forward and Backward tables, to compute posteriors
+    typename T::DPTable *pFW, *pBW;
+    const bfloat fw = T::Forward (&pFW, params, xseq.seq, yseq.seq);
+    T::Backward (&pBW, params, xseq.seq, yseq.seq);
+
+    if (CTAGGING(5,FSA))
+      CTAG(5,FSA) << "Per-site log-likelihood = " << log (fw) / (xseq.length() + yseq.length()) << "." << endl;
+
+    Dotplot dotplot (xseq, yseq);
+    const std::string inner_seq = "sequence2";
+    const int match_id = pBW->getId ("match");
+
+    // the first coordinate in getProb refers to the fastest coordinate (inner loop), sequence2;
+    // therefore switch x and y when calling getProb if necessary
+    if (pFW->outputId[0] == inner_seq) {
+
+      const bfloat total = pBW->getProb ("start", 0, 0);
+      for (unsigned x = 0; x < xlen; ++x) {
+	for (unsigned y = 0; y < ylen; ++y) {
+	  double& p = dotplot (x, y);
+	  p += pFW->getProb (match_id, y + 1, x + 1) * pBW->getProb (match_id, y + 1, x + 1) / total; // HMMoC DP accessor code is 1-based
+	}
+      }
+
+    }
+    // else don't
+    else {
+
+      const bfloat total = pBW->getProb ("start", 0, 0);
+      for (unsigned x = 0; x < xlen; ++x) {
+	for (unsigned y = 0; y < ylen; ++y) {
+	  double& p = dotplot (x, y);
+	  p += pFW->getProb (match_id, x + 1, y + 1) * pBW->getProb (match_id, x + 1, y + 1) / total; // HMMoC DP accessor code is 1-based
+	}
+      }
+
+    }
+
+    // finished, so clean up
+    delete pFW;
+    delete pBW;
+
+    return dotplot;
+  }
+
+  template<class T>
+    Post_probs Model::get_pairwise_post_probs_engine (Params& params, const Sequence& xseq, const Sequence& yseq,
+						      double minprob,
+						      bool left_match, bool right_match, bool ragged_ends) {
+  
+    // print log message
+    if (CTAGGING(6,FSA))
+      CTAG(6,FSA) << "Summing over alignments of '" << xseq.name << "' and '" << yseq.name << "' to get posterior probs." << endl;
+
+    const size_t xlen = xseq.length();
+    const size_t ylen = yseq.length();
+
+    // initialize transition matrix
+    params.init_transition_matrix (left_match, right_match, ragged_ends);
+
+    // ensure that left_match and right_match are reasonable
+    assert (xlen >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+    assert (ylen >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+
+    // calculate the Forward and Backward tables, to compute posteriors
+    typename T::DPTable *pFW, *pBW;
+    const bfloat fw = T::Forward (&pFW, params, xseq.seq, yseq.seq);
+    T::Backward (&pBW, params, xseq.seq, yseq.seq);
+
+    if (CTAGGING(5,FSA))
+      CTAG (5,FSA) << "Per-site log-likelihood = " << log (fw) / (xlen + ylen) << "." << endl;
+
+    // first assemble posterior vector from post prob information
+    Post_probs post_probs;
+
+    const std::string inner_seq = "sequence2";
+    const int match_id = pBW->getId ("match");
+
+    // the first coordinate in getProb refers to the fastest coordinate (inner loop), sequence2;
+    // therefore switch x and y when calling getProb if necessary
+    if (pFW->outputId[0] == inner_seq) {
+
+      const bfloat total = pBW->getProb ("start", 0, 0);
+      for (unsigned x = 0; x < xlen; ++x) {
+	for (unsigned y = 0; y < ylen; ++y) {
+	  double p = pFW->getProb (match_id, y + 1, x + 1) * pBW->getProb (match_id, y + 1, x + 1) / total; // HMMoC DP accessor code is 1-based
+	  // sparse storage
+	  if (p >= minprob)
+	    post_probs.push_back (Post_prob (x, y, p));
+	}
+      }
+
+    }
+    // else don't
+    else {
+
+      const bfloat total = pBW->getProb ("start", 0, 0);
+      for (unsigned x = 0; x < xlen; ++x) {
+	for (unsigned y = 0; y < ylen; ++y) {
+	  double p = pFW->getProb (match_id, x + 1, y + 1) * pBW->getProb (match_id, x + 1, y + 1) / total; // HMMoC DP accessor code is 1-based
+	  // sparse storage
+	  if (p >= minprob)
+	    post_probs.push_back (Post_prob (x, y, p));
+	}
+      }
+
+    }
+
+    // finished, so clean up
+    delete pFW;
+    delete pBW;
+
+    return post_probs;
+  }
+
+  template<class T>
+    bool Model::train_params_engine (Params& params, const Sequence_database& seq_db, const Sequence_pairs& seq_pairs,
+				     bool left_match, bool right_match, bool ragged_ends,
+				     bool learn_gap, bool learn_emit, bool regularize, const Params& pseudocounts, size_t iterations, double min_inc) {
+
+    // get number of seqs
+    const size_t num_seqs = seq_db.size();
+    const size_t num_seq_pairs = seq_pairs.size();
+
+    // log
+    assert (num_seqs >= 2);
+    std::string what_training;
+    if (learn_gap && learn_emit)
+      what_training = "gap and emit";
+    else if (learn_gap && !learn_emit)
+      what_training = "gap";
+    else if (!learn_gap && learn_emit)
+      what_training = "emit";
+    else
+      what_training = "nothing; why am I training?";
+    if ((num_seqs == 2) && CTAGGING(6,FSAEM))
+      CTAG(6,FSAEM) << "Training parameters (" << what_training << ") for '" << seq_db.get_seq (0).name << "' and '" << seq_db.get_seq (1).name << "'." << endl;
+    else if ((num_seqs != 2) && CTAGGING(9,FSAEM))
+      CTAG(9,FSAEM) << "Training parameters (" << what_training << ") for " << seq_db.size() << " sequences (using " << num_seq_pairs << "/" << num_seqs * (num_seqs - 1) / 2 << " possible sequence pairs)." << endl;
+
+    // get alphabet size and alphabet
+    const size_t alphabet_size = params.alphabet_string.length();
+
+    // init DP tables
+    typename T::DPTable* pFW;
+    typename T::BaumWelchCounters baum_welch;
+
+    bfloat curr_fw_total = 0;
+    bfloat prev_fw_total = 0;
+
+    const std::string emit1 = "emit1";
+    const std::string emit2 = "emit2";
+    const std::string emit12 = "emit12";
+
+    for (size_t iter = 1; iter <= iterations; ++iter) { // 1-based for easy logging
+    
+      // initialize transition matrix
+      params.init_transition_matrix (left_match, right_match, ragged_ends);
+
+      // reset counts and begin round of EM
+      baum_welch.resetCounts();
+      curr_fw_total = 0;
+      size_t sites = 0;
+
+      if ((num_seqs == 2) && CTAGGING(6,FSAEM))
+	CTAG(6,FSAEM) << "Beginning EM round " << iter << "/" << iterations << endl;
+      else if ((num_seqs != 2) && CTAGGING(7,FSAEM))
+	CTAG(7,FSAEM) << "Beginning EM round " << iter << "/" << iterations << endl;
+
+      // accumulate counts for all sequence pairs
+      for (size_t cnt = 0; cnt < seq_pairs.size(); ++cnt) {
+	const size_t i = seq_pairs[cnt].first;
+	const size_t j = seq_pairs[cnt].second;
+
+	sites += seq_db.get_seq (i).length() + seq_db.get_seq (j).length();
+
+	// ensure that left_match and right_match are reasonable
+	assert (seq_db.get_seq (i).length() >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+	assert (seq_db.get_seq (j).length() >= static_cast<size_t> (left_match) + static_cast<size_t> (right_match));
+
+	// calculate the forward DP table
+	const bfloat fw = T::Forward (&pFW, params, seq_db.get_seq (i).seq, seq_db.get_seq (j).seq);
+	curr_fw_total += fw;
+
+	if (CTAGGING(4,FSAEM))
+	  CTAG(4,FSAEM) << "Adding counts for '" << seq_db.get_seq (i).name << "' and '" << seq_db.get_seq (j).name << "' (per-site log-likelihood = " << log (fw) / (seq_db.get_seq (i).length() + seq_db.get_seq (j).length()) << ")" << endl;
+
+	// calculate the Baum-Welch estimated transition counts
+	const bfloat bw = T::BackwardBaumWelch (baum_welch, pFW, params, seq_db.get_seq (i).seq, seq_db.get_seq (j).seq);
+
+	// log progress
+	if (num_seqs > 2) {
+	  const unsigned percent_done = static_cast<unsigned> (std::floor ((100.0 * (cnt+1) / num_seq_pairs) + 0.5));
+	  if (CTAGGING(7,FSA))
+	    CTAG(7,FSA) << "Processed sequence pair '" << seq_db.get_seq (i).name << "' and '" << seq_db.get_seq (j).name << "' (" << percent_done << "% complete)." << endl;
+	}
+
+	// remove the forward table
+	delete pFW;
+      }
+
+      if (learn_gap) {
+
+	// get the expected transition counts
+	const double trMM = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trMM")];
+	const double trMI1 = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trMI1")];
+	const double trMD1 = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trMD1")];
+
+	// these guys don't exist if only 1 set of indel states, so do this to avoid a segfault...
+	const double trMI2 = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trMI2")] : 0.;
+	const double trMD2 = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trMD2")] : 0.;
+
+	const double trI1I1 = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trI1I1")];
+	const double trI1M = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trI1M")];
+	const double trD1D1 = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trD1D1")];
+	const double trD1M = baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trD1M")];
+
+	const double trI2I2 = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trI2I2")] : 0.;
+	const double trI2M = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trI2M")] : 0.;
+	const double trD2D2 = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trD2D2")] : 0.;
+	const double trD2M = params.is_indel2 ? (double) baum_welch.transitionBaumWelchCount00[baum_welch.transitionIndex ("trD2M")] : 0.;
+
+	// add DOUBLE_TINY to ensure sanity
+	double match_to_indel1 = trMI1 + trMD1 + DOUBLE_TINY;
+	double indel1_to_indel1 = trI1I1 + trD1D1 + DOUBLE_TINY;
+	double match_to_indel2 = trMI2 + trMD2 + DOUBLE_TINY;
+	double indel2_to_indel2 = trI2I2 + trD2D2 + DOUBLE_TINY;
+	double from_match = trMM + match_to_indel1 + match_to_indel2 + DOUBLE_TINY;
+	double from_indel1 = trI1I1 + trI1M + trD1D1 + trD1M + DOUBLE_TINY;
+	double from_indel2 = trI2I2 + trI2M + trD2D2 + trD2M + DOUBLE_TINY;
+
+	// log transition counts
+	if (CTAGGING(-1,FSAEM)) {
+	  CL << "Transition counts:" << endl
+	     << "match_to_indel1 = " << match_to_indel1 << endl
+	     << "match_to_indel2 = " << match_to_indel2 << endl
+	     << "indel1_to_indel1 = " << indel1_to_indel1 << endl
+	     << "indel2_to_indel2 = " << indel2_to_indel2 << endl
+	     << "from_match = " << from_match << endl
+	     << "from_indel1 = " << from_indel1 << endl
+	     << "from_indel2 = " << from_indel2 << endl;
+	}
+
+	// regularization
+	if (regularize) {
+	  // add pseudocounts, scaled by the number of sequence pairs
+	  if (CTAGGING(2,FSAEM))
+	    CL << "Adding transition pseudocounts" << endl;
+	  match_to_indel1 += pseudocounts.gap_open1 * num_seq_pairs;
+	  match_to_indel2 += pseudocounts.gap_open2 * num_seq_pairs;
+	  from_match += pseudocounts.gap_open1 * num_seq_pairs + pseudocounts.gap_open2 * num_seq_pairs;
+	  indel1_to_indel1 += pseudocounts.gap_extend1 * num_seq_pairs;
+	  indel2_to_indel2 += pseudocounts.gap_extend2 * num_seq_pairs;
+	  from_indel1 += pseudocounts.gap_extend1 * num_seq_pairs;
+	  from_indel2 += pseudocounts.gap_extend2 * num_seq_pairs;
+
+	  // log counts post-regularization
+	  if (CTAGGING(-1,FSAEM)) {
+	    CL << "Transition counts after regularization:" << endl
+	       << "match_to_indel1 = " << match_to_indel1 << endl
+	       << "match_to_indel2 = " << match_to_indel2 << endl
+	       << "indel1_to_indel1 = " << indel1_to_indel1 << endl
+	       << "indel2_to_indel2 = " << indel2_to_indel2 << endl
+	       << "from_match = " << from_match << endl
+	       << "from_indel1 = " << from_indel1 << endl
+	       << "from_indel2 = " << from_indel2 << endl;
+	  }
+	}
+
+	// re-estimate indel parameters
+	params.gap_open1 = match_to_indel1 / from_match;
+	params.gap_extend1 = indel1_to_indel1 / from_indel1;
+	params.gap_open2 = match_to_indel2 / from_match;
+	params.gap_extend2 = indel2_to_indel2 / from_indel2;
+
+	// force indel parameters to be sane:
+	// Problems can arise b/c the Insert->Match transitions are calculated internally in the DP code as 
+	//    1.0 - gap_extend - to_end
+	// and Match->Match probs as
+	//    1.0 - gap_open - to_end
+	// If gap_extend becomes 1 (as is wont to happen), then this quantity becomes negative and Very Bad Things can happen.
+	// Make sure that it doesn't:
+	// Force all transition probabilities to be in the range [DOUBLE_TINY, 1.0 - DOUBLE_TINY].
+
+	// gap-open probability
+	params.gap_open1 = (params.gap_open1 > (1.0 - DOUBLE_TINY)) ? 1.0 - DOUBLE_TINY : params.gap_open1;
+	params.gap_open1 = (params.gap_open1 < DOUBLE_TINY) ? DOUBLE_TINY : params.gap_open1;
+	params.gap_open2 = (params.gap_open2 > (1.0 - DOUBLE_TINY)) ? 1.0 - DOUBLE_TINY : params.gap_open2;
+	params.gap_open2 = (params.gap_open2 < DOUBLE_TINY) ? DOUBLE_TINY : params.gap_open2;
+
+	// gap-extend probability
+	params.gap_extend1 = (params.gap_extend1 > (1.0 - DOUBLE_TINY)) ? 1.0 - DOUBLE_TINY : params.gap_extend1;
+	params.gap_extend1 = (params.gap_extend1 < DOUBLE_TINY) ? DOUBLE_TINY : params.gap_extend1;
+	params.gap_extend2 = (params.gap_extend2 > (1.0 - DOUBLE_TINY)) ? 1.0 - DOUBLE_TINY : params.gap_extend2;
+	params.gap_extend2 = (params.gap_extend2 < DOUBLE_TINY) ? DOUBLE_TINY : params.gap_extend2;
+
+	// gap-close probability
+	if (1.0 - params.gap_extend1 - DOUBLE_TINY < DOUBLE_TINY) // hardcode in parameter to_end = DOUBLE_TINY
+	  params.gap_extend1 -= DOUBLE_TINY;
+	if (1.0 - params.gap_extend2 - DOUBLE_TINY < DOUBLE_TINY) // hardcode in parameter to_end = DOUBLE_TINY
+	  params.gap_extend2 -= DOUBLE_TINY;
+
+	// match->match probability
+	if (1.0 - params.gap_open1 - params.gap_open2 - DOUBLE_TINY < 0) { // hardcode in parameter to_end = DOUBLE_TINY
+	  params.gap_open1 -= DOUBLE_TINY / 2;
+	  params.gap_open2 -= DOUBLE_TINY / 2;
+	}
+
+	// assert sane
+	assert (params.gap_open1 >= 0. && params.gap_open1 <= 1.);
+	assert (params.gap_extend1 >= 0. && params.gap_extend1 <= 1.);
+	assert (params.gap_open2 >= 0. && params.gap_open2 <= 1.);
+	assert (params.gap_extend2 >= 0. && params.gap_extend2 <= 1.);
+	
+      }
+
+      // re-estimate emission parameters
+      if (learn_emit) {
+
+	// accumulate total counts for normalization and log expected counts
+	double singletotal = 0;
+	double pairtotal = 0;
+	if (CTAGGING(-1,FSAEM))
+	  CL << "Emission counts:" << endl;
+	for (size_t i = 0; i < alphabet_size; ++i) {
+	  if (CTAGGING(-1,FSAEM)) {
+	    CL << " " << emit1 << "[" << params.alphabet_string[i] << "]: " << baum_welch.emissionBaumWelchCount10[i][baum_welch.emissionIndex (emit1)] << endl
+	       << " " << emit2 << "[" << params.alphabet_string[i] << "]: " << baum_welch.emissionBaumWelchCount01[i][baum_welch.emissionIndex (emit2)] << endl;
+	  }
+	  singletotal += baum_welch.emissionBaumWelchCount10[i][baum_welch.emissionIndex (emit1)] + baum_welch.emissionBaumWelchCount01[i][baum_welch.emissionIndex (emit2)];
+	}
+	for (size_t i = 0; i < alphabet_size; ++i) {
+	  for (size_t j = 0; j < alphabet_size; ++j) {
+	    if (CTAGGING(-1,FSAEM))
+	      CL << " " << emit12 << "[" << params.alphabet_string[i] << params.alphabet_string[j] << "]: " << baum_welch.emissionBaumWelchCount11[i][j][baum_welch.emissionIndex (emit12)] << endl;
+	    pairtotal += baum_welch.emissionBaumWelchCount11[i][j][baum_welch.emissionIndex (emit12)];
+	  }
+	}
+      
+	// regularization
+	if (regularize) {
+	  // add pseudocounts, scaled by the number of sequence pairs
+	  if (CTAGGING(2,FSAEM))
+	    CL << "Adding emission pseudocounts" << endl;
+	  for (size_t i = 0; i < alphabet_size; ++i) {
+	    baum_welch.emissionBaumWelchCount10[i][baum_welch.emissionIndex (emit1)] += pseudocounts.single_dist[i] * num_seq_pairs; // scale by number of sequence pairs b/c pseudocounts are for a single pairwise comparison
+	    baum_welch.emissionBaumWelchCount01[i][baum_welch.emissionIndex (emit2)] += pseudocounts.single_dist[i] * num_seq_pairs;
+	    singletotal += 2 * pseudocounts.single_dist[i] * num_seq_pairs;
+	    for (size_t j = 0; j < alphabet_size; ++j) {
+	      baum_welch.emissionBaumWelchCount11[i][j][baum_welch.emissionIndex (emit12)] += pseudocounts.pair_dist[i][j] * num_seq_pairs;
+	      pairtotal += pseudocounts.pair_dist[i][j] * num_seq_pairs;
+	    }
+	  }
+
+	  // log counts post-regularization
+	  if (CTAGGING(-1,FSAEM)) {
+	    CL << "Emission counts after regularization:" << endl;
+	    for (size_t i = 0; i < alphabet_size; ++i) {
+	      CL << " " << emit1 << "[" << params.alphabet_string[i] << "]: " << baum_welch.emissionBaumWelchCount10[i][baum_welch.emissionIndex (emit1)] << endl
+		 << " " << emit2 << "[" << params.alphabet_string[i] << "]: " << baum_welch.emissionBaumWelchCount01[i][baum_welch.emissionIndex (emit2)] << endl;
+	    }
+	    for (size_t i = 0; i < alphabet_size; ++i)
+	      for (size_t j = 0; j < alphabet_size; ++j)
+		CL << " " << emit12 << "[" << params.alphabet_string[i] << params.alphabet_string[j] << "]: " << baum_welch.emissionBaumWelchCount11[i][j][baum_welch.emissionIndex (emit12)] << endl;
+	  }
+
+	}
+
+	// re-estimate emission params
+	for (size_t i = 0; i < alphabet_size; ++i) {
+	  params.single_dist[i] = (baum_welch.emissionBaumWelchCount10[i][baum_welch.emissionIndex (emit1)] + baum_welch.emissionBaumWelchCount01[i][baum_welch.emissionIndex (emit2)]) / singletotal;
+	  for (size_t j = 0; j < alphabet_size; ++j)
+	    params.pair_dist[i][j] = baum_welch.emissionBaumWelchCount11[i][j][baum_welch.emissionIndex (emit12)] / pairtotal;
+	}
+
+      }
+
+      // log all new params
+      if (CTAGGING(1,FSAEM)) {
+	CL << "Parameter estimates after EM round " << iter << "/" << iterations << endl;
+	if (learn_gap)
+	  params.show_transition_matrix (CL);
+	if (learn_emit)
+	  params.show_emission (CL);
+      }
+
+      params.assert_normalized();
+
+      // check that fractional increase in log-likelihood is sufficient to continue
+      // (conditional to cover case of first iteration)
+      // in below function, we DON'T use std::log in order to get compiler to call Algebra<BFloatMethods>'s friend method log 
+      const double inc = std::abs (static_cast<double> (log (curr_fw_total) / ((std::abs (log (prev_fw_total)) < DOUBLE_TINY) ? 1.0 : log (prev_fw_total)) - 1.0));
+      if ((curr_fw_total <= prev_fw_total) || (inc < min_inc))	// fractional improvement too low, so stop
+	{
+	  // did our probabilities fail to increase?
+	  if ((curr_fw_total + DOUBLE_TINY < prev_fw_total) && CTAGGING(7,FSAEM)) // ignore rounding errors
+	    CL << "WARNING: per-site log-likelihood dropped from " << log (prev_fw_total) / sites
+	       << " to " << log (curr_fw_total) / sites << " during EM." << endl;
+	  if (CTAGGING(4,FSAEM))
+	    CL << "Failed EM fractional improvement threshold of " << min_inc << "; stopping (inc = " << inc << ")." << endl;
+	  break;
+	}
+      prev_fw_total = curr_fw_total;
+
+    }
+
+    return true;
+  }
+
+
+  /**
+   * \brief Accessor classes for the standard DP algorithms (nucleotide).
+   */
+  class NucleotideWithoutBanding {
+
+  public:
+  
+    typedef NucleotideAlignDPTable    DPTable;
+    typedef NucleotideAlignBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Forward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Backward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelch (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the banded DP algorithms (nucleotide).
+   */
+  class NucleotideWithBanding {
+
+  public:
+
+    typedef NucleotideAlignWithBandingDPTable    DPTable;
+    typedef NucleotideAlignWithBandingBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::ForwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelchBanding (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the standard DP algorithms (amino acid).
+   */
+  class AminoAcidWithoutBanding {
+
+  public:
+  
+    typedef AminoAcidAlignDPTable    DPTable;
+    typedef AminoAcidAlignBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Forward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Backward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelch (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the banded DP algorithms (amino acid).
+   */
+  class AminoAcidWithBanding {
+
+  public:
+
+    typedef AminoAcidAlignWithBandingDPTable    DPTable;
+    typedef AminoAcidAlignWithBandingBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::ForwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelchBanding (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the standard DP algorithms (nucleotide with 2 sets of indel states).
+   */
+  class NucleotideIndel2WithoutBanding {
+
+  public:
+  
+    typedef NucleotideIndel2AlignDPTable    DPTable;
+    typedef NucleotideIndel2AlignBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Forward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Backward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelch (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the banded DP algorithms (nucleotide with 2 sets of indel states).
+   */
+  class NucleotideIndel2WithBanding {
+
+  public:
+
+    typedef NucleotideIndel2AlignWithBandingDPTable    DPTable;
+    typedef NucleotideIndel2AlignWithBandingBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::ForwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelchBanding (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the standard DP algorithms (amino acid with 2 sets of indel states).
+   */
+  class AminoAcidIndel2WithoutBanding {
+
+  public:
+  
+    typedef AminoAcidIndel2AlignDPTable    DPTable;
+    typedef AminoAcidIndel2AlignBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Forward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::Backward (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelch (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix);
+    }
+
+  };
+
+  /**
+   * \brief Accessor classes for the banded DP algorithms (amino acid with 2 sets of indel states).
+   */
+  class AminoAcidIndel2WithBanding {
+
+  public:
+
+    typedef AminoAcidIndel2AlignWithBandingDPTable    DPTable;
+    typedef AminoAcidIndel2AlignWithBandingBaumWelch  BaumWelchCounters;
+
+    static bfloat Forward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::ForwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat Backward (DPTable** ppOutTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBanding (ppOutTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+    static bfloat BackwardBaumWelch (BaumWelchCounters& bw, DPTable* pInTable, Params& params, const std::string& iSequence1, const std::string& iSequence2) {
+      return ::BackwardBaumWelchBanding (bw, pInTable, iSequence1, iSequence2, params.single_dist, params.pair_dist, params.transition_matrix, params.bandwidth);
+    }
+
+  };
+
+}
+
+#endif /* FSA_MODEL_INCLUDED */
diff --git a/src/fsa/mybanding.h b/src/fsa/mybanding.h
new file mode 100644
index 0000000..59fd1fa
--- /dev/null
+++ b/src/fsa/mybanding.h
@@ -0,0 +1,111 @@
+
+/*
+ *    This file is part of HMMoC 1.3, a hidden Markov model compiler.
+ *    Copyright (C) 2007 by Gerton Lunter, Oxford University.
+ *
+ *    HMMoC is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    HMMOC is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with HMMoC; if not, write to the Free Software
+ *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+\*/
+
+#ifndef MYBANDING_INCLUDED
+#define MYBANDING_INCLUDED
+
+#include <iostream>
+#include "fsa/dptables.h"
+
+using std::endl;
+using std::cout;
+using std::min;
+using std::max;
+
+// Implements a traversal of the dynamic programming table along a diagonal band.
+// The band should remain (diagonally) connected even if iWidth==1, and the forward
+// and backward iterations must visit the same sites - these two requirements made the
+// implementation slightly tricky.
+
+class MyBanding : Banding<2> {
+
+ private:
+
+  int iLen0, iLen1;
+  int iWidth;
+  Position pos;
+  int iLastRow;
+
+  int diagonal(int p1) { return (p1 * iLen0 + iLen1/2) / iLen1; }
+
+ public:
+
+  MyBanding( int iLen0, int iLen1, int iWidth ) : iLen0(iLen0), iLen1(iLen1), iWidth(iWidth) {}
+
+  Position& forwardIterator() {
+
+    pos[0] = pos[1] = 0;
+    iLastRow = iLen0;
+    return pos;
+
+  }
+
+  Position& backwardIterator() {
+
+    pos[0] = iLen0;
+    pos[1] = iLen1;
+    iLastRow = 0;
+    return pos;
+
+  }
+
+  bool hasNextForward() {
+
+    if (pos[0] < iLen0 && pos[0] < (iWidth-1)/2 + max( diagonal(pos[1]+1)-1, diagonal(pos[1]))) {
+      ++pos[0];
+      return true;
+    }
+    if (pos[1]<iLen1) {
+      ++pos[1];
+      pos[0] = max(0, diagonal(pos[1]) - iWidth/2);
+      return true;
+    }
+    return false;
+  }
+
+  bool hasNextBackward() {
+
+    if (pos[0] > 0 && pos[0] > diagonal(pos[1]) - iWidth/2) {
+      --pos[0];
+      return true;
+    }
+    if (pos[1]>0) {
+      --pos[1];
+      pos[0] = min(iLen0, (iWidth-1)/2 + max( diagonal(pos[1]+1)-1, diagonal(pos[1])));
+      return true;
+    }
+    return false;
+  }
+
+  bool lastColumnEntry() {
+
+    return pos[0] == iLastRow;
+
+  }
+
+  void warning() {
+
+    cout << "Warning - out of bounds at position (" << pos[0] << "," << pos[1] << ")" << endl;
+
+  }
+
+};
+
+#endif /* MYBANDING_INCLUDED */
diff --git a/src/fsa/nucleotide_indel2dp.cc b/src/fsa/nucleotide_indel2dp.cc
new file mode 100644
index 0000000..e85fad3
--- /dev/null
+++ b/src/fsa/nucleotide_indel2dp.cc
@@ -0,0 +1,2253 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file nucleotide_indel2.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:17 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include "nucleotide_indel2dp.h"
+
+#include "mybanding.h"
+
+const extern string _NucleotideIndel2AlignstateId[];
+const extern string _NucleotideIndel2AlignemissionId[];
+const extern string _NucleotideIndel2AligntransitionId[];
+const extern string _NucleotideIndel2AligntransF[];
+const extern string _NucleotideIndel2AligntransT[];
+const extern string _NucleotideIndel2AligntransP[];
+const extern string _NucleotideIndel2AligntransE[];
+const extern string _NucleotideIndel2AlignoutputId[];
+const extern string _NucleotideIndel2Alignempty;
+const extern int _NucleotideIndel2AlignstateNum;
+const extern int _NucleotideIndel2AlignemitNum;
+const extern int _NucleotideIndel2AligntransNum;
+const extern int _NucleotideIndel2AlignoutputNum;
+
+NucleotideIndel2AlignDPTable::NucleotideIndel2AlignDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignstateId), emissionId(_NucleotideIndel2AlignemissionId), transitionId(_NucleotideIndel2AligntransitionId), transitionFrom(_NucleotideIndel2AligntransF), transitionTo(_NucleotideIndel2AligntransT), transitionProb(_NucleotideIndel2AligntransP), transitionEmit(_NucleotideIndel2AligntransE), outputId(_NucleotideIndel2AlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucIndel2Block2.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucIndel2Block1.allocate();
+    StateMemorynucIndel2Block3.allocate();
+}
+
+
+NucleotideIndel2AlignDPTable::~NucleotideIndel2AlignDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucIndel2Block2.absolve();
+        StateMemorynucIndel2Block1.absolve();
+        StateMemorynucIndel2Block3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideIndel2AlignDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AligntransNum ? _NucleotideIndel2AligntransitionId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignemitNum ? _NucleotideIndel2AlignemissionId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignstateNum ? _NucleotideIndel2AlignstateId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignoutputNum ? _NucleotideIndel2AlignoutputId[id] : _NucleotideIndel2Alignempty; }
+int NucleotideIndel2AlignDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideIndel2AlignstateNum;i++) {
+            (*pmId)[_NucleotideIndel2AlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignemitNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AligntransNum; i++) {  
+            (*pmId)[_NucleotideIndel2AligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignoutputNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideIndel2AlignDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideIndel2AlignDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideIndel2AlignDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block2Secondary;
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
+            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block2Secondary = this->StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucIndel2Block2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
+            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _NucleotideIndel2AlignstateId[];
+const extern string _NucleotideIndel2AlignemissionId[];
+const extern string _NucleotideIndel2AligntransitionId[];
+const extern string _NucleotideIndel2AligntransF[];
+const extern string _NucleotideIndel2AligntransT[];
+const extern string _NucleotideIndel2AligntransP[];
+const extern string _NucleotideIndel2AligntransE[];
+const extern string _NucleotideIndel2AlignoutputId[];
+const extern string _NucleotideIndel2Alignempty;
+const extern int _NucleotideIndel2AlignstateNum;
+const extern int _NucleotideIndel2AlignemitNum;
+const extern int _NucleotideIndel2AligntransNum;
+const extern int _NucleotideIndel2AlignoutputNum;
+
+NucleotideIndel2AlignFoldedDPTable::NucleotideIndel2AlignFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignstateId), emissionId(_NucleotideIndel2AlignemissionId), transitionId(_NucleotideIndel2AligntransitionId), transitionFrom(_NucleotideIndel2AligntransF), transitionTo(_NucleotideIndel2AligntransT), transitionProb(_NucleotideIndel2AligntransP), transitionEmit(_NucleotideIndel2AligntransE), outputId(_NucleotideIndel2AlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucIndel2Block2.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucIndel2Block3.allocate();
+    StateMemorynucIndel2Block1.allocate();
+}
+
+
+NucleotideIndel2AlignFoldedDPTable::~NucleotideIndel2AlignFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucIndel2Block2.absolve();
+        StateMemorynucIndel2Block3.absolve();
+        StateMemorynucIndel2Block1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideIndel2AlignFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AligntransNum ? _NucleotideIndel2AligntransitionId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignemitNum ? _NucleotideIndel2AlignemissionId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignstateNum ? _NucleotideIndel2AlignstateId[id] : _NucleotideIndel2Alignempty; }
+const string& NucleotideIndel2AlignFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignoutputNum ? _NucleotideIndel2AlignoutputId[id] : _NucleotideIndel2Alignempty; }
+int NucleotideIndel2AlignFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideIndel2AlignstateNum;i++) {
+            (*pmId)[_NucleotideIndel2AlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignemitNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AligntransNum; i++) {  
+            (*pmId)[_NucleotideIndel2AligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignoutputNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideIndel2AlignFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideIndel2AlignFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideIndel2AlignFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block2Secondary;
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
+            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block2Secondary = this->StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucIndel2Block2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
+            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int NucleotideIndel2AlignBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideIndel2AlignBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int NucleotideIndel2AlignBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideIndel2AlignBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void NucleotideIndel2AlignBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
+        for (int i=0; i<23; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AligntransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int NucleotideIndel2AlignBaumWelch::transitionIdentifier00[];
+int NucleotideIndel2AlignBaumWelch::emissionIdentifier00[];
+int NucleotideIndel2AlignBaumWelch::emissionIdentifier01[];
+int NucleotideIndel2AlignBaumWelch::emissionIdentifier10[];
+int NucleotideIndel2AlignBaumWelch::emissionIdentifier11[];
+
+void NucleotideIndel2AlignBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> NucleotideIndel2AlignBaumWelch::mId;
+int NucleotideIndel2AlignBaumWelch::atransitionIdx[];
+int NucleotideIndel2AlignBaumWelch::aemissionIdx[];
+
+const extern string _NucleotideIndel2AlignWithBandingstateId[];
+const extern string _NucleotideIndel2AlignWithBandingemissionId[];
+const extern string _NucleotideIndel2AlignWithBandingtransitionId[];
+const extern string _NucleotideIndel2AlignWithBandingtransF[];
+const extern string _NucleotideIndel2AlignWithBandingtransT[];
+const extern string _NucleotideIndel2AlignWithBandingtransP[];
+const extern string _NucleotideIndel2AlignWithBandingtransE[];
+const extern string _NucleotideIndel2AlignWithBandingoutputId[];
+const extern string _NucleotideIndel2AlignWithBandingempty;
+const extern int _NucleotideIndel2AlignWithBandingstateNum;
+const extern int _NucleotideIndel2AlignWithBandingemitNum;
+const extern int _NucleotideIndel2AlignWithBandingtransNum;
+const extern int _NucleotideIndel2AlignWithBandingoutputNum;
+
+NucleotideIndel2AlignWithBandingDPTable::NucleotideIndel2AlignWithBandingDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignWithBandingstateId), emissionId(_NucleotideIndel2AlignWithBandingemissionId), transitionId(_NucleotideIndel2AlignWithBandingtransitionId), transitionFrom(_NucleotideIndel2AlignWithBandingtransF), transitionTo(_NucleotideIndel2AlignWithBandingtransT), transitionProb(_NucleotideIndel2AlignWithBandingtransP), transitionEmit(_NucleotideIndel2 [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucIndel2Block1.allocate();
+    StateMemorynucIndel2Block3.allocate();
+}
+
+
+NucleotideIndel2AlignWithBandingDPTable::~NucleotideIndel2AlignWithBandingDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucIndel2Block2withbanding.absolve();
+        StateMemorynucIndel2Block1.absolve();
+        StateMemorynucIndel2Block3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideIndel2AlignWithBandingDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingtransNum ? _NucleotideIndel2AlignWithBandingtransitionId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingemitNum ? _NucleotideIndel2AlignWithBandingemissionId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingstateNum ? _NucleotideIndel2AlignWithBandingstateId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingoutputNum ? _NucleotideIndel2AlignWithBandingoutputId[id] : _NucleotideIndel2AlignWithBandingempty; }
+int NucleotideIndel2AlignWithBandingDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideIndel2AlignWithBandingstateNum;i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingemitNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingtransNum; i++) {  
+            (*pmId)[_NucleotideIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingoutputNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideIndel2AlignWithBandingDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideIndel2AlignWithBandingDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideIndel2AlignWithBandingDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
+            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block2withbandingSecondary = this->StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucIndel2Block2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
+            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _NucleotideIndel2AlignWithBandingstateId[];
+const extern string _NucleotideIndel2AlignWithBandingemissionId[];
+const extern string _NucleotideIndel2AlignWithBandingtransitionId[];
+const extern string _NucleotideIndel2AlignWithBandingtransF[];
+const extern string _NucleotideIndel2AlignWithBandingtransT[];
+const extern string _NucleotideIndel2AlignWithBandingtransP[];
+const extern string _NucleotideIndel2AlignWithBandingtransE[];
+const extern string _NucleotideIndel2AlignWithBandingoutputId[];
+const extern string _NucleotideIndel2AlignWithBandingempty;
+const extern int _NucleotideIndel2AlignWithBandingstateNum;
+const extern int _NucleotideIndel2AlignWithBandingemitNum;
+const extern int _NucleotideIndel2AlignWithBandingtransNum;
+const extern int _NucleotideIndel2AlignWithBandingoutputNum;
+
+NucleotideIndel2AlignWithBandingFoldedDPTable::NucleotideIndel2AlignWithBandingFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideIndel2AlignWithBandingstateId), emissionId(_NucleotideIndel2AlignWithBandingemissionId), transitionId(_NucleotideIndel2AlignWithBandingtransitionId), transitionFrom(_NucleotideIndel2AlignWithBandingtransF), transitionTo(_NucleotideIndel2AlignWithBandingtransT), transitionProb(_NucleotideIndel2AlignWithBandingtransP), transitionEmit(_Nucl [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucIndel2Block2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucIndel2Block3.allocate();
+    StateMemorynucIndel2Block1.allocate();
+}
+
+
+NucleotideIndel2AlignWithBandingFoldedDPTable::~NucleotideIndel2AlignWithBandingFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucIndel2Block2withbanding.absolve();
+        StateMemorynucIndel2Block3.absolve();
+        StateMemorynucIndel2Block1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingtransNum ? _NucleotideIndel2AlignWithBandingtransitionId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingemitNum ? _NucleotideIndel2AlignWithBandingemissionId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingstateNum ? _NucleotideIndel2AlignWithBandingstateId[id] : _NucleotideIndel2AlignWithBandingempty; }
+const string& NucleotideIndel2AlignWithBandingFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideIndel2AlignWithBandingoutputNum ? _NucleotideIndel2AlignWithBandingoutputId[id] : _NucleotideIndel2AlignWithBandingempty; }
+int NucleotideIndel2AlignWithBandingFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideIndel2AlignWithBandingstateNum;i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingemitNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingtransNum; i++) {  
+            (*pmId)[_NucleotideIndel2AlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideIndel2AlignWithBandingoutputNum; i++) {
+            (*pmId)[_NucleotideIndel2AlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideIndel2AlignWithBandingFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideIndel2AlignWithBandingFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideIndel2AlignWithBandingFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 3, 4, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucIndel2Block1Secondary = this->StateMemorynucIndel2Block1.read();
+            return CurStateMemorynucIndel2Block1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block2withbandingSecondary = this->StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucIndel2Block2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucIndel2Block3Secondary = this->StateMemorynucIndel2Block3.read();
+            return CurStateMemorynucIndel2Block3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int NucleotideIndel2AlignWithBandingBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideIndel2AlignWithBandingBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int NucleotideIndel2AlignWithBandingBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideIndel2AlignWithBandingBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void NucleotideIndel2AlignWithBandingBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22};
+        for (int i=0; i<23; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignWithBandingtransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideIndel2AlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int NucleotideIndel2AlignWithBandingBaumWelch::transitionIdentifier00[];
+int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier00[];
+int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier01[];
+int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier10[];
+int NucleotideIndel2AlignWithBandingBaumWelch::emissionIdentifier11[];
+
+void NucleotideIndel2AlignWithBandingBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<23; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> NucleotideIndel2AlignWithBandingBaumWelch::mId;
+int NucleotideIndel2AlignWithBandingBaumWelch::atransitionIdx[];
+int NucleotideIndel2AlignWithBandingBaumWelch::aemissionIdx[];
+
+const string _NucleotideIndel2AlignstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
+const string _NucleotideIndel2AlignemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _NucleotideIndel2AligntransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
+const string _NucleotideIndel2AligntransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
+const string _NucleotideIndel2AligntransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
+const string _NucleotideIndel2AligntransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
+const string _NucleotideIndel2AligntransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _NucleotideIndel2AlignoutputId[] = {"sequence1","sequence2"};
+const string _NucleotideIndel2Alignempty = "";
+const int _NucleotideIndel2AlignstateNum = 7;
+const int _NucleotideIndel2AlignemitNum = 4;
+const int _NucleotideIndel2AligntransNum = 23;
+const int _NucleotideIndel2AlignoutputNum = 2;
+
+
+
+
+bfloat Forward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2To;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    const bfloat *CurStateMemorynucIndel2Block2From;
+    bfloat *CurStateMemorynucIndel2Block3To;
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideIndel2AlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemorynucIndel2Block1.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block1.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=0; iPos1<iLen2+1; ++iPos1) {
+        for (int iPos0=0; iPos0<iLen1+1; ++iPos0) {
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+            }
+            if (1) {
+                if ((iPos1+-1>=0)) {
+                    iSymbol[0] = iSequence2[iPos1+-1];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+-1>=0)) {
+                    iSymbol[1] = iSequence1[iPos0+-1];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+0<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                    CurStateMemorynucIndel2Block2To[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                    CurStateMemorynucIndel2Block2To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                }
+                if ((iPos1+-1>=0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(1))-(0));
+                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+0<=0)) {
+                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                    CurStateMemorynucIndel2Block2To[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                    CurStateMemorynucIndel2Block2To[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                }
+                if ((iPos0+-1>=0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                    CurStateMemorynucIndel2Block2To[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                }
+                if ((iPos0+-1>=0)&&(iPos1+-1>=0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(1))-(0), (iPos1-(1))-(0));
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                }
+                dp.StateMemorynucIndel2Block2.written();
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                CurStateMemorynucIndel2Block3To = dp.StateMemorynucIndel2Block3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block3To[0] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                }
+                dp.StateMemorynucIndel2Block3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block3From[0];
+        }
+    }
+    *ppOutTable = new NucleotideIndel2AlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelch(NucleotideIndel2AlignBaumWelch& bw,NucleotideIndel2AlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2To;
+    const bfloat *CurStateMemorynucIndel2Block2Secondary;
+    const bfloat *CurStateMemorynucIndel2Block2From;
+    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
+    unsigned char alphaIndexnucleotide[256];
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    bfloat *CurStateMemorynucIndel2Block1To;
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    NucleotideIndel2AlignFoldedDPTable dp(iLen1,2);
+    NucleotideIndel2AlignDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexnucleotide[i]=0;
+    }
+
+//    for (int i=0; i<4; i++) {
+//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
+//    }
+    for (int i=0; i<4; i++) {
+      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
+      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block3Secondary = dp2.StateMemorynucIndel2Block3.read();
+            iTempProb[2] = CurStateMemorynucIndel2Block3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if (iPrevSlowCoord != -1 && iPrevSlowCoord != iPos1) {
+                dp.StateMemorynucIndel2Block2.clear(iPos1);
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                CurStateMemorynucIndel2Block2Secondary = dp2.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block2To[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[15] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[21] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block2To[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[18] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block2To[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[14] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[17] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[20] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+                    CurStateMemorynucIndel2Block2To[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[2];
+                    bw.transitionBaumWelchCount00[13] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[1];
+                    bw.transitionBaumWelchCount00[16] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[4];
+                    bw.transitionBaumWelchCount00[19] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[0];
+                    bw.transitionBaumWelchCount00[22] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block2To[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block2Secondary[3];
+                    bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                }
+                dp.StateMemorynucIndel2Block2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
+                CurStateMemorynucIndel2Block1Secondary = dp2.StateMemorynucIndel2Block1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemorynucIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat Backward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2To;
+    const bfloat *CurStateMemorynucIndel2Block2From;
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    bfloat *CurStateMemorynucIndel2Block1To;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideIndel2AlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block2To = dp.StateMemorynucIndel2Block2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block2To[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    CurStateMemorynucIndel2Block2To[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                    CurStateMemorynucIndel2Block2To[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block2To[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                    CurStateMemorynucIndel2Block2To[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+                    CurStateMemorynucIndel2Block2To[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    CurStateMemorynucIndel2Block2To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    CurStateMemorynucIndel2Block2To[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    CurStateMemorynucIndel2Block2To[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    CurStateMemorynucIndel2Block2To[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                }
+                dp.StateMemorynucIndel2Block2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[0];
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[2];
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2From = dp.StateMemorynucIndel2Block2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2From[3];
+                }
+                dp.StateMemorynucIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
+        }
+    }
+    *ppOutTable = new NucleotideIndel2AlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+const string _NucleotideIndel2AlignWithBandingstateId[] = {"start","delete2","delete1","insert1","match","insert2","end"};
+const string _NucleotideIndel2AlignWithBandingemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _NucleotideIndel2AlignWithBandingtransitionId[] = {"trSM","trSI1","trSD1","trSI2","trSD2","trMM","trMI1","trMD1","trMI2","trMD2","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E","trI2M","trI2I2","trI2E","trD2M","trD2D2","trD2E"};
+const string _NucleotideIndel2AlignWithBandingtransF[] = {"start","start","start","start","start","match","match","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1","insert2","insert2","insert2","delete2","delete2","delete2"};
+const string _NucleotideIndel2AlignWithBandingtransT[] = {"match","insert1","delete1","insert2","delete2","match","insert1","delete1","insert2","delete2","end","match","insert1","end","match","delete1","end","match","insert2","end","match","delete2","end"};
+const string _NucleotideIndel2AlignWithBandingtransP[] = {"probSM","probSI1","probSD1","probSI2","probSD2","probMM","probMI1","probMD1","probMI2","probMD2","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E","probI2M","probI2I2","probI2E","probD2M","probD2D2","probD2E"};
+const string _NucleotideIndel2AlignWithBandingtransE[] = {"emit12","emit1","emit2","emit1","emit2","emit12","emit1","emit2","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _NucleotideIndel2AlignWithBandingoutputId[] = {"sequence1","sequence2"};
+const string _NucleotideIndel2AlignWithBandingempty = "";
+const int _NucleotideIndel2AlignWithBandingstateNum = 7;
+const int _NucleotideIndel2AlignWithBandingemitNum = 4;
+const int _NucleotideIndel2AlignWithBandingtransNum = 23;
+const int _NucleotideIndel2AlignWithBandingoutputNum = 2;
+
+
+
+
+bfloat ForwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
+    bfloat *CurStateMemorynucIndel2Block3To;
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemorynucIndel2Block1.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block1.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.forwardIterator();
+        bool bLastSlowCoordInited = false;
+        int iLastSlowCoord = -1;  
+        do {
+            if (bLastSlowCoordInited) {
+                if (iLastSlowCoord > position[1]) {
+                    cout << "WARNING: Banding (forward): Slowest coordinate should be nondecreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+                }
+                } else {
+                bLastSlowCoordInited = true;
+            }
+            iLastSlowCoord = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+-1>=0)) {
+                        iSymbol[0] = iSequence2[position[1]+-1];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+-1>=0)) {
+                        iSymbol[1] = iSequence1[position[0]+-1];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+0<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                        CurStateMemorynucIndel2Block2withbandingTo[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                    }
+                    if ((position[1]+-1>=0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+0<=0)) {
+                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                        CurStateMemorynucIndel2Block2withbandingTo[2] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                    }
+                    if ((position[0]+-1>=0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+                        CurStateMemorynucIndel2Block2withbandingTo[3] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block1From[0];
+                    }
+                    if ((position[0]+-1>=0)&&(position[1]+-1>=0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(1))-(0), (position[1]-(1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                    }
+                    dp.StateMemorynucIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextForward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                CurStateMemorynucIndel2Block3To = dp.StateMemorynucIndel2Block3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block3To[0] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                    CurStateMemorynucIndel2Block3To[0] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                }
+                dp.StateMemorynucIndel2Block3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block3From[0];
+        }
+    }
+    *ppOutTable = new NucleotideIndel2AlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelchBanding(NucleotideIndel2AlignWithBandingBaumWelch& bw,NucleotideIndel2AlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    const bfloat *CurStateMemorynucIndel2Block3Secondary;
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingSecondary;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
+    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
+    unsigned char alphaIndexnucleotide[256];
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    bfloat *CurStateMemorynucIndel2Block1To;
+    const bfloat *CurStateMemorynucIndel2Block1Secondary;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    NucleotideIndel2AlignWithBandingFoldedDPTable dp(iLen1,2);
+    NucleotideIndel2AlignWithBandingDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexnucleotide[i]=0;
+    }
+
+//    for (int i=0; i<4; i++) {
+//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
+//    }
+    for (int i=0; i<4; i++) {
+      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
+      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block3Secondary = dp2.StateMemorynucIndel2Block3.read();
+            iTempProb[2] = CurStateMemorynucIndel2Block3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (iPrevSlowCoord != -1 && iPrevSlowCoord != position[1]) {
+                    dp.StateMemorynucIndel2Block2withbanding.clear(position[1]);
+                }
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    CurStateMemorynucIndel2Block2withbandingSecondary = dp2.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[0] = iTempProb[1] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[21] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] = iTempProb[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[15] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] = iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[4] = iTempProb[1] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[18] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] = iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[20] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[14] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[17] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[3];
+                        bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += iTempProb[1] = ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[22] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += iTempProb[1] = ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[16] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += iTempProb[1] = ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[13] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += iTempProb[1] = ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        iTempProb[1] *= CurStateMemorynucIndel2Block2withbandingSecondary[4];
+                        bw.transitionBaumWelchCount00[19] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    }
+                    dp.StateMemorynucIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
+                CurStateMemorynucIndel2Block1Secondary = dp2.StateMemorynucIndel2Block1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                    iTempProb[1] *= CurStateMemorynucIndel2Block1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemorynucIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[23];
+    bfloat *CurStateMemorynucIndel2Block2withbandingTo;
+    const bfloat *CurStateMemorynucIndel2Block2withbandingFrom;
+    const bfloat *CurStateMemorynucIndel2Block3From;
+    bfloat *CurStateMemorynucIndel2Block1To;
+    const bfloat *CurStateMemorynucIndel2Block1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideIndel2AlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[0][4];
+    
+    iTransition[4] = iT[0][5];
+    
+    iTransition[5] = iT[1][1];
+    
+    iTransition[6] = iT[1][2];
+    
+    iTransition[7] = iT[1][3];
+    
+    iTransition[8] = iT[1][4];
+    
+    iTransition[9] = iT[1][5];
+    
+    iTransition[10] = iT[1][6];
+    
+    iTransition[11] = iT[2][1];
+    
+    iTransition[12] = iT[2][2];
+    
+    iTransition[13] = iT[2][6];
+    
+    iTransition[14] = iT[3][1];
+    
+    iTransition[15] = iT[3][3];
+    
+    iTransition[16] = iT[3][6];
+    
+    iTransition[17] = iT[4][1];
+    
+    iTransition[18] = iT[4][4];
+    
+    iTransition[19] = iT[4][6];
+    
+    iTransition[20] = iT[5][1];
+    
+    iTransition[21] = iT[5][5];
+    
+    iTransition[22] = iT[5][6];
+    dp.StateMemorynucIndel2Block3.write()[0] = 1.0;
+    dp.StateMemorynucIndel2Block3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucIndel2Block2withbandingTo = dp.StateMemorynucIndel2Block2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[3] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] = ((iTransition[21])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] = ((iTransition[15])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] = ((iTransition[18])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[20])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[14])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[17])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemorynucIndel2Block3From = dp.StateMemorynucIndel2Block3.read();
+                        CurStateMemorynucIndel2Block2withbandingTo[3] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[0] += ((iTransition[22])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[2] += ((iTransition[13])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[1] += ((iTransition[16])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                        CurStateMemorynucIndel2Block2withbandingTo[4] += ((iTransition[19])*(iEmission[0]))*CurStateMemorynucIndel2Block3From[0];
+                    }
+                    dp.StateMemorynucIndel2Block2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucIndel2Block1To = dp.StateMemorynucIndel2Block1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[0];
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[2])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[2];
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[4];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucIndel2Block2withbandingFrom = dp.StateMemorynucIndel2Block2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucIndel2Block1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucIndel2Block2withbandingFrom[3];
+                }
+                dp.StateMemorynucIndel2Block1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucIndel2Block1From = dp.StateMemorynucIndel2Block1.read();
+            iTempProb[0] = CurStateMemorynucIndel2Block1From[0];
+        }
+    }
+    *ppOutTable = new NucleotideIndel2AlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/nucleotide_indel2dp.h b/src/fsa/nucleotide_indel2dp.h
new file mode 100644
index 0000000..9a771ca
--- /dev/null
+++ b/src/fsa/nucleotide_indel2dp.h
@@ -0,0 +1,315 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file nucleotide_indel2.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:17 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _nucleotide_indel2dp_h_
+#define _nucleotide_indel2dp_h_
+
+
+#include "dptables.h"
+#include "algebras.h"
+#include <string>
+
+#include <map>
+
+using std::map;
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesnucIndel2Block2;
+typedef States<bfloat,1> StatesnucIndel2Block1;
+typedef States<bfloat,1> StatesnucIndel2Block3;
+
+class NucleotideIndel2AlignDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesnucIndel2Block2,2> StateMemorynucIndel2Block2;
+    DPTable<StatesnucIndel2Block1,0> StateMemorynucIndel2Block1;
+    DPTable<StatesnucIndel2Block3,0> StateMemorynucIndel2Block3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideIndel2AlignDPTable(int iLen1,int iLen2);
+    ~NucleotideIndel2AlignDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat NucleotideIndel2AlignReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double NucleotideIndel2AlignShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesnucIndel2Block2;
+typedef States<bfloat,1> StatesnucIndel2Block3;
+typedef States<bfloat,1> StatesnucIndel2Block1;
+
+class NucleotideIndel2AlignFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesnucIndel2Block2,2> StateMemorynucIndel2Block2;
+    DPTable<StatesnucIndel2Block3,0> StateMemorynucIndel2Block3;
+    DPTable<StatesnucIndel2Block1,0> StateMemorynucIndel2Block1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideIndel2AlignFoldedDPTable(int iLen1,int iLen2);
+    ~NucleotideIndel2AlignFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class NucleotideIndel2AlignBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    NucleotideIndel2AlignBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[23];
+    static int transitionIdentifier00[23];   
+    static const int transitionDimension00 = 23;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[4][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[4][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[4][4][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[23];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesnucIndel2Block2withbanding;
+typedef States<bfloat,1> StatesnucIndel2Block1;
+typedef States<bfloat,1> StatesnucIndel2Block3;
+
+class NucleotideIndel2AlignWithBandingDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesnucIndel2Block2withbanding,2> StateMemorynucIndel2Block2withbanding;
+    DPTable<StatesnucIndel2Block1,0> StateMemorynucIndel2Block1;
+    DPTable<StatesnucIndel2Block3,0> StateMemorynucIndel2Block3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideIndel2AlignWithBandingDPTable(int iLen1,int iLen2);
+    ~NucleotideIndel2AlignWithBandingDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat NucleotideIndel2AlignWithBandingReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double NucleotideIndel2AlignWithBandingShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,5> StatesnucIndel2Block2withbanding;
+typedef States<bfloat,1> StatesnucIndel2Block3;
+typedef States<bfloat,1> StatesnucIndel2Block1;
+
+class NucleotideIndel2AlignWithBandingFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesnucIndel2Block2withbanding,2> StateMemorynucIndel2Block2withbanding;
+    DPTable<StatesnucIndel2Block3,0> StateMemorynucIndel2Block3;
+    DPTable<StatesnucIndel2Block1,0> StateMemorynucIndel2Block1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideIndel2AlignWithBandingFoldedDPTable(int iLen1,int iLen2);
+    ~NucleotideIndel2AlignWithBandingFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class NucleotideIndel2AlignWithBandingBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    NucleotideIndel2AlignWithBandingBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[23];
+    static int transitionIdentifier00[23];   
+    static const int transitionDimension00 = 23;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[4][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[4][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[4][4][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[23];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+bfloat Forward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat BackwardBaumWelch(NucleotideIndel2AlignBaumWelch& bw,NucleotideIndel2AlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat Backward(NucleotideIndel2AlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat ForwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBaumWelchBanding(NucleotideIndel2AlignWithBandingBaumWelch& bw,NucleotideIndel2AlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBanding(NucleotideIndel2AlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+#endif // _nucleotide_indel2dp_h_
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/nucleotidedp.cc b/src/fsa/nucleotidedp.cc
new file mode 100644
index 0000000..5b1ff4c
--- /dev/null
+++ b/src/fsa/nucleotidedp.cc
@@ -0,0 +1,2013 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file nucleotide.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:16 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+
+#include "nucleotidedp.h"
+
+#include "mybanding.h"
+
+const extern string _NucleotideAlignstateId[];
+const extern string _NucleotideAlignemissionId[];
+const extern string _NucleotideAligntransitionId[];
+const extern string _NucleotideAligntransF[];
+const extern string _NucleotideAligntransT[];
+const extern string _NucleotideAligntransP[];
+const extern string _NucleotideAligntransE[];
+const extern string _NucleotideAlignoutputId[];
+const extern string _NucleotideAlignempty;
+const extern int _NucleotideAlignstateNum;
+const extern int _NucleotideAlignemitNum;
+const extern int _NucleotideAligntransNum;
+const extern int _NucleotideAlignoutputNum;
+
+NucleotideAlignDPTable::NucleotideAlignDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideAlignstateId), emissionId(_NucleotideAlignemissionId), transitionId(_NucleotideAligntransitionId), transitionFrom(_NucleotideAligntransF), transitionTo(_NucleotideAligntransT), transitionProb(_NucleotideAligntransP), transitionEmit(_NucleotideAligntransE), outputId(_NucleotideAlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucBlock2.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucBlock1.allocate();
+    StateMemorynucBlock3.allocate();
+}
+
+
+NucleotideAlignDPTable::~NucleotideAlignDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucBlock2.absolve();
+        StateMemorynucBlock1.absolve();
+        StateMemorynucBlock3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideAlignDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideAligntransNum ? _NucleotideAligntransitionId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideAlignemitNum ? _NucleotideAlignemissionId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignDPTable::getStateId(int id) { return id>=0 && id<_NucleotideAlignstateNum ? _NucleotideAlignstateId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideAlignoutputNum ? _NucleotideAlignoutputId[id] : _NucleotideAlignempty; }
+int NucleotideAlignDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideAlignstateNum;i++) {
+            (*pmId)[_NucleotideAlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideAlignemitNum; i++) {
+            (*pmId)[_NucleotideAlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideAligntransNum; i++) {  
+            (*pmId)[_NucleotideAligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideAlignoutputNum; i++) {
+            (*pmId)[_NucleotideAlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideAlignDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideAlignDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideAlignDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock2Secondary;
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucBlock1Secondary = this->StateMemorynucBlock1.read();
+            return CurStateMemorynucBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock2Secondary = this->StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucBlock2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock3Secondary = this->StateMemorynucBlock3.read();
+            return CurStateMemorynucBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _NucleotideAlignstateId[];
+const extern string _NucleotideAlignemissionId[];
+const extern string _NucleotideAligntransitionId[];
+const extern string _NucleotideAligntransF[];
+const extern string _NucleotideAligntransT[];
+const extern string _NucleotideAligntransP[];
+const extern string _NucleotideAligntransE[];
+const extern string _NucleotideAlignoutputId[];
+const extern string _NucleotideAlignempty;
+const extern int _NucleotideAlignstateNum;
+const extern int _NucleotideAlignemitNum;
+const extern int _NucleotideAligntransNum;
+const extern int _NucleotideAlignoutputNum;
+
+NucleotideAlignFoldedDPTable::NucleotideAlignFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideAlignstateId), emissionId(_NucleotideAlignemissionId), transitionId(_NucleotideAligntransitionId), transitionFrom(_NucleotideAligntransF), transitionTo(_NucleotideAligntransT), transitionProb(_NucleotideAligntransP), transitionEmit(_NucleotideAligntransE), outputId(_NucleotideAlignoutputId) {
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucBlock2.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucBlock3.allocate();
+    StateMemorynucBlock1.allocate();
+}
+
+
+NucleotideAlignFoldedDPTable::~NucleotideAlignFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucBlock2.absolve();
+        StateMemorynucBlock3.absolve();
+        StateMemorynucBlock1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideAlignFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideAligntransNum ? _NucleotideAligntransitionId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideAlignemitNum ? _NucleotideAlignemissionId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideAlignstateNum ? _NucleotideAlignstateId[id] : _NucleotideAlignempty; }
+const string& NucleotideAlignFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideAlignoutputNum ? _NucleotideAlignoutputId[id] : _NucleotideAlignempty; }
+int NucleotideAlignFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideAlignstateNum;i++) {
+            (*pmId)[_NucleotideAlignstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideAlignemitNum; i++) {
+            (*pmId)[_NucleotideAlignemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideAligntransNum; i++) {  
+            (*pmId)[_NucleotideAligntransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideAlignoutputNum; i++) {
+            (*pmId)[_NucleotideAlignoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideAlignFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideAlignFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideAlignFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock2Secondary;
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucBlock1Secondary = this->StateMemorynucBlock1.read();
+            return CurStateMemorynucBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock2Secondary = this->StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucBlock2Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock3Secondary = this->StateMemorynucBlock3.read();
+            return CurStateMemorynucBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int NucleotideAlignBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideAlignBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int NucleotideAlignBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideAlignBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void NucleotideAlignBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+        for (int i=0; i<13; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_NucleotideAligntransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int NucleotideAlignBaumWelch::transitionIdentifier00[];
+int NucleotideAlignBaumWelch::emissionIdentifier00[];
+int NucleotideAlignBaumWelch::emissionIdentifier01[];
+int NucleotideAlignBaumWelch::emissionIdentifier10[];
+int NucleotideAlignBaumWelch::emissionIdentifier11[];
+
+void NucleotideAlignBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> NucleotideAlignBaumWelch::mId;
+int NucleotideAlignBaumWelch::atransitionIdx[];
+int NucleotideAlignBaumWelch::aemissionIdx[];
+
+const extern string _NucleotideAlignWithBandingstateId[];
+const extern string _NucleotideAlignWithBandingemissionId[];
+const extern string _NucleotideAlignWithBandingtransitionId[];
+const extern string _NucleotideAlignWithBandingtransF[];
+const extern string _NucleotideAlignWithBandingtransT[];
+const extern string _NucleotideAlignWithBandingtransP[];
+const extern string _NucleotideAlignWithBandingtransE[];
+const extern string _NucleotideAlignWithBandingoutputId[];
+const extern string _NucleotideAlignWithBandingempty;
+const extern int _NucleotideAlignWithBandingstateNum;
+const extern int _NucleotideAlignWithBandingemitNum;
+const extern int _NucleotideAlignWithBandingtransNum;
+const extern int _NucleotideAlignWithBandingoutputNum;
+
+NucleotideAlignWithBandingDPTable::NucleotideAlignWithBandingDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideAlignWithBandingstateId), emissionId(_NucleotideAlignWithBandingemissionId), transitionId(_NucleotideAlignWithBandingtransitionId), transitionFrom(_NucleotideAlignWithBandingtransF), transitionTo(_NucleotideAlignWithBandingtransT), transitionProb(_NucleotideAlignWithBandingtransP), transitionEmit(_NucleotideAlignWithBandingtransE), outputId(_NucleotideAlignWith [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucBlock2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucBlock1.allocate();
+    StateMemorynucBlock3.allocate();
+}
+
+
+NucleotideAlignWithBandingDPTable::~NucleotideAlignWithBandingDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucBlock2withbanding.absolve();
+        StateMemorynucBlock1.absolve();
+        StateMemorynucBlock3.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideAlignWithBandingDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideAlignWithBandingtransNum ? _NucleotideAlignWithBandingtransitionId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideAlignWithBandingemitNum ? _NucleotideAlignWithBandingemissionId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingDPTable::getStateId(int id) { return id>=0 && id<_NucleotideAlignWithBandingstateNum ? _NucleotideAlignWithBandingstateId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideAlignWithBandingoutputNum ? _NucleotideAlignWithBandingoutputId[id] : _NucleotideAlignWithBandingempty; }
+int NucleotideAlignWithBandingDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideAlignWithBandingstateNum;i++) {
+            (*pmId)[_NucleotideAlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingemitNum; i++) {
+            (*pmId)[_NucleotideAlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingtransNum; i++) {  
+            (*pmId)[_NucleotideAlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingoutputNum; i++) {
+            (*pmId)[_NucleotideAlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideAlignWithBandingDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideAlignWithBandingDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideAlignWithBandingDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock2withbandingSecondary;
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucBlock1Secondary = this->StateMemorynucBlock1.read();
+            return CurStateMemorynucBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock2withbandingSecondary = this->StateMemorynucBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucBlock2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock3Secondary = this->StateMemorynucBlock3.read();
+            return CurStateMemorynucBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+const extern string _NucleotideAlignWithBandingstateId[];
+const extern string _NucleotideAlignWithBandingemissionId[];
+const extern string _NucleotideAlignWithBandingtransitionId[];
+const extern string _NucleotideAlignWithBandingtransF[];
+const extern string _NucleotideAlignWithBandingtransT[];
+const extern string _NucleotideAlignWithBandingtransP[];
+const extern string _NucleotideAlignWithBandingtransE[];
+const extern string _NucleotideAlignWithBandingoutputId[];
+const extern string _NucleotideAlignWithBandingempty;
+const extern int _NucleotideAlignWithBandingstateNum;
+const extern int _NucleotideAlignWithBandingemitNum;
+const extern int _NucleotideAlignWithBandingtransNum;
+const extern int _NucleotideAlignWithBandingoutputNum;
+
+NucleotideAlignWithBandingFoldedDPTable::NucleotideAlignWithBandingFoldedDPTable(int iLen1,int iLen2) : isInCharge(true), stateId(_NucleotideAlignWithBandingstateId), emissionId(_NucleotideAlignWithBandingemissionId), transitionId(_NucleotideAlignWithBandingtransitionId), transitionFrom(_NucleotideAlignWithBandingtransF), transitionTo(_NucleotideAlignWithBandingtransT), transitionProb(_NucleotideAlignWithBandingtransP), transitionEmit(_NucleotideAlignWithBandingtransE), outputId(_Nucleot [...]
+    // init code:
+    this->iLen1 = iLen1;
+    this->iLen2 = iLen2;
+    StateMemorynucBlock2withbanding.allocate(1+iLen1, 1+iLen2);
+    StateMemorynucBlock3.allocate();
+    StateMemorynucBlock1.allocate();
+}
+
+
+NucleotideAlignWithBandingFoldedDPTable::~NucleotideAlignWithBandingFoldedDPTable() {
+    if (!isInCharge) {
+        // make sure data does not get deleted:
+        StateMemorynucBlock2withbanding.absolve();
+        StateMemorynucBlock3.absolve();
+        StateMemorynucBlock1.absolve();
+    } // if(!isInCharge)
+} // destructor
+
+const string& NucleotideAlignWithBandingFoldedDPTable::getTransitionId(int id) { return id>=0 && id<_NucleotideAlignWithBandingtransNum ? _NucleotideAlignWithBandingtransitionId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingFoldedDPTable::getEmissionId(int id) { return id>=0 && id<_NucleotideAlignWithBandingemitNum ? _NucleotideAlignWithBandingemissionId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingFoldedDPTable::getStateId(int id) { return id>=0 && id<_NucleotideAlignWithBandingstateNum ? _NucleotideAlignWithBandingstateId[id] : _NucleotideAlignWithBandingempty; }
+const string& NucleotideAlignWithBandingFoldedDPTable::getOutputId(int id) { return id>=0 && id<_NucleotideAlignWithBandingoutputNum ? _NucleotideAlignWithBandingoutputId[id] : _NucleotideAlignWithBandingempty; }
+int NucleotideAlignWithBandingFoldedDPTable::getId(const string& sId)
+{
+    static bool bInit = false;
+    static map<string,int>* pmId;
+    if (!bInit) {
+        pmId = new map<string,int>();
+        for (int i=0;i<_NucleotideAlignWithBandingstateNum;i++) {
+            (*pmId)[_NucleotideAlignWithBandingstateId[i]] = i;         // add state identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingemitNum; i++) {
+            (*pmId)[_NucleotideAlignWithBandingemissionId[i]] = i;      // add emission identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingtransNum; i++) {  
+            (*pmId)[_NucleotideAlignWithBandingtransitionId[i]] = i;    // add transition identifiers
+        }
+        for (int i=0; i<_NucleotideAlignWithBandingoutputNum; i++) {
+            (*pmId)[_NucleotideAlignWithBandingoutputId[i]] = i;        // finally, add output identifiers
+        }
+        bInit = true;
+    }
+    map<string,int>::iterator iter = pmId->find(sId);
+    if (iter == pmId->end()) {
+        if (sId == "_cleanup_") {
+            delete pmId;
+            } else {
+            cout << "NucleotideAlignWithBandingFoldedDPTable::getId: WARNING: identifier '" << sId << "' not found." << endl;
+        }
+        return -1;
+    }
+    return iter->second;
+}
+
+
+bfloat NucleotideAlignWithBandingFoldedDPTable::getProb(const string sState ,int iPos0,int iPos1) const
+{
+    return getProb(getId(sState) ,iPos0,iPos1);
+}
+
+
+bfloat NucleotideAlignWithBandingFoldedDPTable::getProb(int iState ,int iPos0,int iPos1) const
+{
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock2withbandingSecondary;
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    static const int blockTable[] = {0, 1, 1, 1, 2};
+    static const int stateTable[] = {0, 0, 1, 2, 0};
+    switch (blockTable[iState]) {
+        default:
+        return 0.0;
+        break;
+        case 0:
+        if ((iPos0+0>=0)&&(iPos0+0<=0)&&(iPos1+0>=0)&&(iPos1+0<=0)) {
+            CurStateMemorynucBlock1Secondary = this->StateMemorynucBlock1.read();
+            return CurStateMemorynucBlock1Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 1:
+        if ((iPos0+0>=0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock2withbandingSecondary = this->StateMemorynucBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+            return CurStateMemorynucBlock2withbandingSecondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+        break;
+        case 2:
+        if ((iPos0+0>=iLen1+0)&&(iPos0+0<=iLen1+0)&&(iPos1+0>=iLen2+0)&&(iPos1+0<=iLen2+0)) {
+            CurStateMemorynucBlock3Secondary = this->StateMemorynucBlock3.read();
+            return CurStateMemorynucBlock3Secondary[stateTable[iState]];
+        } 
+        else { 
+            return 0.0;
+            
+        }
+    } // switch
+} // DPTable...::getProb(int,...)
+
+int NucleotideAlignWithBandingBaumWelch::transitionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideAlignWithBandingBaumWelch::transitionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+int NucleotideAlignWithBandingBaumWelch::emissionIndex(string strId) const {
+    map<const string,int>::const_iterator iter = mId.find(strId);
+    if (iter == mId.end()) {
+        cout << "NucleotideAlignWithBandingBaumWelch::emissionIndex: WARNING: identifier '" << strId << "' not found." << endl;
+        return -1;
+    }
+    return iter->second;
+}
+
+
+void NucleotideAlignWithBandingBaumWelch::resetCounts() {
+    static bool bInited = false;
+    if (!bInited) {
+        static const int aTemp[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+        for (int i=0; i<13; i++) {
+            transitionIdentifier00[i] = aTemp[i];
+            atransitionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignWithBandingtransitionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {2};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier00[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {1};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier01[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {3};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier10[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] = 0.0;
+    }
+    if (!bInited) {
+        static const int aTemp[] = {0};
+        for (int i=0; i<1; i++) {
+            emissionIdentifier11[i] = aTemp[i];
+            aemissionIdx[aTemp[i]] = i;
+            mId[_NucleotideAlignWithBandingemissionId[aTemp[i]]] = i;
+        }
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] = 0.0;
+    }
+    bInited = true;
+};
+
+
+int NucleotideAlignWithBandingBaumWelch::transitionIdentifier00[];
+int NucleotideAlignWithBandingBaumWelch::emissionIdentifier00[];
+int NucleotideAlignWithBandingBaumWelch::emissionIdentifier01[];
+int NucleotideAlignWithBandingBaumWelch::emissionIdentifier10[];
+int NucleotideAlignWithBandingBaumWelch::emissionIdentifier11[];
+
+void NucleotideAlignWithBandingBaumWelch::scaleCounts(bfloat scale) {
+    for (int i=0; i<13; i++) {
+        
+        transitionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        
+        emissionBaumWelchCount00[i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount01[v10][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)
+        emissionBaumWelchCount10[v00][i] *= scale;
+    }
+    for (int i=0; i<1; i++) {
+        for(int v00=0;v00<4;v00++)for(int v10=0;v10<4;v10++)
+        emissionBaumWelchCount11[v00][v10][i] *= scale;
+    }
+}
+
+
+map<const string,int> NucleotideAlignWithBandingBaumWelch::mId;
+int NucleotideAlignWithBandingBaumWelch::atransitionIdx[];
+int NucleotideAlignWithBandingBaumWelch::aemissionIdx[];
+
+const string _NucleotideAlignstateId[] = {"start","insert1","match","delete1","end"};
+const string _NucleotideAlignemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _NucleotideAligntransitionId[] = {"trSM","trSI1","trSD1","trMM","trMI1","trMD1","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E"};
+const string _NucleotideAligntransF[] = {"start","start","start","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1"};
+const string _NucleotideAligntransT[] = {"match","insert1","delete1","match","insert1","delete1","end","match","insert1","end","match","delete1","end"};
+const string _NucleotideAligntransP[] = {"probSM","probSI1","probSD1","probMM","probMI1","probMD1","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E"};
+const string _NucleotideAligntransE[] = {"emit12","emit1","emit2","emit12","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _NucleotideAlignoutputId[] = {"sequence1","sequence2"};
+const string _NucleotideAlignempty = "";
+const int _NucleotideAlignstateNum = 5;
+const int _NucleotideAlignemitNum = 4;
+const int _NucleotideAligntransNum = 13;
+const int _NucleotideAlignoutputNum = 2;
+
+
+
+
+bfloat Forward(NucleotideAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2To;
+    const bfloat *CurStateMemorynucBlock1From;
+    const bfloat *CurStateMemorynucBlock2From;
+    bfloat *CurStateMemorynucBlock3To;
+    const bfloat *CurStateMemorynucBlock3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideAlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemorynucBlock1.write()[0] = 1.0;
+    dp.StateMemorynucBlock1.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=0; iPos1<iLen2+1; ++iPos1) {
+        for (int iPos0=0; iPos0<iLen1+1; ++iPos0) {
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+            }
+            if (1) {
+                if ((iPos1+-1>=0)) {
+                    iSymbol[0] = iSequence2[iPos1+-1];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+-1>=0)) {
+                    iSymbol[1] = iSequence1[iPos0+-1];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock2To = dp.StateMemorynucBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+0<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                    CurStateMemorynucBlock2To[2] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                }
+                if ((iPos1+-1>=0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(1))-(0));
+                    CurStateMemorynucBlock2To[2] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock2To[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+0<=0)) {
+                    CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                    CurStateMemorynucBlock2To[0] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                }
+                if ((iPos0+-1>=0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock2To[0] += ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock2To[0] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+-1>=0)&&(iPos0+-1<=0)&&(iPos1+-1>=0)&&(iPos1+-1<=0)) {
+                    CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                    CurStateMemorynucBlock2To[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                }
+                if ((iPos0+-1>=0)&&(iPos1+-1>=0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(1))-(0), (iPos1-(1))-(0));
+                    CurStateMemorynucBlock2To[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock2To[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    CurStateMemorynucBlock2To[1] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                }
+                dp.StateMemorynucBlock2.written();
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                CurStateMemorynucBlock3To = dp.StateMemorynucBlock3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock3To[0] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock3To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    CurStateMemorynucBlock3To[0] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                }
+                dp.StateMemorynucBlock3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+            iTempProb[0] = CurStateMemorynucBlock3From[0];
+        }
+    }
+    *ppOutTable = new NucleotideAlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelch(NucleotideAlignBaumWelch& bw,NucleotideAlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2To;
+    const bfloat *CurStateMemorynucBlock2Secondary;
+    const bfloat *CurStateMemorynucBlock2From;
+    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
+    unsigned char alphaIndexnucleotide[256];
+    const bfloat *CurStateMemorynucBlock3From;
+    bfloat *CurStateMemorynucBlock1To;
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    NucleotideAlignFoldedDPTable dp(iLen1,2);
+    NucleotideAlignDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexnucleotide[i]=0;
+    }
+
+//    for (int i=0; i<4; i++) {
+//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
+//    }
+    for (int i=0; i<4; i++) {
+      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
+      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemorynucBlock3.write()[0] = 1.0;
+    dp.StateMemorynucBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock3Secondary = dp2.StateMemorynucBlock3.read();
+            iTempProb[2] = CurStateMemorynucBlock3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if (iPrevSlowCoord != -1 && iPrevSlowCoord != iPos1) {
+                dp.StateMemorynucBlock2.clear(iPos1);
+            }
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock2To = dp.StateMemorynucBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                CurStateMemorynucBlock2Secondary = dp2.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock2To[2] = iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[1] = iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock2To[0] = iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[1] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock2To[2] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[0] += iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[1] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+                    CurStateMemorynucBlock2To[2] += iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[2];
+                    bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[0] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[0];
+                    bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    CurStateMemorynucBlock2To[1] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock2Secondary[1];
+                    bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                    bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                }
+                dp.StateMemorynucBlock2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock1To = dp.StateMemorynucBlock1.write();
+                CurStateMemorynucBlock1Secondary = dp2.StateMemorynucBlock1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemorynucBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+            iTempProb[0] = CurStateMemorynucBlock1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat Backward(NucleotideAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2To;
+    const bfloat *CurStateMemorynucBlock2From;
+    const bfloat *CurStateMemorynucBlock3From;
+    bfloat *CurStateMemorynucBlock1To;
+    const bfloat *CurStateMemorynucBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideAlignDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemorynucBlock3.write()[0] = 1.0;
+    dp.StateMemorynucBlock3.written();
+    iPrevSlowCoord = -1;
+    for (int iPos1=(iLen2+1)-1; iPos1>=0; --iPos1) {
+        for (int iPos0=(iLen1+1)-1; iPos0>=0; --iPos0) {
+            if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+            }
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock2To = dp.StateMemorynucBlock2.write((iPos0-(0))-(0), (iPos1-(0))-(0));
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock2To[2] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                    CurStateMemorynucBlock2To[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock2To[0] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                    CurStateMemorynucBlock2To[1] += ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock2To[2] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock2To[0] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                    CurStateMemorynucBlock2To[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                }
+                iEmission[0] = 1.0;
+                if ((iPos0+0>=iLen1+0)&&(iPos1+0>=iLen2+0)) {
+                    CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+                    CurStateMemorynucBlock2To[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    CurStateMemorynucBlock2To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    CurStateMemorynucBlock2To[1] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                }
+                dp.StateMemorynucBlock2.written();
+            }
+            if ((iPos0+0<=0)&&(iPos1+0<=0)) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock1To = dp.StateMemorynucBlock1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock2From[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock2From[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2From = dp.StateMemorynucBlock2.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock2From[1];
+                }
+                dp.StateMemorynucBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+            iTempProb[0] = CurStateMemorynucBlock1From[0];
+        }
+    }
+    *ppOutTable = new NucleotideAlignDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+const string _NucleotideAlignWithBandingstateId[] = {"start","insert1","match","delete1","end"};
+const string _NucleotideAlignWithBandingemissionId[] = {"emit12","emit2","empty","emit1"};
+const string _NucleotideAlignWithBandingtransitionId[] = {"trSM","trSI1","trSD1","trMM","trMI1","trMD1","trME","trI1M","trI1I1","trI1E","trD1M","trD1D1","trD1E"};
+const string _NucleotideAlignWithBandingtransF[] = {"start","start","start","match","match","match","match","insert1","insert1","insert1","delete1","delete1","delete1"};
+const string _NucleotideAlignWithBandingtransT[] = {"match","insert1","delete1","match","insert1","delete1","end","match","insert1","end","match","delete1","end"};
+const string _NucleotideAlignWithBandingtransP[] = {"probSM","probSI1","probSD1","probMM","probMI1","probMD1","probME","probI1M","probI1I1","probI1E","probD1M","probD1D1","probD1E"};
+const string _NucleotideAlignWithBandingtransE[] = {"emit12","emit1","emit2","emit12","emit1","emit2","empty","emit12","emit1","empty","emit12","emit2","empty"};
+const string _NucleotideAlignWithBandingoutputId[] = {"sequence1","sequence2"};
+const string _NucleotideAlignWithBandingempty = "";
+const int _NucleotideAlignWithBandingstateNum = 5;
+const int _NucleotideAlignWithBandingemitNum = 4;
+const int _NucleotideAlignWithBandingtransNum = 13;
+const int _NucleotideAlignWithBandingoutputNum = 2;
+
+
+
+
+bfloat ForwardBanding(NucleotideAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2withbandingTo;
+    const bfloat *CurStateMemorynucBlock1From;
+    const bfloat *CurStateMemorynucBlock2withbandingFrom;
+    bfloat *CurStateMemorynucBlock3To;
+    const bfloat *CurStateMemorynucBlock3From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideAlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemorynucBlock1.write()[0] = 1.0;
+    dp.StateMemorynucBlock1.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.forwardIterator();
+        bool bLastSlowCoordInited = false;
+        int iLastSlowCoord = -1;  
+        do {
+            if (bLastSlowCoordInited) {
+                if (iLastSlowCoord > position[1]) {
+                    cout << "WARNING: Banding (forward): Slowest coordinate should be nondecreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+                }
+                } else {
+                bLastSlowCoordInited = true;
+            }
+            iLastSlowCoord = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+-1>=0)) {
+                        iSymbol[0] = iSequence2[position[1]+-1];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+-1>=0)) {
+                        iSymbol[1] = iSequence1[position[0]+-1];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucBlock2withbandingTo = dp.StateMemorynucBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+0<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                        CurStateMemorynucBlock2withbandingTo[2] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                    }
+                    if ((position[1]+-1>=0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[2] += ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                        CurStateMemorynucBlock2withbandingTo[2] += ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+0<=0)) {
+                        CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                        CurStateMemorynucBlock2withbandingTo[0] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                    }
+                    if ((position[0]+-1>=0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucBlock2withbandingTo[0] += ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        CurStateMemorynucBlock2withbandingTo[0] += ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+-1>=0)&&(position[0]+-1<=0)&&(position[1]+-1>=0)&&(position[1]+-1<=0)) {
+                        CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+                        CurStateMemorynucBlock2withbandingTo[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock1From[0];
+                    }
+                    if ((position[0]+-1>=0)&&(position[1]+-1>=0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(1))-(0), (position[1]-(1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                    }
+                    dp.StateMemorynucBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextForward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                CurStateMemorynucBlock3To = dp.StateMemorynucBlock3.write();
+                iEmission[0] = 1.0;
+                if (1) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock3To[0] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                    CurStateMemorynucBlock3To[0] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                    CurStateMemorynucBlock3To[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                }
+                dp.StateMemorynucBlock3.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+            iTempProb[0] = CurStateMemorynucBlock3From[0];
+        }
+    }
+    *ppOutTable = new NucleotideAlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBaumWelchBanding(NucleotideAlignWithBandingBaumWelch& bw,NucleotideAlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    const bfloat *CurStateMemorynucBlock3Secondary;
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2withbandingTo;
+    const bfloat *CurStateMemorynucBlock2withbandingSecondary;
+    const bfloat *CurStateMemorynucBlock2withbandingFrom;
+    unsigned char alphaSymbolnucleotide[4] = {'A', 'C', 'G', 'T'};
+    unsigned char alphaIndexnucleotide[256];
+    const bfloat *CurStateMemorynucBlock3From;
+    bfloat *CurStateMemorynucBlock1To;
+    const bfloat *CurStateMemorynucBlock1Secondary;
+    const bfloat *CurStateMemorynucBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[3];
+    NucleotideAlignWithBandingFoldedDPTable dp(iLen1,2);
+    NucleotideAlignWithBandingDPTable dp2(*pInTable);
+    // make sure tables don't get deleted
+    dp2.isInCharge = false;
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    for (int i=0; i<256; i++) {
+        alphaIndexnucleotide[i]=0;
+    }
+
+//    for (int i=0; i<4; i++) {
+//        alphaIndexnucleotide[alphaSymbolnucleotide[i]]=i;
+//    }
+    for (int i=0; i<4; i++) {
+      alphaIndexnucleotide[tolower (alphaSymbolnucleotide[i])] = i;
+      alphaIndexnucleotide[toupper (alphaSymbolnucleotide[i])] = i;
+    }
+    // treat lower and upper-case characters as equivalent during Baum-Welch
+    // -- RKB
+
+    dp.StateMemorynucBlock3.write()[0] = 1.0;
+    dp.StateMemorynucBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock3Secondary = dp2.StateMemorynucBlock3.read();
+            iTempProb[2] = CurStateMemorynucBlock3Secondary[0];
+            bw.scaleCounts(iTempProb[2]);
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (iPrevSlowCoord != -1 && iPrevSlowCoord != position[1]) {
+                    dp.StateMemorynucBlock2withbanding.clear(position[1]);
+                }
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucBlock2withbandingTo = dp.StateMemorynucBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    CurStateMemorynucBlock2withbandingSecondary = dp2.StateMemorynucBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[2] = iTempProb[1] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[11] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[1] = iTempProb[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[5] += iTempProb[1];
+                        bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[4] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[0] = iTempProb[1] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[8] += iTempProb[1];
+                        bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[2] += iTempProb[1] = ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[10] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[3] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[0] += iTempProb[1] = ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[7] += iTempProb[1];
+                        bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+                        CurStateMemorynucBlock2withbandingTo[2] += iTempProb[1] = ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[2];
+                        bw.transitionBaumWelchCount00[12] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[1] += iTempProb[1] = ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[1];
+                        bw.transitionBaumWelchCount00[6] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                        CurStateMemorynucBlock2withbandingTo[0] += iTempProb[1] = ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                        iTempProb[1] *= CurStateMemorynucBlock2withbandingSecondary[0];
+                        bw.transitionBaumWelchCount00[9] += iTempProb[1];
+                        bw.emissionBaumWelchCount00[0] += iTempProb[1];
+                    }
+                    dp.StateMemorynucBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock1To = dp.StateMemorynucBlock1.write();
+                CurStateMemorynucBlock1Secondary = dp2.StateMemorynucBlock1.read();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] = iTempProb[1] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[2] += iTempProb[1];
+                    bw.emissionBaumWelchCount01[alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock1To[0] += iTempProb[1] = ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[1] += iTempProb[1];
+                    bw.emissionBaumWelchCount10[alphaIndexnucleotide[iSymbol[1]]][0] += iTempProb[1];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] += iTempProb[1] = ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                    iTempProb[1] *= CurStateMemorynucBlock1Secondary[0];
+                    bw.transitionBaumWelchCount00[0] += iTempProb[1];
+                    bw.emissionBaumWelchCount11[alphaIndexnucleotide[iSymbol[1]]][alphaIndexnucleotide[iSymbol[0]]][0] += iTempProb[1];
+                }
+                dp.StateMemorynucBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    bw.scaleCounts(1.0 / iTempProb[2]);
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+            iTempProb[0] = CurStateMemorynucBlock1From[0];
+        }
+    }
+    return iTempProb[0];
+};
+
+
+
+
+
+bfloat BackwardBanding(NucleotideAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth) {
+    bfloat iTransition[13];
+    bfloat *CurStateMemorynucBlock2withbandingTo;
+    const bfloat *CurStateMemorynucBlock2withbandingFrom;
+    const bfloat *CurStateMemorynucBlock3From;
+    bfloat *CurStateMemorynucBlock1To;
+    const bfloat *CurStateMemorynucBlock1From;
+    int iPrevSlowCoord;
+    int iLen1 = iSequence1.size();   // The sequence lengths are not passed as parameters, but are
+    int iLen2 = iSequence2.size();   // computed from the vector<char> itself
+    
+    // indexing for emission probs
+    unsigned char iTranslate[256];
+    for (int i=0; i<256; i++) {
+        iTranslate[i]= 0;
+    }
+    iTranslate[(unsigned)'A'] = 0;   // It is important that this is in alphabetical order, to
+    iTranslate[(unsigned)'a'] = 0;   // make the indices correspond to those used for Baum-Welch
+    iTranslate[(unsigned)'C'] = 1;
+    iTranslate[(unsigned)'c'] = 1;
+    iTranslate[(unsigned)'G'] = 2;
+    iTranslate[(unsigned)'g'] = 2;
+    iTranslate[(unsigned)'T'] = 3;
+    iTranslate[(unsigned)'t'] = 3;
+    MyBanding bandingInstance (iSequence1.size(), iSequence2.size(), iWidth);
+    int iSymbol[2];
+    if (false && iSymbol[0] == iSymbol[0]) {}   // avoid 'unused variable' warnings
+    bfloat iEmission[1];
+    /* temporary storage for ordinary reals */
+    register double iTempResult[1];
+    /* temporary storage for extended-exponent reals */
+    register bfloat iTempProb[1];
+    NucleotideAlignWithBandingDPTable dp(iLen1,iLen2);
+    iTransition[0] = iT[0][1];
+    
+    iTransition[1] = iT[0][2];
+    
+    iTransition[2] = iT[0][3];
+    
+    iTransition[3] = iT[1][1];
+    
+    iTransition[4] = iT[1][2];
+    
+    iTransition[5] = iT[1][3];
+    
+    iTransition[6] = iT[1][6];
+    
+    iTransition[7] = iT[2][1];
+    
+    iTransition[8] = iT[2][2];
+    
+    iTransition[9] = iT[2][6];
+    
+    iTransition[10] = iT[3][1];
+    
+    iTransition[11] = iT[3][3];
+    
+    iTransition[12] = iT[3][6];
+    dp.StateMemorynucBlock3.write()[0] = 1.0;
+    dp.StateMemorynucBlock3.written();
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=iLen2+0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=iLen1+0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+            }
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        Banding<2>::Position& position = bandingInstance.backwardIterator();
+        int iCheckSlowCoordTraversal = -1;  
+        do {
+            if (iCheckSlowCoordTraversal != -1 && iCheckSlowCoordTraversal < position[1]) {
+                cout << "WARNING: Banding (backward): Slowest coordinate be nonincreasing.  Perhaps forgot to specify speed of output coordinates?" << endl;
+            }
+            iCheckSlowCoordTraversal = position[1];
+            if ((position[0]+0>=0)&&(position[0]+0<=iLen1+0)&&(position[1]+0>=0)&&(position[1]+0<=iLen2+0)) {
+                if (1) {
+                    if ((position[1]+0<=iLen2+-1)) {
+                        iSymbol[0] = iSequence2[position[1]+0];
+                    } 
+                    else { 
+                        iSymbol[0] = 'A' /* dummy value */;
+                        
+                    }
+                    if ((position[0]+0<=iLen1+-1)) {
+                        iSymbol[1] = iSequence1[position[0]+0];
+                    } 
+                    else { 
+                        iSymbol[1] = 'A' /* dummy value */;
+                        
+                    }
+                    CurStateMemorynucBlock2withbandingTo = dp.StateMemorynucBlock2withbanding.write((position[0]-(0))-(0), (position[1]-(0))-(0));
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(0))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[1] = ((iTransition[5])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                        CurStateMemorynucBlock2withbandingTo[2] = ((iTransition[11])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                    }
+                    iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(0))-(0));
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[4])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                        CurStateMemorynucBlock2withbandingTo[0] = ((iTransition[8])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                    }
+                    iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                    iEmission[0] = iTempResult[0];
+                    if ((position[0]+1<=iLen1+0)&&(position[1]+1<=iLen2+0)) {
+                        CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((position[0]-(-1))-(0), (position[1]-(-1))-(0));
+                        CurStateMemorynucBlock2withbandingTo[2] += ((iTransition[10])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[3])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                        CurStateMemorynucBlock2withbandingTo[0] += ((iTransition[7])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                    }
+                    iEmission[0] = 1.0;
+                    if ((position[0]+0>=iLen1+0)&&(position[1]+0>=iLen2+0)) {
+                        CurStateMemorynucBlock3From = dp.StateMemorynucBlock3.read();
+                        CurStateMemorynucBlock2withbandingTo[2] += ((iTransition[12])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                        CurStateMemorynucBlock2withbandingTo[1] += ((iTransition[6])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                        CurStateMemorynucBlock2withbandingTo[0] += ((iTransition[9])*(iEmission[0]))*CurStateMemorynucBlock3From[0];
+                    }
+                    dp.StateMemorynucBlock2withbanding.written();
+                }
+                iPrevSlowCoord = position[1];
+            } 
+            else { 
+                bandingInstance.warning();
+                
+            }
+        } while (bandingInstance.hasNextBackward());
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            if (1) {
+                if ((iPos1+0<=iLen2+-1)) {
+                    iSymbol[0] = iSequence2[iPos1+0];
+                } 
+                else { 
+                    iSymbol[0] = 'A' /* dummy value */;
+                    
+                }
+                if ((iPos0+0<=iLen1+-1)) {
+                    iSymbol[1] = iSequence1[iPos0+0];
+                } 
+                else { 
+                    iSymbol[1] = 'A' /* dummy value */;
+                    
+                }
+                CurStateMemorynucBlock1To = dp.StateMemorynucBlock1.write();
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(0))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] = ((iTransition[2])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[2];
+                }
+                iTempResult[0] = iSingleDistribution[iTranslate[iSymbol[1]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(0))-(0));
+                    CurStateMemorynucBlock1To[0] += ((iTransition[1])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[0];
+                }
+                iTempResult[0] = iPairDistribution[iTranslate[iSymbol[1]]][iTranslate[iSymbol[0]]];
+                iEmission[0] = iTempResult[0];
+                if ((iPos0+1<=iLen1+0)&&(iPos1+1<=iLen2+0)) {
+                    CurStateMemorynucBlock2withbandingFrom = dp.StateMemorynucBlock2withbanding.read((iPos0-(-1))-(0), (iPos1-(-1))-(0));
+                    CurStateMemorynucBlock1To[0] += ((iTransition[0])*(iEmission[0]))*CurStateMemorynucBlock2withbandingFrom[1];
+                }
+                dp.StateMemorynucBlock1.written();
+            }
+            iPrevSlowCoord = iPos1;
+        }
+    }
+    iPrevSlowCoord = -1;
+    {
+        int iPos1=0;
+        if (iPos1==iPos1) {} // avoid 'unused variable' warnings
+        {
+            int iPos0=0;
+            if (iPos0==iPos0) {} // avoid 'unused variable' warnings
+            CurStateMemorynucBlock1From = dp.StateMemorynucBlock1.read();
+            iTempProb[0] = CurStateMemorynucBlock1From[0];
+        }
+    }
+    *ppOutTable = new NucleotideAlignWithBandingDPTable(dp);
+    // make sure tables don't get deleted
+    dp.isInCharge = false;
+    return iTempProb[0];
+};
+
+
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/nucleotidedp.h b/src/fsa/nucleotidedp.h
new file mode 100644
index 0000000..628b35f
--- /dev/null
+++ b/src/fsa/nucleotidedp.h
@@ -0,0 +1,315 @@
+/* Code generated by HMMoC version 1.3, Copyright (C) 2006 Gerton Lunter */
+/* Generated from file nucleotide.xml (author:  Robert K. Bradley ) on Tue Dec 23 01:04:16 CST 2008 */
+
+/*
+This file is a work based on HMMoC 1.3, a hidden Markov model compiler.
+Copyright (C) 2006 by Gerton Lunter, Oxford University.
+
+HMMoC and works based on it are free software; you can redistribute 
+it and/or modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+HMMOC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with HMMoC; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#ifndef _nucleotidedp_h_
+#define _nucleotidedp_h_
+
+
+#include "dptables.h"
+#include "algebras.h"
+#include <string>
+
+#include <map>
+
+using std::map;
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesnucBlock2;
+typedef States<bfloat,1> StatesnucBlock1;
+typedef States<bfloat,1> StatesnucBlock3;
+
+class NucleotideAlignDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesnucBlock2,2> StateMemorynucBlock2;
+    DPTable<StatesnucBlock1,0> StateMemorynucBlock1;
+    DPTable<StatesnucBlock3,0> StateMemorynucBlock3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideAlignDPTable(int iLen1,int iLen2);
+    ~NucleotideAlignDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat NucleotideAlignReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double NucleotideAlignShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesnucBlock2;
+typedef States<bfloat,1> StatesnucBlock3;
+typedef States<bfloat,1> StatesnucBlock1;
+
+class NucleotideAlignFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesnucBlock2,2> StateMemorynucBlock2;
+    DPTable<StatesnucBlock3,0> StateMemorynucBlock3;
+    DPTable<StatesnucBlock1,0> StateMemorynucBlock1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideAlignFoldedDPTable(int iLen1,int iLen2);
+    ~NucleotideAlignFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class NucleotideAlignBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    NucleotideAlignBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[13];
+    static int transitionIdentifier00[13];   
+    static const int transitionDimension00 = 13;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[4][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[4][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[4][4][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[13];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesnucBlock2withbanding;
+typedef States<bfloat,1> StatesnucBlock1;
+typedef States<bfloat,1> StatesnucBlock3;
+
+class NucleotideAlignWithBandingDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    DPTable<StatesnucBlock2withbanding,2> StateMemorynucBlock2withbanding;
+    DPTable<StatesnucBlock1,0> StateMemorynucBlock1;
+    DPTable<StatesnucBlock3,0> StateMemorynucBlock3;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideAlignWithBandingDPTable(int iLen1,int iLen2);
+    ~NucleotideAlignWithBandingDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+// give a name to the real type used for this HMM
+typedef bfloat NucleotideAlignWithBandingReal;
+// define type for a 'short' real -- usually double, but can be logspace for efficiency
+typedef double NucleotideAlignWithBandingShortReal;
+
+
+
+// Here go the state memory clique typedefs:
+typedef States<bfloat,3> StatesnucBlock2withbanding;
+typedef States<bfloat,1> StatesnucBlock3;
+typedef States<bfloat,1> StatesnucBlock1;
+
+class NucleotideAlignWithBandingFoldedDPTable {
+    public:
+    // If true, this class' destructor will delete the DP arrays
+    bool isInCharge;
+    // Pointers to arrays containing ids of states and transitions
+    const string* const stateId;
+    const string* const emissionId;
+    const string* const transitionId;
+    const string* const transitionFrom;
+    const string* const transitionTo;
+    const string* const transitionProb;
+    const string* const transitionEmit;
+    const string* const outputId;
+    // The actual DP tables, and total sequence lengths (which determine size of DP arrays) follow:
+    int iLen1;
+    int iLen2;
+    FoldedTable<DPTable,StatesnucBlock2withbanding,2> StateMemorynucBlock2withbanding;
+    DPTable<StatesnucBlock3,0> StateMemorynucBlock3;
+    DPTable<StatesnucBlock1,0> StateMemorynucBlock1;
+    // Member functions:
+    public:
+    // Default copy constructor is used; user has to set isInCharge appropriately afterwards!
+    NucleotideAlignWithBandingFoldedDPTable(int iLen1,int iLen2);
+    ~NucleotideAlignWithBandingFoldedDPTable();
+    // returns probability from DP table, given position and int or string state identifier
+    bfloat getProb(int iState ,int ,int ) const;
+    bfloat getProb(const string sState ,int ,int ) const;
+    // converts string identifier (for state, transition or emission) into integer id
+    static int getId(const string& sState);
+    static const string& getTransitionId(int id);
+    static const string& getEmissionId(int id);
+    static const string& getStateId(int id);
+    static const string& getOutputId(int id);
+    static void _cleanup() { getId("_cleanup_"); }
+};
+
+
+
+class NucleotideAlignWithBandingBaumWelch {
+    public:
+    // Default copy constructor is used.
+    // Void constructor:
+    NucleotideAlignWithBandingBaumWelch() { resetCounts(); }
+    // Not calling resetCounts() across calls allows to aggregate results over multiple datasets
+    void resetCounts();
+    void scaleCounts(bfloat scale);
+    // Translate an identifier (string or integer) to the index into their corresponding Baum-Welch counter array (below)
+    // Which array is used for any particular emission/transition depends on its order signature - see documentation for details
+    int transitionIndex(int intId) const { return atransitionIdx[intId]; }
+    int transitionIndex(string strId) const;
+    int emissionIndex(int intId) const { return aemissionIdx[intId]; }
+    int emissionIndex(string strId) const;
+    // Now follow, in triplets (one for each order signature):
+    //  Transition or emission counters;
+    //  Array of identifiers; and
+    //  Dimension of array (number of counters).
+    bfloat transitionBaumWelchCount00[13];
+    static int transitionIdentifier00[13];   
+    static const int transitionDimension00 = 13;
+    bfloat emissionBaumWelchCount00[1];
+    static int emissionIdentifier00[1];   
+    static const int emissionDimension00 = 1;
+    bfloat emissionBaumWelchCount01[4][1];
+    static int emissionIdentifier01[1];   
+    static const int emissionDimension01 = 1;
+    bfloat emissionBaumWelchCount10[4][1];
+    static int emissionIdentifier10[1];   
+    static const int emissionDimension10 = 1;
+    bfloat emissionBaumWelchCount11[4][4][1];
+    static int emissionIdentifier11[1];   
+    static const int emissionDimension11 = 1;
+    private:
+    static int atransitionIdx[13];
+    static int aemissionIdx[4];
+    static map<const string,int> mId;
+};
+
+
+
+bfloat Forward(NucleotideAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat BackwardBaumWelch(NucleotideAlignBaumWelch& bw,NucleotideAlignDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat Backward(NucleotideAlignDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT);
+
+bfloat ForwardBanding(NucleotideAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBaumWelchBanding(NucleotideAlignWithBandingBaumWelch& bw,NucleotideAlignWithBandingDPTable* pInTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+bfloat BackwardBanding(NucleotideAlignWithBandingDPTable** ppOutTable,const std::string& iSequence1,const std::string& iSequence2,const vector<double>& iSingleDistribution,const vector<vector<double> >& iPairDistribution,const vector<vector<double> >& iT,int iWidth);
+
+#endif // _nucleotidedp_h_
+
+/* --- end of HMMoC-generated file --- */
diff --git a/src/fsa/sequence_pair_selector.cc b/src/fsa/sequence_pair_selector.cc
new file mode 100644
index 0000000..da4f03a
--- /dev/null
+++ b/src/fsa/sequence_pair_selector.cc
@@ -0,0 +1,360 @@
+
+/**
+ * \file sequence_pair_selector.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <queue>
+
+#include "util/logfile.h"
+#include "fsa/sequence_pair_selector.h"
+
+using namespace fsa;
+
+Sequence_pair_selector::Sequence_pair_selector (const Sequence_database& seq_db,
+						const Alphabet& alphabet,
+						const size_t k)
+: __seq_db (seq_db),
+  __k (k),
+  __similarity_matrix (Sequence_similarity_matrix (seq_db,
+						   alphabet,
+						   k)),
+  __added (std::vector<std::vector<bool> > (seq_db.size(), std::vector<bool> (seq_db.size(), false))),
+  __num_selected (0)
+{
+
+  // log
+  CTAG(9,FSA) << "Computed k-mer similarities (k = " << __k << ") between input sequences." << endl;
+
+  // log similarities if requested
+  if (CTAGGING(-1,KMER)) {
+    CL << "Sequence similarity matrix (k = " << __k << "):" << endl;
+    __similarity_matrix.write (CL);
+  }
+
+}
+
+void Sequence_pair_selector::choose_minimum_spanning_tree (const size_t num_mst,
+							   const bool compute_maximum_spanning_tree /* = false */) {
+
+  // iteratively build disjoint minimum spanning trees
+  size_t mst_added = 0;
+  while (mst_added++ < num_mst) {
+
+    // assemble the edge set
+    MST_Kruskal::Edge_set edges;
+    edges.reserve (__seq_db.size() * __seq_db.size());
+    for (size_t i = 0; i < __seq_db.size(); ++i)
+      for (size_t j = i + 1; j < __seq_db.size(); ++j) {
+
+	// don't store previously-added edges
+	if (__added[i][j])
+	  continue;
+
+	// convert the k-mer similarity to a weight
+	// (k-mer similarities necessarily fall in the interval [0, 1])
+	double weight;
+
+	// if we're computing a maximum spanning tree,
+	// then store the weight as a similarity,
+	// so that my minimum spanning tree code will
+	// choose edges with the lowest similarity and thereby
+	// build a maximum spanning tree
+	if (compute_maximum_spanning_tree)
+	  weight = __similarity_matrix.get_similarity (i, j);
+
+	// else we're computing a minimum spanning tree,
+	// so convert the k-mer similarity to a k-mer distance
+	else
+	  weight = 1.0 - __similarity_matrix.get_similarity (i, j);
+
+	// store
+	edges.push_back (MST_Kruskal::Edge (i, j, weight));
+
+      }
+
+    // compute the MST
+    MST_Kruskal::Edge_set mst = MST_Kruskal::compute_mst (edges, __seq_db.size(),
+							  false); // die_on_failure = false
+
+    // if no MST exists, then break (we're done)
+    if (!mst.size())
+      break;
+
+    // log MST if requested
+    if (CTAGGING(-1,KMER)) {
+
+      // compute the total k-mer similarity, summed over branches of the tree
+      double total_similarity = 0;
+      for (MST_Kruskal::Edge_set::const_iterator edge = mst.begin(); edge != mst.end(); ++edge)
+	total_similarity += __similarity_matrix.get_similarity (edge->u, edge->v);
+
+      // display
+      if (compute_maximum_spanning_tree)
+	CL << "Maximum spanning tree on sequences (total k-mer similarity = " << total_similarity << "):" << endl;
+      else
+	CL << "Minimum spanning tree on sequences (total k-mer similarity = " << total_similarity << "):" << endl;
+      for (MST_Kruskal::Edge_set::const_iterator edge = mst.begin(); edge != mst.end(); ++edge)
+	CL << __seq_db.get_seq (edge->u).name << " -- " << __seq_db.get_seq (edge->v).name << " => " << __similarity_matrix.get_similarity (edge->u, edge->v) << endl;
+
+    }
+
+    // store the MST
+    for (MST_Kruskal::Edge_set::const_iterator edge = mst.begin(); edge != mst.end(); ++edge) {
+
+      const size_t u = edge->u;
+      const size_t v = edge->v;
+
+      // sanity check
+      assert (u < v);
+      __added[u][v] = true;
+      ++__num_selected;
+
+    }
+
+  }
+
+}
+
+void Sequence_pair_selector::choose_maximum_spanning_tree (const size_t num_mst) {
+
+  choose_minimum_spanning_tree (num_mst,
+				true);  // compute_maximum_spanning_tree = true
+
+}
+
+void Sequence_pair_selector::choose_minimum_spanning_palm_tree (const size_t num_mst) {
+
+  // check sane
+  if (num_mst > __seq_db.size())
+    THROWEXPR ("Cannot compute more minimum spanning palm trees than there are sequences.");
+
+  // keep track of which sequences we've used as centers of palm trees
+  // (so that we don't repeat ourselves)
+  std::vector<bool> chosen_centers (__seq_db.size(), false);
+
+  // iteratively build minimum spanning palm trees
+  size_t mst_added = 0;
+  while (mst_added++ < num_mst) {
+
+    // find the sequence at the center of the minimum spanning palm tree
+    size_t best_center = 0;
+    double best_similarity = -1;
+    for (size_t i = 0; i < __seq_db.size(); ++i) {
+
+      // avoid repeats
+      if (chosen_centers[i])
+	continue;
+
+      // calculate the total similarity (summed over all branches)
+      // associated with a palm tree whose center is sequence i
+      double tree_similarity = 0;
+      for (size_t j = 0; j < __seq_db.size(); ++j) {
+
+	if (i == j)
+	  continue;
+
+	tree_similarity += __similarity_matrix.get_similarity (i, j);
+
+      }
+
+      // is this a new best center for the palm tree?
+      if (best_similarity < tree_similarity) {
+	best_similarity = tree_similarity;
+	best_center = i;
+      }
+
+    }
+
+    // confirm that we did indeed find a valid MST
+    if (best_similarity < 0)
+      THROWEXPR ("Unable to compute a valid minimum spanning palm tree.");
+
+    // log if requested
+    if (CTAGGING(-1,KMER))
+      CL << "Minimum spanning palm tree on sequences is centered on sequence '" << __seq_db.get_seq (best_center).name << "' (total k-mer similarity = " << best_similarity << ")." << endl;
+
+    // store the MST
+    for (size_t j = 0; j < __seq_db.size(); ++j) {
+
+      if (best_center == j)
+	continue;
+
+      // keep track of how many new sequence pairs we're selecting here
+      // (avoid over-counting previously-selected ones)
+      if (!__added[best_center][j] && !__added[j][best_center])
+	++__num_selected;
+
+      // maintain i < j for consistency
+      if (best_center < j)
+	__added[best_center][j] = true;
+      else
+	__added[j][best_center] = true;
+
+    }
+
+    // record the center so that we don't repeat ourselves
+    chosen_centers[best_center] = true;
+
+  }
+
+}
+
+void Sequence_pair_selector::choose_palm_tree (const std::string& centerseq) {
+
+  // check sane
+  if (!__seq_db.exists_seq (centerseq))
+    THROWEXPR ("Requested center sequence of palm tree does not exist: '" << centerseq << "'.");
+
+  const size_t center = __seq_db.get_seq_index (centerseq);
+
+  // store the MST
+  for (size_t j = 0; j < __seq_db.size(); ++j) {
+
+    if (center == j)
+      continue;
+
+    // keep track of how many new sequence pairs we're selecting here
+    // (avoid over-counting previously-selected ones)
+    if (!__added[center][j] && !__added[j][center])
+      ++__num_selected;
+
+    // maintain i < j for consistency
+    if (center < j)
+      __added[center][j] = true;
+    else
+      __added[j][center] = true;
+
+  }
+
+}
+
+void Sequence_pair_selector::choose_kmer_similarity (const size_t degree) {
+
+  // keep track of how many sequence pairs we've stored
+  size_t num_added = 0;
+
+  // now add sequence pairs based on their k-mer similarity until
+  // we've hit the requested number degree per sequence
+  for (size_t i = 0; i < __seq_db.size(); ++i) {
+
+    // assemble a heap of edges, ordered by descending k-mer similarity
+    // (STL priority_queue order such that the first element is the greatest,
+    // according to the designated strict weak ordering)
+    std::priority_queue<std::pair<double, size_t>, std::vector<std::pair<double, size_t> >, Util::Duple_less<double, size_t> > weighted_edges;
+    for (size_t j = i + 1; j < __seq_db.size(); ++j) {
+      if (!__added[i][j])
+	weighted_edges.push (std::make_pair (__similarity_matrix.get_similarity (i, j), j));
+    }
+
+    // what's the current degree of sequence i?
+    size_t degree_i = 0;
+    for (size_t j = 0; j < __seq_db.size(); ++j) {
+      if (__added[i][j] || __added[j][i])
+	++degree_i;
+    }
+
+    // now add edges one by one until we reach the requested degree
+    // (or run out of edges)
+    while (!weighted_edges.empty()) {
+
+      // have we reached the requested degree for sequence i?
+      if (degree_i >= degree)
+	break;
+
+      // get the lowest-weight edge      
+      const std::pair<double, size_t> weighted_edge = weighted_edges.top();
+      weighted_edges.pop();
+      const size_t j = weighted_edge.second;
+
+      // store it
+      assert (!__added[i][j]);
+      __added[i][j] = true;
+      ++degree_i;
+      ++__num_selected;
+      ++num_added;
+      
+    }
+
+  }
+
+  // log
+  if (CTAGGING(-1,KMER) && degree > 1)
+    CL << "Stored " << num_added << " sequence pairs to reach the requested degree = " << degree << "." << endl;
+
+}
+
+void Sequence_pair_selector::choose_random (size_t num) {
+
+  // make sure that it's possible to store the desired number of sequence pairs without duplicates
+  if ((__num_selected + num) > (__seq_db.size() * (__seq_db.size() - 1) / 2))
+    num = (__seq_db.size() * (__seq_db.size() - 1) / 2) - __num_selected;
+
+  // then randomly add more until we hit num_alignment_pairs
+  size_t num_added = 0;
+  while (num_added < num) {
+      
+    // randomly choose a sequence pair
+    size_t i = static_cast<size_t> (std::floor (Util::rand (__seq_db.size() - 1)));
+    size_t j = static_cast<size_t> (std::floor (Util::rand (__seq_db.size() - 1)));
+
+    // check sane
+    assert (i < __seq_db.size());
+    assert (j < __seq_db.size());
+
+    // skip identities
+    if (i == j)
+      continue;
+
+    // require that i < j for consistency
+    if (i > j)
+      std::swap (i, j);
+    assert (i < j);
+
+    // skip duplicates
+    if (__added[i][j])
+      continue;
+
+    // store
+    __added[i][j] = true;
+    ++num_added;
+    ++__num_selected;
+
+  }
+  assert (num_added == num);
+
+  // log
+  CTAG(8,FSA) << "Stored " << num_added << " randomly-chosen sequence pairs." << endl;
+
+}
+
+void Sequence_pair_selector::choose_all() {
+
+  for (size_t i = 0; i < __added.size(); ++i) {
+    for (size_t j = i + 1; j < __added.size(); ++j)
+      __added[i][j] = true;
+  }
+
+}
+
+Sequence_pairs Sequence_pair_selector::get_chosen_sequence_pairs() const {
+
+  Sequence_pairs sequence_pairs;
+  for (size_t i = 0; i < __added.size(); ++i) {
+    for (size_t j = i + 1; j < __added.size(); ++j)
+      if (__added[i][j])
+	sequence_pairs.push_back (Sequence_pair (i, j));
+  }
+
+  return sequence_pairs;
+
+}
+
+double Sequence_pair_selector::erdos_renyi_p_cutoff (const size_t nodes) {
+
+  const double epsilon = 0.1;
+  return ((1 + epsilon) * std::log (static_cast<double> (nodes)) / static_cast<double> (nodes));
+
+}
+
diff --git a/src/fsa/sequence_pair_selector.h b/src/fsa/sequence_pair_selector.h
new file mode 100644
index 0000000..07c8e72
--- /dev/null
+++ b/src/fsa/sequence_pair_selector.h
@@ -0,0 +1,122 @@
+
+/**
+ * \file sequence_pair_selector.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef FSA_SEQUENCE_PAIR_SELECTOR_INCLUDED
+#define FSA_SEQUENCE_PAIR_SELECTOR_INCLUDED
+
+#include "math/mst.h"
+#include "seq/sequence.h"
+#include "seq/similarity_matrix.h"
+
+namespace fsa {
+
+  typedef std::pair<size_t, size_t> Sequence_pair;     ///< a sequence pair (i, j)
+  typedef std::vector<Sequence_pair> Sequence_pairs;   ///< a vector of sequence pairs
+
+  /**
+   * \brief Select sequence pairs for pairwise comparisons.
+   */
+  struct Sequence_pair_selector {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     * \param seq_db sequence data
+     * \param alphabet alphabet which sequences are defined over
+     * \param k word length to use when computing k-mer similarities
+     */
+    Sequence_pair_selector (const Sequence_database& seq_db,
+			    const Alphabet& alphabet,
+			    const size_t k);
+
+    /**
+     * \brief Choose sequence pairs based on their inclusion in minimum spanning trees.
+     *
+     * Iteratively constructs disjoint minimum spanning trees.
+     * \param num_mst number of disjoint MSTs to construct
+     * \param compute_maximum_spanning_tree compute the maximum, rather than minimum, spanning tree
+     */
+    void choose_minimum_spanning_tree (const size_t num_mst,
+				       const bool compute_maximum_spanning_tree = false);
+
+    /**
+     * \brief Choose sequence pairs based on their inclusion in maximum spanning trees.
+     *
+     * Iteratively constructs disjoint maximum spanning trees.
+     * \param num_mst number of disjoint MSTs to construct
+     * \see choose_minimum_spanning_tree
+     */
+    void choose_maximum_spanning_tree (const size_t num_mst);
+
+    /**
+     * \brief Choose sequence pairs based on their inclusion in the minimum palm spanning tree.
+     *
+     * Iteratively construct minimum palm spanning trees with distinct centers.
+     * \param num_palm_mst number of palm MSTs to construct
+     */
+    void choose_minimum_spanning_palm_tree (const size_t num_palm_mst);
+
+    /**
+     * \brief Choose sequence pairs which form a palm tree with the specified sequence at the center.
+     *
+     * \param seq sequence which is the center of the palm tree
+     * 
+     */
+    void choose_palm_tree (const std::string& centerseq);
+
+    /**
+     * \brief Choose sequence pairs based on their k-mer similarity.
+     *
+     * \param degree every sequence must be included in degree sequence pairs
+     */
+    void choose_kmer_similarity (const size_t degree);
+
+    /**
+     * \brief Choose sequence pairs randomly.
+     *
+     * \param num number of sequence pairs to add randomly
+     */
+    void choose_random (size_t num);
+
+    /**
+     * \brief Choose all sequence pairs.
+     */
+    void choose_all();
+
+    /**
+     * \brief Count the number of selected sequence pairs.
+     */
+    size_t num_selected() const { return __num_selected; }
+
+    /**
+     * \brief Get a list of sequence pairs which we have selected.
+     */
+    Sequence_pairs get_chosen_sequence_pairs() const;
+
+    /**
+     * \brief Erdos-Renyi threshold probability.
+     *
+     * Probability above which an Erdos-Renyi random graph will almost surely be connected.
+     * \param nodes number of nodes in graph
+     */
+    static double erdos_renyi_p_cutoff (const size_t nodes);
+
+  private:
+
+    const Sequence_database& __seq_db;  ///< sequence data
+    const size_t __k;                   ///< k-mer word length
+
+    Sequence_similarity_matrix __similarity_matrix;  ///< k-mer similarity matrix
+    std::vector<std::vector<bool> >__added;          ///< __added[i][j] == true iff sequence pair (i, j) or (j, i) is chosen
+    size_t __num_selected;                           ///< number of sequence pairs selected
+
+  };
+
+}
+
+#endif /* FSA_SEQUENCE_PAIR_SELECTOR_INCLUDED */
diff --git a/src/main/Makefile.am b/src/main/Makefile.am
new file mode 100644
index 0000000..f43ec1f
--- /dev/null
+++ b/src/main/Makefile.am
@@ -0,0 +1,55 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src 
+
+# AM_CXXFLAGS = -finline-limit=10000 --param inline-unit-growth=70
+# Commented out b/c was causing bugs on some older compilers.
+#  --RKB & CD 4/14/09
+
+LDADD = \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a
+
+if HAVE_CONDOR 
+  AM_CPPFLAGS += -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+
+  AM_LDFLAGS = -static -L$(top_builddir)/MW/lib
+  LDADD += \
+	-lMW \
+	-lMWRMComm \
+	-lMWutil \
+	-lNWS \
+	-lMWsocketmaster \
+    -lpthread
+endif
+
+bin_PROGRAMS = \
+	fsa \
+	gapcleaner \
+	isect_mercator_alignment_gff \
+	map_coords \
+	map_gff_coords \
+	percentid \
+	prot2codon \
+	slice_fasta \
+	slice_fasta_gff \
+	slice_mercator_alignment \
+	translate
+
+fsa_SOURCES = main.cc
+gapcleaner_SOURCES = gapcleaner.cc
+isect_mercator_alignment_gff_SOURCES = isect_mercator_alignment_gff.cc
+map_coords_SOURCES = map_coords.cc
+map_gff_coords_SOURCES = map_gff_coords.cc
+percentid_SOURCES = percentid.cc
+prot2codon_SOURCES = prot2codon.cc
+slice_fasta_SOURCES = slice_fasta.cc
+slice_fasta_gff_SOURCES = slice_fasta_gff.cc
+slice_mercator_alignment_SOURCES = slice_mercator_alignment.cc
+translate_SOURCES = translate.cc
+
+noinst_HEADERS = 
diff --git a/src/main/Makefile.in b/src/main/Makefile.in
new file mode 100644
index 0000000..14c3044
--- /dev/null
+++ b/src/main/Makefile.in
@@ -0,0 +1,806 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at HAVE_CONDOR_TRUE@am__append_1 = -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+ at HAVE_CONDOR_TRUE@am__append_2 = \
+ at HAVE_CONDOR_TRUE@	-lMW \
+ at HAVE_CONDOR_TRUE@	-lMWRMComm \
+ at HAVE_CONDOR_TRUE@	-lMWutil \
+ at HAVE_CONDOR_TRUE@	-lNWS \
+ at HAVE_CONDOR_TRUE@	-lMWsocketmaster \
+ at HAVE_CONDOR_TRUE@    -lpthread
+
+bin_PROGRAMS = fsa$(EXEEXT) gapcleaner$(EXEEXT) \
+	isect_mercator_alignment_gff$(EXEEXT) map_coords$(EXEEXT) \
+	map_gff_coords$(EXEEXT) percentid$(EXEEXT) prot2codon$(EXEEXT) \
+	slice_fasta$(EXEEXT) slice_fasta_gff$(EXEEXT) \
+	slice_mercator_alignment$(EXEEXT) translate$(EXEEXT)
+subdir = src/main
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)"
+PROGRAMS = $(bin_PROGRAMS)
+am_fsa_OBJECTS = main.$(OBJEXT)
+fsa_OBJECTS = $(am_fsa_OBJECTS)
+fsa_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+fsa_DEPENDENCIES = $(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_gapcleaner_OBJECTS = gapcleaner.$(OBJEXT)
+gapcleaner_OBJECTS = $(am_gapcleaner_OBJECTS)
+gapcleaner_LDADD = $(LDADD)
+gapcleaner_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_isect_mercator_alignment_gff_OBJECTS =  \
+	isect_mercator_alignment_gff.$(OBJEXT)
+isect_mercator_alignment_gff_OBJECTS =  \
+	$(am_isect_mercator_alignment_gff_OBJECTS)
+isect_mercator_alignment_gff_LDADD = $(LDADD)
+isect_mercator_alignment_gff_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_map_coords_OBJECTS = map_coords.$(OBJEXT)
+map_coords_OBJECTS = $(am_map_coords_OBJECTS)
+map_coords_LDADD = $(LDADD)
+map_coords_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_map_gff_coords_OBJECTS = map_gff_coords.$(OBJEXT)
+map_gff_coords_OBJECTS = $(am_map_gff_coords_OBJECTS)
+map_gff_coords_LDADD = $(LDADD)
+map_gff_coords_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_percentid_OBJECTS = percentid.$(OBJEXT)
+percentid_OBJECTS = $(am_percentid_OBJECTS)
+percentid_LDADD = $(LDADD)
+percentid_DEPENDENCIES = $(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_prot2codon_OBJECTS = prot2codon.$(OBJEXT)
+prot2codon_OBJECTS = $(am_prot2codon_OBJECTS)
+prot2codon_LDADD = $(LDADD)
+prot2codon_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_slice_fasta_OBJECTS = slice_fasta.$(OBJEXT)
+slice_fasta_OBJECTS = $(am_slice_fasta_OBJECTS)
+slice_fasta_LDADD = $(LDADD)
+slice_fasta_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_slice_fasta_gff_OBJECTS = slice_fasta_gff.$(OBJEXT)
+slice_fasta_gff_OBJECTS = $(am_slice_fasta_gff_OBJECTS)
+slice_fasta_gff_LDADD = $(LDADD)
+slice_fasta_gff_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_slice_mercator_alignment_OBJECTS =  \
+	slice_mercator_alignment.$(OBJEXT)
+slice_mercator_alignment_OBJECTS =  \
+	$(am_slice_mercator_alignment_OBJECTS)
+slice_mercator_alignment_LDADD = $(LDADD)
+slice_mercator_alignment_DEPENDENCIES =  \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+am_translate_OBJECTS = translate.$(OBJEXT)
+translate_OBJECTS = $(am_translate_OBJECTS)
+translate_LDADD = $(LDADD)
+translate_DEPENDENCIES = $(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__DEPENDENCIES_1)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(fsa_SOURCES) $(gapcleaner_SOURCES) \
+	$(isect_mercator_alignment_gff_SOURCES) $(map_coords_SOURCES) \
+	$(map_gff_coords_SOURCES) $(percentid_SOURCES) \
+	$(prot2codon_SOURCES) $(slice_fasta_SOURCES) \
+	$(slice_fasta_gff_SOURCES) $(slice_mercator_alignment_SOURCES) \
+	$(translate_SOURCES)
+DIST_SOURCES = $(fsa_SOURCES) $(gapcleaner_SOURCES) \
+	$(isect_mercator_alignment_gff_SOURCES) $(map_coords_SOURCES) \
+	$(map_gff_coords_SOURCES) $(percentid_SOURCES) \
+	$(prot2codon_SOURCES) $(slice_fasta_SOURCES) \
+	$(slice_fasta_gff_SOURCES) $(slice_mercator_alignment_SOURCES) \
+	$(translate_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src $(am__append_1)
+
+# AM_CXXFLAGS = -finline-limit=10000 --param inline-unit-growth=70
+# Commented out b/c was causing bugs on some older compilers.
+#  --RKB & CD 4/14/09
+LDADD = $(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/fsa/libfsa.a \
+	$(top_builddir)/src/annealing/libannealing.a \
+	$(top_builddir)/src/manager/libmanager.a \
+	$(top_builddir)/src/seq/libseq.a \
+	$(top_builddir)/src/util/libutil.a \
+	$(top_builddir)/src/math/libmath.a $(am__append_2)
+ at HAVE_CONDOR_TRUE@AM_LDFLAGS = -static -L$(top_builddir)/MW/lib
+fsa_SOURCES = main.cc
+gapcleaner_SOURCES = gapcleaner.cc
+isect_mercator_alignment_gff_SOURCES = isect_mercator_alignment_gff.cc
+map_coords_SOURCES = map_coords.cc
+map_gff_coords_SOURCES = map_gff_coords.cc
+percentid_SOURCES = percentid.cc
+prot2codon_SOURCES = prot2codon.cc
+slice_fasta_SOURCES = slice_fasta.cc
+slice_fasta_gff_SOURCES = slice_fasta_gff.cc
+slice_mercator_alignment_SOURCES = slice_mercator_alignment.cc
+translate_SOURCES = translate.cc
+noinst_HEADERS = 
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/main/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/main/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	if test -n "$$list"; then \
+	  echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+	  $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+	fi; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p \
+	  ; then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' \
+	    -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	      echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	      $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' \
+	`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+fsa$(EXEEXT): $(fsa_OBJECTS) $(fsa_DEPENDENCIES) $(EXTRA_fsa_DEPENDENCIES) 
+	@rm -f fsa$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(fsa_OBJECTS) $(fsa_LDADD) $(LIBS)
+
+gapcleaner$(EXEEXT): $(gapcleaner_OBJECTS) $(gapcleaner_DEPENDENCIES) $(EXTRA_gapcleaner_DEPENDENCIES) 
+	@rm -f gapcleaner$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(gapcleaner_OBJECTS) $(gapcleaner_LDADD) $(LIBS)
+
+isect_mercator_alignment_gff$(EXEEXT): $(isect_mercator_alignment_gff_OBJECTS) $(isect_mercator_alignment_gff_DEPENDENCIES) $(EXTRA_isect_mercator_alignment_gff_DEPENDENCIES) 
+	@rm -f isect_mercator_alignment_gff$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(isect_mercator_alignment_gff_OBJECTS) $(isect_mercator_alignment_gff_LDADD) $(LIBS)
+
+map_coords$(EXEEXT): $(map_coords_OBJECTS) $(map_coords_DEPENDENCIES) $(EXTRA_map_coords_DEPENDENCIES) 
+	@rm -f map_coords$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(map_coords_OBJECTS) $(map_coords_LDADD) $(LIBS)
+
+map_gff_coords$(EXEEXT): $(map_gff_coords_OBJECTS) $(map_gff_coords_DEPENDENCIES) $(EXTRA_map_gff_coords_DEPENDENCIES) 
+	@rm -f map_gff_coords$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(map_gff_coords_OBJECTS) $(map_gff_coords_LDADD) $(LIBS)
+
+percentid$(EXEEXT): $(percentid_OBJECTS) $(percentid_DEPENDENCIES) $(EXTRA_percentid_DEPENDENCIES) 
+	@rm -f percentid$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(percentid_OBJECTS) $(percentid_LDADD) $(LIBS)
+
+prot2codon$(EXEEXT): $(prot2codon_OBJECTS) $(prot2codon_DEPENDENCIES) $(EXTRA_prot2codon_DEPENDENCIES) 
+	@rm -f prot2codon$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(prot2codon_OBJECTS) $(prot2codon_LDADD) $(LIBS)
+
+slice_fasta$(EXEEXT): $(slice_fasta_OBJECTS) $(slice_fasta_DEPENDENCIES) $(EXTRA_slice_fasta_DEPENDENCIES) 
+	@rm -f slice_fasta$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(slice_fasta_OBJECTS) $(slice_fasta_LDADD) $(LIBS)
+
+slice_fasta_gff$(EXEEXT): $(slice_fasta_gff_OBJECTS) $(slice_fasta_gff_DEPENDENCIES) $(EXTRA_slice_fasta_gff_DEPENDENCIES) 
+	@rm -f slice_fasta_gff$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(slice_fasta_gff_OBJECTS) $(slice_fasta_gff_LDADD) $(LIBS)
+
+slice_mercator_alignment$(EXEEXT): $(slice_mercator_alignment_OBJECTS) $(slice_mercator_alignment_DEPENDENCIES) $(EXTRA_slice_mercator_alignment_DEPENDENCIES) 
+	@rm -f slice_mercator_alignment$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(slice_mercator_alignment_OBJECTS) $(slice_mercator_alignment_LDADD) $(LIBS)
+
+translate$(EXEEXT): $(translate_OBJECTS) $(translate_DEPENDENCIES) $(EXTRA_translate_DEPENDENCIES) 
+	@rm -f translate$(EXEEXT)
+	$(AM_V_CXXLD)$(CXXLINK) $(translate_OBJECTS) $(translate_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gapcleaner.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/isect_mercator_alignment_gff.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/main.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_coords.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/map_gff_coords.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/percentid.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/prot2codon.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/slice_fasta.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/slice_fasta_gff.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/slice_mercator_alignment.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/translate.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
+	clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \
+	distclean distclean-compile distclean-generic distclean-tags \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-binPROGRAMS install-data install-data-am \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/main/gapcleaner.cc b/src/main/gapcleaner.cc
new file mode 100644
index 0000000..e4ec691
--- /dev/null
+++ b/src/main/gapcleaner.cc
@@ -0,0 +1,116 @@
+
+/**
+ * \file gapcleaner.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "annealing/alignment_DAG.h"
+
+using namespace fsa;
+
+static std::string program_name = "gapcleaner";
+
+// short options letters
+const char* const short_options = "vh";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " <multi-FASTA or Stockholm alignment>" << endl
+    << endl
+    << "Find the most-parsimonious ordering of indels." << endl
+    << "Finds the minimal chain decomposition of the POSET of the alignment;" << endl
+    << "this corresponds to minimizing the number of gap-openings across the sequences." << endl
+    << endl
+    << "Input protein alignment must be in multi-FASTA or Stockholm format." << endl
+    << endl;
+}
+
+
+int main (int argc, char** argv) {
+
+  std::string alignfilename;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 1 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  alignfilename = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+  // now do stuff!
+  Sequence_database seq_db;
+  Stockholm stockholm (seq_db);
+
+  bool is_mfa = false;
+  if (Alignment::detect_mfa (alignfilename))
+    is_mfa = true;
+  if (is_mfa)
+    stockholm.read_mfa (alignfilename);
+  else
+    stockholm.read_stockholm (alignfilename);
+    
+  // perform greedy DFS decomposition
+  Alignment_DAG dag (seq_db, stockholm);
+  dag.dfs_topological_sort();
+
+  // show results
+  if (is_mfa)
+    dag.get_stockholm().write_mfa (cout);
+  else
+    dag.get_stockholm().write_stockholm (cout);
+
+  return 0;
+}
diff --git a/src/main/isect_mercator_alignment_gff.cc b/src/main/isect_mercator_alignment_gff.cc
new file mode 100644
index 0000000..151cb0f
--- /dev/null
+++ b/src/main/isect_mercator_alignment_gff.cc
@@ -0,0 +1,244 @@
+
+/**
+ * \file isect_mercator_alignment_gff.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+#include <fstream>
+
+#include "config.h"
+#include "seq/gff.h"
+#include "seq/alignment.h"
+#include "seq/mercator.h"
+
+using namespace fsa;
+
+static std::string program_name = "isect_mercator_alignment_gff";
+
+static std::string type = "";
+
+static std::string datadir = ".";
+static std::string mapdir = ".";
+static std::string aligndir = ".";
+static bool stockholm = false;
+static bool lazy = false;
+static bool truncate_ok = false;
+
+static bool verbose = false;
+
+// short options letters
+const char* const short_options = "hvt:D:M:A:LUse";
+
+// long options
+static struct option long_options[] = {
+  {"help", no_argument, NULL, 'h'},
+  {"version", no_argument, NULL, 'v'},
+
+  {"type", required_argument, NULL, 't'},
+
+  {"data", required_argument, NULL, 'D'},
+  {"map", required_argument, NULL, 'M'},
+  {"align", required_argument, NULL, 'A'},
+  {"lazy", no_argument, NULL, 'L'},
+  {"truncate", no_argument, NULL, 'U'},
+
+  {"stockholm", no_argument, NULL, 's'},
+
+  {"verbose", no_argument, NULL, 'e'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " [options] <genome> <GFF file>" << endl
+    << endl
+    << "Extracts subalignments from a Mercator multiple alignment for the features in the GFF file." << endl
+    << endl
+    << "Options:" << endl
+    << "    -h, --help                  show this message" << endl
+    << "    -v, --version               show version information" << endl
+    << endl
+    << "    -t, --type <string>         only look at features of particular type" << endl
+    << endl
+    << "    -D, --data <directory>      path to map, genome and alignment files" << endl
+    << "    -M, --map <directory>       path to map and genome files" << endl
+    << "    -A, --align <directory>     path to alignment files" << endl
+    << "    -L, --lazy                  warn, rather than die, if the subalignment can't be obtained" << endl
+    << "    -U, --truncate              truncate unmappable sequence (rather than skipping) and show truncated subalignment" << endl
+    << endl
+    << "    -s, --stockholm             use and display Stockholm-format alignments with conservation statistics (default is multi-FASTA)" << endl
+    << endl
+    << "    -e, --verbose               report progress" << endl
+    << endl
+    << "PLEASE NOTE: While this program is reasonably fast if the GFF is properly" << endl
+    << "ordered by chromosome and the start and end coordinates of features, it" << endl
+    << "will be *very slow* if the GFF is not sorted."
+    << endl
+    << "Assumes that the \"seqid\" or \"name\" field (the first field) of the GFF entries" << endl
+    << "holds the chromosome name." << endl
+    << endl
+    << "Note that the GFF specification defines coordinates to be 1-based" << endl
+    << "and fully-closed, therefore representing the interval [start, end]." << endl
+    << "Conformance to this specification is assumed internally." << endl
+    << endl
+    << "If requested, unmappable sequence will be truncated to the mappable portion;" << endl
+    << "note that the truncation will favor the beginning of the requested sequence." << endl
+    << endl
+    << "If a GFF feature is on the - strand, then the corresponding" << endl
+    << "subalignment will be reverse-complemented."
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string genome;
+  std::string gfffile;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 't': // type
+      type = std::string (optarg);
+      break;
+
+    case 'D': // data directory
+      datadir = std::string (optarg);
+      break;
+
+    case 'M': // map directory
+      mapdir = std::string (optarg);
+      break;
+
+    case 'A': // align directory
+      aligndir = std::string (optarg);
+      break;
+
+    case 'L': // lazy
+      lazy = true;
+      break;
+
+    case 'U': // truncate
+      truncate_ok = true;
+      break;
+
+    case 's': // stockholm
+      stockholm = true;
+      break;
+
+    case 'e': // verbose
+      verbose = true;
+      break;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 2 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  genome = std::string (argv[optind++]);
+  gfffile = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+
+  // now do stuff!
+
+  // read GFF file
+  GFF_database gff_db;
+  gff_db.from_file (gfffile,
+		    true); // strip_leading_chr
+
+  // create Mercator map
+  Mercator_alignment mercator_alignment (mapdir != "." ? mapdir : datadir, aligndir != "." ? aligndir : datadir);
+
+  // initialize persistent sequence & alignment information for current bin
+  Sequence_database seq_db_bin;
+  Stockholm stockholm_bin (seq_db_bin);
+  unsigned bin = 0; // initialize to dummy 0 value
+
+  // turn off sync with stdio to try to increase speed of input/output to standard streams
+  std::ios::sync_with_stdio (false);
+
+  // iterate through GFF
+  for (std::vector<GFF>::const_iterator gff = gff_db.begin(); gff != gff_db.end(); ++gff) {
+    
+    // if requested, only look at features of a particular type
+    if (type.length() && type != gff->type)
+      continue;
+
+    // hold subalignment sequence information
+    Sequence_database seq_db_subalign;
+
+    // take slice
+    Stockholm* slice = mercator_alignment.slice (seq_db_subalign,
+						 bin,
+						 stockholm_bin,
+						 genome, gff->seqid,
+						 gff->strand,
+						 gff->start - 1, gff->end - 1, // convert to 0-based coordinates
+						 lazy, truncate_ok,
+						 stockholm, // annotate with homology information if stockholm
+						 verbose);
+
+    // skip empty subalignments
+    // (indicating that no mapping was found)
+    if (slice->columns() == 0)
+      continue;
+
+    // annotate entire alignment with #=GF GFF line
+    slice->add_gf_annot (Stockholm::gff_annotation, gff->to_string());
+
+    // display
+    if (stockholm) {
+      slice->annotate_with_statistics();
+      slice->write_stockholm (cout);
+    }
+    else
+      slice->write_mfa (cout);
+
+    // clean up
+    delete slice;
+
+  }
+
+  return 0;
+    
+}
diff --git a/src/main/main.cc b/src/main/main.cc
new file mode 100644
index 0000000..3d06ea4
--- /dev/null
+++ b/src/main/main.cc
@@ -0,0 +1,59 @@
+
+/**
+ * \file main.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley and Jaeyoung Do.
+ */
+
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+/**
+ * \brief Check whether this appears to be a worker instance.
+ *
+ * Examines command-line arguments and checks whether they conform
+ * to the expected format for worker instances.
+ */
+bool is_mw_worker_format (int argc, char** argv); 
+
+/**
+ * \brief Create & run an FSA object from command-line arguments
+ */
+int main (int argc, char** argv) {
+
+  if (is_mw_worker_format (argc, argv))  {
+    Manager manager;
+    return manager.mw_worker_run (argc, argv);
+  }
+  else { 
+    FSA fsa (argc, argv);
+    return fsa.run();
+  }
+}
+
+/**
+ * \brief Simple method to check whether we seem to be running as a MW_worker.
+ */
+bool is_mw_worker_format(int argc, char** argv) {
+	
+  if (argc == 5) {
+    bool chk_arg2 = (atoi(argv[2]) != 0 ) ? true : false; // 2nd parameter must be an integer value
+    bool chk_arg3 = (atoi(argv[3]) != 0 ) ? true : false; // 3rd parameter must be an integer value
+
+    int dot_cnt = 0;
+    char tmp_argv[512],*dot_pch;
+
+    strcpy(tmp_argv, argv[4]);
+    dot_pch = strtok (tmp_argv, ".");
+
+    while (dot_pch != NULL) {    // check whether 4th parameter is a valid IPv4
+      ++dot_cnt;
+      dot_pch = strtok(NULL, ".");
+    }
+
+    if (chk_arg2 && chk_arg3 && dot_cnt == 4) 
+      return true;
+  }	
+  return false;
+}
diff --git a/src/main/map_coords.cc b/src/main/map_coords.cc
new file mode 100644
index 0000000..5e1b894
--- /dev/null
+++ b/src/main/map_coords.cc
@@ -0,0 +1,205 @@
+
+/**
+ * \file map_coords.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/alignment.h"
+#include "seq/mercator.h"
+
+using namespace fsa;
+
+static std::string program_name = "map_coords";
+
+static std::string datadir = ".";
+static std::string mapdir = ".";
+static std::string aligndir = ".";
+static bool lazy = false;
+static bool truncate_ok = false;
+
+// short options letters
+const char* const short_options = "vhD:M:A:LU";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  {"data", required_argument, NULL, 'D'},
+  {"map", required_argument, NULL, 'M'},
+  {"align", required_argument, NULL, 'A'},
+  {"lazy", no_argument, NULL, 'L'},
+  {"truncate", no_argument, NULL, 'U'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " [options] <source genome> <chromosome> <start> <end> <strand> <target genome>" << endl
+    << endl
+    << "Map coordinates from one genome to another using a Mercator multiple alignment." << endl
+    << endl
+    << "Options:" << endl
+    << "    -h, --help                  show this message" << endl
+    << endl
+    << "    -D, --data <directory>      path to map, genome and alignment files" << endl
+    << "    -M, --map <directory>       path to map and genome files" << endl
+    << "    -A, --align <directory>     path to alignment files" << endl
+    << "    -L, --lazy                  warn, rather than die, if the subalignment can't be obtained" << endl
+    << "    -U, --truncate              truncate unmappable sequence (rather than skipping) and show truncated subalignment" << endl
+    << endl
+    << "Assumes that coordinates are 1-based and fully-closed," << endl
+    << "therefore representing the interval [start, end]." << endl
+    << endl
+    << "If requested, unmappable sequence will be truncated to the mappable portion;" << endl
+    << "note that the truncation will favor the beginning of the requested sequence." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string genome_source;
+  std::string chromosome_source;
+  unsigned start_source, end_source;
+  char strand_source;
+  std::string genome_target;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case 'D': // data directory
+      datadir = std::string (optarg);
+      break;
+
+    case 'M': // map directory
+      mapdir = std::string (optarg);
+      break;
+
+    case 'A': // align directory
+      aligndir = std::string (optarg);
+      break;
+
+    case 'L': // lazy
+      lazy = true;
+      break;
+
+    case 'U': // truncate
+      truncate_ok = true;
+      break;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 6 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  genome_source = std::string (argv[optind++]);
+  chromosome_source = std::string (argv[optind++]);
+  start_source = static_cast<size_t> (atoi (argv[optind++]));
+  end_source = static_cast<size_t> (atoi (argv[optind++]));
+  strand_source = argv[optind++][0];
+  genome_target = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+
+  // now do stuff!
+
+  // create Mercator map
+  Mercator_alignment mercator_alignment (mapdir != "." ? mapdir : datadir, aligndir != "." ? aligndir : datadir);
+
+  // initialize persistent sequence & alignment information for current bin
+  Sequence_database seq_db_bin;
+  Stockholm stockholm_bin (seq_db_bin);
+  unsigned bin = 0; // initialize to dummy 0 value
+
+  // use the alignment to find the homologous interval
+  Genomic_interval region_target = mercator_alignment.find_homologous_interval (bin,
+										stockholm_bin,
+										genome_source, chromosome_source,
+										start_source - 1, end_source - 1, // convert to 0-based coordinates
+										genome_target,
+										lazy, truncate_ok);
+
+
+  // check that it was mapped successfully
+  // (Mercator_alignment::find_homologous_interval returns an empty value
+  // if it wasn't or if homologous subsequence is empty)
+  // NB no need to enforce lazy here, b/c find_homologous_interval does this for us
+  if (region_target.genome == "") {
+    cerr << "WARNING: No homologous sequence found (all gaps)." << endl;
+    return 0;
+  }
+
+  // get the Mercator_interval for the source
+  const size_t idx_source = mercator_alignment.find_mercator_interval (genome_source, chromosome_source,
+								       start_source - 1, end_source - 1, // convert to 0-based coordinates
+								       !truncate_ok);
+  assert (idx_source < mercator_alignment.size());
+  const Mercator_interval& interval_source = mercator_alignment.get_interval (idx_source);
+
+  // use the source interval to determine whether the source feature was 
+  // reverse-complemented w.r.t. the strand in the Mercator_interval
+  // if it was, then the target feature will also be reverse-complemented
+  // w.r.t. the strand in the Mercator_interval
+  const bool is_rc = (interval_source.strand != strand_source);
+
+  std::string chromosome_target = region_target.chromosome;
+  size_t start_target = region_target.start + 1; // convert back to 1-based coordinates
+  size_t end_target = region_target.end + 1;
+  char strand_target;
+  if (strand_source == GFF::unknown_strand)   // if the source feature had no annotated strand, then do the same for the target feature
+      strand_target = GFF::unknown_strand;
+  else {                           // otherwise set the target strand appropriately using the homology mapping implied by the alignment
+    strand_target = region_target.strand;
+    if (is_rc)
+      Sequence::complement_strand (strand_target);
+  }
+
+  cout << genome_target << '\t' << chromosome_target << '\t'
+       << start_target << '\t' << end_target << '\t'
+       << strand_target << endl;
+
+  return 0;
+    
+}
diff --git a/src/main/map_gff_coords.cc b/src/main/map_gff_coords.cc
new file mode 100644
index 0000000..f936204
--- /dev/null
+++ b/src/main/map_gff_coords.cc
@@ -0,0 +1,204 @@
+
+/**
+ * \file map_gff_coords.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/gff.h"
+#include "seq/alignment.h"
+#include "seq/mercator.h"
+
+using namespace fsa;
+
+static std::string program_name = "map_gff_coords";
+
+static std::string type = "";
+
+static std::string datadir = ".";
+static std::string mapdir = ".";
+static std::string aligndir = ".";
+static bool lazy = false;
+static bool truncate_ok = false;
+static bool force_entry = false;
+
+static bool verbose = false;
+
+// short options letters
+const char* const short_options = "vht:D:M:A:LUf:e";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  {"type", required_argument, NULL, 't'},
+
+  {"data", required_argument, NULL, 'D'},
+  {"map", required_argument, NULL, 'M'},
+  {"align", required_argument, NULL, 'A'},
+  {"lazy", no_argument, NULL, 'L'},
+  {"truncate", no_argument, NULL, 'U'},
+
+  {"force-entry", no_argument, NULL, 'f'},
+
+  {"verbose", no_argument, NULL, 'e'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " [options] <source genome> <source GFF file> <target genome>" << endl
+    << endl
+    << "Map coordinates of GFF features from one genome to another using a Mercator multiple alignment." << endl
+    << endl
+    << "Options:" << endl
+    << "    -h, --help                  show this message" << endl
+    << endl
+    << "    -t, --type <string>         only look at features of particular type" << endl
+    << endl
+    << "    -D, --data <directory>      path to map, genome and alignment files" << endl
+    << "    -M, --map <directory>       path to map and genome files" << endl
+    << "    -A, --align <directory>     path to alignment files" << endl
+    << "    -L, --lazy                  warn, rather than die, if the subalignment can't be obtained" << endl
+    << "    -U, --truncate              truncate unmappable sequence (rather than skipping) and show truncated subalignment" << endl
+    << endl
+    << "    -f, --force-entry           if a feature can't be mapped, then add an empty entry to the GFF file (rather than skipping it entirely); implies --lazy" << endl
+    << endl
+    << "    -e, --verbose               report progress" << endl
+    << endl
+    << "PLEASE NOTE: While this program is reasonably fast if the GFF is properly" << endl
+    << "ordered by chromosome and the start and end coordinates of features, it" << endl
+    << "will be *very slow* if the GFF is not sorted."
+    << endl
+    << "Assumes that the \"seqid\" or \"name\" field (the first field) of the GFF entries" << endl
+    << "holds the chromosome name." << endl
+    << endl
+    << "Note that the GFF specification defines coordinates to be 1-based" << endl
+    << "and fully-closed, therefore representing the interval [start, end]." << endl
+    << "Conformance to this specification is assumed internally." << endl
+    << endl
+    << "If requested, unmappable sequence will be truncated to the mappable portion;" << endl
+    << "note that the truncation will favor the beginning of the requested sequence." << endl
+    << endl
+    << "If a GFF feature is on the + strand for the source genome but" << endl
+    << "the corresponding homologous region in the target genome is on the - strand," << endl
+    << "then the mapped GFF feature will be reported as on the - strand." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string genome_source;
+  std::string gfffile;
+  std::string genome_target;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case 't': // type
+      type = std::string (optarg);
+      break;
+
+    case 'D': // data directory
+      datadir = std::string (optarg);
+      break;
+
+    case 'M': // map directory
+      mapdir = std::string (optarg);
+      break;
+
+    case 'A': // align directory
+      aligndir = std::string (optarg);
+      break;
+
+    case 'L': // lazy
+      lazy = true;
+      break;
+
+    case 'U': // truncate
+      truncate_ok = true;
+      break;
+
+    case 'f': // force-entry
+      force_entry = true;
+      lazy = true;
+      break;
+
+    case 'e': // verbose
+      verbose = true;
+      break;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 3 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  genome_source = std::string (argv[optind++]);
+  gfffile = std::string (argv[optind++]);
+  genome_target = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+
+  // now do stuff!
+
+  // read GFF file
+  GFF_database gff_db_from;
+  gff_db_from.from_file (gfffile);
+
+  // create Mercator map
+  Mercator_alignment mercator_alignment (mapdir != "." ? mapdir : datadir, aligndir != "." ? aligndir : datadir);
+
+  // map the GFF!
+  GFF_database gff_db_to = mercator_alignment.map_gff_database (genome_source, genome_target,
+								gff_db_from,
+								lazy, truncate_ok,
+								verbose,
+								force_entry);
+
+  gff_db_to.write (cout);
+
+  return 0;
+    
+}
diff --git a/src/main/percentid.cc b/src/main/percentid.cc
new file mode 100644
index 0000000..14e10a5
--- /dev/null
+++ b/src/main/percentid.cc
@@ -0,0 +1,108 @@
+
+/**
+ * \file percentid.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+static std::string program_name = "percentid";
+
+// short options letters
+const char* const short_options = "vh";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " <multi-FASTA or Stockholm alignment>" << endl
+    << endl
+    << "Calculate the percentage identity of the passed alignment." << endl
+    << endl
+    << "Input protein alignment must be in multi-FASTA or Stockholm format." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string alignfilename;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 1 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  alignfilename = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+  // now do stuff!
+
+  // read in alignment
+  Sequence_database seq_db;
+  Stockholm stockholm (seq_db);
+  bool is_mfa = false;
+  if (Alignment::detect_mfa (alignfilename))
+    is_mfa = true;
+  if (is_mfa)
+    stockholm.read_mfa (alignfilename);
+  else
+    stockholm.read_stockholm (alignfilename);
+  
+  cout << stockholm.percent_id() << endl;
+
+  return 0;
+    
+}
diff --git a/src/main/prot2codon.cc b/src/main/prot2codon.cc
new file mode 100644
index 0000000..8387d90
--- /dev/null
+++ b/src/main/prot2codon.cc
@@ -0,0 +1,133 @@
+
+/**
+ * \file prot2codon.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+static std::string program_name = "prot2codon";
+
+// short options letters
+const char* const short_options = "vh";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " <multi-FASTA or Stockholm alignment> <FASTA file>" << endl
+    << endl
+    << "Find the codon alignment corresponding to the given protein alignment." << endl
+    << endl
+    << "Input protein alignment must be in multi-FASTA or Stockholm format." << endl
+    << "Input nucleotide sequences must be in FASTA format." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string alignfilename;
+  std::string seqfilename;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 2 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  alignfilename = std::string (argv[optind++]);
+  seqfilename = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+  // now do stuff!
+
+  // read in protein alignment
+  Sequence_database seq_db_aa;
+  Stockholm stockholm_aa (seq_db_aa);
+  bool is_mfa = false;
+  if (Alignment::detect_mfa (alignfilename))
+    is_mfa = true;
+  if (is_mfa)
+    stockholm_aa.read_mfa (alignfilename);
+  else
+    stockholm_aa.read_stockholm (alignfilename);
+  
+  // check correct alphabet
+  Protein_alphabet prot = Protein_alphabet();
+  if (!seq_db_aa.matches_alphabet (prot, 0.75)) { // use loose threshold for calling it protein
+    cerr << "ERROR: Input alignment doesn't seem to be protein sequence; I'm bailing." << endl;
+    return 1;
+  }
+
+  // read in nucleotide fasta file
+  if (!Sequence::detect_fasta (seqfilename)) {
+    cerr << "ERROR: Input nucleotide sequences must be in FASTA format.";
+    return 1;
+  }
+  Sequence_database seq_db_codon;
+  seq_db_codon.read_fasta (seqfilename, Alignment::is_gap_char,
+			   false, // strip_leading_chr
+			   true); // verbose
+
+  // translate sequences & display  
+  Stockholm stockholm_codon = stockholm_aa.get_codon_from_aa_alignment (seq_db_codon);
+  if (is_mfa)
+    stockholm_codon.write_mfa (cout);
+  else
+    stockholm_codon.write_stockholm (cout);
+
+  return 0;
+    
+}
diff --git a/src/main/slice_fasta.cc b/src/main/slice_fasta.cc
new file mode 100644
index 0000000..d497cdd
--- /dev/null
+++ b/src/main/slice_fasta.cc
@@ -0,0 +1,170 @@
+
+/**
+ * \file slice_fasta.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+static std::string program_name = "slice_fasta";
+
+// short options letters
+const char* const short_options = "vh";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " <FASTA file> <sequence name> <start> <end> <strand>" << endl
+    << endl
+    << "Slice a subsequence from an input FASTA file." << endl
+    << "Assumes 1-based, fully-closed coordinates." << endl
+    << "If <strand> is omitted, then the + strand is assumed." << endl
+    << "If the - strand is requested, then the subsequence is pulled out and then reverse-complemented." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string filename;
+  std::string seqname;
+  unsigned start;
+  unsigned end;
+  char strand = '+';
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if ((optind + 4 != argc) && (optind + 5 != argc)) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  filename = std::string (argv[optind++]);
+  seqname = std::string (argv[optind++]);
+  Util::strip_leading_chr (seqname);
+  start = static_cast<unsigned> (atoi (argv[optind++]));
+  end = static_cast<unsigned> (atoi (argv[optind++]));
+  // optionally get strand
+  if (optind + 1 == argc)
+    strand = argv[optind++][0];
+
+  // check that arguments are sane
+  if (strand != '+' && strand != '-') {
+    print_usage (cerr);
+    return 1;
+  }
+
+  // check that coordinates are sane
+  if (end < start) {
+    cerr << "ERROR: Please enter valid coordinates." << endl;
+    return 1;
+  }
+  if (start == 0 || end == 0) {
+    cerr << "ERROR: Please enter valid coordinates (remember that they are 1-based)." << endl;
+    return 1;
+  }
+
+  assert (optind == argc);
+
+  // now do stuff!
+  Sequence_database seq_db;
+  if (!Sequence::detect_fasta (filename)) {
+    cerr << "ERROR: Input nucleotide sequences must be in FASTA format.";
+    return 1;
+  }
+  seq_db.read_fasta (filename, Alignment::is_gap_char,
+		     true,  // strip_leading_chr
+		     true); // verbose
+
+  // get requested subsequence
+  if (!seq_db.exists_seq (seqname)) {
+    cerr << "ERROR: No sequence named '" << seqname << "'." << endl
+	 << "Available sequences are:" << endl
+	 << Util::join (seq_db.get_sequence_list(), "\t") << endl;
+    return 1;
+  }
+  const Sequence& sequence = seq_db.get_seq (seqname);
+
+  // convert to 0-based coordinates
+  --start;
+  --end;
+
+  // check coordinates sane
+  if (start >= sequence.length()) {
+    cerr << "ERROR: Requested coordinates are out of bounds." << endl;
+    exit (1);
+  }
+
+  // take subsequence
+  Sequence* subseq = sequence.subsequence (start, end);
+
+  // reverse-complement if relevant
+  const DNA_alphabet dna_alphabet;
+  if (strand == '-') {
+    if (seq_db.matches_alphabet (dna_alphabet))
+      subseq->revcomp (dna_alphabet);
+    else {
+      cerr << "ERROR: Sequences in FASTA file don't match DNA alphabet, so I can't take the reverse-complement." << endl;
+      return 1;
+    }
+  }
+
+  // display  
+  subseq->write_fasta (cout);
+
+  // clean up
+  delete subseq;
+
+  return 0;
+    
+}
diff --git a/src/main/slice_fasta_gff.cc b/src/main/slice_fasta_gff.cc
new file mode 100644
index 0000000..e1d48c2
--- /dev/null
+++ b/src/main/slice_fasta_gff.cc
@@ -0,0 +1,173 @@
+
+/**
+ * \file slice_fasta.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/gff.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+static std::string program_name = "slice_fasta";
+
+static std::string type = "";
+
+// short options letters
+const char* const short_options = "vht:";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  {"type", required_argument, NULL, 't'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " [options] <FASTA file> <GFF file>" << endl
+    << endl
+    << "Options:" << endl
+    << "    -t, --type <string>         only look at features of particular type" << endl
+    << endl
+    << "Slice subsequences from an input FASTA file." << endl
+    << "Assumes 1-based, fully-closed coordinates." << endl
+    << "If no strand information is available, then the + strand is assumed." << endl
+    << "If the - strand is requested, then the subsequence is pulled out and then reverse-complemented." << endl
+    << endl
+    << "Assumes a DNA alphabet." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string filename;
+  std::string gff_filename;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 't': // type
+      type = std::string (optarg);
+      break;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 2 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  filename = std::string (argv[optind++]);
+  gff_filename = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+  // read in sequence
+  Sequence_database seq_db;
+  if (!Sequence::detect_fasta (filename)) {
+    cerr << "ERROR: Input nucleotide sequences must be in FASTA format.";
+    return 1;
+  }
+  seq_db.read_fasta (filename, Alignment::is_gap_char,
+		     true,  // strip_leading_chr
+		     true); // verbose
+
+  // read GFF file
+  GFF_database gff_db;
+  gff_db.from_file (gff_filename,
+		    true); // strip_leading_chr
+
+  // initialize alphabet for reverse-complementing
+  const DNA_alphabet dna_alphabet;
+
+  // iterate through GFF
+  for (std::vector<GFF>::const_iterator gff = gff_db.begin(); gff != gff_db.end(); ++gff) {
+    
+    // if requested, only look at features of a particular type
+    if (type.length() && type != gff->type)
+      continue;
+
+    // confirm that we have sequence data for this chromosome
+    if (!seq_db.exists_seq (gff->seqid)) {
+      cerr << "WARNING: No sequence data found for requested chromosome '" << gff->seqid << "'." << endl;
+      continue;
+    }
+
+    // get sequence data
+    const Sequence& sequence = seq_db.get_seq (gff->seqid);
+
+    // convert to 0-based coordinates
+    const size_t start = gff->start - 1;
+    const size_t end = gff->end - 1;
+
+    // check coordinates sane
+    if (gff->start - 1 >= sequence.length()) {
+      cerr << "ERROR: Requested coordinates are out of bounds:" << endl
+	   << *gff << endl;
+      exit (1);
+    }
+
+    // take subsequence
+    Sequence* subseq = sequence.subsequence (start, end);
+
+    // replace chromosome name with GFF entry
+    subseq->name = gff->to_string();
+
+    // reverse-complement if relevant
+    if (gff->strand == '-')
+      subseq->revcomp (dna_alphabet);
+
+    // display  
+    subseq->write_fasta (cout);
+
+    // clean up
+    delete subseq;
+
+  }
+
+  return 0;
+    
+}
diff --git a/src/main/slice_mercator_alignment.cc b/src/main/slice_mercator_alignment.cc
new file mode 100644
index 0000000..f220af8
--- /dev/null
+++ b/src/main/slice_mercator_alignment.cc
@@ -0,0 +1,227 @@
+
+/**
+ * \file slice_mercator_alignment.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+#include <fstream>
+
+#include "config.h"
+#include "seq/alignment.h"
+#include "seq/mercator.h"
+
+using namespace fsa;
+
+static std::string program_name = "slice_mercator_alignment";
+
+static std::string datadir = ".";
+static std::string mapdir = ".";
+static std::string aligndir = ".";
+static bool stockholm = false;
+static bool lazy = false;
+static bool truncate_ok = false;
+static bool zerobased = false;
+static bool halfopen = false;
+
+// short options letters
+const char* const short_options = "vhD:M:A:LUs0o";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  {"data", required_argument, NULL, 'D'},
+  {"map", required_argument, NULL, 'M'},
+  {"align", required_argument, NULL, 'A'},
+  {"lazy", no_argument, NULL, 'L'},
+  {"truncate", no_argument, NULL, 'U'},
+
+  {"stockholm", no_argument, NULL, 's'},
+
+  {"zerobased", no_argument, NULL, '0'},
+  {"halfopen", no_argument, NULL, 'o'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " [options] <genome> <chromosome> <start> <end> <strand>" << endl
+    << endl
+    << "Extracts the corresponding subalignment from a Mercator multiple alignment." << endl
+    << endl
+    << "Options:" << endl
+    << "    -h, --help                  show this message" << endl
+    << endl
+    << "    -D, --data <directory>      path to map, genome and alignment files" << endl
+    << "    -M, --map <directory>       path to map and genome files" << endl
+    << "    -A, --align <directory>     path to alignment files" << endl
+    << "    -L, --lazy                  warn, rather than die, if the subalignment can't be obtained" << endl
+    << "    -U, --truncate              truncate unmappable sequence (rather than skipping) and show truncated subalignment" << endl
+    << endl
+    << "    -s, --stockholm             use and display Stockholm-format alignments with conservation statistics (default is multi-FASTA)" << endl
+    << endl
+    << "    -0, --zerobased             coordinates are 0-based (default is 1-based)" << endl
+    << "    -o, --halfopen              end coordinate is open, i.e., [start, end)" << endl
+    << endl
+    << "Assumes that coordinates are 1-based and fully-closed," << endl
+    << "therefore representing the interval [start, end]." << endl
+    << endl
+    << "If requested, unmappable sequence will be truncated to the mappable portion;" << endl
+    << "note that the truncation will favor the beginning of the requested sequence." << endl
+    << endl
+    << "If the requested sequence is on the - strand, then the corresponding" << endl
+    << "subalignment will be reverse-complemented." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string genome;
+  std::string chromosome;
+  unsigned start;
+  unsigned end;
+  char strand;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case 'D': // data directory
+      datadir = std::string (optarg);
+      break;
+
+    case 'M': // map directory
+      mapdir = std::string (optarg);
+      break;
+
+    case 'A': // align directory
+      aligndir = std::string (optarg);
+      break;
+
+    case 'L': // lazy
+      lazy = true;
+      break;
+
+    case 'U': // truncate
+      truncate_ok = true;
+      break;
+
+    case 's': // stockholm
+      stockholm = true;
+      break;
+
+    case '0': // zerobased
+      zerobased = true;
+      break;
+
+    case 'o': // halfopen
+      halfopen = true;
+      break;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // get the rest of the command-line arguments
+  if (optind + 5 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  genome = std::string (argv[optind++]);
+  chromosome = std::string (argv[optind++]);
+  start = static_cast<unsigned> (atoi (argv[optind++]));
+  end = static_cast<unsigned> (atoi (argv[optind++]));
+  strand = argv[optind++][0];
+
+  // check that arguments are sane
+  if (strand != '+' && strand != '-') {
+    print_usage (cerr);
+    return 1;
+  }
+
+  // check that coordinates are sane
+  if (end < start) {
+    cerr << "ERROR: Please enter valid coordinates." << endl;
+    return 1;
+  }
+  if (!zerobased && start == 0) {
+    cerr << "ERROR:Please enter a valid start coordinate (remember that they are 1-based by default)." << endl;
+    return 1;
+  }
+
+  assert (optind == argc);
+
+
+  // now do stuff!
+  Sequence_database seq_db;
+
+  // map coordinates to make them 0-based and fully-closed
+  if (!zerobased) {
+    --start; --end;
+  }
+  if (halfopen) {
+    --end;
+  }
+
+  // turn off sync with stdio to try to increase speed of input/output to standard streams
+  std::ios::sync_with_stdio (false);
+
+  // take alignment slice
+  Mercator_alignment mercator_alignment (mapdir != "." ? mapdir : datadir, aligndir != "." ? aligndir : datadir);
+  Sequence_database seq_db_subalign;
+  Stockholm* slice = mercator_alignment.slice (seq_db_subalign,
+					       genome, chromosome,
+					       strand,
+					       start, end,
+					       lazy, truncate_ok,
+					       stockholm);   // annotate with homology information if stockholm
+
+  // display
+  if (stockholm) {
+    slice->annotate_with_statistics();
+    slice->write_stockholm (cout);
+  }
+  else
+    slice->write_mfa (cout);
+
+  // clean up
+  delete slice;
+
+  return 0;
+    
+}
diff --git a/src/main/translate.cc b/src/main/translate.cc
new file mode 100644
index 0000000..b7803be
--- /dev/null
+++ b/src/main/translate.cc
@@ -0,0 +1,107 @@
+
+/**
+ * \file translate.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <getopt.h>
+
+#include "config.h"
+#include "seq/sequence.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+static std::string program_name = "translate";
+
+// short options letters
+const char* const short_options = "vh";
+
+// long options
+static struct option long_options[] = {
+  {"version", no_argument, NULL, 'v'},
+  {"help", no_argument, NULL, 'h'},
+
+  /* required NULL termination of array */
+  {NULL, 0, NULL, 0}
+};
+
+static void print_version (std::ostream& o) {
+  o << program_name << " from " << PACKAGE_STRING << endl;
+}
+
+static void print_usage (std::ostream& o) {
+  print_version (o);
+  o << endl
+    << "Usage: " << program_name << " <FASTA file>" << endl
+    << endl
+    << "Translate input nucleotide sequences into protein sequence." << endl
+    << endl
+    << "Input nucleotide sequences must be in FASTA format." << endl
+    << "Uses the first reading frame and drops incomplete codons at ends of sequences." << endl
+    << endl;
+}
+
+int main (int argc, char** argv) {
+
+  std::string filename;
+
+  // parse options
+  int c;
+  int option_index = 0; // getopt_long stores option index here
+  while (1) {
+
+    // get next option
+    c = getopt_long (argc, argv, short_options,
+		     long_options, &option_index);
+
+    if (c == -1)
+      break;
+
+    switch (c) {
+
+    case 'v': // version message
+      print_version (cout);
+      return 0;
+
+    case 'h': // help message
+      print_usage (cout);
+      return 0;
+
+    case '?': // invalid option
+      print_usage (cerr);
+      return 1;
+
+    default:  // unexpected
+      abort();
+
+    }
+  }
+
+  // stuff
+  if (optind + 1 != argc) {
+    print_usage (cerr);
+    return 1;
+  }
+
+  filename = std::string (argv[optind++]);
+
+  assert (optind == argc);
+
+  // now do stuff!
+  Sequence_database seq_db;
+  if (!Sequence::detect_fasta (filename)) {
+    cerr << "ERROR: Input nucleotide sequences must be in FASTA format.";
+    return 1;
+  }
+  seq_db.read_fasta (filename, Alignment::is_gap_char,
+		     false, // strip_leading_chr
+		     true); // verbose
+
+  // translate sequences & display  
+  seq_db.translate().write_fasta (cout);
+
+  return 0;
+    
+}
diff --git a/src/manager/Makefile.am b/src/manager/Makefile.am
new file mode 100644
index 0000000..44cae56
--- /dev/null
+++ b/src/manager/Makefile.am
@@ -0,0 +1,49 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src -Wno-deprecated
+
+noinst_LIBRARIES = libmanager.a
+
+libmanager_a_SOURCES = \
+	manager.cc \
+	mw_adapter.cc \
+	db_adapter.cc \
+	db_misc.cc 
+
+noinst_HEADERS = \
+	manager.h \
+	mw_adapter.h \
+	db_adapter.h \
+	db_misc.h
+
+if HAVE_CONDOR
+
+AM_CPPFLAGS += -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+
+libmanager_a_SOURCES += \
+	mw_master.cc \
+	mw_worker.cc \
+	mw_task.cc \
+	transfer_data.cc
+
+noinst_HEADERS += \
+	mw_master.h \
+	mw_worker.h \
+	mw_task.h
+
+else
+
+if HAVE_POSTGRES
+libmanager_a_SOURCES += \
+	transfer_data.cc 
+endif
+
+endif
+
+if HAVE_POSTGRES
+
+libmanager_a_SOURCES += \
+	db_postgres.cc 
+
+noinst_HEADERS += \
+	db_postgres.h 
+
+endif
diff --git a/src/manager/Makefile.in b/src/manager/Makefile.in
new file mode 100644
index 0000000..486d3bc
--- /dev/null
+++ b/src/manager/Makefile.in
@@ -0,0 +1,585 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at HAVE_CONDOR_TRUE@am__append_1 = -I$(top_srcdir)/MW/src -I$(top_srcdir)/MW/src/MWControlTasks -I$(top_srcdir)/MW/src/RMComm -I$(top_srcdir)/MW/src/RMComm/MW-Socket
+ at HAVE_CONDOR_TRUE@am__append_2 = \
+ at HAVE_CONDOR_TRUE@	mw_master.cc \
+ at HAVE_CONDOR_TRUE@	mw_worker.cc \
+ at HAVE_CONDOR_TRUE@	mw_task.cc \
+ at HAVE_CONDOR_TRUE@	transfer_data.cc
+
+ at HAVE_CONDOR_TRUE@am__append_3 = \
+ at HAVE_CONDOR_TRUE@	mw_master.h \
+ at HAVE_CONDOR_TRUE@	mw_worker.h \
+ at HAVE_CONDOR_TRUE@	mw_task.h
+
+ at HAVE_CONDOR_FALSE@@HAVE_POSTGRES_TRUE at am__append_4 = \
+ at HAVE_CONDOR_FALSE@@HAVE_POSTGRES_TRUE@	transfer_data.cc 
+
+ at HAVE_POSTGRES_TRUE@am__append_5 = \
+ at HAVE_POSTGRES_TRUE@	db_postgres.cc 
+
+ at HAVE_POSTGRES_TRUE@am__append_6 = \
+ at HAVE_POSTGRES_TRUE@	db_postgres.h 
+
+subdir = src/manager
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(am__noinst_HEADERS_DIST)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libmanager_a_AR = $(AR) $(ARFLAGS)
+libmanager_a_LIBADD =
+am__libmanager_a_SOURCES_DIST = manager.cc mw_adapter.cc db_adapter.cc \
+	db_misc.cc mw_master.cc mw_worker.cc mw_task.cc \
+	transfer_data.cc db_postgres.cc
+ at HAVE_CONDOR_TRUE@am__objects_1 = mw_master.$(OBJEXT) \
+ at HAVE_CONDOR_TRUE@	mw_worker.$(OBJEXT) mw_task.$(OBJEXT) \
+ at HAVE_CONDOR_TRUE@	transfer_data.$(OBJEXT)
+ at HAVE_CONDOR_FALSE@@HAVE_POSTGRES_TRUE at am__objects_2 = transfer_data.$(OBJEXT)
+ at HAVE_POSTGRES_TRUE@am__objects_3 = db_postgres.$(OBJEXT)
+am_libmanager_a_OBJECTS = manager.$(OBJEXT) mw_adapter.$(OBJEXT) \
+	db_adapter.$(OBJEXT) db_misc.$(OBJEXT) $(am__objects_1) \
+	$(am__objects_2) $(am__objects_3)
+libmanager_a_OBJECTS = $(am_libmanager_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libmanager_a_SOURCES)
+DIST_SOURCES = $(am__libmanager_a_SOURCES_DIST)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__noinst_HEADERS_DIST = manager.h mw_adapter.h db_adapter.h \
+	db_misc.h mw_master.h mw_worker.h mw_task.h db_postgres.h
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src -Wno-deprecated $(am__append_1)
+noinst_LIBRARIES = libmanager.a
+libmanager_a_SOURCES = manager.cc mw_adapter.cc db_adapter.cc \
+	db_misc.cc $(am__append_2) $(am__append_4) $(am__append_5)
+noinst_HEADERS = manager.h mw_adapter.h db_adapter.h db_misc.h \
+	$(am__append_3) $(am__append_6)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/manager/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/manager/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libmanager.a: $(libmanager_a_OBJECTS) $(libmanager_a_DEPENDENCIES) $(EXTRA_libmanager_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libmanager.a
+	$(AM_V_AR)$(libmanager_a_AR) libmanager.a $(libmanager_a_OBJECTS) $(libmanager_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libmanager.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/db_adapter.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/db_misc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/db_postgres.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/manager.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mw_adapter.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mw_master.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mw_task.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mw_worker.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/transfer_data.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/manager/db_adapter.cc b/src/manager/db_adapter.cc
new file mode 100644
index 0000000..e76bc3e
--- /dev/null
+++ b/src/manager/db_adapter.cc
@@ -0,0 +1,263 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include "manager/db_adapter.h"
+
+using namespace fsa;
+ 
+DB_adapter::DB_adapter() {
+#ifdef HAVE_POSTGRES
+	m_seqs_schema_id  = DB_NOT_AVAILABLE;
+	m_params_table_id = DB_NOT_AVAILABLE;
+
+	m_db_connection = NULL;
+#endif
+}
+
+DB_adapter::~DB_adapter() {
+	// disconnect the connection
+	disconnect_db();
+}
+
+void DB_adapter::disconnect_db () {
+#ifdef HAVE_POSTGERS
+	if (!m_db_connection) {
+		// if there's previous connection garbage, delete it and create new one 
+		m_db_connection->disconnect_db();
+		delete m_db_connection;
+	}
+	
+	// set various ids as "UNDETERMINED" ids
+	m_seqs_schema_id = DB_NOT_AVAILABLE;
+	m_params_table_id = DB_NOT_AVAILABLE;
+	m_db_connection = NULL;
+
+#endif
+
+}
+
+bool DB_adapter::connect_db (const char *db_hostname, const char *db_hostaddr, const char* db_name, 
+		const int db_port, const char *db_user, const char *db_password) {
+#ifndef HAVE_POSTGRES
+	return DB_BAD;
+#else
+	m_db_connection = new DB_postgres();
+
+	// can we establish a connection to the database server?
+	bool is_db_available = m_db_connection->connect_db(db_hostname, db_hostaddr, db_name, db_port, db_user, db_password);
+
+	if ( !is_db_available) {
+		// in the case that the database we are willing to connect is not running (or does not response)
+		delete m_db_connection;
+		m_db_connection = NULL;
+	}
+
+	return is_db_available;
+#endif
+}
+
+bool DB_adapter::set_up_ids (const int seqs_schema_id, const int params_table_id, const int worker_id) {
+#ifndef HAVE_POSTGRES
+	return DB_BAD;
+#else
+	// set sequence schema id
+	m_db_connection->set_seqs_schema_id (seqs_schema_id);
+
+	// set parameter table id
+	m_db_connection->set_params_table_id (params_table_id);
+
+	// set worker id
+	m_db_connection->set_worker_id (worker_id);
+
+	m_seqs_schema_id = seqs_schema_id;
+	m_params_table_id = params_table_id;
+
+	return DB_OK;
+#endif
+}
+
+bool DB_adapter::init_database(const Sequence_database &seq_db_internal, const DB_opts &db_opts) {
+
+#ifndef HAVE_POSTGRES
+	return DB_BAD;
+#else
+	if ( is_data_available() )  {
+		// in the case of the input sequences that has been previously considered
+		m_db_connection->update_fsa_table ();
+		m_db_connection->update_params_table (db_opts.num_parallelized_jobs);
+	}
+	else {
+		// if the input sequences are available - but possibly there's no relevant parameters
+		if ( is_seqs_available() ) 
+			m_db_connection->update_fsa_table ();
+		else {
+		  std::string whole_seqs    = "";
+			float seqs_avr_length = 0.0;
+			uint32_t hash_key     = 0;
+			int num_seqs          = seq_db_internal.size();
+
+			// generate a hash key based on the input sequences
+			for (int i=0; i<num_seqs; i++) {
+			  whole_seqs += seq_db_internal.get_seq (i).seq;
+			  seqs_avr_length += (float) seq_db_internal.get_seq (i).length();
+			}
+			seqs_avr_length /= (float) num_seqs; 
+			seqs_avr_length = (int) seqs_avr_length;
+			hash_key = Hash_functions::hsieh_hash(whole_seqs.c_str());
+			
+			// create fsa main table "public.fsa_root"
+			m_db_connection->create_fsa_table ();
+			
+			// add a row to the fsa main table for the input sequences
+			m_db_connection->insert_fsa_schema (hash_key, num_seqs, seqs_avr_length);
+
+			// set the id
+			m_seqs_schema_id = m_db_connection->get_seqs_schema_id (hash_key, num_seqs, seqs_avr_length);
+			
+			if (m_seqs_schema_id != DB_NOT_AVAILABLE) 
+				m_db_connection->set_seqs_schema_id (m_seqs_schema_id);
+
+			// create a new schema for the input sequences with the hash key
+			m_db_connection->create_seqs_schema ();
+			
+			// create a parameter table in the schema
+			m_db_connection->create_params_table ();
+			
+			// create seqs table - for information of the input sequences
+			m_db_connection->create_seqs_table ();
+		
+			// insert input sequences into the seqs table
+			m_db_connection->insert_seqs_table (seq_db_internal);
+		}
+
+		// insert parameter info. into the parameter table
+		m_db_connection->insert_params_table (db_opts);
+
+		// set the parameter id
+		m_params_table_id = m_db_connection->get_params_table_id (db_opts);
+		if (m_params_table_id != DB_NOT_AVAILABLE) 
+			m_db_connection->set_params_table_id (m_params_table_id);
+	}
+
+	for (int i=0; i<db_opts.num_parallelized_jobs; i++) {
+
+		// create sparse matrix tables to store pairwise posterior probabilities
+		if ( m_db_connection->create_sparse_matrix_table (i) == DB_BAD ) {
+			m_db_connection->delete_sparse_matrix_table (i); 
+			m_db_connection->drop_sparse_matrix_table_index (i);
+		}
+
+		// create num cells tables
+		// num cells table : how many entries are in each sequence pair
+		// Note that seq1 = 0 and seq2 = 0 indicates the number of edges
+		if ( m_db_connection->create_num_cells_table (i) == DB_BAD ) 
+			m_db_connection->delete_num_cells_table (i);
+
+		// create heap tables to store candidate edges of the null alignment
+		if ( m_db_connection->create_heap_table(i) == DB_BAD ) {
+			m_db_connection->delete_heap_table (i);
+		}
+
+		// create merged heap table
+		// merged heap table: when doing the sequence annealing, the merged heap table acts like the priority queue
+		if ( m_db_connection->create_merged_heap_table() == DB_BAD ) {
+			m_db_connection->delete_merged_heap_table();
+			m_db_connection->drop_merged_heap_table_index ();
+		}
+	}
+	
+	return DB_OK;
+#endif
+
+}
+
+bool DB_adapter::look_up_data (const Sequence_database &seq_db_internal, const DB_opts &db_opts) {
+#ifndef HAVE_POSTGRES
+	return DB_BAD;
+#else
+	// to look up data, the database must be running 
+	if (!is_db_running()) 
+		return DB_NO;
+
+	std::string whole_seqs    = "";
+	float seqs_avr_length = 0.0;
+	uint32_t hash_key     = 0;
+
+	// generate the hash key based on input sequences
+
+	for (int i=0; i<seq_db_internal.size(); i++) {
+	  whole_seqs += seq_db_internal.get_seq (i).seq;
+	  seqs_avr_length += (float) seq_db_internal.get_seq (i).length();
+	}
+
+	seqs_avr_length /= (float) seq_db_internal.size(); 
+	seqs_avr_length = (int) seqs_avr_length;
+
+	hash_key = Hash_functions::hsieh_hash(whole_seqs.c_str());
+
+	// set the sequence table id and the parameter id as looking up the appropriate data based 
+	// on the input sequences (which can be referenced by seq_db_internal) and the options 
+	// (which can be gotten from db_opts) that have been used when running fsa.  
+
+	if ( (m_seqs_schema_id = m_db_connection->get_seqs_schema_id (hash_key, seq_db_internal.size(), seqs_avr_length) ) 
+			!= DB_NOT_AVAILABLE) {
+		m_db_connection->set_seqs_schema_id (m_seqs_schema_id);
+
+		if ( (m_params_table_id = m_db_connection->get_params_table_id (db_opts) ) 
+				!= DB_NOT_AVAILABLE) 
+			m_db_connection->set_params_table_id (m_params_table_id);
+	}
+
+	// see if there are tables for input sequences and input parameters of the sequences. 	
+	if ( m_seqs_schema_id != DB_NOT_AVAILABLE && m_params_table_id != DB_NOT_AVAILABLE)
+		return DB_OK;
+	else
+		return DB_BAD;
+#endif
+
+}
+
+#ifdef HAVE_POSTGRES
+/// get the connection
+DB_postgres* DB_adapter::get_connection () {
+	return m_db_connection;
+}
+
+/// is the database server is running?
+bool DB_adapter::is_db_running () 
+{
+	if ( m_db_connection )
+		return DB_YES;
+	else 
+		return DB_NO;
+}
+
+/// data is available only if there're tables related to input sequences and parameters of the input sequences.
+bool DB_adapter::is_data_available () 
+{
+	if ( is_seqs_available () && is_params_available () )
+		return DB_YES;
+	else 
+		return DB_NO;
+}
+
+/// is seqs available?
+bool DB_adapter::is_seqs_available () 
+{
+	if ( m_seqs_schema_id != DB_NOT_AVAILABLE )
+		return DB_YES;
+	else
+		return DB_NO;
+}
+
+/// is parameters available?
+bool DB_adapter::is_params_available () 
+{
+	if (m_params_table_id != DB_NOT_AVAILABLE )
+		return DB_YES;
+	else
+		return DB_NO;
+}
+#endif
diff --git a/src/manager/db_adapter.h b/src/manager/db_adapter.h
new file mode 100644
index 0000000..8c8aee3
--- /dev/null
+++ b/src/manager/db_adapter.h
@@ -0,0 +1,108 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef DB_ADAPTER_INCLUDED
+#define DB_ADAPTER_INCLUDED
+
+#include "seq/sequence.h"
+#include "util/hash_fcn.h"
+#include "manager/db_misc.h"
+#ifdef HAVE_POSTGRES
+#include "manager/db_postgres.h"
+#endif
+
+namespace fsa {
+
+  /// Class DB_adapter
+  /*
+   * This is a bridge class between the Manager class and Database classes. 
+   * The purpose of this class is to support many different databases. 
+   * Note that currently only PostgresSQL is supported. 
+   *
+   * The organization of db tables and schemas
+   *
+   * fsa_root +- schema_1 ------+-- sequence_info                 // for input sequences
+   *          +- schema_2       +-- parameter_info                // for parameters of the input sequences  
+   *          +- ...            +-- h1_0, h1_1, ...               // heap tables for candidate edges
+   *                            +-- ncells1_0, ncells1_1, ...     // num cells tables
+   *                            +-- s1_0, s1_1, ...               // sparse matrix tables for pairwise posterior probabilities
+   *
+   * Note 1) schema_x (i.e., x is the sequence schema id) matches the unique set of sequences 
+   * Note 2) hy_z, ncellsy_z, sy_z: y is the unique parameter table id, and 0 <= z <= # of workers that have been used 
+   *                                when generating the data
+   */
+
+  class DB_adapter
+  {
+  public:
+    /// Constructor
+    DB_adapter();
+
+    /// Distructor
+    ~DB_adapter();
+
+    /// attempt to establish a connection to the given database host
+    /*
+     * With given information, try to make a connection to database server.
+     * Note that to establish a connection, at least db_hostname (or db_hostaddr) and db_name
+     * must be provided.
+     */
+    bool connect_db (const char *db_hostname, const char* db_hostaddr, const char *db_name, 
+		     const int db_port, const char *db_user, const char *db_password);
+
+    /// disconnect the connection
+    void disconnect_db (); 
+
+    /// look up data to be used when the sequence annealing.
+    /*
+     * seq_db_internal contains information about the input sequence strings. 
+     * db_opts contains the options that have been used when running fsa
+     */
+    bool look_up_data (const Sequence_database &seq_db_internal, const DB_opts &db_opts);
+
+    /// initialize the database 
+    /* 
+     * If necessary, create tables and schemas, and insert tuples to the tables.
+     */
+    bool init_database(const Sequence_database &seq_db_internal, const DB_opts &db_opts); 
+
+    ///  set up various ids
+    /*
+     * <seqs_schema_id, params_table_id> is the unique pair of ids denoting 
+     * specific sequences with the set of options that has been used when 
+     * the data was generated. 
+     */
+    bool set_up_ids (const int seqs_schema_id, const int params_table_id, const int worker_id);
+
+#ifdef HAVE_POSTGRES
+
+  private:
+    int             m_seqs_schema_id;       /// sequence schema id
+    int             m_params_table_id;      /// parameter table id
+    DB_postgres*    m_db_connection;        /// db connection object
+
+  public:
+
+    /// get the db connection
+    DB_postgres* get_connection ();
+
+    /// true if the database server is running
+    bool is_db_running ();
+
+    /// is data available? true if (is_seqs_available() && is_params_available())
+    bool is_data_available ();
+
+    /// is input sequences available?
+    bool is_seqs_available ();
+
+    /// does the data in database correspond with the input parameters?
+    bool is_params_available ();
+#endif
+
+  };
+
+}
+
+#endif
diff --git a/src/manager/db_misc.cc b/src/manager/db_misc.cc
new file mode 100644
index 0000000..0cd64cd
--- /dev/null
+++ b/src/manager/db_misc.cc
@@ -0,0 +1,36 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include "manager/db_misc.h"
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+void DB_opts::copy_opts (const FSA *from) {
+
+	// copy all options 
+
+	fsa = from;	
+	
+	num_refinement_steps = from->num_refinement_steps;
+	anchored = from->anchored;
+	
+	learn_emit_all = from->learn_emit_all;
+	learn_gap = from->learn_gap;                         
+	regularize = from->regularize;                      
+	num_parallelized_jobs = from->num_parallelized_jobs;       
+	num_alignment_pairs = from->num_alignment_pairs;
+	
+	db_hostname = from->db_hostname;
+	db_hostaddr = from->db_hostaddr;
+	db_name = from->db_name;
+	db_port = from->db_port;
+	db_user = from->db_user;
+	db_password = from->db_password;
+	db_max_ram = from->db_max_ram;
+
+	write_db = from->write_db;
+}
+
diff --git a/src/manager/db_misc.h b/src/manager/db_misc.h
new file mode 100644
index 0000000..dba250f
--- /dev/null
+++ b/src/manager/db_misc.h
@@ -0,0 +1,162 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef DB_MISC_INCLUDED
+#define DB_MISC_INCLUDED
+
+#include <string>
+#include "util/sstring.h"
+
+#define BUFFER_RATIO 0.9
+#define MAX_MEM_BUFFER_SIZE 1024*1024*10 // MAX SOCKET SIZE = 10MB
+#define MAX_DB_BUFFER_SIZE 1024*1024*20  // MAX DB SIZE = 1GB
+#define MAX_DB_ENTRY_LENGTH 100
+
+#define DB_FSA_SUFIX           "fsa" 
+#define DB_FSA_TABLE_PREFIX    "root"
+
+#define DB_SEQUENCE_INFO       "sequence_info"
+#define DB_SPARSE_MATRIX_INFO  "sparse_matrix_info"
+#define DB_HEAP_INFO           "heap_info"
+#define DB_PARAMETER_INFO      "parameter_info"
+
+#define DB_SPARSE_MATRIX_SUFIX "s"
+#define DB_HEAP_SUFIX          "h"
+#define DB_MERGED_HEAP_SUFIX   "heap"
+#define DB_NUM_CELLS_SUFIX     "ncells"
+
+#define DB_MEMORY_RATIO        1
+#define DEFAULT_DB_BUFFERSIZE  ULONG_MAX
+
+namespace fsa {
+
+  struct FSA;
+
+  /// Three types of response
+  typedef enum {
+    DB_NOT_AVAILABLE = -1,
+    DB_OK  = 1,
+    DB_BAD = 0
+  } DB_Response_Type;
+
+  /// Yes or No type returns
+  typedef enum {
+    DB_YES = 1,
+    DB_NO  = 0
+  } DB_Yes_No_Type;
+
+  /// the structure of num cells buffer
+  /*
+   * the sparse matrix of the sequence pair (seq1, seq2)
+   * requires size data cells.
+   */
+  typedef struct Num_Cells_Buffer {
+    int seq1;
+    int seq2;
+    int size;
+  } Num_Cells_Buffer;
+
+  /// the structure of sparse matrix buffer
+  typedef struct Sparse_Matrix_Buffer {
+    int pos1;
+    int pos2;
+    float prob;
+  } Sparse_Matrix_Buffer;
+
+  /// the structure of heap buffer
+  typedef struct Heap_Buffer {
+    int seq1;
+    int pos1;
+    int seq2;
+    int pos2;
+    double weight;
+    float  delta;
+  } Heap_Buffer;
+
+  /// the structure of MEM_Buffer 
+  /*  this is used when workers send the data including pairwise posterior probabilities and 
+   *  candidate edges to the master directly.
+   */
+  typedef struct MEM_Buffer {
+    Sparse_Matrix_Buffer *sparse_matrix;
+    Num_Cells_Buffer *num_cells;
+    Heap_Buffer *heap;
+  } MEM_Buffer;
+
+  /// the structure of DB_Buffer
+  /*
+   *  this is used when workers put the data into the database
+   */
+  typedef struct DB_Buffer {
+    sstring	    sparse_matrix;
+    sstring	    num_cells;
+    sstring	    heap;
+  } DB_Buffer;
+
+  /// type define pairs
+  typedef std::pair <int, Sparse_Matrix_Buffer *> Sparse_pair;
+  typedef std::pair <int, Num_Cells_Buffer *> Cells_pair;
+  typedef std::pair <int, Heap_Buffer *> Heap_pair;
+
+  /// type define vectors
+  typedef std::vector <Sparse_pair> Sparse_vector;
+  typedef std::vector <Cells_pair> Cells_vector;
+  typedef std::vector <Heap_pair> Heap_vector;
+
+  /// the structure of MEM_Buffers
+  typedef struct MEM_Buffers {
+    Sparse_vector sparse_matrix_buffers;
+    Cells_vector num_cells_buffers;
+    Heap_vector heap_buffers;
+  } MEM_Buffers;
+
+
+  /// class DB_opts
+  /*
+   * The main purpose of this class is to store states of options that have been used when running FSA
+   */
+  struct DB_opts {
+
+    const FSA *fsa;
+
+    // alignment speedup options
+    int num_alignment_pairs;             /// total number of all (n choose 2) pairs to consider during alignment inference
+
+    // sequence annealing options
+    int num_refinement_steps;            /// number of iterative refinement steps
+
+    // anchoring options
+    bool anchored;                       /// use anchor annealing
+
+    // parameter estimation options
+    bool learn_gap;                           /// learn indel parameters
+    bool regularize;                          /// regularize learned parameters with Dirichlet distribution specified by model
+    bool learn_emit_all;                      /// learn emit parameters over all sequences
+
+    // parallelization options
+    int  num_parallelized_jobs;       /// num of jobs to be simutaneously run
+
+    // database connection options
+    sstring db_hostname;           	  /// database server host name 
+    sstring db_hostaddr;              /// database server host IP address
+    sstring db_name;                  /// database name
+    int 	db_port;                  /// database server port
+    sstring db_user;                  /// database user name
+    sstring db_password;              /// database password
+    int  db_max_ram;                  /// database maximum ram
+
+    // output options
+    bool write_db;           /// write post. prob. matrices and cand. edges to database
+
+    /// constructor
+    DB_opts() {}
+
+    /// Copy all parameters.
+    void copy_opts (const FSA *from); 
+  };
+
+}
+
+#endif
diff --git a/src/manager/db_postgres.cc b/src/manager/db_postgres.cc
new file mode 100644
index 0000000..7420872
--- /dev/null
+++ b/src/manager/db_postgres.cc
@@ -0,0 +1,1011 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include <string.h>
+
+#include "manager/db_postgres.h"
+#include "annealing/alignment_DAG.h"
+
+
+using namespace fsa;
+
+/// connect_db
+bool DB_postgres::connect_db (const char *hostname, const char *hostaddr, const char* dbname, 
+		const int port, const char *user, const char *password) {
+
+	char conninfo[DB_MAX_QUERY_LENGTH];
+	memset( conninfo, 0, sizeof(conninfo) );
+
+	// set conninfo string 
+	if ( strlen(hostname) > 0 )
+		sprintf( conninfo, "host = '%s'", hostname );
+	if ( strlen(hostaddr) > 0 )
+		sprintf( conninfo, "%s hostaddr = '%s'", conninfo, hostaddr );
+	if ( strlen(dbname) > 0 )
+		sprintf( conninfo, "%s dbname = '%s'", conninfo, dbname);
+	if ( port > 0 )
+		sprintf( conninfo, "%s port = %d", conninfo, port);
+	if ( strlen(user) > 0 )
+		sprintf( conninfo, "%s user = '%s'", conninfo, user);
+	if ( strlen(password) > 0 )
+		sprintf( conninfo, "%s password = '%s'", conninfo, password);
+
+	// make a connection to the database	
+	m_conn = PQconnectdb(conninfo);
+
+	// check to see that the backend connection was successfully made 
+	if ( PQstatus(m_conn) != CONNECTION_OK ) {
+		CTAG(5,DB) << "Connection to database '" << PQdb(m_conn) << "' failed." << endl;
+		CTAG(3,DB) << PQerrorMessage(m_conn) << endl;
+		PQfinish(m_conn);
+
+		return DB_BAD;
+	}
+
+	CTAG(9,DB) << "Connection to database '" << PQdb(m_conn) << "' succeeded." << endl;
+
+	return DB_OK;
+}
+
+
+int DB_postgres::get_seqs_schema_id () {
+	return m_seqs_schema_id;
+}
+
+int DB_postgres::get_params_table_id () {
+	return m_params_table_id;
+}
+
+int DB_postgres::get_seqs_schema_id (const uint32_t hash_key, const int num_seqs, const float avg_length) {
+	//TODO: what happen if nTuples>1
+
+	int num_tuples, seqs_schema_id;
+
+	// make a query
+	sprintf(m_query, "SELECT id FROM %s WHERE hash = %u AND num_seqs = %d AND avg_length = %f",
+			m_fsa_table.c_str(), hash_key, num_seqs, avg_length);
+
+	// execute the query
+	if (execute_query() == DB_BAD)
+		return DB_NOT_AVAILABLE;
+
+	// get the number of tuples
+	num_tuples = PQntuples(m_res);
+
+	// error check
+	if (num_tuples == 0) {
+		PQclear (m_res);
+		return DB_NOT_AVAILABLE;
+	}
+
+	// get the sequence schema id
+	seqs_schema_id = atoi (PQgetvalue (m_res, 0, 0));
+
+	PQclear(m_res);
+
+	return seqs_schema_id;
+}
+
+
+int DB_postgres::get_params_table_id (const DB_opts &db_opts) {
+
+	int num_tuples, params_table_id;
+
+	// make a query
+	sprintf(m_query, "SELECT id, num_jobs FROM %s WHERE learn_gap = %s AND learn_emit_all = %s AND regularize = %s AND anchored = %s AND num_refinement_steps = %d",
+			m_params_table.c_str(), (db_opts.learn_gap)? "true" : "false", (db_opts.learn_emit_all)? "true" : "false",
+			(db_opts.regularize)? "true" : "false", (db_opts.anchored)? "true" : "false", db_opts.num_refinement_steps);
+
+	// execute the query
+	if (execute_query() == DB_BAD)
+		return DB_NOT_AVAILABLE;
+
+	// get the number of tuples	
+	num_tuples = PQntuples(m_res);
+
+	// error check
+	if ( num_tuples == 0 ) {
+		PQclear(m_res);
+		return DB_NOT_AVAILABLE;
+	}
+
+	// get the parameter table id and the number of workers that have been used when generating the data
+	params_table_id = atoi (PQgetvalue (m_res, 0, 0));
+	m_num_jobs = atoi (PQgetvalue (m_res, 0, 1));
+
+	PQclear(m_res);
+
+	return params_table_id;
+}
+
+int DB_postgres::get_num_jobs () {
+	return m_num_jobs;
+}
+
+bool DB_postgres::update_fsa_table() {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "UPDATE %s SET last_modified = CURRENT_TIMESTAMP WHERE id = %d", 
+			m_fsa_table.c_str(), m_seqs_schema_id);
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_fsa_table () {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s (id SERIAL, hash BIGINT, num_seqs INT, avg_length INT, first_generated TIMESTAMP with time zone, last_modified TIMESTAMP with time zone)",
+			m_fsa_table.c_str());
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::copy_to_merged_heap_table (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "INSERT INTO %s (seq1, pos1, seq2, pos2, weight, delta ) SELECT * FROM %s_%d",
+			m_merged_heap_table.c_str(), m_heap_table.c_str(), id);
+
+	// exeucte the query
+	if ( res = execute_query () )
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_merged_heap_table_index () {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE INDEX %s_%s_idx ON %s (weight DESC, seq1, seq2, pos1, pos2)",
+			m_seqs_schema.c_str(), m_merged_heap_prefix.c_str(), m_merged_heap_table.c_str());
+
+	// execute the query
+	res = execute_query();
+
+	if (res)
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::insert_fsa_schema (const uint32_t &hash_key, const int &num_seqs, const float &avg_length) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "INSERT INTO %s (hash, num_seqs, avg_length, first_generated, last_modified) VALUES (%u, %d, %f, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)",
+			m_fsa_table.c_str(), hash_key, num_seqs, avg_length);
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_seqs_schema() {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE SCHEMA %s", m_seqs_schema.c_str());	
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_params_table() {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s (id SERIAL, learn_gap BOOLEAN, learn_emit_all BOOLEAN, regularize BOOLEAN, anchored BOOLEAN, num_refinement_steps INT, first_generated TIMESTAMP with time zone, last_modified TIMESTAMP with time zone, num_jobs INT)", 
+			m_params_table.c_str());
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_seqs_table() {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s (id SERIAL, sequence TEXT, length INT, hash BIGINT)",
+			m_seqs_table.c_str());
+
+	// execute the query
+	if (res = execute_query())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::insert_seqs_table(const Sequence_database &seq_db_internal) {
+
+	sstring seqs_buffer;
+	sstring	table_name;
+
+	seqs_buffer.clear();
+	table_name.clear();
+
+	table_name = m_seqs_table.c_str();
+	table_name += " (sequence, length, hash)";
+
+	// make a buffer to contain input sequence strings
+	for (int i = 0; i < seq_db_internal.size(); i++) {
+	  seqs_buffer.append(seq_db_internal.get_seq (i).seq);
+	  sprintf(m_exec, "\t%d\t%lu\n", seq_db_internal.get_seq (i).length(), Hash_functions::hsieh_hash (seq_db_internal.get_seq (i).seq.c_str()));
+		seqs_buffer.append(m_exec);
+	}
+
+	// put the input sequence strings into the database
+	return copy_stdin (table_name.c_str(), seqs_buffer.c_str());
+}
+
+bool DB_postgres::get_merged_heap (const int size, const int offset, double &min_edge_weight, 
+		std::vector<Seq_pos_col_map> &seq_pos_col_maps, std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges, bool &last) {
+
+	// make a query
+	sprintf(m_query,"SELECT seq1, pos1, seq2, pos2, weight, delta FROM %s ORDER BY WEIGHT DESC LIMIT %d OFFSET %d",
+			m_merged_heap_table.c_str(), size, offset * size);
+
+	// execute the query
+	if (!execute_query())
+		return DB_BAD;
+
+	int num_tuples, seq1, pos1, seq2, pos2;
+	double weight;
+	float delta;
+	Edge *edge = NULL;
+
+	// get the number of tuples
+	num_tuples = PQntuples(m_res);
+
+	// if the number of result tuples is less than size, then 
+	// it means that the reult is the last set of tuples 
+	if (num_tuples < size)
+		last = true;
+
+	// error check
+	if (num_tuples == 0) {
+		PQclear (m_res);
+		return DB_BAD;
+	}
+
+	// put edges into the priority queue
+	for (int i = 0; i < num_tuples; i++) {
+		seq1   = atoi (PQgetvalue (m_res, i, 0));
+		pos1   = atoi (PQgetvalue (m_res, i, 1));
+		seq2   = atoi (PQgetvalue (m_res, i, 2));
+		pos2   = atoi (PQgetvalue (m_res, i, 3));
+		weight = atof (PQgetvalue (m_res, i, 4));
+		delta  = atof (PQgetvalue (m_res, i, 5));
+
+		// min_edge_weight == 0.0: initial condition
+		// find the smallest weight
+		if (min_edge_weight == 0.0 || min_edge_weight > weight) 
+			min_edge_weight = weight;
+
+		// create a new edge and push it into the queue
+		edge = new Edge(seq_pos_col_maps[seq1][pos1], seq_pos_col_maps[seq2][pos2], 
+				std::pair<int, int> (seq1, pos1), std::pair<int, int> (seq2, pos2), weight, delta, 2);
+		edges.push(edge);
+	}
+
+	PQclear(m_res);
+
+	return DB_OK;
+}
+
+int DB_postgres::get_heaps (const int worker_id, double &min_edge_weight, std::vector<Seq_pos_col_map> &seq_pos_col_maps, 
+		std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges) {
+
+	sstring	table_name;
+	std::stringstream sstream;
+
+	table_name.clear();
+	sstream << worker_id;
+	
+	// set the table name
+	table_name = m_heap_table.c_str();
+	table_name += "_";
+	table_name += sstream.str();
+
+	// move tuples in database tables to the standard output
+	if ( copy_stdout (table_name.c_str()) != DB_OK)
+		return DB_BAD;
+
+	char *buf;
+	int seq1, seq2, pos1, pos2;
+	double weight;
+	float delta;
+	Edge *edge = NULL;
+
+	// put edges into the priority queue
+	if (PQgetCopyData(m_conn, &buf, 0) != -1) {
+		do {
+			char *pch;
+			pch = strtok(buf, "\t");  seq1   = atoi(pch);
+			pch = strtok(NULL, "\t"); pos1   = atoi(pch);
+			pch = strtok(NULL, "\t"); seq2   = atoi(pch);
+			pch = strtok(NULL, "\t"); pos2   = atoi(pch);
+			pch = strtok(NULL, "\t"); weight = atof(pch);
+			pch = strtok(NULL, "\t"); delta  = atof(pch);
+
+			// deallocated the memory
+			PQfreemem(buf);
+
+			// find the smallest weight
+			if ( min_edge_weight > weight) 
+				min_edge_weight = weight;
+
+			// create a new edge and push it into the queue
+			edge = new Edge(seq_pos_col_maps[seq1][pos1], seq_pos_col_maps[seq2][pos2], 
+					std::pair<int, int> (seq1, pos1), std::pair<int, int> (seq2, pos2), weight, delta, 2);
+			edges.push(edge);
+
+		} while ( (PQgetCopyData(m_conn, &buf, 0)) != -1);
+	} else
+		return DB_NOT_AVAILABLE;
+
+	return DB_OK;
+}
+
+int DB_postgres::get_sparse_matrices (const int worker_id, const Sequence_database &seq_db_internal, 
+		const std::vector<std::vector<int> > &num_cells, std::vector<std::vector<SparseMatrix*> > &sparse_matrices) {
+
+	sstring	table_name;
+	std::stringstream sstream;
+
+	table_name.clear();
+	sstream << worker_id;
+
+	// set the table name
+	table_name = m_sparse_matrix_table.c_str();
+	table_name += "_";
+	table_name += sstream.str();
+
+	// move tuples in database tables to the standard output
+	if ( copy_stdout (table_name.c_str()) != DB_OK)
+		return DB_BAD;
+
+	char *buf;
+	int seq1, seq2, pos1, pos2, offset = 0;
+	int ex_seq1 = -1, ex_seq2 = -1;
+	float prob;
+
+	int cnt = 0;
+
+	// put edges into the priority queue
+	if ( (PQgetCopyData (m_conn, &buf, 0 )) != -1) {
+
+		do {
+			++cnt;
+			char *pch;
+			pch = strtok(buf, "\t");  seq1 = atoi(pch);
+			pch = strtok(NULL, "\t"); pos1 = atoi(pch);
+			pch = strtok(NULL, "\t"); seq2 = atoi(pch);
+			pch = strtok(NULL, "\t"); pos2 = atoi(pch);
+			pch = strtok(NULL, "\t"); prob = atof(pch);
+
+			// deallocated the memory
+			PQfreemem(buf);
+
+			if ( sparse_matrices[seq1][seq2] == NULL ) {
+
+				// once the sparse matrix of the sequence pair (ex_seq1, ex_seq2) has been constructed, 
+				// create a new sparse matrix of sequence pair (ex_seq2, ex_seq1)
+
+				if (ex_seq1 != -1 && ex_seq2 != -1)  
+					sparse_matrices[ex_seq2][ex_seq1] = sparse_matrices[ex_seq1][ex_seq2]->ComputeTranspose();
+
+				offset = 0;
+
+				int seq1Length = seq_db_internal.get_seq (seq1).length();
+				int seq2Length = seq_db_internal.get_seq (seq2).length();
+
+				ex_seq1 = seq1;	
+				ex_seq2 = seq2;
+
+				// create the sparse matrix for the sequence pair (seq1, seq2)
+				sparse_matrices[seq1][seq2] = new SparseMatrix (seq1, seq2,
+										seq1Length, seq2Length,
+										num_cells[seq1][seq2] - seq1Length - seq2Length);
+			}
+
+			// insert a pairwise posterior probabitlity into the sparse matrix
+			sparse_matrices[seq1][seq2]->add_probability (pos1, pos2, prob, offset);
+
+			if (pos1 != 0 && pos2 != 0 ) 
+				offset++;
+
+		} while ( (PQgetCopyData(m_conn, &buf, 0)) != -1);
+
+	}
+	else 
+		return DB_NOT_AVAILABLE;
+
+	// compute the transpose for the last sequence pair
+	sparse_matrices[ex_seq2][ex_seq1] = sparse_matrices[ex_seq1][ex_seq2]->ComputeTranspose();
+
+	return DB_OK;
+}
+
+bool DB_postgres::get_sparse_matrix (const int worker_id, const int seq1, const int seq2, 
+		const int seq1Length, const int seq2Length, 
+		std::vector<std::vector<SparseMatrix*> > &sparse_matrices) {
+
+	// make a query
+	sprintf(m_query,"SELECT pos1, pos2, prob FROM %s_%d where seq1 = %d and seq2 = %d order by pos1, pos2", 
+			m_sparse_matrix_table.c_str(), worker_id, seq1, seq2);
+
+	// execute the query
+	if (!execute_query())
+		return DB_BAD;
+
+	int num_tuples, pos1, pos2, offset = 0;
+	float prob;
+
+	// get the number of tuples
+	num_tuples = PQntuples(m_res);
+
+	if (num_tuples == 0) {
+		PQclear (m_res);
+		return DB_BAD;
+	}
+
+	// create the sparse matrix for the sequence pair (seq1, seq2)
+	sparse_matrices[seq1][seq2] = new SparseMatrix (seq1, seq2,
+							seq1Length, seq2Length,
+							num_tuples - seq1Length - seq2Length);
+
+	for (int i = 0; i < num_tuples; i++) {
+		pos1 = atoi (PQgetvalue (m_res, i, 0));
+		pos2 = atoi (PQgetvalue (m_res, i, 1));
+		prob = atof (PQgetvalue (m_res, i, 2));
+
+		// insert a pairwise posterior probability to the sparse matrix
+		sparse_matrices[seq1][seq2]->add_probability (pos1, pos2, prob, offset);
+
+		if (pos1 != 0 && pos2 != 0)
+			offset++;
+	}	
+
+	PQclear (m_res);
+
+	return DB_OK;
+}
+
+int DB_postgres::get_list_of_available_pairs (const int worker_id, std::vector<std::vector<int> > &available_sparse_matrices, 
+		const Sequence_database *seq_db_internal, double &avg_sparse_matrix_size, int &num_pairs, int &orig_edges_size) {
+
+	sstring	table_name;
+	std::stringstream sstream;
+
+	table_name.clear();
+	sstream << worker_id;
+
+	// set the table name
+	table_name = m_num_cells_table.c_str();
+	table_name += "_";
+	table_name += sstream.str();
+
+	// move tuples in the database tables to the standard output
+	if ( copy_stdout (table_name.c_str()) != DB_OK)
+		return DB_BAD;
+
+	char *buf;
+	int seq1, seq2, nCells;
+
+	double avg_size = 0.0;
+	int cnt_pairs = 0;
+
+	if (PQgetCopyData(m_conn, &buf, 0)!= -1) {
+		do {	
+			char *pch;
+			pch = strtok(buf, "\t");  seq1 = atoi(pch);
+			pch = strtok(NULL, "\t"); seq2 = atoi(pch);
+			pch = strtok(NULL, "\t"); nCells = atoi(pch);
+
+			// deallocate the memory
+			PQfreemem(buf);
+
+			int seq1Length = seq_db_internal->get_seq (seq1).length();
+			int seq2Length = seq_db_internal->get_seq (seq2).length();
+
+			if (seq1 == 0 && seq2 == 0 )
+				orig_edges_size += nCells;
+			else {
+				cnt_pairs++;
+
+				// flag the availability of the sparse matrix (seq1, seq2) on by setting the worker id
+				// which has generated the sparse matrix
+				available_sparse_matrices[seq1][seq2] = worker_id;
+				avg_size += sizeof (int) * (seq1Length + 1) + sizeof (int) * (seq1Length + 1) + 
+					sizeof(float) * (seq1Length + seq2Length + 2) + (sizeof (int) + sizeof(float)) * nCells;
+			}
+		} while ( (PQgetCopyData(m_conn, &buf, 0)) != -1);
+	} else 
+		return DB_NOT_AVAILABLE;
+
+	// compute the average sparse matrix size
+	avg_sparse_matrix_size = ((avg_sparse_matrix_size * (double) num_pairs ) + avg_size) / ((double) (num_pairs + cnt_pairs));
+
+	// compute the sum of available sequence pairs	
+	num_pairs += cnt_pairs;
+
+	return DB_OK;
+}
+
+int DB_postgres::get_num_cells (const int worker_id, std::vector<std::vector<int> > &num_cells) {
+
+	sstring	table_name;
+	std::stringstream sstream;
+
+	table_name.clear();
+	sstream << worker_id;
+
+	// set the table name
+	table_name = m_num_cells_table.c_str();
+	table_name += "_";
+	table_name += sstream.str();
+
+	// move the tuples in the database tables to the standard output
+	if ( copy_stdout (table_name.c_str()) != DB_OK)
+		return DB_BAD;
+
+	char *buf;
+	int seq1, seq2, nCells;
+
+	if (PQgetCopyData(m_conn, &buf, 0)!= -1) {
+		do {	
+			char *pch;
+			pch = strtok(buf, "\t");  seq1 = atoi(pch);
+			pch = strtok(NULL, "\t"); seq2 = atoi(pch);
+			pch = strtok(NULL, "\t"); nCells = atoi(pch);
+
+			// deallocate the memory
+			PQfreemem(buf);
+
+			// set the number of data cells that are used for the sparse matrix (seq1, seq2)
+			num_cells[seq1][seq2] += nCells;
+
+		} while ( (PQgetCopyData(m_conn, &buf, 0)) != -1);
+	} else 
+		return DB_NOT_AVAILABLE;
+
+	return DB_OK;
+}
+
+bool DB_postgres::copy_stdout (const char *table_name) {
+
+	// make a query
+	sprintf(m_query, "COPY %s TO STDOUT", table_name);
+
+	// execute the query
+	execute_query();
+
+	PQclear(m_res);
+
+	return DB_OK;
+}
+
+bool DB_postgres::copy_stdin (const char *table_name, const char* copy_string) {
+
+	// make a query
+	sprintf(m_query, "COPY %s FROM STDIN", table_name);
+
+	// execute the query
+	execute_query();
+
+	PQclear(m_res);
+
+	PQputCopyData(m_conn, copy_string, strlen(copy_string));
+
+	PQputCopyEnd(m_conn, NULL);
+
+	m_res = PQgetResult(m_conn);
+
+	// error check
+	if (PQresultStatus(m_res) != PGRES_COPY_IN && PQresultStatus(m_res) != PGRES_COMMAND_OK) {
+		PQclear(m_res);
+		return DB_BAD;
+	}
+
+	PQclear(m_res);
+	return DB_OK;
+}
+
+bool DB_postgres::insert_params_table (const DB_opts &db_opts) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "INSERT INTO %s (learn_gap, learn_emit_all, regularize, anchored, num_refinement_steps, first_generated, last_modified, num_jobs) VALUES (%s, %s, %s, %s, %d, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, %d)", 
+			m_params_table.c_str(), (db_opts.learn_gap)? "true" : "false", 
+			(db_opts.learn_emit_all)? "true" : "false",
+			(db_opts.regularize)? "true" : "false", 
+			(db_opts.anchored)? "true" : "false", db_opts.num_refinement_steps, 
+			db_opts.num_parallelized_jobs);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_num_cells_table (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s_%d (seq1 INT, seq2 INT, num_cells INT)",
+			m_num_cells_table.c_str(), id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_sparse_matrix_table (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s_%d (seq1 INT, pos1 INT, seq2 INT, pos2 INT, prob FLOAT)",
+			m_sparse_matrix_table.c_str(), id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::delete_num_cells_table(const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "TRUNCATE %s_%d", m_num_cells_table.c_str(), id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::delete_sparse_matrix_table(const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "TRUNCATE %s_%d", m_sparse_matrix_table.c_str(), id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::update_params_table (const int num_parallelized_jobs) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "UPDATE %s SET last_modified = CURRENT_TIMESTAMP, num_jobs = %d WHERE id = %d",
+			m_params_table.c_str(), num_parallelized_jobs, m_params_table_id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear(m_res);
+
+	// set the number of jobs (Note that this is equivalent to the nubmer of workers)
+	m_num_jobs = num_parallelized_jobs;
+
+	return res;
+}
+
+bool DB_postgres::drop_sparse_matrix_table_index (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "DROP INDEX %s.%s_%s_%d_idx", 
+			m_seqs_schema.c_str(), m_seqs_schema.c_str(), m_sparse_matrix_prefix.c_str(), id);
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear (m_res);
+
+	return res;
+}
+
+bool DB_postgres::drop_merged_heap_table_index () {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "DROP INDEX %s.%s_%s_idx", 
+			m_seqs_schema.c_str(), m_seqs_schema.c_str(), m_merged_heap_prefix.c_str());
+
+	// execute the query
+	if (res = execute_query ())
+		PQclear (m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_heap_table (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s_%d (seq1 INT, pos1 INT, seq2 INT, pos2 INT, weight DOUBLE PRECISION, delta FLOAT )",
+			m_heap_table.c_str(), id);
+
+	// execute the query
+	if ( res = execute_query () )
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::create_merged_heap_table () {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE TABLE %s (seq1 INT, pos1 INT, seq2 INT, pos2 INT, weight DOUBLE PRECISION, delta FLOAT ) ",
+			m_merged_heap_table.c_str());
+
+	// execute the query
+	if ( res = execute_query () )
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::delete_merged_heap_table () {
+
+	bool res;	
+
+	// make a query
+	sprintf(m_query, "TRUNCATE %s", 
+			m_merged_heap_table.c_str());
+
+	// execute the query
+	if (res = execute_query() )
+		PQclear(m_res);
+
+	return res;
+}
+
+bool DB_postgres::delete_heap_table (const int id) {
+
+	bool res;	
+
+	// make a query
+	sprintf(m_query, "TRUNCATE %s_%d", 
+			m_heap_table.c_str(),id);
+
+	// execute the query
+	if (res = execute_query() )
+		PQclear(m_res);
+
+	return res;
+}
+
+void DB_postgres::flush_merged_heap_buffer(const char* string) 
+{
+	// move the contents in the buffer (i.e., char* string) to the database table
+	if (strlen (string) > 0 )
+		copy_stdin (m_merged_heap_table.c_str(), string);
+}
+
+void DB_postgres::flush_sparse_matrix_buffer(const char* string) 
+{
+	// move the contents in the buffer (i.e., char* string) to the database table
+	if (strlen (string) > 0) 
+		copy_stdin (m_sparse_matrix_table.c_str(), string);
+}
+
+void DB_postgres::flush_num_cells_buffer(const char* string) 
+{
+	// move the contents in the buffer (i.e., char* string) to the database table
+	if (strlen(string) > 0) 
+		copy_stdin (m_num_cells_table.c_str(), string);
+}
+
+void DB_postgres::flush_heap_buffer(const char *string) 
+{
+	// move the contents in the buffer (i.e., char* string) to the database table
+	if (strlen (string) > 0 ) {
+		copy_stdin (m_heap_table.c_str(), string);
+	}
+}
+
+void DB_postgres::set_worker_id (const int worker_id) {
+
+	// append the worker id to the heap table name, the sparse matrix table name, 
+	// and the num cells table name
+	std::stringstream sstream;
+	sstream << worker_id;
+
+	m_heap_table += "_" + sstream.str();
+	m_sparse_matrix_table += "_" + sstream.str();
+	m_num_cells_table += "_" + sstream.str();
+}
+
+void DB_postgres::set_seqs_schema_id (const int seqs_schema_id) {
+
+	// make the sequence schema name, the sequence table name, the sparse matrix info table name,
+	// the heap info table name, and the parameter table name
+	m_seqs_schema_id = seqs_schema_id;
+	std::stringstream sstream;
+	sstream << m_seqs_schema_id;
+
+	m_seqs_schema.clear();
+	m_seqs_schema = DB_FSA_SUFIX;
+	m_seqs_schema += "_";
+	m_seqs_schema += sstream.str();
+
+	m_seqs_table.clear();
+	m_seqs_table = m_seqs_schema;
+	m_seqs_table += ".";
+	m_seqs_table += DB_SEQUENCE_INFO;
+
+	m_sparse_matrix_info.clear();
+	m_sparse_matrix_info = m_seqs_schema;
+	m_sparse_matrix_info += ".";
+	m_sparse_matrix_info += DB_SPARSE_MATRIX_INFO;
+
+	m_heap_info.clear();
+	m_heap_info = m_seqs_schema;
+	m_heap_info += ".";
+	m_heap_info += DB_HEAP_INFO;
+
+	m_params_table.clear();
+	m_params_table = m_seqs_schema;
+	m_params_table += ".";
+	m_params_table += DB_PARAMETER_INFO;
+}
+
+void DB_postgres::set_params_table_id (const int params_table_id) {
+
+	// make the heap_table name, the merged_heap_table name, the sparse_matrix_table name, 
+	// and the num cells table name
+	m_params_table_id = params_table_id;
+	std::stringstream sstream;
+	sstream << m_params_table_id;
+
+	m_heap_prefix.clear();
+	m_heap_prefix = DB_HEAP_SUFIX;
+	m_heap_prefix += sstream.str();
+
+	m_heap_table.clear();
+	m_heap_table = m_seqs_schema;
+	m_heap_table += ".";
+	m_heap_table += m_heap_prefix;
+
+	m_merged_heap_prefix.clear();
+	m_merged_heap_prefix = DB_MERGED_HEAP_SUFIX;
+	m_merged_heap_prefix += sstream.str();
+
+	m_merged_heap_table.clear();
+	m_merged_heap_table = m_seqs_schema;
+	m_merged_heap_table += ".";
+	m_merged_heap_table += m_merged_heap_prefix;
+
+	m_sparse_matrix_prefix.clear();
+	m_sparse_matrix_prefix = DB_SPARSE_MATRIX_SUFIX;
+	m_sparse_matrix_prefix += sstream.str();
+
+	m_sparse_matrix_table.clear();
+	m_sparse_matrix_table = m_seqs_schema;
+	m_sparse_matrix_table += ".";
+	m_sparse_matrix_table += m_sparse_matrix_prefix;
+
+	m_num_cells_table.clear();
+	m_num_cells_table = m_seqs_schema;
+	m_num_cells_table += ".";
+	m_num_cells_table += DB_NUM_CELLS_SUFIX;
+	m_num_cells_table += sstream.str();
+}
+
+bool DB_postgres::execute_query() {
+
+	// execute the query
+	m_res = PQexec(m_conn, m_query);
+
+	// error check
+	if (PQresultStatus(m_res) != PGRES_COMMAND_OK && PQresultStatus(m_res) != PGRES_TUPLES_OK
+			&& PQresultStatus(m_res) != PGRES_COPY_IN && PQresultStatus(m_res) != PGRES_COPY_OUT) {
+
+		PQclear(m_res);
+		m_res = NULL;
+		return DB_BAD;
+	}
+
+	return DB_OK;
+}
+
+DB_postgres::DB_postgres() {
+	m_conn = NULL;
+
+	// make the fsa_table name, which is the main table name
+	m_fsa_table.clear();
+	m_fsa_table = DB_FSA_SUFIX;
+	m_fsa_table += "_";
+	m_fsa_table += DB_FSA_TABLE_PREFIX;
+}
+
+DB_postgres::~DB_postgres() {}
+
+void DB_postgres::disconnect_db() {
+	PQfinish(m_conn);
+}
+
+bool DB_postgres::create_sparse_matrix_table_index (const int id) {
+
+	bool res;
+
+	// make a query
+	sprintf(m_query, "CREATE INDEX %s_%s_%d_idx ON %s_%d (seq1, seq2, pos1, pos2)",
+			m_seqs_schema.c_str(), m_sparse_matrix_prefix.c_str(), id, m_sparse_matrix_table.c_str(), id);
+
+	// execute the query
+	res = execute_query();
+
+	if (res)
+		PQclear(m_res);
+
+	return res;
+}
+
+int DB_postgres::get_merged_heap_size() {
+	
+	bool res;
+
+	// make a query
+	sprintf(m_query, "SELECT COUNT(weight) FROM %s",
+			m_merged_heap_table.c_str());
+
+	// execute the query
+	res = execute_query();
+
+	if (res)
+		PQclear(m_res);
+
+	return res;
+}
diff --git a/src/manager/db_postgres.h b/src/manager/db_postgres.h
new file mode 100644
index 0000000..fe8fb78
--- /dev/null
+++ b/src/manager/db_postgres.h
@@ -0,0 +1,301 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef DB_POSTGRES_INCLUDED
+#define DB_POSTGRES_INCLUDED
+
+#include <queue>
+#include <string>
+
+#include "libpq-fe.h" 
+#include "manager/db_misc.h"
+
+#include "seq/sequence.h"
+#include "util/hash_fcn.h"
+#include "annealing/SparseMatrix.h"
+
+namespace fsa {
+
+  class Edge;
+  class Column;
+  class smaller_weight;
+
+  /// Map a position in a sequence to the containing Column*.
+  typedef std::vector<Column*> Seq_pos_col_map;
+
+  /// Maximum length of queries
+#define DB_MAX_QUERY_LENGTH 1000
+
+  /// DB_postgres class
+  /*
+   * This class contains database methods depending on PostgreSQL.
+   * This class has developed based on PostgreSQL 8.3.1 
+   *
+   * For more information about PostgreSQL, 
+   * please visit http://www.postgresql.org
+   *
+   * For more information about database tables, schemas, ids, etc, 
+   * please see db_adapter.h
+   */
+
+  class DB_postgres 
+  {
+  public:
+    /// Constructor
+    DB_postgres();
+
+    /// Destructor
+    ~DB_postgres();
+
+    /// Attempt to establish a connection to the given database host
+    /*
+     * With given information, try to make a connection to database server.
+     * Note that to establish a connection, at least db_hostname (or db_hostaddr) and db_name
+     * must be provided.
+     */
+    bool connect_db (const char *hostname, const char *hostaddr, const char* dbname, 
+		     const int port, const char *user, const char *password); 
+
+    /// Disconnect from the database
+    void disconnect_db();
+
+    /// Get methods
+
+    /// Return sequence schema id 
+    /* 
+     * Looking up the database with a combination of hash_key (that has been generated by using
+     * input sequences), the number of the input sequences, and the average length of the sequences.
+     */
+    int get_seqs_schema_id (const uint32_t hash_key, const int num_seqs, const float avg_length);
+
+    /// Return sequence schema id
+    /*
+     * Just return the sequence schema id. This method is called only from the WORKER instance.
+     */
+    int get_seqs_schema_id (); 
+
+    /// Return parameter table id
+    /*
+     * Looking up the database with a combination of options that has been inputed when running FSA.
+     * If no options are used, then select conditions are filled with default options.
+     */
+    int get_params_table_id (const DB_opts &db_opts);
+
+    /// Return parameter table id  
+    /*
+     * Just return the parameter table id. This method is called  only from the WORKER instance.
+     */
+    int get_params_table_id ();
+
+    /// Return the number of jobs
+    /*
+     * Return the number of workers that have been used to generate the data.
+     */
+    int get_num_jobs ();
+
+    /// Create sparse matrices
+    /* 
+     * Construct all sparse matrices with pairwise posterior probabilties in the database.
+     */
+    int get_sparse_matrices (const int worker_id, const Sequence_database &seq_db_internal, 
+			     const std::vector<std::vector<int> > &num_cells, std::vector<std::vector<SparseMatrix*> > &sparse_matrices); 
+
+    /// Create a sparse matrix
+    /*
+     * Construct a sparse matrix of the sequence pair (seq1, seq2)
+     */
+    bool get_sparse_matrix (const int worker_id, const int seq1, const int seq2, 
+			    const int seq1Length, const int seq2Length, std::vector<std::vector<SparseMatrix*> > &sparse_matrices);
+
+    /// Get a number of cells that is constituted for each sparse matrix
+    /*
+     * A num_cells table contains the number of data cells that are used to construct each sparse matrix.
+     */
+    int get_num_cells (const int worker_id, std::vector<std::vector<int> > &num_cells);
+
+    /// Get the list of available pairs
+    /*
+     * If there's N input sequences, total N*(N-1)/2 pairs are considered for the annealing. However, it does
+     * not always heppen (ex, --fast option). Therefore, we need to determine which sequence pairs would be 
+     * considered for the sequence annealing.
+     */
+    int get_list_of_available_pairs (const int worker_id, std::vector<std::vector<int> > &available_sparse_matrices, 
+				     const Sequence_database *seq_db_internal, double &avg_sparse_matrix_size, int &num_pairs, int &orig_edges_size);
+
+    /// Get all candidate edges of the null alignment
+    /*
+     * Construct the initial priority queue with candidate edges of the null alignment. 
+     */
+    int get_heaps (const int worker_id, double &min_edge_weight, std::vector<Seq_pos_col_map> &seq_pos_col_maps, 
+		   std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges); 
+
+    /// Get some of candidate edges of the null alignment	
+    /*
+     * When there's a restriction on the memory size that can be consumed, instead of getting all candidate edges
+     * at once, it is needed to get some candidate edges. The number of candidate edges that are gotten at once is 
+     * size.
+     */
+    bool get_merged_heap (const int size, const int offset, double &min_edge_weight, 
+			  std::vector<Seq_pos_col_map> &seq_pos_col_maps, std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges, bool &last); 
+
+    /// Return the size of merged heap.
+    int get_merged_heap_size(); 
+
+    /// Put pairwise posterior probabilities into the database.
+    void flush_sparse_matrix_buffer(const char *string);
+
+    /// Put numbers of data cells of sparse matrices into the database.
+    void flush_num_cells_buffer(const char *string);
+
+    /// Put candidate edges of the null alignment into the database.
+    void flush_heap_buffer(const char *string);
+
+    /// Put re-weighted edges into the database.
+    void flush_merged_heap_buffer(const char* string); 
+
+    /// Insert-related methods
+
+    /// Insert a tuple into the fsa_main table for a schema related to the input sequences.	
+    bool insert_fsa_schema (const uint32_t &hash_key, const int &num_seqs, const float &avg_length); 
+
+    /// Insert tuples into the sequence table, with each tuple matching to the each input sequence.
+    bool insert_seqs_table (const Sequence_database &seq_db_internal);
+
+    /// Insert a tuple into the parameter table for the options that have been used when generating  the data.
+    bool insert_params_table (const DB_opts &db_opts);
+
+
+    /// Set methods	
+
+    ///	Set sequence schema id.
+    void set_seqs_schema_id (const int seqs_schema_id); 
+
+    /// Set parameter table id.
+    void set_params_table_id (const int params_table_id);
+
+    /// Set worker id.
+    void set_worker_id (const int worker_id); 
+
+    /// Update methods
+
+    /// Update the tuple that has already been in the main_fsa table.
+    bool update_fsa_table (); 
+
+    /// Update the tuple that has already been in the parameter table.
+    bool update_params_table (const int num_parallelized_jobs); 
+
+
+    /// Create methods
+
+    /// Create fsa_table which is the main table.
+    bool create_fsa_table ();
+
+    /// Create a sequence schema which is related to a set of input sequences.
+    bool create_seqs_schema ();
+
+    /// Create the parameter table which belongs to a sequence schema.
+    bool create_params_table(); 
+
+    /// Create a sequence table.
+    bool create_seqs_table(); 
+
+    /// Create a sparse matrix table with given id.
+    bool create_sparse_matrix_table (const int id); 
+
+    /// Create an index on the sparse matrix table_id.
+    bool create_sparse_matrix_table_index (const int id);
+
+    /// Create a num_cells table.
+    bool create_num_cells_table (const int id); 
+
+    /// Create a heap table.
+    bool create_heap_table (const int id);
+
+    /// Create the merged_heap_table.
+    bool create_merged_heap_table (); 
+
+    /// Create an index on the merged heap table.
+    bool create_merged_heap_table_index (); 
+
+
+    /// Delete methods 
+
+    /// Delete tuples in the sparse matrix table.
+    bool delete_sparse_matrix_table (const int id); 
+
+    /// Delete tuples in the num_cells table.
+    bool delete_num_cells_table (const int id); 
+
+    /// Delete tuples in the heap table.
+    bool delete_heap_table (const int id); 
+
+    /// Delete tuples in the merged heap table.
+    bool delete_merged_heap_table (); 
+
+
+    /// Drop methods
+
+    /// Drop the sparse matrix table index
+    bool drop_sparse_matrix_table_index (const int id); 
+
+    /// Drop the merged heap table index
+    bool drop_merged_heap_table_index (); 
+
+
+    /// Execute_query
+    /*
+     * Execute the query in m_query 
+     */
+    bool execute_query ();
+
+    /// move contents in the buffer (copy_string) to the database tables
+    /*
+     * NOTE: it is PostgreSQL specific methods. It is much much faster than just "INSERT" query
+     */	
+    bool copy_stdin (const char *table_name, const char* copy_string);
+
+    /// move contents in the database tables to the standard output
+    /*
+     * NOTE: it is PostgreSQL specific methods. It is much much faster than just "SELECT" query
+     */
+    bool copy_stdout (const char *table_name); 
+
+    /// Copy heap tables to the merged heap table
+    /*
+     * The merged heap table is used only when the db-maxram option is used.
+     */
+    bool copy_to_merged_heap_table (const int id); 
+
+  private:
+    PGconn     *m_conn;                                     // the class to access PostgreSQL database
+    PGresult   *m_res;                                      // the class to represent the query result tuples
+    char        m_query[DB_MAX_QUERY_LENGTH];               // common buffer for queries
+    char        m_exec[DB_MAX_QUERY_LENGTH];                // common buffer for execution commands
+
+    int         m_seqs_schema_id;        // seqeunce schema id
+    int         m_params_table_id;       // parameter table id
+    int 	    m_num_jobs;              // the number of jobs (workers)
+
+    sstring     m_seqs_schema;           // sequence schema name
+    sstring     m_params_table;          // parameter table name
+    sstring     m_seqs_table;            // sequence table name 
+
+    sstring     m_sparse_matrix_info;   // sparse matrix info
+    sstring     m_heap_info;            // heap info
+
+    sstring     m_fsa_table;            // fsa table name
+    sstring     m_heap_table;           // heap table name
+    sstring     m_merged_heap_table;    // merged heap table name
+    sstring     m_sparse_matrix_table;  // sparse matrix table name
+    sstring     m_num_cells_table;      // num cells table name
+
+    sstring     m_sparse_matrix_prefix; // sparse matrix prefix
+    sstring 	m_heap_prefix;          // heap prefix
+    sstring 	m_merged_heap_prefix;   // merged heap prefix
+  };
+
+}
+
+#endif
diff --git a/src/manager/manager.cc b/src/manager/manager.cc
new file mode 100644
index 0000000..8dc0025
--- /dev/null
+++ b/src/manager/manager.cc
@@ -0,0 +1,772 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include "manager/manager.h"
+#include "annealing/alignment_DAG.h"
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+
+#ifdef HAVE_POSTGRES
+extern void init_single_worker(const FSA *fsa, DB_adapter *db_adapter, Params &params_seed, Params &pseudocounts); 
+extern void build_multiple_alignment();
+extern void build_anchored_multiple_alignment();
+#endif
+
+Manager::Manager() {
+	m_seq_db_internal = NULL;
+	m_db_opts = NULL;
+
+#ifdef HAVE_POSTGRES
+	m_num_cells = NULL;
+	m_available_sparse_matrices = NULL;
+	m_sparse_matrix_scheduler = NULL;
+#endif
+
+}
+
+Manager::Manager(const Sequence_database &seq_db_internal, DB_opts &db_opts) {
+
+	m_seq_db_internal = &seq_db_internal;
+	m_db_opts = &db_opts;
+
+#ifdef HAVE_POSTGRES
+	bool is_db_running, is_db_available;
+
+	// make a connection to the database
+	is_db_running = m_db_adapter.connect_db(m_db_opts->db_hostname.c_str(), m_db_opts->db_hostaddr.c_str(), 
+			m_db_opts->db_name.c_str(), m_db_opts->db_port, m_db_opts->db_user.c_str(), m_db_opts->db_password.c_str());
+
+	if (!is_db_running && m_db_opts->write_db)
+		THROWEXPR ("ERROR: We can not access database server. exit");
+
+	// try to find data of input sequences
+	is_db_available = m_db_adapter.look_up_data (seq_db_internal, db_opts); 
+
+	if (is_db_running && !m_db_opts->write_db && !is_db_available) 
+		CL << "WARNING: there's no relevent data of the input sequences in the database." << endl;
+
+	// initialize variables
+	SPARSE_MATRIX_MAX_SIZE = 0;
+	HEAP_WINDOW_SIZE = 0;
+
+	m_db_merged_heap_buffer.clear();
+
+	m_num_inserted_edges = 0;
+	m_min_edge_weight = 0;
+	m_merged_heap_offset = 0;
+	m_num_cells = NULL;
+	m_available_sparse_matrices = NULL;
+	m_sparse_matrix_scheduler = NULL;
+
+	m_last_edge_chunk =  (m_db_opts->db_max_ram > 0)? false : true;
+#endif
+
+}
+
+Manager::~Manager() {
+#ifdef HAVE_POSTGRES
+	if (m_num_cells)
+		delete m_num_cells;
+
+	if (m_available_sparse_matrices)
+		delete m_available_sparse_matrices;
+
+	if (m_sparse_matrix_scheduler)
+		delete m_sparse_matrix_scheduler;
+#endif
+}
+
+bool Manager::check_available_sparse_matrices () { 
+
+#ifdef HAVE_POSTGRES
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (db_connection) {
+
+		int num_jobs = db_connection->get_num_jobs ();
+		int num_seqs = m_seq_db_internal->size();
+
+		if (num_jobs > 0) {	
+			int seq_pair_position = 1;
+			int num_seq_pairs = num_seqs * (num_seqs - 1 ) / 2; 
+			int num_of_pairs = num_seq_pairs / num_jobs; 
+			int num_remains = num_seq_pairs % num_jobs;
+
+			for (int i=0; i<num_jobs; i++) {
+				m_sparse_matrix_ref.push_back (seq_pair_position);
+				int length = (i < num_remains) ? num_of_pairs + 1 : num_of_pairs;
+				seq_pair_position += length;
+			}	
+		}
+
+		CTAG(4,MANAGER) << "Checking available sparse matrices." << endl;
+		m_available_sparse_matrices = new std::vector<std::vector<int> > (num_seqs, std::vector<int> (num_seqs, -1)); 
+
+		std::vector<int> added_workers;
+
+		avg_sparse_matrix_size = 0.0;
+		int num_pairs = 0;
+
+		for (int i = 0; i < num_jobs; i++)
+			added_workers.push_back (i);
+
+		while (!added_workers.empty()) {
+			int id = added_workers.front();
+			if (db_connection->get_list_of_available_pairs (id, *m_available_sparse_matrices, m_seq_db_internal, avg_sparse_matrix_size, num_pairs, m_orig_edges_size))
+				added_workers.erase (added_workers.begin());
+		}
+
+
+		if (m_db_opts && m_db_opts->db_max_ram > 0) {
+		  m_sparse_matrix_scheduler = new std::queue <Sparse_matrix_entry> ();
+			m_cnt_sparse_matrices = 0;
+			
+			// by the default, we assign 90% of total memory for the sparse matirces and the 10% of it to the priority queue
+			SPARSE_MATRIX_MAX_SIZE = (int)(0.90 * m_db_opts->db_max_ram * 1024 * 1024) / (sizeof (SparseMatrix) + (int) avg_sparse_matrix_size);
+			HEAP_WINDOW_SIZE = (int)(0.10 * m_db_opts->db_max_ram * 1024 * 1024 ) / sizeof (Edge);
+
+			if (HEAP_WINDOW_SIZE > m_orig_edges_size) {
+				// in this case, we can assign more memory for the sparse matrices
+				HEAP_WINDOW_SIZE = m_orig_edges_size; 
+				SPARSE_MATRIX_MAX_SIZE = (int)(m_db_opts->db_max_ram * 1024 * 1024 - sizeof(Edge) * m_orig_edges_size) / (sizeof (SparseMatrix) + (int) avg_sparse_matrix_size);
+			} 
+		} 
+	}
+
+	return true;
+#endif
+
+	return false;
+}
+
+
+#ifdef HAVE_POSTGRES
+bool Manager::update_size (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges) {
+	if (!m_db_opts)
+		return false;
+
+	SPARSE_MATRIX_MAX_SIZE = (int)(m_db_opts->db_max_ram * 1024 * 1024 - sizeof(Edge) * edges.size()) / (sizeof (SparseMatrix) + (int) avg_sparse_matrix_size);
+
+	return true;
+}
+#endif
+
+bool Manager::get_num_cells () { 
+
+#ifdef HAVE_POSTGRES
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (db_connection) {
+
+		int num_jobs = db_connection->get_num_jobs ();
+		int num_seqs = m_seq_db_internal->size();
+
+		if (num_jobs > 0) {	
+			int seq_pair_position = 1;
+			int num_seq_pairs = num_seqs * (num_seqs - 1 ) / 2; 
+			int num_of_pairs = num_seq_pairs / num_jobs; 
+			int num_remains = num_seq_pairs % num_jobs;
+
+			for (int i=0; i<num_jobs; i++) {
+				m_sparse_matrix_ref.push_back (seq_pair_position);
+				int length = (i < num_remains) ? num_of_pairs + 1 : num_of_pairs;
+				seq_pair_position += length;
+			}	
+		}
+
+		CTAG(4,MANAGER) << "Getting the number of cells of each sparse matrix." << endl;
+		m_num_cells = new std::vector<std::vector<int> > (num_seqs, std::vector<int> (num_seqs, 0)); 
+
+		std::vector<int> added_workers;
+
+		for (int i = 0; i < num_jobs; i++)
+			added_workers.push_back (i);
+
+		while (!added_workers.empty()) {
+			int id = added_workers.front();
+			if (db_connection->get_num_cells (id, *m_num_cells) == DB_OK)
+				added_workers.erase (added_workers.begin());
+		}
+
+
+		m_orig_edges_size = (*m_num_cells)[0][0]; /// [0][0] => heap size 
+	}
+	return true;
+#endif
+
+	return false;
+}
+
+bool Manager::is_edges_available () { 
+#ifdef HAVE_CONDOR
+	if (!(m_mem_buffers.heap_buffers).empty()) {
+		return true;
+	}
+#endif
+
+#ifdef HAVE_POSTGRES
+	if (m_db_adapter.is_data_available()) {
+		return true;
+	}
+#endif
+	return false;
+}
+
+bool Manager::is_sparse_matrices_available () { 
+#ifdef HAVE_CONDOR
+	if (!(m_mem_buffers.sparse_matrix_buffers).empty()) {
+		return true;
+	}
+#endif
+#ifdef HAVE_POSTGRES
+	if (m_db_adapter.is_data_available()) {
+		return true;
+	}
+#endif
+
+	return false;
+}
+
+bool Manager::is_sparse_matrix_available (const int i, const int j) {
+
+
+#ifdef HAVE_POSTGRES
+	if ( (m_num_cells && ((*m_num_cells)[i][j] > 0 || (*m_num_cells)[j][i]>0)) || 
+			(m_available_sparse_matrices && ((*m_available_sparse_matrices)[i][j] > -1|| (*m_available_sparse_matrices)[j][i] > -1)) )
+		return true;
+#endif
+	return false;
+
+}
+
+#ifdef HAVE_POSTGRES
+int Manager::look_up_sparse_matrix_table_id (const int i, const int j) { 
+
+	// binary search
+	int num_seqs = m_seq_db_internal->size();
+	int input_seq_position = (int) (i * (2 * num_seqs - i - 1) / 2) + (j - i);
+
+	int first = 0;
+	int last = m_sparse_matrix_ref.size() - 1;
+
+	//binary search
+	while (first <= last) {
+		int mid = (first + last) / 2; //compute mid point
+
+		if ( m_sparse_matrix_ref[mid] <= input_seq_position ) {
+			if (((mid == m_sparse_matrix_ref.size()-1)) || (input_seq_position < m_sparse_matrix_ref[mid+1])) 
+				return mid;
+			else
+				first = mid + 1;
+		}
+
+		if ( input_seq_position < m_sparse_matrix_ref[mid] ) {
+
+			if (mid == 0 || (m_sparse_matrix_ref[mid-1] <= input_seq_position))  
+				return mid-1;
+			else
+				last = mid - 1;
+		}
+	}
+
+	return -1;
+}
+#endif
+
+bool Manager::get_sparse_matrix (std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const int i, const int j) { 
+
+#ifdef HAVE_POSTGRES
+	// get a sparse matrix from the database
+	if ( !is_sparse_matrix_available (i, j) ) 
+		return false;
+
+	if (sparse_matrices[i][j] != NULL)
+		return true;
+
+	assert (sparse_matrices[i][j] == NULL);
+
+	// see if transpose is possible
+	if (sparse_matrices[j][i]) {
+		sparse_matrices[i][j] = sparse_matrices[j][i]->ComputeTranspose();
+
+		//check 
+		if (m_cnt_sparse_matrices > SPARSE_MATRIX_MAX_SIZE) {
+			SparseMatrix **sparse_matrix_ptr = m_sparse_matrix_scheduler->front();
+			m_sparse_matrix_scheduler->pop();
+			delete (*sparse_matrix_ptr);
+			(*sparse_matrix_ptr) = NULL;
+			m_cnt_sparse_matrices--;
+		}
+
+		if (m_sparse_matrix_scheduler->size() < MAX_SPARSE_MATRIX_COUNT) {
+			m_sparse_matrix_scheduler->push (&sparse_matrices[i][j]);
+			m_cnt_sparse_matrices++;
+		} else
+			m_cnt_sparse_matrices++;
+
+		return true;
+	}
+
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (!db_connection)
+		return false;
+
+	int seq1 = (i<j)? i : j;
+	int seq2 = (i<j)? j : i;
+
+	int seq1Length = m_seq_db_internal->get_seq (seq1).length();
+	int seq2Length = m_seq_db_internal->get_seq (seq2).length();
+
+	/*get the table for (seq1, seq2) from the database */
+	int id = (*m_available_sparse_matrices)[i][j];
+	if (id == -1) 
+		return false;
+
+	bool res = db_connection->get_sparse_matrix (id, seq1, seq2, seq1Length, seq2Length, sparse_matrices);
+
+	assert (sparse_matrices[i][j]);
+
+	//check 
+	if (m_cnt_sparse_matrices > SPARSE_MATRIX_MAX_SIZE) {
+		SparseMatrix **sparse_matrix_ptr = m_sparse_matrix_scheduler->front();
+		m_sparse_matrix_scheduler->pop();
+		delete (*sparse_matrix_ptr);
+		(*sparse_matrix_ptr) = NULL;
+		m_cnt_sparse_matrices--;
+	}
+
+	if (m_sparse_matrix_scheduler->size() < MAX_SPARSE_MATRIX_COUNT) {
+		m_sparse_matrix_scheduler->push (&sparse_matrices[i][j]);
+		m_cnt_sparse_matrices++;
+	} else
+		m_cnt_sparse_matrices++;
+
+	if (res && sparse_matrices[i][j] == NULL) {
+		sparse_matrices[i][j] = sparse_matrices[j][i]->ComputeTranspose();
+
+		//check 
+		if (m_cnt_sparse_matrices > SPARSE_MATRIX_MAX_SIZE) {
+			SparseMatrix **sparse_matrix_ptr = m_sparse_matrix_scheduler->front();
+			m_sparse_matrix_scheduler->pop();
+			delete (*sparse_matrix_ptr);
+			(*sparse_matrix_ptr) = NULL;
+			m_cnt_sparse_matrices--;
+		}
+
+		if (m_sparse_matrix_scheduler->size() < MAX_SPARSE_MATRIX_COUNT) {
+			m_sparse_matrix_scheduler->push (&sparse_matrices[i][j]);
+			m_cnt_sparse_matrices++;
+		} else
+			m_cnt_sparse_matrices++;
+	}
+
+	assert (sparse_matrices[i][j]);
+
+	return res;
+#else
+	return false;
+#endif
+}
+
+bool Manager::get_all_sparse_matrices (std::vector<std::vector<SparseMatrix*> >& sparse_matrices) {
+
+#ifdef HAVE_CONDOR
+	// get pairwise posterior probabilties from the database
+	Cells_vector &num_cells_buffers = m_mem_buffers.num_cells_buffers;
+	Sparse_vector &sparse_matrix_buffers = m_mem_buffers.sparse_matrix_buffers;
+
+	if (!num_cells_buffers.empty()) {
+
+		Num_Cells_Buffer *num_cells_buffer = NULL;
+		Sparse_Matrix_Buffer *sparse_matrix_buffer = NULL;
+		int size = 0;
+
+		while (!num_cells_buffers.empty()) {
+			Cells_pair &cells_pair = num_cells_buffers.front();
+			Sparse_pair &sparse_pair = sparse_matrix_buffers.front();
+
+			size = cells_pair.first;
+
+			Num_Cells_Buffer *num_cells_buffer = cells_pair.second;
+			Sparse_Matrix_Buffer *sparse_matrix_buffer = sparse_pair.second;
+
+			int pre_len = 0;
+			int len = 0;
+
+			// create a sparse matrix and the trasposed one
+			for (int cnt = 0; cnt < size; cnt++) {
+				int i = num_cells_buffer[cnt].seq1;
+				int j = num_cells_buffer[cnt].seq2;
+
+				len = num_cells_buffer[cnt].size;
+
+				int seq1Length = m_seq_db_internal->get_seq (i).length();
+				int seq2Length = m_seq_db_internal->get_seq (j).length();
+
+				sparse_matrices[i][j] = new SparseMatrix (i, j,
+									  seq1Length, seq2Length,
+									  pre_len, len, sparse_matrix_buffer);
+				sparse_matrices[j][i] = sparse_matrices[i][j]->ComputeTranspose();
+
+				pre_len += len;
+			}
+
+			assert (pre_len == sparse_pair.first);
+			if (num_cells_buffer)
+				free (num_cells_buffer); // prevent memory leak
+
+			if (sparse_matrix_buffer)
+				free (sparse_matrix_buffer);
+			num_cells_buffers.erase (num_cells_buffers.begin()); //erase
+			sparse_matrix_buffers.erase (sparse_matrix_buffers.begin());
+		}
+		assert (m_mem_buffers.num_cells_buffers.size() == 0);
+		assert (m_mem_buffers.sparse_matrix_buffers.size() == 0);
+
+		return true;
+	}
+
+#endif
+
+#ifdef HAVE_POSTGRES
+	// get pairwise posterior probabilities from the workers
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (!db_connection)
+		return false;
+
+	int num_seqs = m_seq_db_internal->size();
+
+	// get the nubmer of jobs
+	int num_jobs = db_connection->get_num_jobs ();
+
+	if ( num_jobs == 0 )
+		return false;
+
+	std::vector<int> added_workers;
+
+	for (int i = 0; i < num_jobs; i++)
+		added_workers.push_back (i);
+
+	while (!added_workers.empty()) {
+		int id = added_workers.front();
+		if (db_connection->get_sparse_matrices (id, *m_seq_db_internal, *m_num_cells, sparse_matrices) == DB_OK) 
+			added_workers.erase (added_workers.begin());
+	}
+
+	return true;
+#endif
+	return false;
+}
+
+
+bool Manager::get_all_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+		std::vector<Seq_pos_col_map> &seq_pos_col_maps) {  
+
+#ifdef HAVE_CONDOR
+	// get all edges from the workers
+	Heap_vector &heap_buffers = m_mem_buffers.heap_buffers;
+
+	if (!heap_buffers.empty()) {
+
+		while (!heap_buffers.empty()) {
+			Heap_pair &heap_pair = heap_buffers.front();
+
+			int size = heap_pair.first;
+			Heap_Buffer *heap_buffer = heap_pair.second;
+			
+			// create a new edge and push it into the priority queue
+			for (int i = 0; i < size; i++) {
+				Edge *edge = new Edge(seq_pos_col_maps[heap_buffer[i].seq1][heap_buffer[i].pos1], 
+						seq_pos_col_maps[heap_buffer[i].seq2][heap_buffer[i].pos2], 
+						      std::pair<int, int> (heap_buffer[i].seq1, heap_buffer[i].pos1), 
+						      std::pair<int, int> (heap_buffer[i].seq2, heap_buffer[i].pos2), 
+						heap_buffer[i].weight, heap_buffer[i].delta, 2);
+
+				edges.push(edge);
+
+			}
+			if (heap_buffer) 
+				free (heap_buffer); // prevent memory leak
+			heap_buffers.erase (heap_buffers.begin()); //erase
+
+		}
+		return true;
+	}
+#endif
+
+#ifdef HAVE_POSTGRES
+	// get all edges from the database
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (!db_connection)
+		return false;
+
+	int num_seqs = m_seq_db_internal->size();
+
+	// get the number of jobs ( = workers)
+	int num_jobs = db_connection->get_num_jobs ();
+
+	if ( num_jobs == 0 )
+		return false;
+
+	std::vector<int> added_workers;
+
+	for (int i = 0; i < num_jobs; i++)
+		added_workers.push_back (i);
+
+	while (!added_workers.empty()) {
+		int id = added_workers.front();
+		if (db_connection->get_heaps (id, m_min_edge_weight, seq_pos_col_maps, edges) == DB_OK)
+			added_workers.erase (added_workers.begin());
+	}
+
+	return true;
+#endif
+
+	return false;
+}
+
+
+bool Manager::mw_master_run (int argc, char** argv, const Params &params_seed, const Params &pseudocounts) {
+
+#ifdef HAVE_CONDOR
+	if (m_db_opts && m_db_opts->write_db)  {
+
+	int seqs_schema_id = 0;
+	int params_table_id = 0;
+
+#ifdef HAVE_POSTGRES
+		if ( !m_db_adapter.init_database (*m_seq_db_internal, *m_db_opts) ) 
+			THROWEXPR ("ERROR: We can not initialize database server. exit");
+
+		// set the sequence schema id and the parameter table id 
+		seqs_schema_id  = (m_db_adapter.get_connection())->get_seqs_schema_id ();
+		params_table_id = (m_db_adapter.get_connection())->get_params_table_id ();
+#endif 
+	
+	}
+	// if it is not the database mode , just send dummy values for seqs_schema_id and params_table_id
+	m_mw_adapter.master_run (argc, argv, params_seed, pseudocounts, m_mem_buffers, 
+			m_seq_db_internal->size(), m_db_opts->num_alignment_pairs, m_db_opts->num_parallelized_jobs,
+			seqs_schema_id, params_table_id);
+
+#ifdef HAVE_POSTGRES
+	m_db_adapter.look_up_data(*m_seq_db_internal, *m_db_opts);
+#endif //endif for HAVE_POSTGRES
+	return true;
+
+#else
+	// else for HAVE_CONDOR
+	return false;
+#endif
+}
+
+bool Manager::mw_worker_run(int argc, char** argv) {
+	// run the worker instance
+
+#ifdef HAVE_CONDOR
+	return m_mw_adapter.worker_run (argc, argv, m_db_adapter);
+#else
+
+	return false;
+#endif
+
+}
+
+bool Manager::mw_single_worker_run (Params &params_seed, Params &pseudocounts) {
+
+#ifdef HAVE_POSTGRES
+	
+	assert(m_db_opts);
+
+	m_db_opts->num_parallelized_jobs = 1;
+
+	if ( !m_db_adapter.init_database (*m_seq_db_internal, *m_db_opts) ) 
+		THROWEXPR ("ERROR: We can not initialize database server. exit");
+
+	init_single_worker(m_db_opts->fsa, &m_db_adapter, params_seed, pseudocounts);
+	if (m_db_opts->anchored)
+		build_anchored_multiple_alignment ();
+	else
+		build_multiple_alignment ();
+
+	m_db_adapter.look_up_data(*m_seq_db_internal, *m_db_opts);
+
+	return true;
+#else
+	return false;
+#endif
+
+}
+
+void Manager::push_edge(std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges, Edge *edge) {
+
+#ifdef HAVE_POSTGRES
+	edges.push(edge);
+	return;
+
+	if ( edge->weight >= m_min_edge_weight) 
+		edges.push (edge);
+	else {
+	
+		DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+		Seq_pos_map::const_iterator seq_pos_source= edge->source->get_seq_pos_map().begin();
+		Seq_pos_map::const_iterator seq_pos_dest = edge->dest->get_seq_pos_map().begin();
+
+		// put the edge into the buffer
+		char entry[MAX_DB_ENTRY_LENGTH];
+		sprintf(entry,"%d\t%d\t%d\t%d\t%lf\t%f\n", 
+				seq_pos_source->first, seq_pos_source->second, seq_pos_dest->first, seq_pos_dest->second, edge->weight, edge->delta);
+
+		m_db_merged_heap_buffer.append (entry);
+
+		// increase the number of inserted re-weighted edges by one
+		++m_num_inserted_edges;
+
+		delete edge;
+	}
+#else
+
+	edges.push (edge);
+#endif
+
+}
+
+
+bool Manager::get_next_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+		std::vector<Seq_pos_col_map> &seq_pos_col_maps) { 
+
+#ifdef HAVE_POSTGRES
+	// that is, this method is called only when the --db-maxram option is used
+	if (m_db_opts && m_db_opts->db_max_ram == 0)
+		return false;
+
+	DB_postgres *db_connection = m_db_adapter.get_connection ();
+
+	if (!db_connection)
+		return false;
+
+	// before getting the next edges, put re-weighted edges in the merged_heap_buffer to 
+	// the merged heap table
+	db_connection->flush_merged_heap_buffer ( m_db_merged_heap_buffer.c_str());
+	m_db_merged_heap_buffer.clear();
+
+	// get the next edges
+	if ( (db_connection->get_merged_heap (HEAP_WINDOW_SIZE, m_merged_heap_offset, m_min_edge_weight, 
+					seq_pos_col_maps, edges, m_last_edge_chunk)) == DB_BAD)
+		return false;
+	++m_merged_heap_offset;
+
+	return true;
+#else
+	
+	return false;
+#endif
+
+}
+
+
+int Manager::get_edges_size(std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges) {
+
+#ifdef HAVE_POSTGRES
+	if ( is_edges_available ())
+		// the merged heap table is needed to be considered
+		return (edges.size() + m_orig_edges_size - (m_merged_heap_offset * HEAP_WINDOW_SIZE) + m_num_inserted_edges); 
+	else 
+		return edges.size();
+#else
+
+	return edges.size();
+#endif
+
+}
+
+
+void Manager::get_sparse_matrices (std::vector<std::vector<SparseMatrix*> >& sparse_matrices) { 
+
+#ifdef HAVE_POSTGRES
+	if (m_db_opts && m_db_opts->db_max_ram > 0) {
+
+		DB_postgres *db_connection = m_db_adapter.get_connection ();
+		int num_jobs = db_connection->get_num_jobs ();
+
+		// create an index on each table.
+		for (int i=0;i<num_jobs;i++) 
+			db_connection->create_sparse_matrix_table_index(i);
+
+		// drop merged heap table index
+		//   it is much faster to insert tuples into a table that does not have an index 
+		//   than the one having an index
+		db_connection->drop_merged_heap_table_index();
+		db_connection->delete_merged_heap_table();
+
+		// copy to merged heap
+		for (int i=0; i<num_jobs;i++) {
+			db_connection->copy_to_merged_heap_table (i);
+		}
+
+		// create merged_heap index
+		db_connection->create_merged_heap_table_index();
+
+		//m_orig_edges_size = db_connection->get_merged_heap_size();
+		CTAG(1,MANAGER) << "Original edge size : " << m_orig_edges_size << endl;
+
+		check_available_sparse_matrices();
+	} else 
+#endif
+	{
+
+		// in the case of database || parallelization
+		get_num_cells ();
+		get_all_sparse_matrices (sparse_matrices);
+	}
+
+}
+
+void Manager::get_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+		std::vector<Seq_pos_col_map> &seq_pos_col_maps) {  
+
+#ifdef HAVE_POSTGRES
+	if (m_db_opts && m_db_opts->db_max_ram > 0) {
+		get_next_edges (edges, seq_pos_col_maps);
+	} else 
+#endif
+	{
+		// in the case of database || parallelization
+		get_all_edges (edges, seq_pos_col_maps);
+	}
+
+}
+
+Edge* Manager::get_next_top_edge (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+		std::vector<Seq_pos_col_map> &seq_pos_col_maps) { 
+
+	Edge *edge = edges.top();
+
+#ifdef HAVE_POSTGRES
+	if (m_db_opts && m_db_opts->db_max_ram > 0) {
+		// if --db-maxram option is used
+		if (m_last_edge_chunk== true )  {
+			update_size(edges);
+		}
+
+		if (m_last_edge_chunk == false && edge->weight < m_min_edge_weight || edges.size() == 1) {
+			// in the case of getting next edges
+			get_next_edges (edges, seq_pos_col_maps);
+			edge = edges.top();
+		}
+	}
+#endif
+
+    edges.pop();
+	
+	return edge;
+
+}
diff --git a/src/manager/manager.h b/src/manager/manager.h
new file mode 100644
index 0000000..96fe70b
--- /dev/null
+++ b/src/manager/manager.h
@@ -0,0 +1,217 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef MANAGER_INCLUDED 
+#define MANAGER_INCLUDED 
+#include <queue>
+#include <float.h>
+
+#include "seq/sequence.h"
+#include "annealing/SparseMatrix.h"
+#include "manager/db_adapter.h"
+#include "manager/mw_adapter.h"
+
+#define MAX_SPARSE_MATRIX_COUNT 10
+
+#ifdef HAVE_POSTGRES
+#include "manager/db_postgres.h"
+#endif
+
+namespace fsa {
+
+  class Edge;
+  class Column;
+  class smaller_weight;
+
+  /// Point a cell (which is SparseMatrix*) in a SparseMatrix 
+  typedef SparseMatrix** Sparse_matrix_entry;
+
+  /// Map a position in a sequence to the containing Column*.
+  typedef std::vector<Column*> Seq_pos_col_map;
+
+  // Class Manager
+  /*
+   * This class is needed to glue the fsa class together with some classes for the parallelization and the database
+   */
+  class Manager {
+
+  public:
+
+    /// Constructor
+    Manager();
+
+    /// Constructor
+    /*
+     * Detects whether the database is running, and we can get the appropriate data from the database
+     */
+    Manager (const Sequence_database& seq_db_internal, DB_opts &db_opts);
+
+    /// Destructor
+    ~Manager(); 				
+
+
+    /// Get methods
+
+    /// Get a sparse matrix from the database
+    /*
+     * Create a new sparse matrix for the sequence pair (i,j)
+     */
+    bool get_sparse_matrix(std::vector<std::vector<SparseMatrix*> >& sparse_matrices, const int i, const int j); 
+
+    /// Get numbers of data cells that are required for the sparse matrices
+    bool get_num_cells (); 
+
+    /// Create all sparse matrices.
+    /*
+     * If the database mode is being used, pairwise posterior probabilities are gotten from the database. 
+     * If the parallizaition mode is being used, the data are transfered from the workers
+     */
+    bool get_all_sparse_matrices (std::vector<std::vector<SparseMatrix*> >& sparse_matrices); 
+
+
+    /// Construct the priority queue with the candidate edges of the null alignment
+    /*
+     * If the database mode is being used, candidate edges are gotten from the database. 
+     * If the parallizaition mode is being used, the data are transfered from the workers
+     */
+    bool get_all_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges, 
+			std::vector<Seq_pos_col_map> &seq_pos_col_maps); 
+
+    /// Get the size of edges
+    /*
+     * In the case that the --db-maxram option is used:
+     * The priority queue, edges, contains only some portion of the total edges so that 
+     * the number of tuples in the merged heap table is needed to be considered. 
+     * Otherwise, just return the size of the priority queue 
+     */
+    int get_edges_size(std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges); 
+
+    /// Get edges
+    /*
+     * In the case that the --db-maxram option is used:
+     * instead of getting all candidate edges of the null alignment at once, some portion of 
+     * candidate edges are gotten from the merged heap table. 
+     * Otherwise, get all candidate edges at once from either the database or the workers
+     */
+    void get_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+		    std::vector<Seq_pos_col_map> &seq_pos_col_maps);
+
+    /// Get some of candidate edges from the database
+    bool get_next_edges (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+			 std::vector<Seq_pos_col_map> &seq_pos_col_maps);
+
+    /// Get sparse matrices
+    /*
+     * In the case that the --db-maxram option is used:
+     * Create the merged heap table and copy all tuples in the heap tables into the merged heap table. 
+     * Note that sparse matrix is gotten from the database on-the-fly during the sequence annealing
+     */	
+    void get_sparse_matrices (std::vector<std::vector<SparseMatrix*> >& sparse_matrices); 
+
+    /// Get the top element in the priority queue
+    /*
+     * In the case that the --db-maxram option is used:
+     * once next some edges have been gotten from the database, return the top element in the priority queue.
+     * Otherwise, just return the top element in the priority queue
+     */
+    Edge* get_next_top_edge (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges,
+			     std::vector<Seq_pos_col_map> &seq_pos_col_maps); 
+
+    /// Push edge
+    /*
+     * In the case that the --db-maxram option is used:
+     * If the recomputed weight of the edge is greater than the m_min_edge_weight, the smallest
+     * edge weight among edge weights in the priority queue, push it into the priority queue. 
+     * Otherwise, put this edge into the merged heap table. This is because if the recomputed 
+     * weight is less than the m_min_edge_weight, there might be an edge whose initial weight is
+     * greater then the edge. 
+     *
+     * In the case that the --db-maxram option is NOT used:
+     * push it into the priority queue
+     */
+    void push_edge(std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges, Edge *edge); 
+
+    /// Is the appropriate data in the database?
+    bool is_data_available (); 
+
+    /// Can we use the sparse matrix of the sequence pair (i,j)?
+    bool is_sparse_matrix_available (const int i, const int j); 
+
+    /// Are sparse matrices avialable?
+    bool is_sparse_matrices_available (); 
+
+    /// Are edges available?
+    bool is_edges_available (); 
+
+    /// Get the list of available sparse matrices
+    bool check_available_sparse_matrices (); 
+
+    /// run the master instance
+    bool mw_master_run (int argc, char** argv, const Params &params_seed, const Params &pseudocounts);
+
+    /// run the worker instance
+    bool mw_worker_run(int argc, char** argv);
+
+    bool mw_single_worker_run (Params &params_seed, Params &pseudocounts); 
+
+  private:
+
+    const Sequence_database *m_seq_db_internal;        // hold all input sequence data (FSA's internal format)
+    DB_opts *m_db_opts;                    // hold all options that have been used when running FSA
+
+    DB_adapter m_db_adapter;               // database adapter class
+    MW_adapter m_mw_adapter;               // master-worker adapter class
+
+#ifdef HAVE_POSTGRES
+  public:
+
+    /// Find the worker id that has generated the sparse matrix of the sequence pair (i,j)
+    int look_up_sparse_matrix_table_id (const int i, const int j);                     
+
+    /// Re-set the maximum number of sparse matrices to be stored in the memory
+    /*
+     * Note that this method is called when the --db-maxram option is used
+     */
+    bool update_size (std::priority_queue<Edge*, std::vector<Edge*>, smaller_weight> &edges);
+
+  private:
+
+    bool m_last_edge_chunk;              // is this the last chunk of edges?
+
+    int m_num_inserted_edges;            // the number of inserted re-weighted edges to the merged heap table duing the sequence anenaling
+    int m_merged_heap_offset;            // merged heap offet to be used to get some portion of edges
+    double m_min_edge_weight;            // the smallest edge weight among edges in the priority queue
+
+    std::vector<std::vector<int> > *m_num_cells;                      // 2-dim vector to keep numbers of data cells
+    std::vector<std::vector<int> > *m_available_sparse_matrices;      // 2-dim vector for the available sparse matrices: 
+    //   The entry [i][j] stores the worker id that has generated the sparse matrix[i][j]
+
+    std::queue <Sparse_matrix_entry> *m_sparse_matrix_scheduler; // queue to keep the maximum number of sparse matrices that are on memory
+    int m_cnt_sparse_matrices;                              // how many sparse matrices are on the memory?
+
+    std::vector<int> m_sparse_matrix_ref;		                // 1-dim vector to be used in look_up_sparse_matrix_table_id method
+
+    int m_orig_edges_size;                                  // the number of candidate edges of the null alignment
+
+    int HEAP_WINDOW_SIZE;                      // how many edges can we hold at a time?
+    int SPARSE_MATRIX_MAX_SIZE;                // how many sparse matrices can we hold at a time? 
+
+    sstring	    m_db_merged_heap_buffer;              // the merged_heap_buffer
+
+    double avg_sparse_matrix_size;                    // the average sparse matrix size
+#endif
+
+#ifdef HAVE_CONDOR
+  private:
+    MEM_Buffers m_mem_buffers;                        // MEM buffers
+#endif
+
+  };
+
+}
+
+#endif
+
+
diff --git a/src/manager/mw_adapter.cc b/src/manager/mw_adapter.cc
new file mode 100644
index 0000000..f7d0be7
--- /dev/null
+++ b/src/manager/mw_adapter.cc
@@ -0,0 +1,31 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+#include "manager/mw_adapter.h"
+
+using namespace fsa;
+
+int MW_adapter::worker_run(int argc, char** argv, DB_adapter &db_adapter) {
+#ifdef HAVE_CONDOR
+	MWWorker::RMC = new MWSocketRC ( FALSE, 0 );
+	MWTask::RMC = MWWorker::RMC;
+	MWDriver::RMC = NULL;
+
+	MW_worker mw_worker (db_adapter);
+	mw_worker.go (argc, argv); //start worker 
+#endif
+	return 0;
+}
+
+int MW_adapter::master_run(int argc, char** argv, const Params &params_seed, const Params &pseudocounts, MEM_Buffers &mem_buffers, 
+		const int num_seqs, const int num_seqs_pairs, const int num_jobs,
+		const int seqs_schema_id, const int params_table_id) {
+#ifdef HAVE_CONDOR
+	MW_master mw_master (params_seed, pseudocounts, mem_buffers, num_seqs, num_seqs_pairs, num_jobs, seqs_schema_id, params_table_id);
+	mw_master.go (argc, argv); //start master
+#endif
+	return 0;
+}
+
+
diff --git a/src/manager/mw_adapter.h b/src/manager/mw_adapter.h
new file mode 100644
index 0000000..ad1d7f4
--- /dev/null
+++ b/src/manager/mw_adapter.h
@@ -0,0 +1,54 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef MW_ADAPTER_INCLUDED
+#define MW_ADAPTER_INCLUDED
+
+#include "seq/sequence.h"
+
+#include "manager/db_misc.h"
+#include "manager/db_adapter.h"
+
+#ifdef HAVE_CONDOR
+#include "MW.h"
+#include "MWSocketRC.h"
+#include "MWDriver.h"
+
+#include "manager/mw_master.h"
+#include "manager/mw_worker.h"
+#endif
+
+namespace fsa {
+
+  struct Params;
+
+  /// MW_adapter class
+  /*
+   * This class manages all stuffs related to the Master-Worker framework
+   */
+  class MW_adapter {
+  private:
+
+  public:	
+    /// constructor
+    MW_adapter() {}
+		
+    /// destructor
+    ~MW_adapter() {}
+
+    /// run the worker instance
+    int worker_run(int argc, char** argv, DB_adapter &db_adapter); 
+
+    /// run the master instance
+    int master_run(int argc, char** argv, 
+		   const Params &params_seed, const Params &pseudocounts, MEM_Buffers &mem_buffers, 
+		   const int num_seqs, const int num_seqs_pairs, const int num_jobs,
+		   const int seqs_schema_id, const int params_table_id); 
+
+  };
+
+}
+
+#endif
diff --git a/src/manager/mw_master.cc b/src/manager/mw_master.cc
new file mode 100644
index 0000000..4d4214f
--- /dev/null
+++ b/src/manager/mw_master.cc
@@ -0,0 +1,530 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+// TODO int meanlen = (int) floor (seq_db.mean_length());
+
+#include <arpa/inet.h>
+#include <pthread.h>
+
+#include "manager/mw_master.h"
+#include "manager/db_adapter.h"
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+static pthread_mutex_t worker_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+typedef struct ThreadData {
+	MW_task* m_task;
+	MW_master* m_driver;
+} ThreadData;
+
+MW_master::MW_master(const Params &params_seed, const Params &pseudocounts, MEM_Buffers &mem_buffers,
+		const int num_seqs, const int num_seqs_pairs, const int num_jobs,
+		const int seqs_schema_id, const int params_table_id) {
+
+	set_MWprintf_level (1);
+
+	m_num_parallelized_jobs = num_jobs;
+	m_params_seed = &params_seed;
+	m_pseudocounts = &pseudocounts;
+	m_num_seqs = num_seqs;
+	m_num_seq_pairs = num_seqs_pairs;
+
+	m_seqs_schema_id = seqs_schema_id;
+	m_params_table_id = params_table_id;
+
+	m_mem_buffers = &mem_buffers;
+}
+
+
+static void *__do_raw_unpack(void *ptr) 
+{
+	ThreadData* tdata = (ThreadData*)ptr;
+	MW_task* t = tdata->m_task;
+	MW_master* driver = tdata->m_driver;
+
+	int worker_id = t->worker->get_id1();
+	free(tdata);
+
+	double wall_time = 0.0;
+	double cpu_time = 0.0;
+	bool ret = driver->do_raw_unpack(t, wall_time, cpu_time);
+
+	// Now we have finished reading data from socket
+	// So we transfer the control over the socket to main process
+	t->RMC->thread_stop(worker_id);
+
+	if( !ret ) {
+		fprintf(stderr, "do_raw_unpack failed from worker(id=%d,name=%s)\n", 
+				worker_id, t->worker->machine_name());
+		fprintf(stderr, "Creating a new task for this failed task\n");
+		fflush(stderr);
+		// Fail
+		//in case of error, need to put this task into job queue again..
+		
+		// Create a new Task
+		MW_task *new_task = new MW_task;
+		assert(new_task);
+
+		new_task->m_worker_id = t->m_worker_id;
+		new_task->m_prev_length_sum = t->m_prev_length_sum;
+		new_task->m_length = t->m_length;
+		new_task->m_start_seq_i = t->m_start_seq_i;
+		new_task->m_start_seq_j = t->m_start_seq_j;
+
+		driver->getGlobalLock();
+
+		// Delete old one
+		MWWorkerID* w = t->worker;
+		wall_time = 0.0;
+		cpu_time = 0.0;
+		t->completedTask(wall_time, cpu_time);
+		delete t;
+
+		// Add new one
+		driver->AddTask((MWTask*)new_task);
+
+		driver->getGlobalUnLock();
+	}else {
+		// success 
+		driver->getGlobalLock();
+		MWWorkerID* w = t->worker;
+		t->completedTask(wall_time, cpu_time);
+		delete t;
+		driver->getGlobalUnLock();
+	}
+
+	driver->decreasePendingNum();
+	return NULL;
+}
+
+/// get_userinfo 
+MWReturn MW_master::get_userinfo(int argc, char **argv) 
+{
+
+	char arch[10];
+	char requirements[100];
+
+	char *exec_ptr = NULL;
+
+	m_argc = argc;
+	m_argv = argv;
+
+	/* exec classes */
+	RMC->set_num_exec_classes(1);
+	/* arch classes */
+	RMC->set_num_arch_classes(1);
+	/* set architecture and linux type */
+
+	if (get_proc_cpuinfo(arch)) {
+		sprintf(requirements,"((Arch==\"%s\") && (Opsys==\"LINUX\"))",arch);
+		RMC->set_arch_class_attributes (0, requirements); 
+	}
+	else 
+		RMC->set_arch_class_attributes (0, "((Arch==\"INTEL\") && (Opsys==\"LINUX\"))");  // default setting
+
+	/* we have only one executable - fsa */
+	RMC->set_num_executables(1);
+
+	RMC->add_executable(0, 0, (((exec_ptr = strchr(argv[0], '/')) != NULL)? (exec_ptr + 1) : argv[0]), "");  
+
+	/* checkpoint requirement */
+	set_checkpoint_frequency(0);
+
+	/* Set the number of jobs */
+
+	RMC->set_target_num_workers(m_num_parallelized_jobs);
+	RMC->set_worker_increment(m_num_parallelized_jobs);
+
+	m_num_of_pairs = m_num_seq_pairs / m_num_parallelized_jobs; 
+	m_num_remains = m_num_seq_pairs % m_num_parallelized_jobs;
+
+	return OK;
+}
+
+/// setup (generate and push) the first batch of tasks in the beginning 
+MWReturn MW_master::setup_initial_tasks(int *n_init , MWTask ***init_tasks) 
+{
+	// Create initial tasks
+	*n_init = m_num_parallelized_jobs;
+	*init_tasks = new MWTask* [m_num_parallelized_jobs];
+
+	CTAG(9, MW) << "Creating " << m_num_parallelized_jobs << " job(s)." << endl;
+
+	// Starting pair of sequence
+	int seq_i = 0;
+	int seq_j = 1;
+	int i = 0;
+	int prev_length_sum = 0;
+
+	for (i = 0; i < m_num_parallelized_jobs; i++) {
+
+		MW_task *new_task = new MW_task;
+
+		int prev_length = (i == 0) ? 0 : (((i - 1) < m_num_remains) ? (1 + m_num_of_pairs) : (m_num_of_pairs));
+
+		int length = (i < m_num_remains) ? m_num_of_pairs + 1 : m_num_of_pairs;
+		prev_length_sum += prev_length;
+
+		compute_next_starting_pair(seq_i, seq_j, prev_length, m_num_seqs);
+
+		new_task->m_worker_id = i;
+		new_task->m_prev_length_sum = prev_length_sum;
+		new_task->m_length = length;
+		new_task->m_start_seq_i = seq_i;
+		new_task->m_start_seq_j = seq_j;
+
+		(*init_tasks)[i] = new_task;
+	}
+
+	return OK;
+}
+
+void MW_master::pack_params(const Params &params) {
+
+	// bandwidth 
+	RMC->pack(&(params.bandwidth), 1,1);
+
+	// is_indel2 
+	char is_indel2 = (params.is_indel2)	? 1 : 0;
+	RMC->pack(&is_indel2, 1,1);
+
+	// gap_open1 
+	RMC->pack(&(params.gap_open1), 1,1);
+
+	// gap_open2 
+	RMC->pack(&(params.gap_open2), 1,1);
+
+	// gap_extend1 
+	RMC->pack(&(params.gap_extend1), 1,1);
+
+	// gap extend2 
+	RMC->pack(&(params.gap_extend2), 1,1);
+
+	// to_end 
+	RMC->pack(&(params.to_end), 1,1);
+
+	// time 
+	RMC->pack(&(params.time), 1,1);
+
+	// alphabet_string 
+	RMC->pack(params.alphabet_string.c_str());
+
+	// single_dist: size 
+	int size = (int) params.single_dist.size();
+	RMC->pack(&size, 1,1);
+
+	// single_dist: values 
+	for (int i=0;i<(int) params.single_dist.size();i++) 
+		RMC->pack(&(params.single_dist[i]), 1,1);
+
+	// pair_dist: size(n) -> n by n array 
+	size = (int) params.pair_dist.size();
+	RMC->pack(&size, 1,1);
+
+	// pair_dist: values 
+	for (int i=0;i<(int) params.pair_dist.size();i++) 
+		for (int j=0;j<(int) params.pair_dist.size();j++)
+			RMC->pack(&(params.pair_dist[i][j]), 1,1);
+
+	// transition_matrix: column size 
+	size = (int) params.transition_matrix.size();
+	RMC->pack(&size, 1,1);
+
+	for (int i=0;i<(int) params.transition_matrix.size();i++) 
+		for (int j=0;j<(int) params.transition_matrix[i].size();j++) 
+			RMC->pack(&(params.transition_matrix[i][j]), 1,1);
+}
+
+/// The first batch of data for a newly spawned worker, e.g. init data 
+MWReturn MW_master::pack_worker_init_data() {
+
+	int argc=0;
+	char argv[100][512];
+
+	// Send arguments without the arugment having information of the number of jobs
+	for (int i=0; i<m_argc; i++)  {
+		if (strstr(m_argv[i], "--parallelize") != NULL) 
+			++i;
+		else {
+			strcpy(argv[argc], m_argv[i]);
+			++argc;
+		}
+	}
+
+	strcpy(argv[argc++], "--noannealing");
+
+
+	// Send the total number of arguments 
+	RMC->pack(&argc,1,1);
+
+	for (int i=0; i<argc; i++) 
+		RMC->pack(argv[i]); 
+
+	// Send the schema id of DB 
+	RMC->pack(&m_seqs_schema_id, 1,1);
+
+	// Send the data id of DB 
+	RMC->pack(&m_params_table_id, 1,1);
+
+	pack_params (*m_params_seed);
+	pack_params (*m_pseudocounts);
+
+	return OK;
+}
+
+static bool raw_unpack(MWRMComm* _RMC, int worker_id, char* buf, int len)
+{
+	static int cnt = 0;
+	cnt++;
+
+	int got = _RMC->raw_unpack(worker_id, buf, len);
+	if( got != len ) {
+		fprintf(stderr, "raw_unpack[%d] failed to read the size of data.\n", cnt);
+		fprintf(stderr, "need to read(%d) but got(%d)\n", len, got);
+		fflush(stderr);
+		return false;
+	}
+	return true;
+}
+
+bool MW_master::do_raw_unpack(MW_task *tf, double& wall_time, double& cpu_time)
+{
+	int tmpSize = 0;
+	int hostSize = 0;
+
+	int worker_id = tf->worker->get_id1();
+	MWRMComm* _RMC = tf->RMC;
+
+	Sparse_Matrix_Buffer *sparse_matrix_buffer = NULL;
+	Num_Cells_Buffer *num_cells_buffer = NULL;
+	Heap_Buffer *heap_buffer = NULL; 
+
+	int what_data = 0;
+	int num_edges = 0;
+	int num_probs = 0;
+	int num_logs = 0;
+
+	MEM_Buffers mem_buffers;	
+
+	do {
+		if (!raw_unpack( _RMC, worker_id, (char*)&what_data, sizeof(int)))
+			return false;
+
+		if ( what_data == 1 ) {
+
+			if (!raw_unpack( _RMC, worker_id, (char*)&num_logs, sizeof(int))) {
+				return false;
+			}
+
+			num_cells_buffer = (Num_Cells_Buffer *) malloc (sizeof (Num_Cells_Buffer) * num_logs);
+			assert(num_cells_buffer);
+
+
+			if (!raw_unpack( _RMC, worker_id, (char*) num_cells_buffer, num_logs * sizeof(Num_Cells_Buffer))) {
+				return false;
+			}
+
+			if (!raw_unpack( _RMC, worker_id, (char*)&num_probs, sizeof(int))) {
+				return false;
+			}
+
+			sparse_matrix_buffer = (Sparse_Matrix_Buffer *) malloc (sizeof (Sparse_Matrix_Buffer) * num_probs);
+			assert(sparse_matrix_buffer);
+
+			if (!raw_unpack( _RMC, worker_id, (char*) sparse_matrix_buffer, num_probs * sizeof(Sparse_Matrix_Buffer))) {
+				return false;
+			}
+			
+			mem_buffers.num_cells_buffers.push_back (Cells_pair (num_logs, num_cells_buffer) );
+			
+			mem_buffers.sparse_matrix_buffers.push_back (Sparse_pair (num_probs, sparse_matrix_buffer) );
+
+
+		}
+		else if ( what_data == 2) {
+
+			if (!raw_unpack( _RMC, worker_id, (char*)&num_edges, sizeof(int))) {
+				return false;
+			}
+
+			heap_buffer = (Heap_Buffer *) malloc (sizeof (Heap_Buffer) * num_edges);
+			assert(heap_buffer);
+
+			if (!raw_unpack( _RMC, worker_id, (char*) heap_buffer, num_edges * sizeof(Heap_Buffer))) {
+				return false;
+			}
+
+			mem_buffers.heap_buffers.push_back (Heap_pair (num_edges, heap_buffer) );
+		}
+
+	} while ( what_data > 0 );
+
+	// We finished to read all data
+	// Now, we need to read two doubles
+	wall_time = 0.0;
+	cpu_time = 0.0;
+	if (!raw_unpack( _RMC, worker_id, (char*)&wall_time, sizeof(double))) {
+		return false;
+	}
+	if (!raw_unpack( _RMC, worker_id, (char*)&cpu_time, sizeof(double))) {
+		return false;
+	}
+
+	pthread_mutex_lock(&worker_thread_mutex);	
+
+	for (int i = 0; i < mem_buffers.num_cells_buffers.size(); i++) {
+		m_mem_buffers->num_cells_buffers.push_back (mem_buffers.num_cells_buffers[i]);
+	}
+
+	for (int i = 0; i < mem_buffers.sparse_matrix_buffers.size(); i++) {
+		m_mem_buffers->sparse_matrix_buffers.push_back (mem_buffers.sparse_matrix_buffers[i]);
+	}
+
+	for (int i = 0; i < mem_buffers.heap_buffers.size(); i++) {
+		m_mem_buffers->heap_buffers.push_back (mem_buffers.heap_buffers[i]);
+	}
+	
+	pthread_mutex_unlock(&worker_thread_mutex);	
+
+
+	return true;
+}
+
+/// Implement application behavior to process a just completed task */
+MWReturn MW_master::act_on_completed_task( MWTask *t ) {
+	MW_task *tf = dynamic_cast<MW_task *>(t);
+
+	if( !tf->m_raw_flag ) {
+		return OK;
+	}
+
+	/// It means that we need to call raw_unpack
+	int worker_id = tf->worker->get_id1();
+
+	// Set the timeout of Main process select/poll to 1 sec
+	tf->RMC->setPollTimeOut(5);
+		
+	// This will indicate 
+	// "this socket will be taken over by new thread"
+	// "So main thread MUST do nothing on it"
+	tf->RMC->thread_start(worker_id);
+
+	// Create pthread
+	increasePendingNum();
+
+	ThreadData* tdata = (ThreadData*)malloc(sizeof(ThreadData));
+	assert(tdata);
+
+	tdata->m_task = tf;
+	tdata->m_driver = this;
+
+	pthread_t thread;
+	if( pthread_create(&thread, NULL, __do_raw_unpack, (void *)tdata) != 0 ) {
+		fprintf(stderr, "Failed to create a new thread\n");	
+		free(tdata);
+
+		tf->RMC->thread_stop(worker_id);
+
+		decreasePendingNum();
+
+		double wall_time = 0.0;
+		double cpu_time = 0.0;
+		if( do_raw_unpack(tf, wall_time, cpu_time) == false ) {
+			fprintf(stderr, "do_raw_unpack failed from worker(id=%d,name=%s)\n", 
+					worker_id, tf->worker->machine_name());
+			return ABORT;
+		}
+	}else {
+		// Detach this thread
+		pthread_detach(thread);
+	}
+
+	return PENDING;
+}
+
+
+/// printresults
+void MW_master::printresults() {
+
+	assert(getPendingNum() == 0 );
+
+}
+
+/// Write app-specific master checkpoint info 
+void MW_master::write_master_state( FILE *fp ) {
+	// Nothing to be written 
+}
+
+/// Read app-specific master checkpoint info 
+void MW_master::read_master_state( FILE *fp ) {
+	// Nothing to be read 
+}
+
+/// Return a new application task object 
+MWTask* MW_master::gimme_a_task() {
+	return new MW_task;
+}
+
+/// Return a new driver object 
+MWDriver* gimme_the_master() {
+	return NULL;
+}
+
+void 
+MW_master::AddTask( MWTask* t)
+{
+	addTask(t);
+}
+
+/// compute_next_starting_pair 
+void MW_master::compute_next_starting_pair(int& seq_i, int& seq_j, int length, int total_seq_num) {
+
+	int tmp_length = length;
+
+	// Compute the next sequence pair 
+	while( tmp_length > 0 ) {
+		if( (seq_j + tmp_length) < total_seq_num ) {
+			seq_j += tmp_length;
+			break;
+		} else {
+			tmp_length -= total_seq_num - seq_j;
+			seq_j = ++seq_i + 1;
+		}
+	}
+}
+
+/// get_proc_cpuinfo 
+bool MW_master::get_proc_cpuinfo(char *arch) {
+	char path[64];
+	FILE *fp;
+	char line_input[1024];
+
+	memset(path, 0, sizeof(path));
+	strcpy(path, "/proc/cpuinfo");
+
+	if ((fp = fopen(path, "r")) != NULL ) {
+		while (!feof(fp)) {
+			fgets ( line_input, 1024, fp);
+			if (strstr ( line_input, "flags" ) != NULL && strstr(line_input, " lm ") != NULL) {
+				strcpy(arch,"X86_64");
+				fclose ( fp );
+				return true;
+			}
+		}
+	}
+	else {
+		fclose (fp);
+		return false;
+	}
+
+	strcpy(arch,"INTEL");
+	fclose (fp);
+	return true;
+
+}
+
+
diff --git a/src/manager/mw_master.h b/src/manager/mw_master.h
new file mode 100644
index 0000000..2117061
--- /dev/null
+++ b/src/manager/mw_master.h
@@ -0,0 +1,93 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef MW_MASTER_INCLUDED
+#define MW_MASTER_INCLUDED
+
+#include "MWDriver.h"
+#include "seq/sequence.h"
+#include "manager/mw_task.h"
+#include "manager/db_misc.h"
+
+#ifdef HAVE_POSTGRES
+#include "manager/db_postgres.h"
+#endif
+
+namespace fsa {
+
+  class Params;
+  class DB_opts;
+
+  /// Application Driver subclass derived from MWDriver 
+  class MW_master : public MWDriver 
+  {
+  public:
+
+    /// constructor
+    MW_master();
+
+    /// constructor
+    MW_master(const Params &params_seed, const Params &pseudocounts, MEM_Buffers &mem_buffers,
+	      const int num_seqs, const int num_seqs_pairs, const int num_jobs,
+	      const int seqs_schema_id, const int params_table_id); 
+
+
+    /// Get the info from the user.  Don't forget to get the worker_executable! 
+    MWReturn get_userinfo(int argc, char **argv);
+
+    /// Set up an array of tasks here 
+    MWReturn setup_initial_tasks( int *, MWTask *** );
+
+    /// What to do when a task finishes 
+    MWReturn act_on_completed_task( MWTask * );
+
+    /// Put things in the send buffer here that go to a worker 
+    MWReturn pack_worker_init_data( void );
+
+    /// Print the results	
+    void printresults();
+
+    /// Write out the state of the master to a file. 
+    void write_master_state( FILE *fp );
+
+    /// Read in the state from a file. 
+    void read_master_state( FILE *fp );
+
+    /// Just return a newly constructed application task 
+    MWTask* gimme_a_task();
+
+    /// Compute next candidate starting pair 
+    void compute_next_starting_pair(int& seq_i, int& seq_j, int length, int total_seq_num);
+
+    /// Get cpuinfo 
+    bool get_proc_cpuinfo(char *arch); 
+
+    bool do_raw_unpack (MW_task *tf, double&, double& );
+
+    void pack_params(const Params &params); 
+
+    void AddTask( MWTask* t);
+
+  private:
+		
+    int m_num_parallelized_jobs;
+    int m_num_seq_pairs;
+    int m_num_of_pairs; 
+    int m_num_remains;
+    int m_num_seqs;
+    int m_seqs_schema_id; 
+    int m_params_table_id;
+
+    const Params *m_params_seed;
+    const Params *m_pseudocounts;
+    int    m_argc;
+    char** m_argv;
+
+    MEM_Buffers *m_mem_buffers;
+  };
+
+}
+
+#endif
diff --git a/src/manager/mw_task.cc b/src/manager/mw_task.cc
new file mode 100644
index 0000000..6f0375b
--- /dev/null
+++ b/src/manager/mw_task.cc
@@ -0,0 +1,62 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include "manager/mw_task.h"
+
+using namespace fsa;
+
+/// this funtion is called inside pack_results
+extern void transfer_data(MW_task *);
+
+MW_task::MW_task() {
+	m_raw_flag = 0;
+}
+
+MW_task::~MW_task() {}
+
+void MW_task::printself( int level ) {
+	// do nothing
+}
+
+void MW_task::pack_work( void ) {
+
+	RMC->pack(&m_worker_id,1,1);                // the number of sequence pairs
+	RMC->pack(&m_prev_length_sum,1,1);
+	RMC->pack(&m_length,1,1);                   // the number of sequence pairs
+	RMC->pack(&m_start_seq_i,1,1);              // the first sequence of the starting sequence pair
+	RMC->pack(&m_start_seq_j,1,1);              // the secnod sequence of the starting sequence pair
+}
+
+void MW_task::unpack_work( void ) {
+	RMC->unpack(&m_worker_id,1,1);              // the number of sequence pairs
+	RMC->unpack(&m_prev_length_sum,1,1);
+	RMC->unpack(&m_length,1,1);                 // the number of sequence pairs
+	RMC->unpack(&m_start_seq_i,1,1);            // the first sequence of the starting sequence pair
+	RMC->unpack(&m_start_seq_j,1,1);            // the second sequence of the starting sequence pair
+
+}
+
+void MW_task::pack_results( void ) {
+	RMC->pack(&m_raw_flag, 1, 1);
+
+	if (m_raw_flag) {
+		RMC->pre_send(RESULTS); 
+	}
+
+	transfer_data(this);
+}
+
+void MW_task::unpack_results( void ) {
+	m_raw_flag = 0;
+	RMC->unpack(&m_raw_flag, 1, 1);
+}
+
+void MW_task::write_ckpt_info( FILE *fp )  {
+	// Nothing in this app, will lose data if it crashes. 
+}
+
+void MW_task::read_ckpt_info( FILE *fp ) {
+	// Nothing to be read since nothing is written 
+}
diff --git a/src/manager/mw_task.h b/src/manager/mw_task.h
new file mode 100644
index 0000000..7e2e7bd
--- /dev/null
+++ b/src/manager/mw_task.h
@@ -0,0 +1,63 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef MW_TASK_INCLUDED
+#define MW_TASK_INCLUDED
+
+#include "MWTask.h"
+
+namespace fsa {
+
+  /// MW_task class
+  /*
+   * The master and the workers communicate by passing this class
+   */
+  class MW_task : public MWTask 
+  {
+  public:
+    /// constructor
+    MW_task();
+
+    /// Destructor 
+    ~MW_task();
+
+
+    /// App is required to implement the following functions. 
+		
+    /// The driver packs the input data via RMC, the data which will be sent to a worker. 
+    void pack_work( void );
+
+    /// The worker unpacks input data via RMC, need to allocate space for data 
+    void unpack_work( void );
+
+    /// The worker packs result data via RMC, the result will be sent back to driver 
+    void pack_results( void );
+
+    /// The driver unpacks result data via RMC 
+    void unpack_results( void );
+
+    /// The following functions have default implementation. 
+
+    /// Print the task to stdout 
+    void printself( int level = 70 );
+
+    /// write checkpoint info per task, for each task haven't been finished 
+    void write_ckpt_info( FILE *fp );
+
+    /// read checkpoint info, in the order written into the file 
+    void read_ckpt_info( FILE *fp );
+
+    int m_start_seq_i;
+    int m_start_seq_j;
+    int m_prev_length_sum;
+    int m_length;
+    int m_worker_id;
+
+    int m_raw_flag;
+  };
+
+}
+
+#endif
diff --git a/src/manager/mw_worker.cc b/src/manager/mw_worker.cc
new file mode 100644
index 0000000..89fe720
--- /dev/null
+++ b/src/manager/mw_worker.cc
@@ -0,0 +1,232 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include <arpa/inet.h>
+#include <pthread.h>
+#include <string.h>
+
+#include "manager/mw_worker.h"
+#include "fsa/fsa.h"
+
+using namespace fsa;
+
+extern FSA *m_fsa;
+extern DB_adapter *m_db_adapter;
+extern Params m_params_seed;
+extern Params m_pseudocounts;
+extern MEM_Buffer m_mem_buffer;
+extern DB_Buffer m_db_buffer;
+extern bool final_buffer;
+extern bool send_thread_waiting;
+
+
+
+MW_worker::MW_worker() {}
+
+MW_worker::MW_worker(DB_adapter &db_adapter) 
+{
+	// how much info you wants the driver to print 
+	set_MWprintf_level( 1 );
+
+	m_db_adapter = &db_adapter;
+
+	workingTask = new MW_task;
+
+	m_mem_buffer.sparse_matrix = NULL;
+	m_mem_buffer.num_cells = NULL;
+	m_mem_buffer.heap = NULL;
+}
+
+MW_worker::~MW_worker() {
+	for (int i=0; i<m_argc; i++)
+		free (m_argv[i]);
+	free (m_argv);
+
+	if (workingTask)
+		delete workingTask;
+}
+
+double MW_worker::benchmark( MWTask *t ) {
+	// As we don't have benchmark, we do nothing
+	return (double)3.14;
+}
+
+void MW_worker::unpack_params (Params &params) {
+	// bandwidth 
+	RMC->unpack(&(params.bandwidth), 1,1);
+
+	// is_indel2 
+	char is_indel2;
+	RMC->unpack(&is_indel2, 1, 1);
+	params.is_indel2 = (is_indel2 == 1) ? true : false;
+
+	// gap_open1 
+	RMC->unpack(&(params.gap_open1), 1,1);
+
+	// gap_open2 
+	RMC->unpack(&(params.gap_open2), 1,1);
+
+	// gap_extend1 
+	RMC->unpack(&(params.gap_extend1), 1,1);
+
+	// gap extend2 
+	RMC->unpack(&(params.gap_extend2), 1,1);
+
+	// to_end 
+	RMC->unpack(&(params.to_end), 1,1);
+
+	// time 
+	RMC->unpack(&(params.time), 1,1);
+
+	// alphabet_string 
+	char *temp_char =  (char *) malloc (1024 * sizeof (char) );
+	RMC->unpack(temp_char);
+	params.alphabet_string = temp_char;
+	free (temp_char);
+
+	// single_dist: size 
+	int size;
+	RMC->unpack(&size, 1,1);
+	params.single_dist.resize(size);
+
+	// single_dist: values 
+	for (int i=0;i<size;i++) 
+		RMC->unpack(&(params.single_dist[i]), 1,1);
+
+	// pair_dist: size(n) -> n by n array 
+	RMC->unpack(&size, 1,1);
+	params.pair_dist.resize(size);
+
+	// pair_dist: values 
+	for (int i=0;i<size;i++) { 
+		params.pair_dist[i].resize(size);
+		for (int j=0;j<size;j++)
+			RMC->unpack(&(params.pair_dist[i][j]), 1,1);
+	}
+
+	// transaction_matrix: column size 
+	RMC->unpack(&size, 1,1);
+	params.transition_matrix.resize(size);
+
+	for (int i=0;i<size;i++)  {
+		params.transition_matrix[i].resize(size);
+		for (int j=0;j<size;j++) 
+			RMC->unpack(&(params.transition_matrix[i][j]), 1,1);
+	}
+}
+
+/// unpack the init data from the driver 
+MWReturn MW_worker::unpack_init_data( void )  {
+
+	// Read the total number of arguments 
+	RMC->unpack(&m_argc,1,1);
+
+	// Read arguments 
+	m_argv = (char**) malloc(m_argc * sizeof(char*));
+
+	for (int i = 0; i < m_argc; i++) {
+		m_argv[i] = (char *) malloc (512 * sizeof(char));
+		RMC->unpack(m_argv[i]);
+	}
+
+	// Read schema id of DB 
+	RMC->unpack(&m_seqs_schema_id, 1,1);
+
+	// Read data id of DB 
+	RMC->unpack(&m_params_table_id, 1,1);
+
+	unpack_params (m_params_seed);
+	unpack_params (m_pseudocounts);
+
+	return OK;
+}
+
+void MW_worker::init_transfer(const int worker_id, int &raw_flag) {
+
+	final_buffer = false;
+	send_thread_waiting = false;
+
+	if (m_fsa->write_db) {
+		bool is_db_running = false;
+		m_db_buffer.sparse_matrix.clear();
+		m_db_buffer.num_cells.clear();
+		m_db_buffer.heap.clear();
+
+		// connect DB
+		is_db_running = m_db_adapter->connect_db(m_fsa->db_hostname.c_str(), m_fsa->db_hostaddr.c_str(), m_fsa->db_name.c_str(), 
+				m_fsa->db_port, m_fsa->db_user.c_str(), m_fsa->db_password.c_str());
+
+		if (!is_db_running)
+			THROWEXPR ("ERROR: We can not access database server.");
+
+		m_db_adapter->set_up_ids (m_seqs_schema_id, m_params_table_id, worker_id);
+
+		raw_flag = 0;
+
+	}
+	else {
+		if (!m_mem_buffer.sparse_matrix) 
+			m_mem_buffer.sparse_matrix = (Sparse_Matrix_Buffer*) malloc (
+					sizeof (Sparse_Matrix_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Sparse_Matrix_Buffer))));
+		
+
+		if (!m_mem_buffer.num_cells)	
+			m_mem_buffer.num_cells = (Num_Cells_Buffer *) malloc ( 
+					sizeof (Num_Cells_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Num_Cells_Buffer))));
+
+		if (!m_mem_buffer.heap)
+			m_mem_buffer.heap = (Heap_Buffer *) malloc ( 
+					sizeof (Heap_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Heap_Buffer))));
+
+		raw_flag = 1;
+
+	}
+}
+
+/// Execute each task 
+void MW_worker::execute_task( MWTask *t ) {
+
+	MW_task *tf = dynamic_cast<MW_task *>(t);
+	int num_seq_pairs = tf->m_length;
+	int prev_seq_pairs_sum = tf->m_prev_length_sum;
+	std::pair <int,int> start_seq_pair (tf->m_start_seq_i, tf->m_start_seq_j);
+
+	// create fsa
+	m_fsa = new FSA (m_argc, m_argv);
+
+	// create buffers and init
+	m_fsa->init_for_mw_worker (start_seq_pair, prev_seq_pairs_sum, num_seq_pairs);
+
+	try
+	{
+		// It's important that we input the data /before/ parsing the command-line 
+		// This allows us to set preset values for DNA, RNA and proteins and then let
+		// them be overriden by the command-line 
+		m_fsa->init_opts();
+		m_fsa->input_data();
+		m_fsa->set_up_defaults();
+		m_fsa->parse_opts();
+		m_fsa->assemble_sequence_data();
+		m_fsa->choose_seq_pairs();
+
+		init_transfer(tf->m_worker_id, tf->m_raw_flag);
+	}
+	catch (const Dart_exception& e)
+	{
+		CLOGERR << e.what();
+		exit(1);
+	}
+
+}
+
+MWTask* MW_worker::gimme_a_task() {
+	return new MW_task;
+}
+
+// Just return a newly created application worker object 
+MWWorker* gimme_a_worker () {
+	return new MW_worker;
+}
+
diff --git a/src/manager/mw_worker.h b/src/manager/mw_worker.h
new file mode 100644
index 0000000..5187bd8
--- /dev/null
+++ b/src/manager/mw_worker.h
@@ -0,0 +1,63 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#ifndef MW_WORKER_INCLUDED
+#define MW_WORKER_INCLUDED
+
+#include "MWWorker.h"
+
+#include "manager/db_adapter.h"
+#include "manager/mw_task.h"
+
+namespace fsa {
+
+  class Params;
+
+  class MW_worker : public MWWorker 
+  {
+  public:
+
+    /// constructor
+    MW_worker();
+
+    /// constructor
+    MW_worker(DB_adapter &db_adapter);
+
+    /// destructor
+    ~MW_worker();
+
+    /// Benchmarking 
+    double benchmark( MWTask *t );
+
+    /// return a task
+    MWTask* gimme_a_task();
+
+    /// unpack init data 
+    MWReturn unpack_init_data( void );
+
+    /// unpack parameters
+    void unpack_params(Params &params);
+
+    /// do the real work for each task 
+    void execute_task( MWTask * );
+
+    void init_transfer(const int worker_id, int &raw_flag); 
+
+  private:
+
+    int m_seqs_schema_id;
+    int m_params_table_id;
+		
+    // command arguments
+    int    m_argc;                
+    char **m_argv;
+
+
+
+  };
+
+}
+
+#endif
diff --git a/src/manager/transfer_data.cc b/src/manager/transfer_data.cc
new file mode 100644
index 0000000..f9fd41b
--- /dev/null
+++ b/src/manager/transfer_data.cc
@@ -0,0 +1,634 @@
+/*
+ *  This file is part of FSA, a sequence alignment algorithm.
+ *  Source code in this file was written by Jaeyoung Do.
+ */
+
+#include "fsa/fsa.h"
+#include <errno.h>
+
+#if defined(HAVE_CONDOR) 
+#include "MW.h"
+#include "MWSystem.h"
+#endif
+
+#define END_DATA    0
+#define SPARSE_DATA 1
+#define HEAP_DATA   2
+
+using namespace fsa;
+
+FSA *m_fsa = NULL;
+DB_adapter *m_db_adapter = NULL;
+
+Params m_params_seed;
+Params m_pseudocounts;
+
+MEM_Buffer m_mem_buffer;
+DB_Buffer m_db_buffer;
+
+static int num_probs = 0;
+static int num_logs = 0;
+static int num_edges = 0;
+
+typedef struct MEM_Container {
+	int what_data;
+
+	int size1;
+	char* buffer1;
+	int size2;
+	char* buffer2;
+
+} MEM_Container;
+
+static std::queue<MEM_Container*> buffer_queue;
+
+bool final_buffer = false;
+bool send_thread_waiting = false;
+
+static pthread_mutex_t queue_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER;
+
+static double wall_time = 0.0;
+static double cpu_time = 0.0;
+
+void compute_data (SparseMatrix *ijMatrix, int i, int j); 
+
+void insert_posterior_probability (int seq1, int pos1, int seq2, int pos2, float prob);
+void insert_num_cells (int seq1, int seq2, int size);
+void insert_edge (int seq1, int pos1, int seq2, int pos2, double weight, float delta);
+
+void flush_on_the_fly (bool force);
+
+void build_multiple_alignment();
+void build_anchored_multiple_alignment();
+
+static void enqueue_buffer(MEM_Container* buffer, bool final);
+static MEM_Container* dequeue_buffer(void);
+
+#if defined(HAVE_POSTGRES) 
+void init_single_worker(const FSA *fsa, DB_adapter *db_adapter, Params &params_seed, Params &pseudocounts); 
+#endif
+
+#if defined(HAVE_CONDOR) 
+static void* send_thread(void *ptr);
+static bool do_raw_pack (MWRMComm* RMC, MEM_Container *mem_container);
+static bool raw_pack(MWRMComm* _RMC, char* buf, int len);
+void transfer_data(MW_task *t);
+#endif
+
+
+void insert_posterior_probability (int seq1, int pos1, int seq2, int pos2, float prob) {
+
+	if (m_fsa->write_db) {
+		char entry[MAX_DB_ENTRY_LENGTH];
+		sprintf(entry,"%d\t%d\t%d\t%d\t%lf\n", seq1, pos1, seq2, pos2, prob);
+		m_db_buffer.sparse_matrix.append (entry);
+	}
+	else {
+		m_mem_buffer.sparse_matrix[num_probs].pos1 = pos1;
+		m_mem_buffer.sparse_matrix[num_probs].pos2 = pos2;
+		m_mem_buffer.sparse_matrix[num_probs].prob = prob;
+	}
+
+	num_probs++;
+}
+
+void insert_num_cells (int seq1, int seq2, int size) {
+
+
+	if (m_fsa->write_db) {
+		char entry[MAX_DB_ENTRY_LENGTH];
+		sprintf(entry,"%d\t%d\t%d\n", seq1, seq2, size);
+		m_db_buffer.num_cells.append (entry);
+	}
+	else {
+		if (seq1 == 0 && seq2 == 0 )
+			return;
+
+		m_mem_buffer.num_cells[num_logs].seq1 = seq1;
+		m_mem_buffer.num_cells[num_logs].seq2 = seq2;
+		m_mem_buffer.num_cells[num_logs].size = size;
+	}
+
+	num_logs++;
+}
+
+void insert_edge (int seq1, int pos1, int seq2, int pos2, double weight, float delta) {
+
+
+	if (m_fsa->write_db) {
+		char entry[MAX_DB_ENTRY_LENGTH];
+		sprintf(entry,"%d\t%d\t%d\t%d\t%lf\t%f\n", seq1, pos1, seq2, pos2, weight, delta);
+		m_db_buffer.heap.append (entry);
+	}
+	else {
+
+		m_mem_buffer.heap[num_edges].seq1 = seq1;
+		m_mem_buffer.heap[num_edges].pos1 = pos1;
+		m_mem_buffer.heap[num_edges].seq2 = seq2;
+		m_mem_buffer.heap[num_edges].pos2 = pos2;
+		m_mem_buffer.heap[num_edges].weight = weight;
+		m_mem_buffer.heap[num_edges].delta = delta;
+	}
+
+	num_edges++;
+}
+
+
+void compute_data (SparseMatrix *ijMatrix, int i, int j) 
+{
+	if (ijMatrix == 0)
+		return;
+
+	int xlen = m_fsa->seq_db.get_seq (i).length();
+	int ylen = m_fsa->seq_db.get_seq (j).length();
+
+	int pre_num_probs = num_probs;
+
+	for (int jj = 0; jj < ylen; jj++)  
+		insert_posterior_probability (i, 0, j, jj+1, ijMatrix->get_gap_prob (1, jj+1));
+
+	// for all entries in the SparseMatrix, calculate the corresponding weight
+	// and store the edge
+	for (int ii = 0; ii < xlen; ii++) { // note 0-based indexing for sequences
+		float p_gap_ii = ijMatrix->get_gap_prob (0, ii + 1);
+
+		insert_posterior_probability (i, ii+1, j, 0, p_gap_ii);
+
+		for (std::vector<Matrix_entry>::iterator rowPtr = ijMatrix->GetRowPtr (ii + 1),
+				rowEnd = rowPtr + ijMatrix->GetRowSize (ii + 1); rowPtr != rowEnd; rowPtr++) {
+			int jj = rowPtr->first - 1; // convert from SparseMatrix's 1-based coords to the 0-based coords which we use here
+
+			insert_posterior_probability (i, ii+1, j, jj+1, ijMatrix->get_match_prob(ii+1, jj+1));
+
+			float p_match = rowPtr->second;
+			if (!p_match)
+				continue;
+
+			float p_gap = p_gap_ii + ijMatrix->get_gap_prob (1, jj + 1);
+			float weight = m_fsa->use_tgf ? (2 * p_match / p_gap) : (2 * p_match - m_fsa->gap_factor * p_gap);
+			float delta = 2 * p_match - p_gap;
+
+			float edge_weight_threshold = 0; //TODO it should be the same with in fsa
+
+			// if the edge already scores too low to ever be accepted, then skip it
+			if ((weight < edge_weight_threshold) || (m_fsa->use_tgf && weight < m_fsa->gap_factor))
+				continue;
+
+			insert_edge (i, ii, j, jj, weight, delta);
+		}
+	}
+
+	insert_num_cells (i, j, (num_probs - pre_num_probs));
+}
+
+void build_anchored_multiple_alignment() {
+
+  // read in weights for sequence pairs if information present
+  if (m_fsa->tree_weights_file != "")
+    m_fsa->tree_weights.from_file (m_fsa->seq_db, m_fsa->tree_weights_file);
+
+    // get resolved anchors for the sequence pairs which we're going use for alignment
+    Anchor_resolver anchor_resolver (m_fsa->seq_db, m_fsa->seq_db_internal, m_fsa->alignment_seq_pairs);
+
+    // add Mercator constraints if present
+    if (m_fsa->mercator_constraint_file != "")
+      anchor_resolver.add_mercator_constraints (m_fsa->mercator_constraint_file);
+
+    // now actually get resolved anchors
+    std::vector<Anchors > resolved_anchors_list = anchor_resolver.get_resolved_anchors (m_fsa->tree_weights,
+											m_fsa->anchor_minlen, m_fsa->anchor_max_join_length, m_fsa->use_translated,
+										   m_fsa->exonerate, m_fsa->exonerate_minscore, m_fsa->softmasked,
+										   m_fsa->hardmasked,
+										   m_fsa->num_refinement_steps,
+										   m_fsa->output_for_gui, m_fsa->gui_prefix);
+
+    // loop through sequence database
+    for (size_t cnt = 0; cnt < m_fsa->alignment_seq_pairs.size(); ++cnt) {
+
+      // initialize all the sequence data
+      int i = m_fsa->alignment_seq_pairs[cnt].first;
+      int j = m_fsa->alignment_seq_pairs[cnt].second;
+
+	  // initialize all the sequence data
+      const Sequence& xseq = m_fsa->seq_db_internal.get_seq (i);
+      const Sequence& yseq = m_fsa->seq_db_internal.get_seq (j);
+
+      Post_probs post_probs = m_fsa->perform_anchored_pairwise_inference (m_params_seed, xseq, yseq,
+										   m_pseudocounts,
+										   resolved_anchors_list[cnt]);
+
+      // we need the original sequences in case we've been hardmasking
+      const Sequence& xseq_orig = (m_fsa->seq_db).get_seq (i);
+      const Sequence& yseq_orig = (m_fsa->seq_db).get_seq (j);
+
+      // if hardmasking, map coords back to original sequence
+      if (m_fsa->hardmasked) {
+	for (Post_probs::iterator p = post_probs.begin(); p != post_probs.end(); ++p) {
+	  (*p).x = xseq_orig.map_stripped_to_orig ((*p).x);
+	  (*p).y = yseq_orig.map_stripped_to_orig ((*p).y);
+	}
+      }
+
+      SparseMatrix *ijMatrix = new SparseMatrix (i, j,
+						 xseq_orig.length(), yseq_orig.length(),
+						 post_probs);
+
+	  compute_data (ijMatrix, i, j);
+
+	  flush_on_the_fly (false);
+
+	  delete ijMatrix;
+
+    } // end loop over seq_db_internal
+
+	insert_num_cells (0, 0, num_edges);
+
+	flush_on_the_fly (true);
+
+}
+
+
+void build_multiple_alignment() {
+
+  // read in weights for sequence pairs if information present
+  if (m_fsa->tree_weights_file != "")
+    m_fsa->tree_weights.from_file (m_fsa->seq_db, m_fsa->tree_weights_file);
+
+	bool left_match = false;  // do not require homology beyond sequence boundaries
+	bool right_match = false;
+
+	// loop through sequence database
+	for (size_t cnt = 0; cnt < m_fsa->alignment_seq_pairs.size(); ++cnt) {
+
+		// initialize all the sequence data
+		int i = m_fsa->alignment_seq_pairs[cnt].first;
+		int j = m_fsa->alignment_seq_pairs[cnt].second;
+
+		// initialize all the sequence data
+		const Sequence& xseq = m_fsa->seq_db_internal.get_seq (i);
+		const Sequence& yseq = m_fsa->seq_db_internal.get_seq (j);
+		
+		Params params_seed;
+		params_seed.copy_all (m_params_seed);
+
+		Post_probs post_probs = m_fsa->perform_pairwise_inference  (params_seed, xseq, yseq, 
+										   left_match, right_match, m_fsa->ragged_ends, m_pseudocounts);
+
+      // we need the original sequences in case we've been hardmasking
+      const Sequence& xseq_orig = (m_fsa->seq_db).get_seq (i);
+      const Sequence& yseq_orig = (m_fsa->seq_db).get_seq (j);
+
+      // if hardmasking, map coords back to original sequence
+      if (m_fsa->hardmasked) {
+	for (Post_probs::iterator p = post_probs.begin(); p != post_probs.end(); ++p) {
+	  (*p).x = xseq_orig.map_stripped_to_orig ((*p).x);
+	  (*p).y = yseq_orig.map_stripped_to_orig ((*p).y);
+	}
+      }
+
+      SparseMatrix *ijMatrix = new SparseMatrix (i, j,
+						 xseq_orig.length(), yseq_orig.length(),
+						 post_probs);
+
+		compute_data(ijMatrix, i, j);
+
+		delete ijMatrix;
+
+		flush_on_the_fly (false);
+	}
+
+	insert_num_cells (0, 0, num_edges);
+
+	flush_on_the_fly (true);
+	
+}
+
+void flush_on_the_fly (bool force) {
+	if (m_fsa->write_db) {
+		if ( force || ( (m_db_buffer.sparse_matrix.size() + m_db_buffer.num_cells.size() + m_db_buffer.heap.size() ) > (BUFFER_RATIO * MAX_DB_BUFFER_SIZE))) {
+#if defined(HAVE_POSTGRES) 
+			(m_db_adapter->get_connection())->flush_sparse_matrix_buffer (m_db_buffer.sparse_matrix.c_str());
+			m_db_buffer.sparse_matrix.clear();
+
+			(m_db_adapter->get_connection())->flush_num_cells_buffer (m_db_buffer.num_cells.c_str());
+			m_db_buffer.num_cells.clear();
+
+			(m_db_adapter->get_connection())->flush_heap_buffer (m_db_buffer.heap.c_str());
+			m_db_buffer.heap.clear();
+#endif
+		}
+
+	} else  {
+		
+		if ( force || (num_probs * sizeof (Sparse_Matrix_Buffer) > (BUFFER_RATIO * MAX_MEM_BUFFER_SIZE))) {
+			MEM_Container *mem_container = (MEM_Container*) malloc ( sizeof (MEM_Container) );
+			assert (mem_container);
+
+			mem_container->what_data = SPARSE_DATA;
+
+			mem_container->size1 = num_logs * sizeof (Num_Cells_Buffer);
+			mem_container->buffer1 = (char*) m_mem_buffer.num_cells;
+
+			mem_container->size2 = num_probs * sizeof (Sparse_Matrix_Buffer);
+			mem_container->buffer2 = (char*) m_mem_buffer.sparse_matrix;
+
+			enqueue_buffer(mem_container, false);
+
+			if (!force) {
+
+				m_mem_buffer.num_cells = (Num_Cells_Buffer *) malloc ( 
+						sizeof (Num_Cells_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Num_Cells_Buffer))));
+				assert(m_mem_buffer.num_cells);
+
+				m_mem_buffer.sparse_matrix = (Sparse_Matrix_Buffer*) malloc (
+						sizeof (Sparse_Matrix_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Sparse_Matrix_Buffer))));
+				assert(m_mem_buffer.sparse_matrix);
+			} else {
+				m_mem_buffer.num_cells = NULL;
+				m_mem_buffer.sparse_matrix = NULL;
+			}
+
+			num_probs = 0;
+			num_logs = 0;
+		}
+
+		if ( force || (num_edges * sizeof (Heap_Buffer) > (BUFFER_RATIO * MAX_MEM_BUFFER_SIZE))) {
+
+			MEM_Container *mem_container = (MEM_Container*) malloc ( sizeof (MEM_Container) );
+			assert (mem_container);
+
+			mem_container->what_data = HEAP_DATA;
+
+			mem_container->size1 = num_edges * sizeof (Heap_Buffer);
+			mem_container->buffer1 = (char*) m_mem_buffer.heap;
+
+			mem_container->size2 = 0;
+			mem_container->buffer2 = NULL;
+
+			enqueue_buffer(mem_container, false);
+
+			if (!force) {
+				m_mem_buffer.heap = (Heap_Buffer *) malloc ( 
+						sizeof (Heap_Buffer) * ((int) (MAX_DB_BUFFER_SIZE / sizeof (Heap_Buffer))));
+				assert(m_mem_buffer.heap);
+			}
+			else
+				m_mem_buffer.heap = NULL;
+
+			num_edges = 0;
+		}
+
+		if ( force ) {
+			// send last signal
+			MEM_Container *mem_container = (MEM_Container*) malloc ( sizeof (MEM_Container) );
+			assert (mem_container);
+
+			mem_container->what_data = END_DATA;
+			mem_container->size1 = 0;
+			mem_container->buffer1 = NULL;
+
+			mem_container->size2 = 0;
+			mem_container->buffer2 = NULL;
+			
+			enqueue_buffer(mem_container, true);
+		}
+	}
+}
+
+
+
+static void enqueue_buffer(MEM_Container* buffer, bool final)
+{
+	if( !buffer ) {
+		return;
+	}
+
+	pthread_mutex_lock(&queue_lock);
+
+	buffer_queue.push(buffer);
+	if( final ) {
+		final_buffer = true;
+	}
+
+	if( send_thread_waiting ) {
+		pthread_cond_signal(&queue_cond);
+	}
+
+	pthread_mutex_unlock(&queue_lock);
+
+}
+
+static MEM_Container* dequeue_buffer (void) {
+
+	MEM_Container *mem_container;
+
+	if (buffer_queue.empty() )
+		mem_container = NULL;
+	else {
+		mem_container = buffer_queue.front();
+		buffer_queue.pop();
+	}
+
+	return  mem_container;
+}
+
+#if defined(HAVE_CONDOR) 
+
+static void* send_thread(void *ptr) 
+{
+	
+	MWTask* t = (MWTask*)ptr;
+
+	while(1) {
+		MEM_Container* mem_container = NULL;
+		bool done = false;
+
+		pthread_mutex_lock(&queue_lock);
+		while( (mem_container = dequeue_buffer()) == NULL ) {
+
+			if( final_buffer ) { 
+				break;
+			}else {
+				send_thread_waiting = true;
+				pthread_cond_wait(&queue_cond, &queue_lock);
+				send_thread_waiting = false;
+			}	
+		}
+
+		if(buffer_queue.empty()) {
+			done = final_buffer;
+		}
+
+		pthread_mutex_unlock(&queue_lock);
+
+		if( mem_container ) {
+			if(!do_raw_pack (t->RMC, mem_container) ) {
+				fprintf(stderr, "Failed to send data\n");
+				exit(1);
+			}
+
+			if (mem_container->buffer1) {
+				free (mem_container->buffer1);
+			}
+
+			if (mem_container->buffer2) {
+				free (mem_container->buffer2);
+			}
+			
+
+			free(mem_container);
+		}
+
+		if( done ) {
+			// Now, we have sent all data
+			// Here, we will send two extra double for stats
+			wall_time += MWSystem::gettimeofday();
+			cpu_time += MWSystem::getcputime();
+			if (!raw_pack (t->RMC, (char*)&wall_time, sizeof(double))) {
+				fprintf(stderr, "Failed to send stats data\n");
+				exit(1);
+			}
+			if (!raw_pack (t->RMC, (char*)&cpu_time, sizeof(double))) {
+				fprintf(stderr, "Failed to send stats data\n");
+				exit(1);
+			}
+			break;
+		}
+	}
+
+	return NULL;
+}
+
+static bool raw_pack(MWRMComm* _RMC, char* buf, int len)
+{
+	static int cnt = 0;
+
+	cnt++;
+	int ret = _RMC->raw_pack(buf, len);
+	if( ret != len ) {
+		fprintf(stderr, "raw_pack(%d) failed to write the size of data.\n", cnt);
+		fprintf(stderr, "need to send (%d), but ret = %d\n", len, ret);
+		if( ret < 0 ) {
+			fprintf(stderr, "errno=%d, string=%s\n", errno, strerror(errno));
+			fflush(stderr);
+		}
+		return false;
+	}
+
+	return true;
+}
+
+static bool do_raw_pack (MWRMComm* RMC, MEM_Container *mem_container) 
+{
+	int network_int = mem_container->what_data;
+	if (!raw_pack (RMC, (char*) &network_int, sizeof (int)))
+		return false;
+
+	switch (mem_container->what_data) {
+		case SPARSE_DATA : 
+			{
+				network_int = ((int) (mem_container->size1 / sizeof(Num_Cells_Buffer)));
+
+				if (!raw_pack (RMC, (char*) &network_int, sizeof (int)))
+					return false;
+
+				if (!raw_pack (RMC, (char*) mem_container->buffer1, mem_container->size1))
+					return false;
+
+				network_int = ((int) mem_container->size2 / sizeof(Sparse_Matrix_Buffer));
+
+				if (!raw_pack (RMC, (char*) &network_int, sizeof (int)))
+					return false;
+
+				if (!raw_pack (RMC, (char*) mem_container->buffer2, mem_container->size2))
+					return false;
+
+				break;
+			}
+		case HEAP_DATA : 
+			{
+				network_int = ((int) mem_container->size1 / sizeof (Heap_Buffer));
+				if (!raw_pack (RMC, (char*) &network_int, sizeof(int))) {
+					return false;
+				}
+
+				if (!raw_pack (RMC, (char*) mem_container->buffer1, mem_container->size1)) {
+					return false;
+				}
+
+				break;
+			}
+		default :
+			break;
+	}
+
+	return true;
+}
+
+void transfer_data(MW_task *t)
+{
+
+	// Record times for stats
+	// Set our stopwatch
+	wall_time -= MWSystem::gettimeofday();
+	cpu_time -= MWSystem::getcputime();
+
+	pthread_t thread;
+	if( t->m_raw_flag ) {
+		// we need to create a new thread
+		if( pthread_create(&thread, NULL, send_thread, (void *)t ) != 0 ) {
+			fprintf(stderr, "Failed to create a new thread\n");
+			exit(1);
+		}
+	}
+
+	if (m_fsa->anchored)
+		build_anchored_multiple_alignment ();
+	else
+		build_multiple_alignment ();
+
+	delete m_fsa;
+
+	if( t->m_raw_flag ) {
+		// Now, we have to wait for send_thread to be finished.
+		void *ptr;
+		int ret = pthread_join(thread, &ptr);
+		if( ret != 0 ) {
+			fprintf(stderr, "pthread_join error %d\n", ret);
+			exit(1);
+		}
+		
+	}
+}
+
+#endif
+
+#if defined(HAVE_POSTGRES) 
+void init_single_worker(const FSA *fsa, DB_adapter *db_adapter, Params &params_seed, Params &pseudocounts) {
+	m_fsa = const_cast<FSA *> (fsa);
+	m_db_adapter = db_adapter;
+
+	m_params_seed.copy_all (params_seed);
+	m_pseudocounts.copy_all (pseudocounts);
+
+	int seqs_schema_id = 0;
+	int params_table_id = 0;
+
+	final_buffer = false;
+	send_thread_waiting = false;
+
+	bool is_db_running = false;
+
+	m_db_buffer.sparse_matrix.clear();
+	m_db_buffer.num_cells.clear();
+	m_db_buffer.heap.clear();
+
+	// set the sequence schema id and the parameter table id 
+	seqs_schema_id  = (m_db_adapter->get_connection())->get_seqs_schema_id ();
+	params_table_id = (m_db_adapter->get_connection())->get_params_table_id ();
+
+	m_db_adapter->set_up_ids (seqs_schema_id, params_table_id, 0);
+}
+#endif
+
diff --git a/src/math/Makefile.am b/src/math/Makefile.am
new file mode 100644
index 0000000..498159b
--- /dev/null
+++ b/src/math/Makefile.am
@@ -0,0 +1,10 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+noinst_LIBRARIES = libmath.a
+libmath_a_SOURCES = \
+	mathematics.cc \
+	mst.cc
+
+noinst_HEADERS = \
+	mathematics.h \
+	mst.h
diff --git a/src/math/Makefile.in b/src/math/Makefile.in
new file mode 100644
index 0000000..f3a3983
--- /dev/null
+++ b/src/math/Makefile.in
@@ -0,0 +1,549 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/math
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libmath_a_AR = $(AR) $(ARFLAGS)
+libmath_a_LIBADD =
+am_libmath_a_OBJECTS = mathematics.$(OBJEXT) mst.$(OBJEXT)
+libmath_a_OBJECTS = $(am_libmath_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libmath_a_SOURCES)
+DIST_SOURCES = $(libmath_a_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+noinst_LIBRARIES = libmath.a
+libmath_a_SOURCES = \
+	mathematics.cc \
+	mst.cc
+
+noinst_HEADERS = \
+	mathematics.h \
+	mst.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/math/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/math/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libmath.a: $(libmath_a_OBJECTS) $(libmath_a_DEPENDENCIES) $(EXTRA_libmath_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libmath.a
+	$(AM_V_AR)$(libmath_a_AR) libmath.a $(libmath_a_OBJECTS) $(libmath_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libmath.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mathematics.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mst.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/math/mathematics.cc b/src/math/mathematics.cc
new file mode 100644
index 0000000..dc13fd6
--- /dev/null
+++ b/src/math/mathematics.cc
@@ -0,0 +1,36 @@
+
+/**
+ * \file mathematics.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "math/mathematics.h"
+
+using namespace fsa;
+
+const double Mathematics::double_tiny = 0.001;
+const double Mathematics::double_very_tiny = 0.000001;
+
+unsigned Mathematics::factorial (unsigned x) {
+
+  unsigned f = 1;
+
+  while (x > 0) {
+    f *= x--;
+  }
+
+  return f;
+}
+
+double Mathematics::log_factorial (unsigned x) {
+
+  double logf = 0;
+
+  while (x > 1) {
+    logf += std::log (static_cast<double> (x--));
+  }
+
+  return logf;
+}
+
diff --git a/src/math/mathematics.h b/src/math/mathematics.h
new file mode 100644
index 0000000..ac52479
--- /dev/null
+++ b/src/math/mathematics.h
@@ -0,0 +1,195 @@
+
+/**
+ * \file mathematics.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef MATH_MATHEMATICS_INCLUDED
+#define MATH_MATHEMATICS_INCLUDED
+
+#include <cmath>
+#include <utility>
+#include <vector>
+#include <algorithm>
+#include <functional>
+#include <limits>
+
+#include "config.h"
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#include "util/misc.h"
+
+namespace fsa {
+
+  struct Mathematics {
+
+  public:
+
+    /**
+     * \brief Is a number a power of 2?
+     */
+    static bool is_power_of_2 (const uintmax_t num);
+
+    /**
+     * \brief Calculates power of 2.
+     */
+    static uintmax_t power_of_2 (const unsigned n);
+
+    /**
+     * \brief Calculates power of k^n, where both k and n are integers.
+     */
+    static uintmax_t power_of_integer (const unsigned k, const unsigned n);
+
+    /**
+     * \brief Calculate factorial x!.
+     */
+    static unsigned factorial (unsigned x);
+
+    /**
+     * \brief Calculate log-factorial log (x!).
+     */
+    static double log_factorial (unsigned x);
+
+    /**
+     * \brief Compute the average value.
+     */
+    template<typename T>
+    static double mean (const std::vector<T>& values);
+
+    /**
+     * \brief Compute the median value.
+     * \param is_sorted true if the data are already sorted low-to-high
+     */
+    template<typename T>
+    static T median (std::vector<T>& values,
+		     const bool is_sorted = false);
+
+    /**
+     * \brief Compute the value at a particular percentile (in [0, 1]).
+     * \param is_sorted true if the data are already sorted low-to-high
+     */
+    template<typename T>
+    static T percentile_value (std::vector<T>& values, const float percentile,
+			       const bool is_sorted = false);
+
+    /**
+     * \brief Return original value if inside range, or bound if outside.
+     */
+    template<typename N>
+    static N bounded_value (N n, N min_bound, N max_bound) {
+      return n < min_bound
+	? min_bound
+	: (n > max_bound ? max_bound : n);
+    }
+
+    /**
+     * \brief Function object to compute the normalized difference function (x - y) / (x + y).
+     */
+    template<typename T>
+    struct normalized_difference {
+      double operator() (const T x, const T y) const {
+	return (x - y) / (x + y);
+      }
+    };
+
+
+
+    static const double double_tiny;             ///< small double value
+    static const double double_very_tiny;        ///< very small double value
+
+  };
+
+  inline bool Mathematics::is_power_of_2 (const uintmax_t num) {
+    return (num & (num - 1)) == 0;
+  }
+
+  inline uintmax_t Mathematics::power_of_2 (const unsigned n) {
+#ifndef NDEBUG
+    if (std::pow (static_cast<double> (2), static_cast<int> (n)) > std::numeric_limits<uintmax_t>::max()) {
+      cerr << "ERROR: Overflow of uintmax_t type: attempting to calculate 2^" << n << endl;
+      exit (1);
+    }      
+#endif
+    return static_cast<uintmax_t> (1) << n;
+  }
+
+  inline uintmax_t Mathematics::power_of_integer (const unsigned k, const unsigned n) {
+#ifndef NDEBUG
+    if (std::pow (static_cast<double> (k), static_cast<int> (n)) > std::numeric_limits<uintmax_t>::max()) {
+      cerr << "ERROR: Overflow of uintmax_t type: attempting to calculate " << k << "^" << n << endl;
+      exit (1);
+    }      
+#endif
+    uintmax_t sum = 1;
+    for (size_t i = 0; i < n; ++i)
+      sum *= k;
+    return sum;
+  }
+
+  template<typename T>
+    double Mathematics::mean (const std::vector<T>& values) {
+
+    if (!values.size()) {
+      cerr << "ERROR: Tried to take the mean of an empty vector." << endl;
+      exit (1);
+    }
+
+    double total = 0.0;
+    for (typename std::vector<T>::const_iterator value = values.begin(); value != values.end(); ++value)
+      total += *value;
+
+    return (total / values.size());
+
+  }
+  
+  template<typename T>
+    T Mathematics::median (std::vector<T>& values,
+			   const bool is_sorted /* = false */) {
+
+    return percentile_value (values, 0.5,
+			     is_sorted);
+
+  }
+
+  template<typename T>
+    T Mathematics::percentile_value (std::vector<T>& values, const float percentile,
+				     const bool is_sorted /* = false */) {
+
+    // check sane
+    if (percentile < 0.0 || percentile > 1.0) {
+      cerr << "ERROR: A percentile of " << percentile << " is not meaningful." << endl;
+      exit (1);
+    }
+
+    if (!values.size()) {
+      cerr << "ERROR: Tried to find a percentile within an empty vector." << endl;
+      exit (1);
+    }
+
+    // sort values if necessary
+    if (!is_sorted)
+      std::sort (values.begin(), values.end());
+
+    // pull out the index into the vector for the appropriate percentile
+    size_t index = static_cast<size_t> (std::floor (values.size() * percentile));
+
+    // catch the case of percentile_value = 1
+    if (index == values.size())
+      index = values.size() - 1;
+    else if (index > values.size()) {
+      cerr << "ERROR: Array index indicated by percentile value overflows the vector indices!" << endl
+	   << "index = " << index << "; array size = " << values.size() << endl;
+      exit (1);
+    }
+
+    // take array slice to get appropriate percentile
+    return values[index];
+
+  }
+
+}
+
+#endif /* MATH_MATHEMATICS_INCLUDED */
diff --git a/src/math/mst.cc b/src/math/mst.cc
new file mode 100644
index 0000000..78133e5
--- /dev/null
+++ b/src/math/mst.cc
@@ -0,0 +1,101 @@
+
+/**
+ * \file mst.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "math/mst.h"
+
+using namespace fsa;
+
+Disjoint_set::Disjoint_set (const size_t n) {
+  
+  __elements.reserve (n);
+  for (size_t e = 0; e < n; ++e)
+    __elements.push_back (Element (e, 0)); // parent = e, rank = 0
+
+}
+
+Disjoint_set::Index Disjoint_set::find_dj (const Disjoint_set::Index e) {
+
+  Element& element = get_element (e);
+  if (element.parent == e)
+    return e;
+  else {
+    element.parent = find_dj (element.parent);
+    return element.parent;
+  }    
+
+}
+
+void Disjoint_set::union_dj (const Disjoint_set::Index e1, const Disjoint_set::Index e2) {
+
+  Disjoint_set::Index root1index = find_dj (e1);
+  Element& root1 = get_element (root1index);
+  Disjoint_set::Index root2index = find_dj (e2);
+  Element& root2 = get_element (root2index);
+
+  if (root1.rank > root2.rank)
+    root2.parent = root1index;
+  else if (root1.rank < root2.rank)
+    root1.parent = root2index;
+  // unless e1 and e2 are already in the same set, merge them
+  else if (root1 != root2) {
+    root2.parent = root1index;
+    root1.rank = root1.rank + 1;
+  }
+
+}
+
+MST_Kruskal::Edge_set MST_Kruskal::compute_mst (MST_Kruskal::Edge_set& edges, const size_t N,
+						const bool die_on_failure /* = true */) {
+
+  MST_Kruskal::Edge_set mst;
+  mst.reserve (N);
+
+  // initialize forest:
+  // each vertex is a tree
+  Disjoint_set dj (N);
+
+  // sort edges, ordered by increasing weight
+  std::sort (edges.begin(), edges.end());
+
+  // loop over edges, lowest weight first
+  for (MST_Kruskal::Edge_set::const_iterator edge = edges.begin(); edge != edges.end(); ++edge) {
+
+    // get vertices connected by this edge
+    const size_t u = edge->u;
+    const size_t v = edge->v;
+
+    // check that the vertices are labeled as 0, ..., (N - 1)
+    assert ((u < N) && (v < N));
+
+    // if connecting u and v does not form a cycle
+    // (if the trees containing them are distinct),
+    // then do so
+    if (dj.find_dj (u) != dj.find_dj (v)) {
+      mst.push_back (*edge);
+      dj.union_dj (u, v);
+    }
+
+    // have we assembled a MST?
+    if (mst.size() == N - 1)
+      break;
+
+  }
+
+  // confirm that we've created a spanning tree
+  // (i.e., that the graph was complete to begin with)
+  if (mst.size() != N - 1) {
+    if (die_on_failure) {
+      cerr << "ERROR: Unable to compute a minimal spanning tree.  Was the graph complete to begin with?" << endl;
+      exit (1);
+    } else
+      return MST_Kruskal::Edge_set();
+  }
+
+  return mst;
+
+}
+
diff --git a/src/math/mst.h b/src/math/mst.h
new file mode 100644
index 0000000..5736f5f
--- /dev/null
+++ b/src/math/mst.h
@@ -0,0 +1,166 @@
+
+/**
+ * \file mst.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef MATH_MST_INCLUDED
+#define MATH_MST_INCLUDED
+
+#include "util/misc.h"
+#include "math/mathematics.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a disjoint set with UNION-FIND capabilities.
+   *
+   * Representation is a disjoint set forest, where each set is represented
+   * by a tree and each node in the tree (element in the set) holds a reference
+   * to the root of the tree, the representative element of the set.
+   * This is essentially an implementation of the wikipedia description:
+   *  http://en.wikipedia.org/wiki/Disjoint-set_data_structure
+   */
+  struct Disjoint_set {
+
+  public:
+
+    typedef size_t Index;
+
+    /**
+     * \brief Constructor.
+     *
+     * Create a disjoint set with the specified number of elements;
+     * each element is in its own set.
+     * Implicitly implements the make_set operation.
+     */
+    Disjoint_set (const size_t n);
+
+    /**
+     * \brief Find the set containing the element e.
+     *
+     * Can also be used to determine whether two elements are in the same set.
+     * Implements the path compression heuristic.
+     * \param e index of element
+     * \return index of the representative of the set
+     */
+    Index find_dj (const Index e);
+
+    /**
+     * \brief Merge the sets containing two elements into a single set.
+     *
+     * Implements the union by rank heuristic.
+     * Awkward name is because "union" is reserved by C++.
+     * \param e1 index of element in set 1 to be merged
+     * \param e2 index of element in set 2 to be merged
+     */
+    void union_dj (const Index e1, const Index e2);
+
+  private:
+
+    /**
+     * \brief Represent a single element in the disjoint set.
+     */
+    struct Element {
+
+      Element (const Index parent, const size_t rank)
+      : parent (parent), rank (rank)
+      { }
+
+      Index parent;
+      size_t rank;
+
+      /**
+       * \brief Equality iff parents are identical.
+       * \see find_dj
+       */
+      bool operator== (const Element& e) const {
+	return parent == e.parent;
+      }
+
+      bool operator!= (const Element& e) const {
+	return !(*this == e);
+      }
+
+    };
+
+    /**
+     * \brief Get an element by its index.
+     */
+    Element& get_element (const Index e) {
+      assert (e < __elements.size());
+      return __elements[e];
+    }
+
+    std::vector<Element> __elements;  ///< elements in the disjoint set
+
+  };
+
+  /**
+   * \brief Perform's Kruskal's algorithm for finding the minimum spanning tree of a graph.
+   */
+  struct MST_Kruskal {
+
+  public:
+
+    /**
+     * \brief Represent a weighted, undirected edge.
+     */
+    struct Edge {
+
+      /**
+       * \brief Constructor.
+       */
+      Edge (const unsigned short u, const unsigned short v,
+	    const float weight)
+      : u (u), v (v), weight (weight)
+      { }
+
+      unsigned short u;
+      unsigned short v;
+      float weight;
+      
+      /**
+       * \brief Comparison operator.
+       */
+      bool operator< (const Edge& e) const {
+	return (weight < e.weight);
+      }
+
+      /**
+       * \brief Comparison operator.
+       */
+      bool operator> (const Edge& e) const {
+	return (weight > e.weight);
+      }
+
+      /**
+       * \brief Output operator.
+       */
+      friend std::ostream& operator<< (std::ostream& o, const Edge& edge) {
+	o << edge.u << " -- " << edge.v << " => " << edge.weight;
+	return o;
+      }
+
+    };
+
+    typedef std::vector<Edge> Edge_set;  ///< a set of edges
+
+    /**
+     * \brief Find the minimum spanning tree on the given set of edges.
+     *
+     * The vertices in edges MUST be numbered as 0,...,(N - 1)!
+     * \param edges list of edges of graph
+     * \param N number of nodes in the graph
+     * \param die_on_failure die if the graph is not complete (a MST does not exist)
+     * \return the edges composing the MST (empty if no MST found)
+     */
+    static Edge_set compute_mst (Edge_set& edges, const size_t N,
+				 const bool die_on_failure = true);
+
+  };
+
+}
+
+#endif /* MATH_MST_INCLUDED */
diff --git a/src/seq/Makefile.am b/src/seq/Makefile.am
new file mode 100644
index 0000000..f100263
--- /dev/null
+++ b/src/seq/Makefile.am
@@ -0,0 +1,22 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+LDADD = \
+	$(top_builddir)/src/util/libutil.a
+
+noinst_LIBRARIES = libseq.a
+libseq_a_SOURCES = \
+	alphabet.cc \
+	alignment.cc \
+	gff.cc \
+	mercator.cc \
+	sequence.cc \
+	similarity_matrix.cc
+
+noinst_HEADERS = \
+	alphabet.h \
+	alignment.h \
+	gff.h \
+	interval.h \
+	mercator.h \
+	sequence.h \
+	similarity_matrix.h
diff --git a/src/seq/Makefile.in b/src/seq/Makefile.in
new file mode 100644
index 0000000..8420c0e
--- /dev/null
+++ b/src/seq/Makefile.in
@@ -0,0 +1,567 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/seq
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libseq_a_AR = $(AR) $(ARFLAGS)
+libseq_a_LIBADD =
+am_libseq_a_OBJECTS = alphabet.$(OBJEXT) alignment.$(OBJEXT) \
+	gff.$(OBJEXT) mercator.$(OBJEXT) sequence.$(OBJEXT) \
+	similarity_matrix.$(OBJEXT)
+libseq_a_OBJECTS = $(am_libseq_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libseq_a_SOURCES)
+DIST_SOURCES = $(libseq_a_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+LDADD = \
+	$(top_builddir)/src/util/libutil.a
+
+noinst_LIBRARIES = libseq.a
+libseq_a_SOURCES = \
+	alphabet.cc \
+	alignment.cc \
+	gff.cc \
+	mercator.cc \
+	sequence.cc \
+	similarity_matrix.cc
+
+noinst_HEADERS = \
+	alphabet.h \
+	alignment.h \
+	gff.h \
+	interval.h \
+	mercator.h \
+	sequence.h \
+	similarity_matrix.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/seq/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/seq/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libseq.a: $(libseq_a_OBJECTS) $(libseq_a_DEPENDENCIES) $(EXTRA_libseq_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libseq.a
+	$(AM_V_AR)$(libseq_a_AR) libseq.a $(libseq_a_OBJECTS) $(libseq_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libseq.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/alignment.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/alphabet.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gff.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mercator.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sequence.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/similarity_matrix.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/seq/alignment.cc b/src/seq/alignment.cc
new file mode 100644
index 0000000..f30c050
--- /dev/null
+++ b/src/seq/alignment.cc
@@ -0,0 +1,1154 @@
+
+/**
+ * \file alignment.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <numeric>
+#include <functional>
+#include <algorithm>
+
+#include "util/regexp.h"
+#include "seq/alignment.h"
+
+using namespace fsa;
+
+// NB: Who knows why, but I get linker errors when these definitions
+// are in the header file.  It works fine when they're not.  Very strange!
+
+const char Alignment::gap_char = '-';
+
+const std::string Stockholm::gff_annotation = "GFF";
+const std::string Stockholm::percent_id_annotation = "Percent_id";
+const std::string Stockholm::gap_fraction_annotation = "Gap_fraction";
+
+const std::string Stockholm::format_identifier = "STOCKHOLM";
+const std::string Stockholm::version_identifier = "1.0";
+const std::string Stockholm::alignment_header = "# " + Stockholm::format_identifier + ' ' + Stockholm::version_identifier;
+const std::string Stockholm::alignment_separator = "//";
+
+const std::string Stockholm::file_annotation = "#=GF";
+const std::string Stockholm::column_annotation = "#=GC";
+const std::string Stockholm::sequence_annotation = "#=GS";
+const std::string Stockholm::sequence_column_annotation = "#=GR";
+
+const char Stockholm::annotation_wildcard_char = '.';
+
+
+
+Alignment_row::Alignment_row (Row_path* row_path)
+  : __row_path (row_path) {
+
+  // calculate the total sequence length
+  __seqlength = static_cast<size_t> (accumulate (__row_path->begin(), __row_path->end(), 0));
+
+  build_coordinate_indices();
+
+}
+
+Alignment_row::Alignment_row (const Alignment_row& parent) {
+
+  // deep copy
+  __seq_to_align_coords_map = parent.__seq_to_align_coords_map;
+  __align_to_seq_coords_map = parent.__align_to_seq_coords_map;
+  __row_path = new Row_path (*parent.__row_path);
+  __seqlength = parent.__seqlength;
+
+}
+
+Alignment_row& Alignment_row::operator= (const Alignment_row& parent) {
+
+  // check for self-assignment
+  if (this == &parent)
+    return *this;
+
+  // clear old memory
+  delete __row_path;
+
+  // deep copy
+  __seq_to_align_coords_map = parent.__seq_to_align_coords_map;
+  __align_to_seq_coords_map = parent.__align_to_seq_coords_map;
+  __row_path = new Row_path (*parent.__row_path);
+  __seqlength = parent.__seqlength;
+
+  return *this;
+
+}
+
+Alignment_row::~Alignment_row() {
+
+  delete __row_path;
+
+}
+
+void Alignment_row::build_coordinate_indices() {
+
+  __seq_to_align_coords_map.clear();
+  __align_to_seq_coords_map.clear();
+
+  // build map from sequence to alignment coordinates, as well as
+  // map from alignment to sequence coordinates
+  // if an alignment position is gapped, then store the sequence
+  // position corresponding to the next ungapped alignment position
+  // note that this means that if the alignment ends with a run of gaps,
+  // then the gapped alignment positions will be mapped to __seqlength,
+  // so this end case must be explicitly checked for
+  __seq_to_align_coords_map.reserve (__seqlength);
+  __align_to_seq_coords_map.reserve (__row_path->size());
+  size_t seqpos = 0; // this always holds the "next" sequence position
+  for (size_t alignpos = 0; alignpos < __row_path->size(); ++alignpos) {
+
+    if (is_gapped (alignpos)) {
+      // do nothing for __seq_to_align_coords_map
+      // record previous sequence position for __align_to_seq_coords_map
+      __align_to_seq_coords_map.push_back (seqpos);
+    }
+
+    else {
+      // record for __seq_to_align_coords_map
+      __seq_to_align_coords_map.push_back (alignpos);
+      // records for __align_to_seq_coords_map
+      __align_to_seq_coords_map.push_back (seqpos);
+      ++seqpos;
+    }
+    
+  }
+  assert (__seq_to_align_coords_map.size() == __seqlength);
+  assert (__align_to_seq_coords_map.size() == __row_path->size());
+  assert (seqpos == __seqlength); // sanity check
+
+}
+
+Alignment_row* Alignment_row::subalignment (const unsigned start, const unsigned end) const {
+
+  assert (!__seqlength || (end < length()));
+
+  Row_path* row_path = NULL;
+  if (end < start)
+    row_path = new Row_path();
+  else
+    row_path = new Row_path (__row_path->begin() + start, __row_path->begin() + end + 1);
+
+  return new Alignment_row (row_path);
+  
+}
+
+Alignment_row::Row_path* Alignment_row::subalignment_row_path (const unsigned start, const unsigned end) const {
+
+  assert (!__seqlength || (end < length()));
+  if (end < start)
+    return new Row_path();
+  return new Row_path (__row_path->begin() + start, __row_path->begin() + end + 1);
+  
+}
+
+void Alignment_row::reverse() {
+
+  // reverse the alignment
+  std::reverse (__row_path->begin(), __row_path->end());
+
+  // and then re-build coordinate indices (it is NOT sufficient to merely reverse these!)
+  build_coordinate_indices();
+
+}
+
+Alignment::Alignment (Sequence_database& seq_db)
+  : seq_db (&seq_db) {
+
+}
+
+Alignment::Alignment (const Alignment& parent) {
+
+  // perform deep copy
+  seq_db = parent.seq_db;
+  for (std::vector<Alignment_row*>::const_iterator row = parent.__rows.begin(); row != parent.__rows.end(); ++row) {
+    Alignment_row* a = new Alignment_row (**row);
+    __rows.push_back (a);
+  }
+  __row_index = parent.__row_index;
+
+}
+
+Alignment& Alignment::Alignment::operator= (const Alignment& parent) {
+
+  // check for self-assignment
+  if (this == &parent)
+    return *this;
+
+  // perform deep copy
+  seq_db = parent.seq_db;
+  for (std::vector<Alignment_row*>::const_iterator row = parent.__rows.begin(); row != parent.__rows.end(); ++row) {
+    Alignment_row* a = new Alignment_row (**row);
+    __rows.push_back (a);
+  }
+  __row_index = parent.__row_index;
+
+  return *this;
+
+}
+
+Alignment::~Alignment() {
+
+  for (std::vector<Alignment_row*>::iterator row = __rows.begin(); row != __rows.end(); ++row)
+    delete *row;
+
+}
+
+bool Alignment::detect_mfa (const std::string& filename) {
+
+  return Sequence::detect_fasta (filename);
+
+}
+
+void Alignment::read_mfa (const std::string& filename, const bool strict /* = true */,
+			  const bool verbose /* = true */) {
+
+  clear();
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  if (verbose)
+    cerr << "Reading multi-FASTA alignment '" << filename << "'...";
+
+  Regexp re_name ("^[ \t]*" + Sequence::fasta_seq_start + "([^ \t]*)[ \t]*(.*)");
+
+  std::string line;
+
+  std::vector<std::string> gapped_seqs_names;
+  std::vector<std::string> gapped_seqs;
+  std::vector<std::string> gapped_seqs_info;
+
+  bool in_seq_body = false;
+  size_t curr_idx = 0; // dummy value to prevent compiler warnings
+  while (!filestream.eof()) {
+
+    getline (filestream, line);
+
+    // are we at a name line?
+    if (re_name.Match (line.c_str())) {
+      if (re_name.SubStrings() < 1) { continue; }
+      // store name
+      const std::string name = re_name[1];
+      curr_idx = gapped_seqs_names.size();
+      gapped_seqs_names.push_back (name);
+      // store info following name, if present
+      std::string info;
+      if (re_name.SubStrings() >= 2)
+	info = re_name[2];
+      gapped_seqs_info.push_back (info);
+      // store empty row
+      gapped_seqs.push_back ("");
+      in_seq_body = true;
+    }
+    // if not, then we must be reading sequence data
+    else if (in_seq_body) {
+      // if this is the first line of data for this sequence
+      if (gapped_seqs.size() < gapped_seqs_names.size())
+	gapped_seqs.push_back (line);
+      else
+	gapped_seqs[curr_idx] += line;
+    }
+
+  }
+  filestream.close();
+
+  // assert sane
+  if (gapped_seqs.size() != gapped_seqs_names.size()) {
+    cerr << "ERROR: Sequence names and data don't match up.  Is your MFA file improperly formatted?" << endl;
+    exit (1);
+  }
+  assert (gapped_seqs_names.size() == gapped_seqs_info.size());
+
+  // now store
+  for (size_t r = 0; r < gapped_seqs.size(); ++r) {
+
+    const std::string& name = gapped_seqs_names[r];
+    std::string& gapped_seq = gapped_seqs[r];
+    std::string& info = gapped_seqs_info[r];
+
+    // strip out whitespace
+    std::string::iterator last_pos = std::remove_if (gapped_seq.begin(), gapped_seq.end(),
+						     isspace);
+    gapped_seq.erase (last_pos, gapped_seq.end());
+
+    // remove newline from info, if present
+    Util::chomp (info);
+
+    // create ungapped sequence
+    std::string ungapped_seq;
+    ungapped_seq.resize (gapped_seq.length());
+    last_pos = std::remove_copy_if (gapped_seq.begin(), gapped_seq.end(),
+				    ungapped_seq.begin(),
+				    Alignment::is_gap_char);
+    ungapped_seq.erase (last_pos, ungapped_seq.end()); // erase unnecessary positions
+
+    // create alignment path
+    Alignment_row::Row_path* row_path = new Alignment_row::Row_path (gapped_seq.length()); // allocate space
+    std::transform (gapped_seq.begin(), gapped_seq.end(),
+		    row_path->begin(),
+		    std::not1 (std::ptr_fun (Alignment::is_gap_char)));
+
+    // now store row
+    Sequence* sequence = new Sequence (name, ungapped_seq, info);
+    add_row (sequence,
+	     row_path);
+  }
+
+  if (strict)
+    assert_flush();
+
+  if (verbose)
+    cerr << "done." << endl;
+
+}
+
+const Alignment_row& Alignment::get_row (const std::string& name) const {
+
+#ifndef NDEBUG
+  if (!exists_row (name)) {
+    cerr << "ERROR: No row named '" << name << "'." << endl;
+    write_mfa (cerr, false);
+  }
+#endif
+  assert (exists_row (name));
+
+  return *__rows[__row_index.find (name)->second];
+
+}
+
+double Alignment::percent_id() const {
+
+  return percent_id (0, columns() - 1);
+
+}
+
+double Alignment::percent_id (const unsigned start, const unsigned end) const {
+
+  assert (start <= end);
+  assert (end < columns());
+
+  double id = 0.;   // sum of per-column percent IDs
+  size_t cols = 0;  // number of columns used in calculation
+
+  for (size_t c = start; c <= end; ++c) {
+
+    // count the (maximal) fraction of identical characters in the column
+    std::map<char, size_t> char_count;
+    size_t colsize = 0; // # of non-gap characters in column
+    for (size_t r = 0; r < rows(); ++r) {
+      if (!is_gapped (r, c)) {
+	++char_count[static_cast<char> (tolower (get_char (r, c)))];
+	++colsize;
+      }
+    }
+
+    // only count columns with > 1 non-gap character
+    if (colsize < 2)
+      continue;
+
+    // find the most common character
+    std::map<char, size_t>::const_iterator max = std::max_element (char_count.begin(), char_count.end(),
+								   Util::Map_value_less<std::map<char, size_t> >());
+    // if no character appears more than once,
+    // then percent id = 0
+    if (max->second > 1)
+      id += static_cast<double> (max->second) / colsize;
+
+    // increment columns counter
+    ++cols;
+
+  }
+
+  if (cols == 0)
+    return 0;
+
+  return (id / cols);
+
+}
+
+double Alignment::gap_fraction() const {
+
+  return gap_fraction (0, columns() - 1);
+
+}
+
+double Alignment::gap_fraction (const unsigned start, const unsigned end) const {
+
+  assert (start <= end);
+  assert (end < columns());
+
+  if (columns() == 0 || rows() == 0)
+    return 0;
+
+  size_t gaps = 0;
+
+  for (size_t c = start; c <= end; ++c) {
+    for (size_t r = 0; r < rows(); ++r) {
+      if (is_gapped (r, c))
+	++gaps;
+    }
+  }
+
+  return (static_cast<double> (gaps) / ((end - start + 1) * rows()));
+
+}
+
+const Sequence Alignment::get_gapped_row (const std::string& name) const {
+
+  assert (exists_row (name));
+
+  return get_gapped_row (__row_index.find (name)->second);
+
+}
+
+const Sequence Alignment::get_gapped_row (const size_t r) const {
+
+  assert (r < rows());
+
+  return get_row (r).get_gapped_seq (seq_db->get_seq (r), Alignment::gap_char);  
+
+}
+
+std::vector<std::string> Alignment::get_row_names() const {
+
+  std::vector<std::string> names (rows());
+  for (size_t r = 0; r < rows(); ++r)
+    names[r] = get_row_name (r);
+
+  return names;
+
+}
+
+void Alignment::add_row (Sequence* sequence,
+			 Alignment_row::Row_path* row_path) {
+
+#ifndef NDEBUG
+  // check that sequence length matches (implied) alignment sequence length
+  if (sequence->seq.length() != static_cast<size_t> (accumulate (row_path->begin(), row_path->end(), 0))) {
+    cerr << "ERROR: Sequence length mismatch for " << sequence->name << "." << endl
+	 << "Sequence:                " << sequence->seq << endl
+	 << "Alignment_row::Row_path: " << Util::join (*row_path, "") << endl;
+    exit (1);
+  }
+#endif
+  assert (sequence->seq.length() == static_cast<size_t> (accumulate (row_path->begin(), row_path->end(), 0)));
+
+  // store in Sequence_database
+  if (!seq_db->exists_seq (sequence->name))
+    seq_db->add_seq (sequence);
+  // now store alignment information
+  __rows.push_back (new Alignment_row (row_path));
+  // only create a new entry in __row_index if there isn't one already
+  if (!exists_row (sequence->name))
+    __row_index.insert (make_pair (sequence->name, __rows.size() - 1));
+
+#ifndef NDEBUG
+  // check that the sequence indices for the rows in *this
+  // and sequences in the Sequence_database& are still in sync
+  // after this operation
+  if (get_row_index (sequence->name) != seq_db->get_seq_index (sequence->name)) {
+    cerr << "ERROR: Sequence indices are out of sync between the Alignment (index = " << get_row_index (sequence->name) << ") and corresponding Sequence_database& (index = " << seq_db->get_seq_index (sequence->name) << ") after storing '" << sequence->name << "'." << endl;
+    exit (1);
+  }
+#endif
+
+}
+
+void Alignment::add_row (Sequence* sequence,
+			 Alignment_row* alignment_row) {
+
+#ifndef NDEBUG
+  // check that sequence length matches alignment sequence length
+  if (sequence->seq.length() != alignment_row->seqlength()) {
+    cerr << "ERROR: Sequence length mismatch for " << sequence->name << "." << endl
+	 << "Sequence:                " << sequence->seq << endl
+	 << "Alignment_row::Row_path: " << *alignment_row << endl;
+  }
+#endif
+  assert (sequence->seq.length() == alignment_row->seqlength());  
+
+  // store in Sequence_database
+  if (!seq_db->exists_seq (sequence->name))
+    seq_db->add_seq (sequence);
+  // now store alignment information
+  __rows.push_back (alignment_row);
+  // only create a new entry in __row_index if there isn't one already
+  if (!exists_row (sequence->name))
+    __row_index.insert (make_pair (sequence->name, __rows.size() - 1));
+
+#ifndef NDEBUG
+  // check that the sequence indices for the rows in *this
+  // and sequences in the Sequence_database& are still in sync
+  // after this operation
+  if (get_row_index (sequence->name) != seq_db->get_seq_index (sequence->name)) {
+    cerr << "ERROR: Sequence indices are out of sync between the Alignment (index = " << get_row_index (sequence->name) << ") and corresponding Sequence_database& (index = " << seq_db->get_seq_index (sequence->name) << ") after storing '" << sequence->name << "'." << endl;
+    exit (1);
+  }
+#endif
+
+}
+
+void Alignment::set_row (const std::string& name,
+			 Alignment_row::Row_path* row_path) {
+
+  // confirm that such a sequence already exists in the Sequence_database
+  if (!seq_db->exists_seq (name)) {
+    cerr << "ERROR: No sequence 'name' found in the stored Sequence_database." << endl;
+    exit (1);
+  }
+
+#ifndef NDEBUG
+  const Sequence& sequence = seq_db->get_seq (name);
+  // check that sequence length matches (implied) alignment sequence length
+  if (sequence.seq.length() != static_cast<size_t> (accumulate (row_path->begin(), row_path->end(), 0))) {
+    cerr << "ERROR: Sequence length mismatch for " << sequence.name << "." << endl
+	 << "Sequence:                " << sequence.seq << endl
+	 << "Alignment_row::Row_path: " << Util::join (*row_path, "") << endl;
+    exit (1);
+  }
+  assert (sequence.seq.length() == static_cast<size_t> (accumulate (row_path->begin(), row_path->end(), 0)));
+#endif
+
+  // store alignment information
+
+  // only create a new entry in __row_index if there isn't one already
+  if (!exists_row (name)) {
+    __rows.push_back (new Alignment_row (row_path));
+    __row_index.insert (make_pair (name, __rows.size() - 1));
+  } else {
+    __rows[get_row_index (name)] = new Alignment_row (row_path);
+  }
+
+#ifndef NDEBUG
+  // check that the sequence indices for the rows in *this
+  // and sequences in the Sequence_database& are still in sync
+  // after this operation
+  if (get_row_index (name) != seq_db->get_seq_index (name)) {
+    cerr << "ERROR: Sequence indices are out of sync between the Alignment (index = " << get_row_index (name) << ") and corresponding Sequence_database& (index = " << seq_db->get_seq_index (name) << ") after storing '" << name << "'." << endl;
+    exit (1);
+  }
+#endif
+
+}
+
+void Alignment::clear() {
+
+  seq_db->clear();
+
+  for (std::vector<Alignment_row*>::iterator row = __rows.begin(); row != __rows.end(); ++row)
+    delete *row;
+  __rows.clear();
+
+  __row_index.clear();
+
+}
+
+Sequence Alignment_row::get_gapped_seq (const Sequence& ungapped, const char gap_char) const {
+
+#ifndef NDEBUG
+  // check lengths ok
+  if (ungapped.length() != static_cast<size_t> (accumulate (__row_path->begin(), __row_path->end(), 0))) {
+    cerr << "ERROR: Sequence length mismatch for " << ungapped.name << "." << endl
+	 << "Sequence:                " << ungapped.seq << endl
+	 << "Alignment_row::Row_path: " << *this << endl;
+  }
+#endif
+  assert (ungapped.length() == static_cast<size_t> (accumulate (__row_path->begin(), __row_path->end(), 0)));
+
+  std::string gapped (__row_path->size(), gap_char);
+  size_t pos = 0;                                        // sequence position
+  for (size_t col = 0; col < gapped.length(); ++col) {   // column (alignment position)
+    if (!is_gapped (col))
+      gapped[col] = ungapped.seq[pos++];
+  }
+
+  return Sequence (ungapped.name, gapped, ungapped.info);
+
+}
+
+void Alignment::assert_flush() const {
+
+#ifndef NDEBUG
+
+  for (std::vector<Alignment_row*>::const_iterator row = __rows.begin(); row != __rows.end(); ++row) {
+    if (columns() != (*row)->length()) {
+      write_mfa (cerr, false);
+      cerr << "ERROR: Alignment not flush." << endl;
+      exit (1);
+    }
+  }
+
+#endif
+
+}
+
+void Alignment::write_mfa (std::ostream& o, const bool strict /* = true */) const {
+
+  if (strict)
+    assert_flush();
+
+  // align to left
+  o.setf (std::ios_base::left);
+
+  for (size_t r = 0; r < rows(); ++r) {
+
+    const Sequence& sequence = get_gapped_row (r);
+    o << Sequence::fasta_seq_start << sequence.name
+      << (sequence.info.length() ? (' ' + sequence.info) : "") << endl
+      << sequence.seq << endl;
+  }
+
+}
+
+Stockholm::Stockholm (Sequence_database& seq_db)
+  : Alignment (seq_db) {
+
+}
+
+void Stockholm::read_stockholm (const std::string& filename, const bool strict /* = true */,
+				const bool verbose /* = true */) {
+
+  clear();
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  if (verbose)
+    cerr << "Reading Stockholm alignment '" << filename << "'...";
+
+  Regexp re_stock ("^[ \t]*#[ \t]*" + format_identifier + "[ \t]*" + version_identifier + "[ \t]*$");               // format & version identifiers
+  Regexp re_sep ("^[ \t]*" + alignment_separator + "[ \t]*$");                                                      // alignment separator lines, "//"
+  Regexp re_gf ("^[ \t]*" + file_annotation + "[ \t]+([^ \t]+)[ \t]+(.*)$");                                        // #=GF lines
+  Regexp re_gc ("^[ \t]*" + column_annotation + "[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]*$");                           // #=GC lines
+  Regexp re_gs ("^[ \t]*" + sequence_annotation + "[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+(.*)$");                     // #=GS lines
+  Regexp re_gr ("^[ \t]*" + sequence_column_annotation + "[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]+([^ \t]+)[ \t]*$");   // #=GR lines
+  Regexp re_row ("^[ \t]*([^ \t#]+)[ \t]+([^ \t]*)[ \t]*$");                                                        // alignment row data
+  Regexp re_nonwhite ("[^ \t]");                                                                                    // whitespace
+
+  // first store gapped sequences in database,
+  // then parse them later to initialize the alignment
+
+  // hold raw (gapped) sequence data read in from file
+  std::vector<std::string> gapped_seqs;
+  std::vector<std::string> gapped_seqs_names;
+
+  std::string line;
+  while (!filestream.eof()) {
+
+    getline (filestream, line);
+    Util::chomp (line);
+
+    // ignore format-version identifiers
+    if (re_stock.Match (line.c_str()))
+      continue;
+
+    // break if we encounter an alignment separator
+    else if (re_sep.Match (line.c_str()))
+      break;
+
+    // #=GF
+    else if (re_gf.Match (line.c_str()) && re_gf.SubStrings() == 2) {
+      const std::string& gf_key = re_gf[1];
+      const std::string& gf_data = re_gf[2];
+      __gf_annot.push_back (std::make_pair (gf_key, gf_data));
+      __gf_index[gf_key].insert (__gf_annot.size() - 1);
+    }
+
+    // #=GC
+    else if (re_gc.Match (line.c_str()) && re_gc.SubStrings() == 2)
+      __gc_annot[re_gc[1]].append (re_gc[2]);
+
+    // #=GS
+    else if (re_gs.Match (line.c_str()) && re_gs.SubStrings() == 3)
+      __gs_annot[re_gs[1]][re_gs[2]] = re_gs[3];
+
+    // #=GR
+    else if (re_gr.Match (line.c_str()) && re_gr.SubStrings() == 3)
+      __gr_annot[re_gr[1]][re_gr[2]].append (re_gr[3]);
+
+    // row data
+    else if (re_row.Match (line.c_str()) && re_row.SubStrings() == 2) {
+
+      const std::string name = re_row[1];
+      const std::string gapped_seq = re_row[2];
+
+      // is it the first time that we've seen this sequence?
+      if (!exists_row (name)) {
+
+	gapped_seqs_names.push_back (name);
+	__row_index.insert (std::make_pair (name, __row_index.size()));
+	gapped_seqs.push_back (gapped_seq);
+
+	if (__gs_annot.find (name) == __gs_annot.end())
+	  __gs_annot[name] = Annotation();
+
+	if (__gr_annot.find (name) == __gr_annot.end())
+	  __gr_annot[name] = Annotation();
+
+      }
+      // if not, then just append sequence data
+      else {
+	gapped_seqs[__row_index.find (name)->second] += gapped_seq;
+      }
+
+    }
+      
+    else if (line.size() && re_nonwhite.Match (line.c_str())) {
+      cerr << "WARNING: couldn't parse the following alignment line:" << endl << line << endl;
+      continue;
+    }
+
+  }
+  filestream.close();
+
+  // now parse this gapped sequence data into an alignment
+  for (size_t r = 0; r < gapped_seqs.size(); ++r) {
+
+    const std::string& name = gapped_seqs_names[r];
+    const std::string& gapped_seq = gapped_seqs[r];
+
+    // create ungapped sequence
+    std::string ungapped_seq;
+    ungapped_seq.resize (gapped_seq.length());
+    std::string::iterator last_pos = remove_copy_if (gapped_seq.begin(), gapped_seq.end(),
+						     ungapped_seq.begin(),
+						     Alignment::is_gap_char);
+    ungapped_seq.erase (last_pos, ungapped_seq.end()); // erase unnecessary positions
+
+    // create alignment path
+    Alignment_row::Row_path* row_path = new Alignment_row::Row_path (gapped_seq.length()); // allocate space
+    transform (gapped_seq.begin(), gapped_seq.end(),
+	       row_path->begin(),
+	       std::not1 (std::ptr_fun (Alignment::is_gap_char)));
+
+    // now store row
+    Sequence* sequence = new Sequence (name, ungapped_seq);
+    add_row (sequence,
+	     row_path);
+
+  }
+
+  if (strict)
+    assert_all_flush();
+
+  if (verbose)
+    cerr << "done." << endl;
+
+}
+
+void Stockholm::write_stockholm (std::ostream& o, const bool strict /* = true */) const {
+
+  if (strict)
+    assert_all_flush();
+
+  o << alignment_header << endl;
+
+  // align to left
+  o.setf (std::ios_base::left);
+
+  // get the field width for the key columns
+  // max_name_width takes into account sequence names, GF/GS/GC/GR annotations,
+  // and GS annotations for internal nodes...
+  // scroll down to see where it gets its final value
+  size_t max_name_width = 0;
+  for (size_t r = 0; r < rows(); r++) {
+    // sequence names
+    const std::string& name = get_row_name (r);
+    max_name_width = std::max (max_name_width, name.length());
+    // 6 chars for "#=GS name "
+    const Row_annotation::const_iterator gs_annot_row = __gs_annot.find (name);
+    if (gs_annot_row != __gs_annot.end()) {
+      for (Annotation::const_iterator gs = gs_annot_row->second.begin();gs != gs_annot_row->second.end(); ++gs)
+	max_name_width = std::max (max_name_width, gs->first.size() + name.length() + 6);
+    }
+    // 6 chars for "#=GR name "
+    const Row_annotation::const_iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::const_iterator gr = gr_annot_row->second.begin();gr != gr_annot_row->second.end(); ++gr)
+	max_name_width = std::max (max_name_width, gr->first.size() + name.length() + 6);
+    }
+  }
+  // 5 chars for "#=GF "
+  for (std::vector<std::pair<std::string, std::string> >::const_iterator gf = __gf_annot.begin(); gf != __gf_annot.end(); ++gf)
+    max_name_width = std::max (max_name_width, gf->first.length() + 5);
+  // 5 chars for "#=GC "
+  for (Annotation::const_iterator gc = __gc_annot.begin();gc != __gc_annot.end(); ++gc)
+    max_name_width = std::max (max_name_width, gc->first.size() + 5);
+
+  // #=GF lines
+  for (std::vector<std::pair<std::string, std::string> >::const_iterator gf = __gf_annot.begin(); gf != __gf_annot.end(); ++gf) {
+    std::string key = file_annotation + ' ' + gf->first;
+    o.width (max_name_width + 1);
+    o << key << gf->second << endl;
+  }
+
+  // #=GS lines
+  for (size_t r = 0; r < rows(); ++r) {
+    const std::string& name = get_row_name (r);
+    const Row_annotation::const_iterator gs_annot_row = __gs_annot.find (name);
+    if (gs_annot_row != __gs_annot.end()) {
+      for (Annotation::const_iterator gs = gs_annot_row->second.begin(); gs != gs_annot_row->second.end(); ++gs) {
+	std::string key = sequence_annotation + ' ' + name + ' ' + gs->first;
+	o.width (max_name_width + 1);
+	o << key << gs->second << endl;
+      }
+    }
+
+  }
+
+  // main body of alignment
+  for (size_t r = 0; r < rows(); r++) {
+    const std::string& name = get_row_name (r);
+
+    // sequence data
+    o.width (max_name_width + 1);
+    const Sequence& sequence = get_gapped_row (r);
+    o << sequence.name
+      << sequence.seq << endl;
+
+    // #=GR lines
+    const Row_annotation::const_iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::const_iterator gr = gr_annot_row->second.begin(); gr != gr_annot_row->second.end(); ++gr) {
+	std::string key = sequence_column_annotation + ' ' + name + ' ' + gr->first;
+	o.width (max_name_width + 1);
+	o << key << gr->second << endl;
+      }
+    }
+
+  }
+
+  // #=GC lines
+  for (Annotation::const_iterator gc = __gc_annot.begin(); gc != __gc_annot.end(); ++gc) {
+    std::string key;
+    key = column_annotation + ' ' + gc->first;
+    o.width (max_name_width + 1);
+    o << key << gc->second << endl;
+  }
+
+  o << alignment_separator << endl;
+
+}
+
+void Stockholm::read_stockholm_or_mfa (const std::string& filename, const bool strict /* = true */,
+				       const bool verbose /* = true */) {
+
+  if (!detect_mfa (filename))
+    read_stockholm (filename, strict,
+		    verbose);
+  else
+    read_mfa (filename, strict,
+	      verbose);
+
+}
+
+std::string Stockholm::get_gf_annot (const std::string& key) const {
+
+  std::string s;
+  const std::map<std::string, std::set<size_t> >::const_iterator index = __gf_index.find (key);
+  if (index != __gf_index.end()) {
+    for (std::set<size_t>::const_iterator i = index->second.begin(); i != index->second.end(); ++i)
+      s.append (__gf_annot[*i].second);
+  }
+
+  return s;
+
+}
+
+std::string Stockholm::get_gc_annot (const std::string& key) const {
+
+  std::string s;
+  const Annotation::const_iterator gc_iter = __gc_annot.find (key);
+  if (gc_iter != __gc_annot.end())
+    s = gc_iter->second;
+
+  return s;
+
+}
+
+std::string Stockholm::get_gs_annot (const std::string& seq, const std::string& key) const {
+
+  std::string s;
+  const Row_annotation::const_iterator gs_row_annot = __gs_annot.find (seq);
+  if (gs_row_annot != __gs_annot.end()) {
+    const Annotation::const_iterator gs = gs_row_annot->second.find (key);
+    if (gs != gs_row_annot->second.end())
+      s = gs->second;
+  }
+
+  return s;
+
+}
+
+std::string Stockholm::get_gr_annot (const std::string& seq, const std::string& key) const {
+
+  std::string s;
+  const Row_annotation::const_iterator gr_row_annot = __gr_annot.find (seq);
+  if (gr_row_annot != __gr_annot.end()) {
+    const Annotation::const_iterator gr = gr_row_annot->second.find (key);
+    if (gr != gr_row_annot->second.end())
+      s = gr->second;
+  }
+
+  return s;
+
+}
+
+void Stockholm::clear() {
+
+  this->Alignment::clear();
+  clear_annot();
+
+}
+
+void Stockholm::clear_annot() {
+
+  __gf_annot.clear();
+  __gc_annot.clear();
+  __gs_annot.clear();
+  __gr_annot.clear();
+  __gf_index.clear();
+
+}
+
+void Stockholm::add_gf_annot (const std::string& key, const std::string& value) {
+  __gf_annot.push_back (std::make_pair (key, value));
+  __gf_index[key].insert (__gf_annot.size() - 1);
+}
+
+void Stockholm::set_gc_annot (const std::string& key, const std::string& value) {
+  __gc_annot[key] = value;
+}
+
+void Stockholm::set_gs_annot (const std::string& seq, const std::string& key, const std::string& value) {
+  __gs_annot[seq].insert (std::make_pair (key, value));
+}
+
+
+void Stockholm::set_gr_annot (const std::string& seq, const std::string& key, const std::string& value) {
+  __gr_annot[seq].insert (std::make_pair (key, value));
+}
+
+Stockholm* Stockholm::subalignment (Sequence_database& seq_db_subalign,
+				    const unsigned start, const unsigned end) const {
+
+  Stockholm* subalign = new Stockholm (seq_db_subalign);
+  subalign->clear();
+
+  // #=GF lines
+  for (std::vector<std::pair<std::string, std::string> >::const_iterator gf = __gf_annot.begin(); gf != __gf_annot.end(); ++gf)
+    subalign->add_gf_annot (gf->first, gf->second);
+
+  // #=GS lines
+  for (size_t r = 0; r < rows(); ++r) {
+    const std::string& name = get_row_name (r);
+    const Row_annotation::const_iterator gs_annot_row = __gs_annot.find (name);
+    if (gs_annot_row != __gs_annot.end()) {
+      for (Annotation::const_iterator gs = gs_annot_row->second.begin(); gs != gs_annot_row->second.end(); ++gs)
+	subalign->set_gs_annot (name, gs->first, gs->second);
+    }
+  }
+
+  // main body of alignment
+  for (size_t r = 0; r < rows(); ++r) {
+
+    const std::string& name = get_row_name (r);
+    const Alignment_row& row = get_row (r);
+
+    // sequence data
+    const Interval seq_coords = row.map_align_to_seq (start, end);
+    subalign->add_row (seq_db->get_seq (r).subsequence (seq_coords.start, seq_coords.end),
+		       row.subalignment_row_path (start, end));
+    // (note that the called functions properly handle the case of the 0-length interval (1, 0)
+    // which map_align_to_seq may return)
+
+    // #=GR lines
+    const Row_annotation::const_iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::const_iterator gr = gr_annot_row->second.begin(); gr != gr_annot_row->second.end(); ++gr)
+	subalign->set_gr_annot (name, gr->first, gr->second.substr (start, start < end ? end - start + 1 : 0)); // catch case of the empty alignment
+    }
+
+  }
+
+  // #=GC lines
+  for (Annotation::const_iterator gc = __gc_annot.begin(); gc != __gc_annot.end(); ++gc)
+    subalign->set_gc_annot (gc->first, gc->second.substr (start, start < end ? end - start + 1 : 0));
+
+  return subalign;
+
+}
+
+void Stockholm::assert_all_flush() const {
+
+#ifndef NDEBUG
+
+  assert_flush();
+
+  // now check annotations
+  for (size_t r = 0; r < rows(); ++r) {
+
+    const std::string& name = get_row_name (r);
+
+    // #=GR lines
+    const Row_annotation::const_iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::const_iterator gr = gr_annot_row->second.begin(); gr != gr_annot_row->second.end(); ++gr) {
+	if (columns() != gr->second.length()) {
+	  write_stockholm (cerr, false);
+	  cerr << "ERROR: Alignment annotations not flush." << endl;
+	  exit (1);
+	}
+      }
+    }
+
+  }
+
+  // #=GC lines
+  for (Annotation::const_iterator gc = __gc_annot.begin(); gc != __gc_annot.end(); ++gc) {
+    if (columns() != gc->second.length()) {
+      write_stockholm (cerr, false);
+      cerr << "ERROR: Alignment annotations not flush." << endl;
+      exit (1);
+    }
+  }
+
+#endif
+
+}
+
+void Stockholm::revcomp (const Alphabet& alphabet) {
+
+  // revcomp sequences
+  seq_db->revcomp (alphabet);
+
+  // now reverse per-column annotations
+  for (size_t r = 0; r < rows(); ++r) {
+
+    const std::string& name = get_row_name (r);
+
+    // reverse alignment row
+    // note that this method properly re-builds the coordinate indices with Alignment_row::build_coordinate_indices
+    get_row (r).reverse();
+
+    // #=GR lines
+    const Row_annotation::iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::iterator gr = gr_annot_row->second.begin(); gr != gr_annot_row->second.end(); ++gr)
+	std::reverse (gr->second.begin(), gr->second.end());
+    }
+
+  }
+
+  // #=GC lines
+  for (Annotation::iterator gc = __gc_annot.begin(); gc != __gc_annot.end(); ++gc)
+    std::reverse (gc->second.begin(), gc->second.end());
+
+}
+
+Stockholm Stockholm::get_codon_from_aa_alignment (Sequence_database& seq_db_codon) const {
+
+  // sanity check on number of seqs
+  assert (this->rows() == seq_db_codon.size());
+
+  // calculate the appropriate number of columns for the codon alignment
+  size_t cols = 3 * this->columns(); // columns in aa alignment
+  for (size_t i = 0; i < seq_db_codon.size(); ++i) {
+    const Sequence& sequence = seq_db_codon.get_seq (i);
+    const unsigned rem = sequence.length() % 3;        // add columns for overhanging nt
+    cols += rem;
+  }
+
+  // initialize codon alignment
+  Stockholm stockholm_codon (seq_db_codon);
+
+  // #=GF lines
+  stockholm_codon.__gf_annot = this->__gf_annot;
+  stockholm_codon.__gf_index = this->__gf_index;
+
+  // #=GS lines
+  for (size_t r = 0; r < rows(); ++r) {
+    const std::string& name = get_row_name (r);
+    const Row_annotation::const_iterator gs_annot_row = __gs_annot.find (name);
+    if (gs_annot_row != __gs_annot.end()) {
+      for (Annotation::const_iterator gs = gs_annot_row->second.begin(); gs != gs_annot_row->second.end(); ++gs)
+	stockholm_codon.set_gs_annot (name, gs->first, gs->second);
+    }
+  }
+
+  // store nt alignment
+  unsigned indent = 0;
+  for (size_t i = 0; i < seq_db_codon.size(); ++i) {
+
+    const std::string& name = seq_db_codon.get_seq (i).name;
+
+    // #=GR lines
+    const Row_annotation::const_iterator gr_annot_row = __gr_annot.find (name);
+    if (gr_annot_row != __gr_annot.end()) {
+      for (Annotation::const_iterator gr = gr_annot_row->second.begin(); gr != gr_annot_row->second.end(); ++gr) {
+	std::string gr_codon (cols, Stockholm::annotation_wildcard_char);
+	for (size_t s = 0; s < gr->second.length(); ++s)
+	  gr_codon[(3 * s)] = gr_codon[(3 * s) + 1] = gr_codon[(3 * s) + 2] = gr->second[s];
+	stockholm_codon.set_gr_annot (name, gr->first, gr_codon);
+      }
+    }
+
+    // store this row of alignment as vector of booleans
+    const Alignment_row& row_aa = this->get_row (i);
+    Alignment_row::Row_path* row_path_nt = new Alignment_row::Row_path (cols, false);
+    size_t ii;
+    for (ii = 0; ii < row_aa.length(); ++ii) {
+      // if a character (aa) here, mark the corresponding codon as aligned
+      if (!row_aa.is_gapped (ii))
+	(*row_path_nt)[(3 * ii)] = (*row_path_nt)[(3 * ii) + 1] = (*row_path_nt)[(3 * ii) + 2] = true;
+    }
+
+    // store overhangs if necessary as unaligned nt
+    const unsigned len_aa = this->get_row (i).seqlength();
+    const unsigned len_nt = seq_db_codon.get_seq (i).length();
+    if (static_cast<unsigned> (len_nt / 3) != len_aa) { // sanity check on sequence lengths
+      cerr << "ERROR: Sequence lengths in protein and codon space don't agree (even when rounded to the lowest multiple of 3)." << endl;
+      exit (1);
+    }
+
+    if (len_nt > 3 * len_aa) {
+      for (size_t overhang = len_nt - (3 * len_aa); overhang > 0; --overhang)
+	(*row_path_nt)[(3 * ii) + overhang + indent - 1] = true;
+      indent += len_nt - (3 * len_aa);
+    }
+
+    // add the row to the alignment
+    stockholm_codon.set_row (seq_db_codon.get_seq (i).name, row_path_nt);
+
+  }
+
+  // #=GC lines
+  for (Annotation::const_iterator gc = __gc_annot.begin(); gc != __gc_annot.end(); ++gc) {
+    std::string gc_codon (cols, Stockholm::annotation_wildcard_char);
+    for (size_t s = 0; s < gc->second.length(); ++s)
+      gc_codon[(3 * s)] = gc_codon[(3 * s) + 1] = gc_codon[(3 * s) + 2] = gc->second[s];
+    stockholm_codon.set_gc_annot (gc->first, gc_codon);
+  }
+
+  stockholm_codon.assert_all_flush();
+
+  return stockholm_codon;
+
+}
+
+void Stockholm::annotate_with_statistics() {
+
+  add_gf_annot (Stockholm::percent_id_annotation, Util::to_string (percent_id()));
+  add_gf_annot (Stockholm::gap_fraction_annotation, Util::to_string (gap_fraction()));
+
+}
diff --git a/src/seq/alignment.h b/src/seq/alignment.h
new file mode 100644
index 0000000..48075ad
--- /dev/null
+++ b/src/seq/alignment.h
@@ -0,0 +1,729 @@
+
+/**
+ * \file alignment.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ * Parsing of Stockholm-format alignments is based on Ian Holmes's
+ * Stockholm class.
+ */
+
+#ifndef SEQ_ALIGNMENT_INCLUDED
+#define SEQ_ALIGNMENT_INCLUDED
+
+#include <set>
+#include <algorithm>
+
+#include "seq/sequence.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a single row of an alignment.
+   *
+   * All coordinates are 0-based.
+   * Intervals are always fully-closed, [start, end].
+   */
+  struct Alignment_row {
+
+  public:
+
+    /**
+     * \brief Represention of row of alignment.
+     *
+     * True indicates that a character is present at an alignment position;
+     * false otherwise.
+     */
+    typedef std::vector<bool> Row_path;
+
+    /**
+     * \brief Constructor.
+     */
+    Alignment_row (Row_path* path);
+    Alignment_row (const Alignment_row& parent);
+    Alignment_row& operator= (const Alignment_row& parent);
+
+    /**
+     * \brief Destructor.
+     */
+    ~Alignment_row();
+
+    /**
+     * \brief Build mapping between sequence and alignment coordinates.
+     */
+    void build_coordinate_indices();
+
+    /**
+     * \brief Length of alignment row.
+     */
+    inline size_t length() const { return __row_path->size(); }
+
+    /**
+     * \brief Length of ungapped sequence.
+     */
+    inline size_t seqlength() const { return __seqlength; }
+
+    /**
+     * \brief Get gapped sequence corresponding to this row.
+     * \param ungapped ungapped sequence
+     */
+    Sequence get_gapped_seq (const Sequence& ungapped, const char gap_char) const;
+
+    /**
+     * \brief Get (possibly-gapped) character for a column of this row.
+     * \param col column of Alignment_row
+     */
+    inline char get_char (const size_t col,
+			  const Sequence& ungapped, const char gap_char) const;
+
+    /**
+     * \brief Extract subalignment.
+     * 
+     * \param start start coordinate of alignment row
+     * \param end end coordinate of alignment row
+     */
+    Alignment_row* subalignment (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Extract Row_path subalignment.
+     * 
+     * \param start start coordinate of alignment row
+     * \param end end coordinate of alignment row
+     */
+    Row_path* subalignment_row_path (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Map a sequence position to the corresponding alignment coordinate.
+     */
+    inline unsigned map_seq_to_align (const unsigned pos) const;
+
+    /**
+     * \brief Map subalignment coordinates to the corresponding sequence interval.
+     *
+     * \param start start coordinate of alignment row
+     * \param end end coordinate of alignment row
+     * \return sequence interval, or (1, 0) if the interval is empty
+     */
+    inline Interval map_align_to_seq (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Reverse alignment.
+     *
+     * Calls build_coordinate_indices.
+     */
+    void reverse();
+
+    /**
+     * \brief Is an alignment coordinate (column) gapped in this sequence?
+     */
+    inline bool is_gapped (const unsigned col) const {
+      assert (col < __row_path->size());
+      return !(*__row_path)[col];
+    }
+
+    /**
+     * \brief Output operator (write Row_path).
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Alignment_row& row) {
+      o << Util::join (*row.__row_path, "") << endl;
+      return o;
+    }
+
+  private:
+
+    std::vector<size_t> __seq_to_align_coords_map;  ///< map sequence to alignment coordinates
+    std::vector<size_t> __align_to_seq_coords_map;  ///< map alignment to sequence coordinates (next ungapped position)
+    Row_path* __row_path;                           ///< alignment path
+    size_t __seqlength;                             ///< length of ungapped sequence
+
+  };
+
+  /**
+   * \brief Represent a matrix-form global alignment.
+   *
+   * All coordinates are 0-based.
+   * An Alignment holds a reference to the Sequence_database
+   * which contains the actual sequence information.
+   * The reference is non-const because an Alignment
+   * can modify the sequence information (e.g., when it reads 
+   * in an alignment).
+   */
+  struct Alignment {
+
+  public:
+
+    static const char gap_char;   ///< gap character
+
+    /**
+     * \brief Constructor.
+     * \param seq_db Sequence_database to hold actual sequence information
+     */
+    Alignment (Sequence_database& seq_db);
+    Alignment (const Alignment& parent);
+    Alignment& operator= (const Alignment& parent);
+
+    /**
+     * \brief Detect whether an alignment seems to be in multi-FASTA format.
+     * \see Sequence::detect_fasta
+     */
+    static bool detect_mfa (const std::string& filename);
+
+    /**
+     * \brief Initialize from multi-FASTA alignment.
+     *
+     * Clears all alignment and sequence data.
+     * Populates seq_db as appropriate,
+     * being very careful to maintain ordering of sequences
+     * for consistency when indexing seq_db and __rows.
+     * \param filename alignment filename
+     * \param strict Require that alignment be flush.
+     */
+    void read_mfa (const std::string& filename, const bool strict = true,
+		   const bool verbose = true);
+
+    /**
+     * \brief Write in multi-FASTA format.
+     * \param strict Require that alignment be flush.
+     */
+    void write_mfa (std::ostream& o, const bool strict = true) const;
+
+    /**
+     * \brief Assert all alignment rows of equal length.
+     */
+    void assert_flush() const;
+
+    /**
+     * \brief Map a sequence position to the corresponding alignment coordinate.
+     * \param seq sequence name
+     * \see Alignment_row::map_seq_to_align
+     */
+    inline size_t map_seq_to_align (const std::string& seq, const unsigned pos) const {
+      return get_row (seq).map_seq_to_align (pos);
+    }
+
+    /**
+     * \brief Map subalignment coordinates to the corresponding sequence interval.
+     *
+     * Maps to the sequence interval which is strictly contained by
+     * the subalignment.
+     * \param seq sequence name
+     * \param start start coordinate of alignment row
+     * \param end end coordinate of alignment row
+     * \return sequence interval, or (1, 0) if the interval is empty
+     * \see Alignment_row::map_align_to_seq
+     */
+    inline Interval map_align_to_seq (const std::string& seq, const unsigned start, const unsigned end) const {
+      return get_row (seq).map_align_to_seq (start, end);
+    }
+
+    /**
+     * \brief Map an interval in one sequence to the corresponding interval in another.
+     *
+     * Maps to the sequence interval in seq_to which is strictly contained by
+     * the subalignment implied by the sequence interval in seq_from.
+     * \return sequence interval, or (1, 0) if the interval is empty
+     * \see map_seq_to_align
+     * \see map_align_to_seq
+     */
+    inline Interval map_seq_to_seq (const std::string& seq_from, const unsigned start_from, const unsigned end_from,
+				    const std::string& seq_to) const;
+
+    /**
+     * \brief Calculate average per-column percentage identity of alignment.
+     *
+     * Reports the average per-column percent id:
+     *  sum_columns (# identical characters in column / total # non-gap characters in column) / num_columns
+     * Gaps are ignored in both the numerator and denominator.
+     */
+    double percent_id() const;
+
+    /**
+     * \brief Calculate average per-column percentage identity of subalignment [start, end].
+     *
+     * Reports the average per-column percent id:
+     *  sum_columns (# identical characters in column / total # non-gap characters in column) / num_columns
+     * Gaps are ignored in both the numerator and denominator.
+     * \param start start column of subalignment
+     * \param end end column of subalignment
+     */
+    double percent_id (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Calculate fraction of gaps in the alignment.
+     */
+    double gap_fraction() const;
+
+    /**
+     * \brief Calculate fraction of gaps in the subalignment [start, end].
+     *
+     * \param start start column of subalignment
+     * \param end end column of subalignment
+     */
+    double gap_fraction (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Get row of alignment.
+     * \param name sequence name
+     */
+    const Alignment_row& get_row (const std::string& name) const;
+
+    /**
+     * \brief Get gapped row of alignment formatted for display.
+     * \param name sequence name
+     */
+    const Sequence get_gapped_row (const std::string& name) const;
+
+    /**
+     * \brief Get gapped row of alignment formatted for display.
+     * \param r index in __rows or seq_db
+     */
+    const Sequence get_gapped_row (const size_t r) const;
+
+    /**
+     * \brief Remove all gaps from the passed string.
+     */
+    static void remove_gaps (std::string& str);
+
+    /**
+     * \brief Get name of row of alignment.
+     * \param r index in __rows or seq_db
+     */
+    const std::string& get_row_name (const size_t r) const {
+      assert (r < __rows.size());
+      return seq_db->get_seq (r).name;
+    }
+
+    /**
+     * \brief Get index of row in alignment.
+     * \param name sequence name
+     */
+    size_t get_row_index (const std::string& name) const {
+      assert (exists_row (name));
+      return __row_index.find (name)->second;
+    }
+
+    /**
+     * \brief Get names of rows in the alignment.
+     *
+     * Row names are ordered as they are indexed in the alignment.
+     */
+    std::vector<std::string> get_row_names() const;
+
+    /**
+     * \brief Add a row to the alignment.
+     * 
+     * Helper for reading alignment files from disk.
+     * Generally preferred over the other add_row for efficiency.
+     * Add sequence information to Sequence_database as well
+     * if nothing is present for the sequence name.
+     * Beware: This function may not behave as you expect.
+     * \param sequence sequence for alignment row
+     * \param row_path Alignment_row::row_path for row
+     */
+    void add_row (Sequence* sequence,
+		  Alignment_row::Row_path* row_path);
+
+    /**
+     * \brief Add a row to the alignment.
+     * 
+     * Helper for reading alignment files from disk.
+     * Add sequence information to Sequence_database as well
+     * if nothing is present for the sequence name.
+     * Beware: This function may not behave as you expect.
+     * \param sequence sequence for alignment row
+     * \param alignment_row Alignment_row for row
+     */
+    void add_row (Sequence* sequence,
+		  Alignment_row* alignment_row);
+
+    /**
+     * \brief Set a row in the alignment.
+     * 
+     * This function should be used when constructing a new alignment
+     * of sequence data which has already been stored in 
+     * the Sequence_database&; if you want to read in an alignment
+     * and sequence data simultaneously (e.g., when reading an alignment
+     * file from disk), then you should use add_row.
+     * 
+     * Assumes (and requires) that there is a sequence named 'name'
+     * in the stored Sequence_database; dies if not.
+     * If there is a corresponding row already stored in __rows,
+     * then overwrite it; otherwise store 
+     * Note that if improperly used, this function can cause
+     * the sequence indices for the Alignment object and the 
+     * stored Sequence_database& object to go out of sync!
+     * Be very careful.
+     * \param name name of seqence for alignment row
+     * \param row_path Alignment_row::row_path for row
+     */
+    void set_row (const std::string& name,
+		  Alignment_row::Row_path* row_path);
+
+    /**
+     * \brief Do we have a row for a particular sequence name?
+     * \param name sequence name
+     */
+    bool exists_row (const std::string& name) const {
+      return (__row_index.find (name) != __row_index.end());
+    }
+
+    /**
+     * \brief Clear all alignment and sequence data.
+     *
+     * \see Sequence_database::clear
+     */
+    virtual void clear();
+
+    /**
+     * \brief Number of sequences in alignment.
+     */
+    inline size_t rows() const;
+
+    /**
+     * \brief Number of columns in alignment.
+     */
+    inline size_t columns() const;
+
+    /**
+     * \brief Is a character a gap?
+     * 
+     * Gaps can be: gap_char . _
+     */
+    static inline bool is_gap_char (char c) {
+      return (c == gap_char || c == '.' || c == '_');
+    }
+
+    /**
+     * \brief Is a particular (row, column) gapped?
+     * \param row row index for sequence
+     * \param col column of alignment
+     */
+    inline bool is_gapped (const size_t row, const size_t col) const;
+
+  protected:
+
+    /**
+     * \brief Get row of alignment.
+     * \param r index in __rows or seq_db
+     */
+    const Alignment_row& get_row (const size_t r) const {
+      assert (r < __rows.size());
+      return *__rows[r];
+    }
+
+    /**
+     * \brief Get row of alignment.
+     * \param r index in __rows or seq_db
+     */
+    Alignment_row& get_row (const size_t r) {
+      assert (r < __rows.size());
+      return *__rows[r];
+    }
+
+    /**
+     * \brief Get the character at a particular (row, column).
+     * \param row row index for sequence
+     * \param col column of alignment
+     * \see Alignment_row::get_char
+     */
+    char get_char (const size_t row, const size_t col) const;
+
+    /**
+     * \brief Destructor.
+     * 
+     * Note that the memory for seq_db is NOT freed,
+     * since we assume that it was allocated elsewhere.
+     */
+    virtual ~Alignment();
+
+    Sequence_database* seq_db;                   ///< sequences of the alignment
+    std::vector<Alignment_row*> __rows;          ///< individual rows of the alignment
+    std::map<std::string, size_t> __row_index;   ///< map from row names to position in __rows
+
+  };
+
+  /**
+   * \brief Represent a Stockholm-format alignment.
+   */
+  struct Stockholm : public Alignment {
+
+    /**
+     * \brief Constructor.
+     */
+    Stockholm (Sequence_database& seq_db);
+
+    /**
+     * \brief Initialize from Stockholm alignment.
+     *
+     * Clears all alignment and sequence data.
+     * Populates seq_db as appropriate,
+     * being very careful to maintain ordering of sequences
+     * for consistency when indexing seq_db and __rows.
+     * \param filename alignment filename.
+     * \param strict Require that alignment be flush.
+     * \see Alignment::clear
+     */
+    void read_stockholm (const std::string& filename, const bool strict = true,
+			 const bool verbose = true);
+
+    /**
+     * \brief Initialize from Stockholm or multi-FASTA alignment.
+     *
+     * Clears all alignment and sequence data.
+     * \param filename alignment filename.
+     * \param strict Require that alignment be flush.
+     * \see Alignment::clear
+     */
+    void read_stockholm_or_mfa (const std::string& filename, const bool strict = true,
+				const bool verbose = true);
+
+    /**
+     * \brief Write in Stockholm format.
+     * \param strict Require that alignment be flush.
+     */
+    void write_stockholm (std::ostream& o, const bool strict = true) const;
+
+    /**
+     * \brief Extract subalignment.
+     * 
+     * \param seq_db_subalign Sequence_database to store sequence information for subalignment
+     * \param start start coordinate of alignment
+     * \param end end coordinate of alignment
+     */
+    Stockholm* subalignment (Sequence_database& seq_db_subalign,
+			     const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Get all #=GF lines with a given key.
+     */
+    std::string get_gf_annot (const std::string& key) const;
+
+    /**
+     * \brief Get #=GC line with a given key.
+     */
+    std::string get_gc_annot (const std::string& key) const;
+
+    /**
+     * \brief Get #=GS line for a given sequence with a given key.
+     */
+    std::string get_gs_annot (const std::string& seq, const std::string& key) const;
+
+    /**
+     * \brief Get #=GR line for a given sequence with a given key.
+     */
+    std::string get_gr_annot (const std::string& seq, const std::string& key) const;
+
+    /**
+     * \brief Add a #=GF line.
+     */
+    void add_gf_annot (const std::string& key, const std::string& value);
+
+    /**
+     * \brief Set a #=GC line.
+     */
+    void set_gc_annot (const std::string& key, const std::string& value);
+
+    /**
+     * \brief Set a #=GS line.
+     */
+    void set_gs_annot (const std::string& seq, const std::string& key, const std::string& value);
+
+    /**
+     * \brief Set a #=GR line.
+     */
+    void set_gr_annot (const std::string& seq, const std::string& key, const std::string& value);
+
+    /**
+     * \brief Clear all alignment and sequence data as well as annotations.
+     *
+     * \see Sequence_database::clear
+     */
+    void clear();
+
+    /**
+     * \brief Clear all annotation lines.
+     */
+    void clear_annot();
+
+    /**
+     * \brief Assert all alignment rows and per-column annotations of equal length.
+     */
+    void assert_all_flush() const;
+
+    /**
+     * \brief Reverse-complement alignment and associated sequence data under the passed alphabet.
+     *
+     * Handles annotations, etc. properly.
+     * (This is why it's a method of Stockholm rather than the parent Alignment class.)
+     * \param alphabet Alphabet to reverse-complement under
+     */
+    void revcomp (const Alphabet& alphabet);
+
+    /**
+     * \brief Map amino acid alignment to corresponding codon alignment.
+     *
+     * Assumes that the sequences in seq_db_codon are ordered as in this->seq_db.
+     * Handles annotations, etc. properly (overhangs are annotated as '.').
+     * \param seq_db_codon sequence data in nucleotide space
+     */
+    Stockholm get_codon_from_aa_alignment (Sequence_database& seq_db_codon) const;
+
+    /**
+     * \brief Annotate alignment with alignment statistics.
+     * 
+     * Assumes that the (implicit) alphabet is NOT case-sensitive.
+     * \see Alignment::percent_id
+     * \see Alignment::gap_fraction
+     */
+    void annotate_with_statistics();
+
+
+    static const std::string gff_annotation;                         ///< GFF annotation key
+    static const std::string percent_id_annotation;                  ///< percent id annotation key
+    static const std::string gap_fraction_annotation;                ///< gap fraction annotation key
+
+
+
+  private:
+
+    static const std::string format_identifier;
+    static const std::string version_identifier;
+    static const std::string alignment_header;
+    static const std::string alignment_separator;
+
+    static const std::string file_annotation;
+    static const std::string column_annotation;
+    static const std::string sequence_annotation;
+    static const std::string sequence_column_annotation;
+
+    static const char annotation_wildcard_char;                      ///< Annotation unknown character
+
+    typedef std::map<std::string, std::string> Annotation;           ///< keyed annotations
+    typedef std::map<std::string, Annotation> Row_annotation;        ///< Annotation keyed by sequence
+
+    std::vector<std::pair<std::string, std::string> > __gf_annot;    ///< sorted list of #=GF annotations
+    Annotation __gc_annot;                                           ///< per-column annotation
+    Row_annotation __gs_annot;                                       ///< per-sequence annotation
+    Row_annotation __gr_annot;                                       ///< per-sequence, per-column annotation
+    std::map<std::string, std::set<size_t> > __gf_index;             ///< map from keys to #=GF lines
+
+  };
+
+
+  /****************************************
+   * Function definitions.
+   ****************************************/
+
+  inline unsigned Alignment_row::map_seq_to_align (const unsigned pos) const {
+    assert (pos < __seq_to_align_coords_map.size());
+    return __seq_to_align_coords_map[pos];
+  }
+
+  inline Interval Alignment_row::map_align_to_seq (const unsigned start, const unsigned end) const {
+
+    if (start > end)
+      cerr << "start = " << start << ", end = " << end << endl;
+    assert (start <= end);
+    assert (end < __align_to_seq_coords_map.size());
+
+    const unsigned s = __align_to_seq_coords_map[start]; // next ungapped position
+    unsigned e = __align_to_seq_coords_map[end];
+
+    // check for e == 0
+    if (e == 0) {
+
+      // if e == 0 and sequence is gapped at column end,
+      // then [s, e] must map to a run of gaps at the start of the alignment
+      if (is_gapped (end))
+	return Interval (1, 0);
+
+      // if sequence isn't gapped at column end,
+      // then we must have a situation like this:
+      // 000000123
+      // -----AGGC
+      //   s  e
+      // where column end corresponds to the first ungapped position in the sequence
+      // very very tricky...
+      else {
+	assert (s == e);
+	assert (e == 0);
+	return Interval (0, 0);
+      }
+
+    }
+
+    // from here on we can safely assume that e > 0
+
+    // check for end being gapped;
+    // if it is, then set e to the previous ungapped position
+    // (this also catches case of e running off the end of the sequence)
+    if (is_gapped (end))
+      --e;
+
+    // catch cases giving empty sequence:
+    // - no sequence data in alignment
+    // - case of e < s (interval must be all gaps)
+    if ((__seqlength == 0) || (e < s))
+      return Interval (1, 0);
+
+    return Interval (s, e);
+  }
+
+  inline void Alignment::remove_gaps (std::string& str) {
+
+    std::string::iterator last_pos = std::remove_if (str.begin(), str.end(),
+						     Alignment::is_gap_char);
+    str.erase (last_pos, str.end());
+
+  }
+
+  inline size_t Alignment::rows() const {
+    assert (seq_db->size() == __rows.size());
+    assert (__rows.size() == __row_index.size());
+    return __rows.size();
+  }
+
+  inline size_t Alignment::columns() const {
+    if (__rows.size())
+      return __rows[0]->length();
+    return 0;
+  }
+
+  inline Interval Alignment::map_seq_to_seq (const std::string& seq_from, const unsigned start_from, const unsigned end_from,
+					     const std::string& seq_to) const {
+
+    assert (start_from <= end_from);
+
+    const unsigned start_align = map_seq_to_align (seq_from, start_from);
+    const unsigned end_align = map_seq_to_align (seq_from, end_from);
+
+    return map_align_to_seq (seq_to, start_align, end_align);
+
+  }
+
+  inline bool Alignment::is_gapped (const size_t row, const size_t col) const {
+
+    return get_row (row).is_gapped (col);
+
+  }
+
+  inline char Alignment_row::get_char (const size_t col,
+				       const Sequence& ungapped, const char gap_char) const {
+
+    assert (col < __align_to_seq_coords_map.size());
+
+    if (is_gapped (col))
+      return gap_char;
+
+    return ungapped.seq[__align_to_seq_coords_map[col]];
+
+  }
+
+  inline char Alignment::get_char (const size_t row, const size_t col) const {
+
+    return get_row (row).get_char (col,
+				   seq_db->get_seq (row), Alignment::gap_char);
+  }
+
+}
+
+#endif /* SEQ_ALIGNMENT_INCLUDED */
diff --git a/src/seq/alphabet.cc b/src/seq/alphabet.cc
new file mode 100644
index 0000000..9c22fdf
--- /dev/null
+++ b/src/seq/alphabet.cc
@@ -0,0 +1,193 @@
+
+/**
+ * \file sequence.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <climits>
+#include <algorithm>
+
+#include "seq/alphabet.h"
+
+using namespace fsa;
+
+const std::string DNA_alphabet::DNA_alphabet_name = "DNA";
+const std::string RNA_alphabet::RNA_alphabet_name = "RNA";
+const std::string Protein_alphabet::Protein_alphabet_name = "Protein";
+
+
+
+Alphabet::Alphabet (std::string name, size_t size, bool case_sensitive /* = false */)
+  : __name (name), __size (size), __case_sensitive (case_sensitive) {
+
+}
+
+void Alphabet::init_chars (const std::string& chars, const std::string complement /* = "" */) {
+
+  __has_complement = (complement.length() > 0);
+
+  // check sane
+  assert (__size == chars.length());
+  if (__has_complement) {
+    assert (__size == complement.length());
+    __char_complement_list.resize (__size);
+  }
+
+  // now create the __char_index data structure:
+  // this holds a mapping from (non-degenerate) characters in the alphabet
+  // to their numerical indices in __char_list
+  // for speed, we use a vector rather than a map;
+  // elements are accessed by casting the character to int
+  // if a character isn't in the alphabet then it's given an index of __size;
+  // if it is, then it's given the corresponding index in __char_list
+  // (which is smaller than __size by definition)
+
+  // assign dummy value to all entries in __char_index
+  // (indicating not present in alphabet) of __size
+  // NB: CHAR_MAX is defined in climits
+  __char_index.assign (CHAR_MAX + 1, __size);
+
+  // store the alphabet
+  __char_list.resize (__size);  
+  for (size_t i = 0; i < chars.length(); ++i) {
+    char ch = chars[i];
+    if (!__case_sensitive)
+      ch = tolower (ch);
+    __char_list[i] = ch;
+    if (__has_complement)
+      __char_complement_list[i] = complement[i];
+    assert (__char_index.size() > static_cast<size_t> (ch));
+    __char_index[ch] = i;
+  }
+
+}
+
+void Alphabet::add_degen_char (char ch, const std::string& nondegen) {
+
+  // initialize __degen_char_map by storing a
+  // dummy empty vector for all characters
+  // (similar in spirit to how __char_index works; see init_chars)
+  // if this is the first time that this function was called
+  if (!__degen_char_map.size())
+  __degen_char_map.assign (CHAR_MAX + 1, std::vector<char>());
+
+  if (!__case_sensitive)
+    ch = tolower (ch);
+
+  std::vector<char> nondegen_chars (nondegen.length());
+  for (size_t i = 0; i < nondegen.length(); ++i)
+    nondegen_chars[i] = nondegen[i];
+  __degen_char_map[ch] = nondegen_chars;
+  
+}
+
+void Alphabet::set_unknown_char (const char ch) {
+
+  __unknown_char = ch;
+
+}
+
+void Alphabet::make_nondegen (std::string& seq) const {
+
+  for (std::string::iterator c = seq.begin(); c != seq.end(); ++c)
+    *c = get_nondegen_char (*c);
+
+}
+
+std::string Alphabet::get_nondegen (const std::string& seq) const {
+
+  std::string seq_nondegen;
+  seq_nondegen.resize (seq.length());
+  for (size_t i = 0; i < seq.length(); ++i)
+    seq_nondegen[i] = get_nondegen_char (seq[i]);
+
+  return seq_nondegen;
+
+}
+
+void Alphabet::revcomp (std::string& seq, bool (*is_gap_char) (char) /* = NULL */) const {
+
+  if (!__has_complement) {
+    cerr << "ERROR: Tried to reverse-complement under an alphabet without a complementary alphabet." << endl;
+    exit (1);
+  }
+
+  // first reverse
+  std::reverse (seq.begin(), seq.end());
+
+  // then complement
+  for (std::string::iterator ch = seq.begin(); ch != seq.end(); ++ch) {
+    // if requested, ignore gap characters
+    if ((is_gap_char != 0) && is_gap_char (*ch))
+      continue;
+    // complement nondegen chars
+    if (is_nondegen_char (*ch)) {
+      if (isupper (*ch))
+	*ch = toupper (__char_complement_list[__char_index[tolower (*ch)]]);
+      else
+	*ch = tolower (__char_complement_list[__char_index[*ch]]);
+    }
+    // and set degen & unknown chars to __unknown_char
+    else {
+      *ch = isupper (*ch) ? toupper (__unknown_char) : __unknown_char;
+    }
+  }
+
+}
+
+std::string Alphabet::revcomp (const std::string& seq, bool (*is_gap_char) (char) /* = NULL */) const {
+  
+  std::string seq_revcomp = seq;
+  revcomp (seq_revcomp, is_gap_char);
+  return seq_revcomp;
+
+}
+
+DNA_alphabet::DNA_alphabet()
+  : Alphabet (DNA_alphabet_name, 4, false) {
+
+  init_chars ("acgt", "tgca");
+  set_unknown_char ('n');
+  add_degen_char ('u', "t");
+  add_degen_char ('r', "ag");
+  add_degen_char ('y', "ct");
+  add_degen_char ('m', "ac");
+  add_degen_char ('k', "gt");
+  add_degen_char ('s', "cg");
+  add_degen_char ('w', "at");
+  add_degen_char ('h', "act");
+  add_degen_char ('b', "cgt");
+  add_degen_char ('v', "acg");
+  add_degen_char ('d', "agt");
+
+}
+
+RNA_alphabet::RNA_alphabet()
+  : Alphabet (RNA_alphabet_name, 4, false) {
+
+  init_chars ("acgu", "ugca");
+  set_unknown_char ('n');
+  add_degen_char ('t', "u");
+  add_degen_char ('r', "ag");
+  add_degen_char ('y', "ct");
+  add_degen_char ('m', "ac");
+  add_degen_char ('k', "gt");
+  add_degen_char ('s', "cg");
+  add_degen_char ('w', "at");
+  add_degen_char ('h', "act");
+  add_degen_char ('b', "cgt");
+  add_degen_char ('v', "acg");
+  add_degen_char ('d', "agt");
+
+}
+
+Protein_alphabet::Protein_alphabet()
+  : Alphabet (Protein_alphabet_name, 20, false) {
+
+  init_chars ("acdefghiklmnpqrstvwy");
+  set_unknown_char ('x');
+  add_degen_char ('b', "nd");
+  add_degen_char ('z', "qe");
+
+}
diff --git a/src/seq/alphabet.h b/src/seq/alphabet.h
new file mode 100644
index 0000000..952214a
--- /dev/null
+++ b/src/seq/alphabet.h
@@ -0,0 +1,320 @@
+
+/**
+ * \file alphabet.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ * The alphabet representation code is loosely based on Ian Holmes's
+ * Alphabet class.
+ */
+
+#ifndef SEQ_ALPHABET_INCLUDED
+#define SEQ_ALPHABET_INCLUDED
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <vector>
+
+#include "util/misc.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a sequence alphabet.
+   */
+  struct Alphabet {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     *
+     * Unless the alphabet is designated as case-sensitive,
+     * alphabet information is stored as lower-case internally.
+     * \param name alphabet name
+     * \param size alphabet size
+     * \param case_sensitive is the alphabet case-sensitive?
+     */
+    Alphabet (std::string name, size_t size, bool case_sensitive = false);
+
+    /**
+     * \brief Get the name of the alphabet.
+     */
+    const std::string& name() const { return __name; }
+
+    /**
+     * \brief Make a sequence nondegenerate.
+     */
+    void make_nondegen (std::string& sequence) const;
+
+    /**
+     * \brief Get nondegenerate sequence.
+     */
+    std::string get_nondegen (const std::string& sequence) const;
+
+    /**
+     * \brief Does the alphabet have a complement defined?
+     */
+    bool has_complement() const { return __has_complement; }
+
+    /**
+     * \brief Reverse-complement sequence under alphabet.
+     *
+     * Degenerate characters are set to __unknown_char after reverse-complementing.
+     * If requested, ignores gap characters as defined by the passed function.
+     * \param seq sequence to be reverse-complemented
+     * \param is_gap_char function pointer defining a gap character
+     */
+    void revcomp (std::string& seq, bool (*is_gap_char) (char) = NULL) const;
+
+    /**
+     * \brief Reverse-complement sequence under alphabet.
+     * \see revcomp
+     */
+    std::string revcomp (const std::string& seq, bool (*is_gap_char) (char) = NULL) const;
+
+    /**
+     * \brief Get alphabet size.
+     */
+    inline size_t size() const { return __size; };
+
+    /**
+     * \brief Is this a non-degenerate character in the alphabet?
+     */
+    inline bool is_nondegen_char (char ch) const;
+
+    /**
+     * \brief Is this a degenerate character in the alphabet?
+     */
+    inline bool is_degen_char (char ch) const;
+
+    /**
+     * \brief Does the alphabet contain a possibly-degenerate character?
+     * \see is_nondegen_char
+     * \see is_degen_char
+     */
+    inline bool contains_char (const char ch) const;
+
+    /**
+     * \brief Is this an unknown character?
+     */
+    inline bool is_unknown_char (const char ch) const;
+
+    /**
+     * \brief Convert a possibly-degenerate character to a non-degenerate character.
+     *
+     * Randomizes unknown characters across the entire alphabet.
+     * Preserves character case.
+     */
+    inline char get_nondegen_char (const char ch) const;
+
+    /**
+     * \brief Get the numerical index for a character.
+     *
+     * If the character is degenerate or unknown,
+     * randomizes the character prior to getting the index.
+     */
+    inline size_t get_char_index (char ch) const;
+
+    /**
+     * \brief Get a character from its numerical index.
+     */
+    inline char get_char_from_index (const size_t index) const;
+
+  protected:
+
+    /**
+     * \brief Initialize characters in alphabet.
+     */
+    void init_chars (const std::string& chars, const std::string complement = "");
+
+    /**
+     * \brief Add a degenerate character to the alphabet.
+     */
+    void add_degen_char (char ch, const std::string& nondegen);
+
+    /**
+     * \brief Set the unknown character for the alphabet.
+     */
+    void set_unknown_char (const char ch);
+
+  private:
+
+    std::string __name;          ///< alphabet name
+    size_t __size;               ///< alphabet size (# of non-degenerate characters)
+    bool __case_sensitive;       ///< is the alphabet case-sensitive?
+    bool __has_complement;       ///< does the alphabet have a complement?
+
+    std::vector<char> __char_list;                          ///< ordered list of characters
+    std::vector<char> __char_complement_list;               ///< ordered list of complementary characters
+    std::vector<size_t> __char_index;                       ///< map from characters (cast to int) to index in __char_list
+    char __unknown_char;                                    ///< character representing unknown character
+    std::vector<std::vector<char> > __degen_char_map;       ///< map from degenerate to non-degenerate characters (similar in spirit to __char_index)
+
+  };
+
+  /**
+   * \brief Represent a DNA alphabet.
+   */
+  struct DNA_alphabet : public Alphabet {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    DNA_alphabet();
+
+    /**
+     * \brief Define the hardmasked character (ignores case!).
+     */
+    static bool is_hardmask_char (const char ch) {
+      return toupper (ch) == 'N';
+    }
+
+    /**
+     * \brief Call all lower-case characters softmasked.
+     */
+    static bool is_softmasked (const char ch) {
+      return islower (ch);
+    }
+
+  private:
+
+    static const std::string DNA_alphabet_name;   ///< alphabet name
+
+  };
+
+  /**
+   * \brief Represent a RNA alphabet.
+   */
+  struct RNA_alphabet : public Alphabet {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    RNA_alphabet();
+
+  private:
+
+    static const std::string RNA_alphabet_name;   ///< alphabet name
+
+  };
+
+  /**
+   * \brief Represent a protein alphabet.
+   *
+   * Characters are in IUPAC alphabetical order, 'acdefghiklmnpqrstvwy'.
+   */
+  struct Protein_alphabet : public Alphabet {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    Protein_alphabet();
+
+  private:
+
+    static const std::string Protein_alphabet_name;   ///< alphabet name
+
+  };
+
+  inline bool Alphabet::is_nondegen_char (char ch) const {
+    if (!__case_sensitive)
+      ch = tolower (ch);
+    // test for membership in the alphabet
+    if (__char_index[ch] < __size)
+      return true;
+    return false;
+  }
+
+  inline bool Alphabet::is_degen_char (char ch) const {
+    if (!__case_sensitive)
+      ch = tolower (ch);
+    if (__degen_char_map[ch].size())
+      return true;
+    return false;
+  }
+
+  inline bool Alphabet::contains_char (const char ch) const {
+    return (is_nondegen_char (ch) || is_degen_char (ch));
+  }
+
+  inline bool Alphabet::is_unknown_char (const char ch) const {
+    return ((__case_sensitive ? ch : tolower (ch)) == __unknown_char);
+  }
+
+  inline char Alphabet::get_nondegen_char (const char ch) const {
+
+    // if upper-case
+    if (isupper (ch)) {
+
+      // if nondegenerate
+      if (is_nondegen_char (ch))
+	return ch;
+
+      // else if degenerate
+      else if (is_degen_char (ch)) {
+	const std::vector<char>& nondegen = __degen_char_map[__case_sensitive ? ch : tolower (ch)];
+	return toupper (nondegen[Util::rand (nondegen.size() - 1)]);
+      }
+      // else we don't know anything about it, so treat as unknown
+      else
+	return toupper (__char_list[Util::rand (__size - 1)]);
+
+    }
+
+    // if lower-case
+    else {
+
+      // if nondegenerate
+      if (is_nondegen_char (ch))
+	return ch;
+
+      // else if degenerate
+      else if (is_degen_char (ch)) {
+	const std::vector<char>& nondegen = __degen_char_map[__case_sensitive ? ch : tolower (ch)];
+	return tolower (nondegen[Util::rand (nondegen.size() - 1)]);
+      }
+      // else we don't know anything about it, so treat as unknown
+      else {
+	return tolower (__char_list[Util::rand (__size - 1)]);
+      }
+
+    }
+
+  }
+
+  inline size_t Alphabet::get_char_index (char ch) const {
+
+    if (!__case_sensitive)
+      ch = tolower (ch);
+
+    // if this is a non-degenerate character, then return the index
+    if (__char_index[ch] < __size)
+      return __char_index[ch];
+
+    // else randomize and return the corresponding index
+    else {
+      ch = get_nondegen_char (ch);
+      return __char_index[ch];
+    }
+
+  }
+  
+  inline char Alphabet::get_char_from_index (const size_t index) const {
+    
+    assert (index < __char_list.size());
+    return __char_list[index];
+
+  }
+
+}
+
+#endif /* SEQ_ALPHABET_INCLUDED */
diff --git a/src/seq/gff.cc b/src/seq/gff.cc
new file mode 100644
index 0000000..aa269af
--- /dev/null
+++ b/src/seq/gff.cc
@@ -0,0 +1,364 @@
+
+/**
+ * \file gff.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <fstream>
+#include <sstream>
+#include <cmath>
+#include <algorithm>
+
+#include "util/regexp.h"
+#include "math/mathematics.h"
+#include "seq/gff.h"
+
+using namespace fsa;
+
+const std::string GFF::comment_char = "#";
+const std::string GFF::undef_char = ".";
+
+const char GFF::unknown_strand = '.';
+
+const std::string GFF::attributes_split_char = ";";
+const std::string GFF::attributes_assign_char = "=";
+const std::string GFF::attributes_list_char = ",";
+    
+const std::string GFF::key_id = "ID";
+const std::string GFF::key_name = "Name";
+
+const size_t GFF::default_flanking = 10000;
+
+Regexp GFF::re_key_value = "^([^=]+)=(.*)$";
+
+void GFF::from_string (const std::string& str, const bool strip_leading_chr /* = true */) {
+
+  std::vector<std::string> tokens = Util::split (str, "\t"); // hold tab-separated tokens
+
+  // now parse tokens
+
+  // sanity checks
+  if (tokens.size() != 9) {
+    cerr << "ERROR: Not a GFF-format line: " << str << endl;
+    exit (1);
+  }
+
+  seqid = tokens[0];
+  if (strip_leading_chr)
+    Util::strip_leading_chr (seqid);
+  source = tokens[1];
+  type = tokens[2];
+  set_start (atoi (tokens[3].c_str()));
+  end = static_cast<unsigned> (atoi (tokens[4].c_str()));
+  score = (tokens[5] != "" && tokens[5] != GFF::undef_char) ? atof (tokens[5].c_str()) : -1.;
+  strand = (tokens[6])[0];
+  phase = (tokens[7] != "" && tokens[7] != GFF::undef_char) ? static_cast<unsigned> (atoi (tokens[7].c_str())) : 3;
+
+  parse_attributes_string (tokens[8]);
+  
+}
+
+void GFF::set_start (const int s) {
+
+  if (s < 1) {
+    cerr << "WARNING: setting GFF feature start coordinate " << s << " to 1." << endl;
+    start = 1;
+  }
+  
+  else {
+    start = static_cast<unsigned> (s);
+  }
+
+}
+
+void GFF::parse_attributes_string (const std::string& str) {
+
+  std::vector<std::string> key_value_pairs = Util::split (str, GFF::attributes_split_char);
+  for (std::vector<std::string>::const_iterator key_value = key_value_pairs.begin(); key_value != key_value_pairs.end(); ++key_value) {
+    if (re_key_value.Match (key_value->c_str())) {
+      std::string key = re_key_value[1];
+      std::vector<std::string> values = Util::split (re_key_value[2], GFF::attributes_list_char);
+      if (values.size())
+	attributes_ordering.push_back (key);
+      for (std::vector<std::string>::const_iterator value = values.begin(); value != values.end(); ++value)
+	attributes_map[key].push_back (*value);
+    }
+  }
+
+}
+
+std::string GFF::get_attributes_string() const {
+
+  std::string s;
+
+  // iterate over keys
+  for (std::vector<std::string>::const_iterator key = attributes_ordering.begin(); key != attributes_ordering.end(); ++key) {
+    std::map<std::string, std::vector<std::string> >::const_iterator key_value = attributes_map.find (*key);
+    // iterate over values
+    if (key_value->second.size())
+      s += *key + GFF::attributes_assign_char;
+    for (std::vector<std::string>::const_iterator value = key_value->second.begin(); value != key_value->second.end(); ++value)
+      s += *value + GFF::attributes_list_char;
+    if (s.length())
+      s.erase (s.end() - 1, s.end()); // strip off final comma
+    s += GFF::attributes_split_char;
+  }
+
+  if (!s.length())
+    s += GFF::undef_char;
+
+  return s;
+
+}
+
+std::string GFF::to_string() const {
+
+  std::stringstream ss;
+
+  ss << (seqid != "" ? seqid : GFF::undef_char) << "\t"
+     << (source != "" ? source : GFF::undef_char) << "\t"
+     << (type != "" ? type : GFF::undef_char) << "\t"
+     << start << "\t" << end << "\t";
+  if (score != -1.) { ss << score; }
+  else { ss << GFF::undef_char; }
+  ss << "\t";
+  ss << strand << "\t";
+  if (phase != 3) { ss << phase; }
+  else { ss << GFF::undef_char; }
+  ss << "\t";
+  ss << get_attributes_string();
+
+  return ss.str();
+
+}
+
+void GFF_database::from_file (const std::string& filename, const bool strip_leading_chr /* = true */) {
+
+  Regexp re_gff ("^[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*\t[^\t]*$");
+
+  // open file
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  cerr << "Reading GFF file '" << filename << "'...";
+
+  // parse file
+  std::string line;
+  while (!filestream.eof()) {
+    getline (filestream, line);
+    Util::chomp (line);
+    // skip lines which don't seem to be in GFF format
+    if (!line.length() || !re_gff.Match (line.c_str()))
+      continue;
+    GFF gff;
+    gff.from_string (line, strip_leading_chr);
+    store_entry (gff);
+    __maxlen = std::max (__maxlen, gff.length());
+  }
+
+  cerr << "done." << endl;
+
+  // clean up
+  filestream.close();
+
+}
+
+void GFF_database::write (std::ostream& o) const {
+
+  for (std::vector<GFF>::const_iterator gff = this->begin(); gff != this->end(); ++gff)
+    o << *gff;
+
+}
+
+void GFF_database::append (const GFF_database& gff_db) {
+
+  for (std::vector<GFF>::const_iterator gff = gff_db.begin(); gff != gff_db.end(); ++gff)
+    this->store_entry (*gff);
+  __maxlen = (gff_db.maxlen() > __maxlen) ? gff_db.maxlen() : __maxlen;
+
+}
+
+void GFF_database::create_unique_ids() {
+
+  if (!size())
+    return;
+
+  size_t width = static_cast<size_t> (log10 (size()));
+  std::string format = "%" + Util::to_string (width) + "d";
+  for (size_t i = 0; i < size(); ++i) {
+    std::string id (width - static_cast<size_t> (log10 (i)), '0');  // hack to format the IDs nicely
+    id += Util::to_string (i);
+    __entries[i].set_id (id);
+  }
+
+}
+
+void GFF_database::sort_entries() {
+
+  std::sort (__entries.begin(), __entries.end(), GFF::GFF_less());
+  __is_sorted = true;
+
+}
+
+GFF GFF_database::find_closest_feature_five_prime (const std::string& chromosome,
+						   unsigned start, unsigned end,
+						   const size_t flanking /* = default_flanking */) const {
+
+  return find_closest_feature (chromosome,
+			       start, end,
+			       flanking,
+			       true); // use_feature_five_prime
+
+}
+
+GFF GFF_database::find_closest_feature_three_prime (const std::string& chromosome,
+						    unsigned start, unsigned end,
+						    const size_t flanking /* = default_flanking */) const {
+
+  return find_closest_feature (chromosome,
+			       start, end,
+			       flanking,
+			       false); // use_feature_five_prime
+
+}
+
+GFF GFF_database::find_closest_feature (const std::string& chromosome,
+					unsigned start, unsigned end,
+					const size_t flanking /* = default_flanking */,
+					const bool use_feature_five_prime /* = true */) const {
+
+  const unsigned centroid = start + (end - start + 1) / 2;
+  start = (start < flanking) ? 0 : start - flanking;
+  end += flanking;
+
+  const GFF_database isects = intersect_genomic_interval (chromosome,
+							  start, end);
+
+  if (!isects.size())
+    return GFF();
+
+  size_t closest_i = 0;
+  size_t closest_distance = std::numeric_limits<size_t>::max();
+  for (size_t i = 0; i < isects.size(); ++i) {
+    const GFF& gff = isects[i];
+    size_t distance = 0;
+    unsigned gff_boundary; // either the 5' or 3' end of the feature, as specified by use_feature_five_prime (0-based)
+    if (gff.strand == '-')
+      gff_boundary = use_feature_five_prime ? gff.end - 1 : gff.start - 1;
+    else
+      gff_boundary = use_feature_five_prime ? gff.start - 1 : gff.end - 1;
+    distance = std::max (centroid, gff_boundary) - std::min (centroid, gff_boundary);
+    if (distance < closest_distance) {
+      closest_i = i;
+      closest_distance = distance;
+    }
+  }
+
+  return isects[closest_i];
+
+}
+
+GFF_database GFF_database::intersect_genomic_interval (const std::string& chromosome,
+						       const unsigned start, const unsigned end) const {
+
+  if (!__is_sorted) {
+    cerr << "ERROR: You must call sort_entries before attepting use this function." << endl;
+    exit (1);
+  }
+
+  GFF_database intersections;
+
+  // check for empty interval or no features
+  if (end < start || !size())
+    return intersections;
+
+  // initialize dummy object for comparison
+  GFF g;
+  g.seqid = chromosome;
+  Util::strip_leading_chr (g.seqid);
+
+  // two intervals 1 and 2 intersect iff
+  // 1.start <= 2.end && 1.end >= 2.start
+  // features in database are 1; query interval is 2
+
+  // check first condition (1.start <= 2.end)
+  g.start = end + 1; // convert to 1-based coordinates
+  g.end = end + 1;
+  std::vector<GFF>::const_iterator gff_upper = std::upper_bound (__entries.begin(),
+								 __entries.end(),
+								 g,
+								 GFF::GFF_less());
+
+  // decrement element to try to get to the upper-bound entry
+  // which (possibly) intersects the query interval
+  if (gff_upper != __entries.begin())
+    --gff_upper;
+
+  // now check that we're on the correct chromosome
+  if (gff_upper->seqid != chromosome)
+    return intersections;
+
+  // check that gff_upper doesn't fall completely to the right of the query interval
+  // if gff_upper is __entries.begin(), then it may!
+  if (gff_upper->start > end)
+    return intersections;
+
+  // now iterate backwards through the sorted entries,
+  // checking the second condition (1.end >= 2.start)
+  // as we go
+  while (gff_upper != __entries.begin() - 1) {
+
+    // if we're no longer on the correct chromosome, then we're done
+    if (gff_upper->seqid != chromosome)
+      break;
+
+    // does it intersect the query interval?
+    if (gff_upper->end >= start)
+      intersections.store_entry (*gff_upper);
+
+    // check whether we're done
+    // (i.e., whether given __maxlen, there cannot be any more features close
+    // enough to the query interval to intersect it)
+    if (gff_upper->start + __maxlen < start)
+      break;
+
+    --gff_upper;
+  }
+
+  // sort nicely
+  intersections.sort_entries();
+
+  return intersections;
+
+}
+
+size_t GFF_database::meanlen() const {
+
+  std::vector<size_t> lengths (size(), 0);
+  for (size_t i = 0; i < size(); ++i)
+    lengths[i] = (*this)[i].length();
+
+  assert (static_cast<size_t> (Mathematics::mean (lengths)) <= maxlen());
+
+  return static_cast<size_t> (Mathematics::mean (lengths));
+
+}
+
+
+size_t GFF_database::medianlen() const {
+
+  std::vector<size_t> lengths (size(), 0);
+  for (size_t i = 0; i < size(); ++i)
+    lengths[i] = (*this)[i].length();
+  std::sort (lengths.begin(), lengths.end());
+  
+  assert (Mathematics::median (lengths) <= maxlen());
+
+  return Mathematics::median (lengths);
+
+}
diff --git a/src/seq/gff.h b/src/seq/gff.h
new file mode 100644
index 0000000..b69a484
--- /dev/null
+++ b/src/seq/gff.h
@@ -0,0 +1,531 @@
+
+/**
+ * \file gff.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef SEQ_GFF_INCLUDED
+#define SEQ_GFF_INCLUDED
+
+#include <cstdlib>
+#include <string>
+#include <iostream>
+#include <vector>
+#include <map>
+
+#include "util/misc.h"
+
+namespace fsa {
+
+  /**
+   * \brief Bare-bones representation of a single GFF entry.
+   *
+   * This class repeatedly assumes that the seqid field holds the
+   * chromosome which the feature is on.
+   * Note that GFF coordinates are always 1-based and fully-closed.
+   * This class stores coordinates for GFF features accordingly
+   * (in contrast to the 0-based indexing used throughout other
+   * parts of this code).
+   * See http://www.sequenceontology.org/gff3.shtml.
+   */
+  struct GFF {
+
+    typedef std::map<std::string, std::vector<std::string>, fsa::Util::String_equal_ci> Attribute_table;  ///< (case-insensitive) map of key, value pairs
+
+  public:
+
+    std::string seqid;        ///< field 0
+    std::string source;       ///< field 1
+    std::string type;
+    unsigned start;
+    unsigned end;
+    float score;
+    char strand;
+    unsigned phase;
+    std::vector<std::string> attributes_ordering;     ///< sorted list of keys in attributes field
+    Attribute_table attributes_map;                   ///< map of key, value pairs
+
+    /**
+     * \brief Default constructor.
+     *
+     * Initializes a feature of length 0 (nonsense coordinates [2, 1]).
+     */
+  GFF()
+  : seqid (""), source (""), type (""),
+      start (2), end (1),
+      score (-1.), strand (GFF::unknown_strand), phase (3)
+    { }
+
+    /**
+     * \brief Constructor.
+     *
+     * Initialize from a (possibly-scored) interval.
+     */
+    GFF (std::string seqid, unsigned start, unsigned end, float score = -1.)
+    : seqid (seqid), source (""), type (""),
+      start (start), end (end),
+      score (score), strand (GFF::unknown_strand), phase (3)
+    { }
+
+    /**
+     * \brief Set start coordinate.
+     *
+     * This deserves an accessor method in order to catch the case of negative start coordinates,
+     * which are unfortunately often found in real annotation files.
+     */
+    void set_start (const int s);
+
+    /**
+     * \brief Length of feature.
+     */
+    inline size_t length() const;
+
+    /**
+     * \brief 5' end of feature.
+     */
+    inline unsigned five_prime_end() const;
+
+    /**
+     * \brief 3' end of feature.
+     */
+    inline unsigned three_prime_end() const;
+
+    /**
+     * \brief Add a (possibly-new) key, value pair to the attributes field.
+     *
+     * If values for the key already exist, then the new value is appended.
+     */
+    template<typename K, typename V>
+      inline void add_value (const K& key, const V& value);
+
+    /**
+     * \brief Set a (possibly-new) key, value pair in the attributes field.
+     *
+     * If values for the key already exist, then all old values are cleared
+     * and replaced with the single new value.
+     */
+    template<typename K, typename V>
+      inline void set_value (const K& key, const V& value);
+
+    /**
+     * \brief Get the values for a key.
+     * \return values, or empty vector if no such key
+     * \see get_value
+     */
+    inline std::vector<std::string> get_values (const std::string& key) const;
+
+    /**
+     * \brief Get the first value for a key.
+     * \return value, or empty string if no such key
+     * \see get_values
+     */
+    inline std::string get_value (const std::string& key) const;
+
+    /**
+     * \brief Set name in attributes field.
+     */
+    inline void set_name (const std::string& name);
+
+    /**
+     * \brief Get name from attributes field.
+     */
+    inline std::string get_name() const;
+
+    /**
+     * \brief Set ID in attributes field.
+     */
+    inline void set_id (const std::string& id);
+
+    /**
+     * \brief Get ID from attributes field.
+     */
+    inline std::string get_id() const;
+
+    /**
+     * \brief Initialize from a GFF-formatted std::string.
+     * \param strip_leading_chr strips the leading 'chr', if present, from the seqid field
+     * possibly holding the chromosome name
+     */
+    void from_string (const std::string& str, const bool strip_leading_chr = true);
+
+    /**
+     * \brief Write to GFF-formatted string.
+     */
+    std::string to_string() const;
+
+    /**
+     * \brief Output operator.
+     *
+     * Prints undef_char for undefined fields.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const GFF& gff) {
+      o << gff.to_string() << endl;
+      return o;
+    }
+
+
+    static const std::string comment_char;                    ///< comment character
+    static const std::string undef_char;                      ///< character for undefined fields
+
+    static const char unknown_strand;                         ///< character for unknown strand
+
+    static const std::string attributes_split_char;           ///< split key, value pairs in attributes field
+    static const std::string attributes_assign_char;          ///< assign value to key in attributes field
+    static const std::string attributes_list_char;            ///< separate values for a single key in attributes field
+
+    static const std::string key_id;                          ///< GFF key for ID
+    static const std::string key_name;                        ///< GFF key for Name
+
+    static const size_t default_flanking;                     ///< \see find_closest_feature
+
+    /**
+     * \brief Function object for binary comparison of GFF objects (sort by seqid, start, end).
+     */
+    struct GFF_less : std::binary_function<GFF, GFF, bool> {
+    public:
+      bool operator() (const GFF& l, const GFF& r) const {
+	if (l.seqid == r.seqid) {
+	  if (l.start == r.start)
+	    return l.end < r.end;
+	  return l.start < r.start;
+	}
+	return l.seqid < r.seqid;
+      }
+    };
+
+
+  protected:
+  
+    /**
+     * \brief Get string for the attributes field.
+     */
+    std::string get_attributes_string() const;
+
+  private:
+
+    /**
+     * \brief Set start coordinate.
+     */
+    inline void set_start (const unsigned s);
+
+    /**
+     * \brief Parse attributes string into key, value pairs.
+     */
+    void parse_attributes_string (const std::string& str);
+
+    static Regexp re_key_value;                                  ///< match key, value pairs in attributes field
+
+  };
+
+  /**
+   * \brief Represent a GFF file.
+   */
+  struct GFF_database {
+
+    /**
+     * \brief Constructor.
+     */
+    GFF_database()
+    : __maxlen (0) { }
+
+    /**
+     * \brief Load from a file.
+     * \param strip_leading_chr strips the leading 'chr', if present, from the seqid field
+     * possibly holding the chromosome name
+     */
+    void from_file (const std::string& filename, const bool strip_leading_chr = true);
+
+    /**
+     * \brief Write.
+     */
+    void write (std::ostream& o) const;
+
+    /**
+     * \brief Store an entry.
+     */
+    inline void store_entry (const GFF& gff);
+
+    /**
+     * \brief Append a GFF_database to this one.
+     */
+    void append (const GFF_database& gff_db);
+
+    /**
+     * \brief Set a (possibly-new) key, value pair in the attributes field for every entry.
+     *
+     * If values for the key already exist, then all old values are cleared
+     * and replaced with the single new value.
+     * \see GFF::set_value
+     */
+    template<typename K, typename V>
+      inline void set_value (const K& key, const V& value);
+
+    /**
+     * \brief Create nicely-formatted numerical IDs for all entries.
+     */
+    void create_unique_ids();
+
+    /**
+     * \brief Sort entries in database.
+     *
+     * This must be called in order for intersect_genomic_interval to work properly.
+     */
+    void sort_entries();
+
+    /**
+     * \brief Find the GFF feature whose 5' end is closest to the passed interval.
+     * \see find_closest_feature
+     */
+    GFF find_closest_feature_five_prime
+    (const std::string& chromosome,
+     unsigned start, unsigned end,
+     const size_t flanking = GFF::default_flanking) const;
+
+    /**
+     * \brief Find the GFF feature whose 3' end is closest to the passed interval.
+     * \see find_closest_feature
+     */
+    GFF find_closest_feature_three_prime
+    (const std::string& chromosome,
+     unsigned start, unsigned end,
+     const size_t flanking = GFF::default_flanking) const;
+
+    /**
+     * \brief Find GFF features which intersect the passed interval.
+     * 
+     * Assumes that the seqid field holds the chromosome
+     * and that the passed interval coordinates are 0-based
+     * and fully closed.  Note the contrast with the 1-based
+     * coordinates used for the GFF features themselves.
+     * Note that the entries MUST be sorted in order for this to function properly.
+     * \see GFF_database::sort_entries
+     */
+    GFF_database intersect_genomic_interval (const std::string& chromosome,
+					     const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Maximum length of entry.
+     */
+    size_t maxlen() const { return __maxlen; }
+
+    /**
+     * \brief Average length of entry.
+     */
+    size_t meanlen() const;
+
+    /**
+     * \brief Median length of entry.
+     */
+    size_t medianlen() const;
+
+    /**
+     * \brief Number of entries.
+     */
+    size_t size() const { return __entries.size(); }
+
+    /**
+     * \brief Data access operator.
+     */
+    const GFF& operator[] (const size_t i) const {
+      assert (i < __entries.size());
+      return __entries[i];
+    }
+
+
+    /**
+     * \brief Get iterator to start of __entries.
+     */
+    std::vector<GFF>::iterator begin() {
+      return __entries.begin();
+    }
+
+    /**
+     * \brief Get const_iterator to start of __entries.
+     */
+    std::vector<GFF>::const_iterator begin() const {
+      return __entries.begin();
+    }
+
+    /**
+     * \brief Get iterator to end of __entries.
+     */
+    std::vector<GFF>::iterator end() {
+      return __entries.end();
+    }
+
+    /**
+     * \brief Get const_iterator to end of __entries.
+     */
+    std::vector<GFF>::const_iterator end() const {
+      return __entries.end();
+    }
+
+  private:
+
+    /**
+     * \brief Find the GFF feature whose 3' or 5' end is closest to the passed interval.
+     *
+     * The closest feature is defined as the feature whose 3' or 5' end
+     * (specified by use_feature_five_prime) is closest to the centroid of the passed interval.
+     * \param flanking search for features within this distance of the requested interval
+     * \param use_feature_five_prime look for features whose 5' end is closest to the passed interval (false for 3')
+     * \return closest feature, or empty feature if no feature within flanking distance
+     * \see intersect_genomic_interval
+     */
+    GFF find_closest_feature (const std::string& chromosome,
+			      unsigned start, unsigned end,
+			      const size_t flanking = GFF::default_flanking,
+			      const bool use_feature_five_prime = true) const;
+
+    std::vector<GFF> __entries; ///< individual GFF entries in database
+
+    size_t __maxlen;            ///< maximum length of an entry in the database
+    bool __is_sorted;           ///< have the entries been sorted?
+
+  };
+
+
+
+  /****************************************
+   * Function definitions.
+   ****************************************/
+
+  inline size_t GFF::length() const {
+    // catch case of 0-length feature
+    if (end < start)
+      return 0;
+    return end - start + 1;
+  }
+
+  inline unsigned GFF::five_prime_end() const {
+    if (strand == '-')
+      return end;
+    return start;
+  }
+
+  inline unsigned GFF::three_prime_end() const {
+    if (strand == '-')
+      return start;
+    return end;
+  }
+
+  inline void GFF::set_start (const unsigned s) {
+    if (s >= 1)
+      start = s;
+    else {
+      cerr << "Setting start coordinate " << s << " to 0." << endl;
+      start = 0;
+    }
+  }
+
+  template<typename K, typename V>
+    inline void GFF::add_value (const K& key, const V& value) {
+
+    // use stringstream to convert key and value to string
+    std::string key_str = Util::to_string (key);
+    std::string value_str = Util::to_string (value);
+
+    // now store
+    // if we already have this key, then append value
+    std::map<std::string, std::vector<std::string> >::iterator value_vector = attributes_map.find (key_str);
+    if (value_vector != attributes_map.end())
+      value_vector->second.push_back (value_str);
+    // else add new key and append value
+    else {
+      attributes_ordering.push_back (key_str);
+      attributes_map[key_str].push_back (value_str);
+    }
+
+  }
+
+  template<typename K, typename V>
+    inline void GFF::set_value (const K& key, const V& value) {
+
+    // use stringstream to convert key and value to string
+    std::string key_str = Util::to_string (key);
+    std::string value_str = Util::to_string (value);
+
+    // now store
+    // if we already have this key, then clear old value and record new value
+    std::map<std::string, std::vector<std::string> >::iterator value_vector = attributes_map.find (key_str);
+    if (value_vector != attributes_map.end()) {
+      value_vector->second.clear();
+      value_vector->second.push_back (value_str);
+    }
+    else {
+      attributes_ordering.push_back (key_str);
+      attributes_map[key_str].push_back (value_str);
+    }
+
+  }
+
+  inline std::vector<std::string> GFF::get_values (const std::string& key) const {
+
+    std::map<std::string, std::vector<std::string> >::const_iterator value_vector = attributes_map.find (key);
+    if (value_vector != attributes_map.end())
+      return value_vector->second;
+    else
+      return std::vector<std::string>();
+
+  }
+
+  inline std::string GFF::get_value (const std::string& key) const {
+
+    std::map<std::string, std::vector<std::string> >::const_iterator value_vector = attributes_map.find (key);
+    if (value_vector != attributes_map.end() && value_vector->second.size())
+      return (value_vector->second)[0];
+    else
+      return "";
+
+  }
+  
+  inline void GFF::set_name (const std::string& name) {
+    set_value (key_name, name);
+  }
+
+  inline std::string GFF::get_name() const {
+    const std::vector<std::string> names = get_values (key_name);
+    if (!names.size())
+      return "";
+    else if (names.size() > 1) {
+      cerr << "Warning: More than one name detected in GFF entry!" << endl
+	   << *this << endl;
+    }
+
+    return names[0];
+  }
+
+  inline void GFF::set_id (const std::string& id) {
+    set_value (key_id, id);
+  }
+
+  inline std::string GFF::get_id() const {
+    const std::vector<std::string> ids = get_values (key_id);
+    if (!ids.size())
+      return "";
+    else if (ids.size() > 1) {
+      cerr << "Warning: More than one ID detected in GFF entry!" << endl
+	   << *this << endl;
+    }
+
+    return ids[0];
+  }
+
+  inline void GFF_database::store_entry (const GFF& gff) {
+
+    __entries.push_back (gff);
+    __maxlen = (gff.end - gff.start + 1 > __maxlen) ? gff.end - gff.start + 1 : __maxlen;
+
+  }
+
+  template<typename K, typename V>
+    inline void GFF_database::set_value (const K& key, const V& value) {
+
+    for (std::vector<GFF>::iterator gff = begin(); gff != end(); ++gff)
+      gff->set_value (key, value);
+  }
+
+}
+
+#endif /* SEQ_GFF_INCLUDED */
diff --git a/src/seq/interval.h b/src/seq/interval.h
new file mode 100644
index 0000000..41d99d3
--- /dev/null
+++ b/src/seq/interval.h
@@ -0,0 +1,130 @@
+
+/**
+ * \file interval.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef SEQ_INTERVAL_INCLUDED
+#define SEQ_INTERVAL_INCLUDED
+
+#include "config.h"
+#include "util/misc.h"
+#include "seq/gff.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a 0-based, fully-closed interval.
+   */
+  struct Interval {
+
+  public:
+
+    Interval()
+    { }
+
+    /**
+     * \brief Constructor.
+     */
+    Interval (const unsigned start, const unsigned end)
+    : start (start), end (end)
+    { }
+
+    unsigned start;           ///< start coordinate of interval
+    unsigned end;             ///< end coordinate of interval
+
+    /**
+     * \brief Length of interval.
+     */
+    size_t length() const;
+
+  };
+
+  /**
+   * \brief Represent a single genomic interval.
+   *
+   * As with all FSA code unless otherwise noted,
+   * this object is intended to use 0-based, fully-closed coordinates.
+   */
+  struct Genomic_interval : public Interval {
+
+  public:
+
+    Genomic_interval() { }
+
+    /**
+     * \brief Constructor.
+     */
+    Genomic_interval (const std::string& genome, const std::string& chromosome,
+		      const unsigned start, const unsigned end, const char strand = GFF::unknown_strand)
+      : Interval (start, end),
+      genome (genome), chromosome (chromosome),
+      strand (strand)
+    { }
+
+    std::string genome;       ///< genome
+    std::string chromosome;   ///< chromosome name
+    char strand;              ///< strand
+
+    /**
+     * \brief Write in a Mercator-like format.
+     */
+    std::string to_string() const {
+      std::string str;
+      return str;
+    }
+
+    /**
+     * \brief Convert Genomic_intervals to GFFs.
+     *
+     * Assumes that the coordinates in intervals are 0-based and converts them to 1-based coordinates.
+     */
+    static GFF_database convert_to_gff_db (const std::vector<Genomic_interval>& intervals);
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Genomic_interval& interval) {
+      o << ((interval.genome == "") ? "." : interval.genome) << '\t' << interval.chromosome + '\t'
+	<< Util::to_string (interval.start) << '\t' << Util::to_string (interval.end) << '\t'
+	<< interval.strand;
+      return o;
+    }
+
+    /**
+     * \brief Compare two Genomic_interval objects based on their starting coordinates.
+     */
+    bool operator< (const Genomic_interval& r) const {
+      if (genome == r.genome) {
+	if (chromosome == r.chromosome)
+	  return (start < r.start);
+	return chromosome < r.chromosome;
+      }
+      return genome < r.genome;
+    }
+
+    /**
+     * \brief Function object for binary comparison of Genomic_interval objects.
+     *
+     * \see Genomic_interval::operator<
+     */
+    struct Genomic_interval_less : std::binary_function<Genomic_interval, Genomic_interval, bool> {
+    public:
+      bool operator() (const Genomic_interval& l, const Genomic_interval& r) const {
+	return l < r;
+      }
+    };
+
+  };
+
+  inline size_t Interval::length() const {
+    // catch case of an empty interval
+    if (start > end)
+      return 0;
+    return end - start + 1;
+  }
+
+}
+
+#endif /* SEQ_INTERVAL_INCLUDED */
diff --git a/src/seq/mercator.cc b/src/seq/mercator.cc
new file mode 100644
index 0000000..39889aa
--- /dev/null
+++ b/src/seq/mercator.cc
@@ -0,0 +1,856 @@
+
+/**
+ * \file mercator.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <algorithm>
+#include <numeric>
+
+#include "seq/mercator.h"
+#include "seq/gff.h"
+
+using namespace fsa;
+
+const std::string Mercator_map::mercator_empty_interval = "NA";
+const Alphabet Mercator_alignment::alphabet = DNA_alphabet();
+
+
+GFF_database Genomic_interval::convert_to_gff_db (const std::vector<Genomic_interval>& intervals) {
+
+  GFF_database gff_db;
+  for (std::vector<Genomic_interval>::const_iterator interval = intervals.begin(); interval != intervals.end(); ++interval)
+    gff_db.store_entry (GFF (interval->chromosome, interval->start + 1, interval->end + 1));  // convert to 1-based coordinates
+
+  return gff_db;
+
+}
+
+Mercator_map::Mercator_map (const std::string& map_dir)
+  : __num_bins (0) {
+
+  from_file (map_dir + "/genomes", map_dir + "/map");
+  init_bin_index(); // this MUST only be done after sorting __intervals...
+
+}
+
+void Mercator_map::from_file (const std::string& genomes_filename,
+			      const std::string& map_filename) {
+
+  cerr << "Reading Mercator map '" << map_filename << "'...";
+
+  std::ifstream filestream;
+
+  // read genomes file
+  filestream.open (genomes_filename.c_str(), std::ifstream::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << genomes_filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  std::string line;
+  while (!filestream.eof()) {
+    getline (filestream, line);
+
+    std::stringstream ss (line);
+    std::string buffer;
+    std::vector<std::string> tokens; // hold whitespace-separated tokens
+    while (ss >> buffer)
+      tokens.push_back (buffer);
+    
+    for (size_t i = 0; i < tokens.size(); ++i) {
+      __genomes.push_back (tokens[i]);
+      __genome_index.insert (std::make_pair (tokens[i], i));
+    }
+
+  }
+  filestream.close();
+
+  // read map file
+  filestream.open (map_filename.c_str(), std::ifstream::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << map_filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  while (!filestream.eof()) {
+    getline (filestream, line);
+    Util::chomp (line);
+    if (!line.length()) { continue; }
+    parse_line (line);
+  }
+  filestream.close();
+
+  // sort entries!  otherwise binary search will fail
+  std::sort (__intervals.begin(), __intervals.end(),
+	     Genomic_interval::Genomic_interval_less());
+
+  cerr << "done." << endl;
+
+}
+
+void Mercator_map::init_bin_index() {
+  
+  // __bin_index[bin][__genome_index[genome]] is the index in __intervals
+  // for a particular (bin, genome) pair
+
+  // initialize stuff
+  // add a dummy entry for the 0th bin (hence bins() + 1)
+  // so that we can index with the actual Mercator bin number
+  // set everything to the nonsense index size() at first
+  __bin_index.assign (bins() + 1, std::vector<size_t> (__genome_index.size(), size()));
+
+  // store indices for each Mercator_interval
+  for (size_t i = 0; i < size(); ++i) {
+    const Mercator_interval& interval = get_interval (i);
+    assert (interval.bin < __bin_index.size());
+    assert (__bin_index[interval.bin].size() > __genome_index[interval.genome]);
+    __bin_index[interval.bin][__genome_index[interval.genome]] = i;
+  }
+  
+}
+
+void Mercator_map::parse_line (const std::string& line) {
+
+  std::stringstream ss (line);
+  std::string buffer;
+  std::vector<std::string> tokens; // hold whitespace-separated tokens
+  while (ss >> buffer)
+    tokens.push_back (buffer);
+
+  // sanity checks
+  if (tokens.size() != 4 * __genomes.size() + 1) {
+    cerr << "WARNING: Can't parse line: '" << line << "'; skipping." << endl;
+    return;
+  }
+
+  // extract bin number for this line of the map file  
+  const unsigned bin = static_cast<unsigned> (atoi (tokens[0].c_str()));
+
+  // keep track of how many bins there are
+  // (remember that bins use 1-based numbering)
+  if (bin > __num_bins)
+    __num_bins = bin;
+
+  for (size_t i = 1; i < tokens.size(); i += 4) {
+
+    // if this is an empty interval,
+    // meaning that this genome has no orthologous sequence in this bin,
+    // then store nothing for this genome
+    if (tokens[i] == mercator_empty_interval)
+      continue;
+
+    const std::string& genome = __genomes[i / 4];
+    std::string& chromosome = tokens[i];
+    Util::strip_leading_chr (chromosome);
+    const unsigned start = atoi (tokens[i + 1].c_str());
+    const unsigned end = atoi (tokens[i + 2].c_str()) - 1; // (remember that Mercator coordinates are half-open, [start, end); convert to fully-closed here)
+    const char strand = (tokens[i + 3])[0];
+
+    assert (end >= start);
+    // strand sanity checks
+    assert (tokens[i + 3].size() == 1);
+    if (strand != '+' && strand != '-') {
+      cerr << "ERROR: Unrecognized strand " << strand << "." << endl;
+      exit (1);
+    }
+
+    // store interval plus indexing from bin -> interval
+    __intervals.push_back (Mercator_interval (bin,
+					      genome, chromosome,
+					      start, end, strand));
+
+  }
+  
+
+}
+
+std::vector<Mercator_interval> Mercator_map::get_mercator_intervals (const std::string& genome) const {
+
+  std::vector<Mercator_interval> gintervals;
+  for (std::vector<Mercator_interval>::const_iterator interval = __intervals.begin(); interval != __intervals.end(); ++interval) {
+    if (interval->genome == genome)
+      gintervals.push_back (*interval);
+  }
+
+  return gintervals;
+
+}
+
+std::string Mercator_map::get_genomes_string() const {
+
+  return Util::join (__genomes, "\t");
+
+}
+
+size_t Mercator_map::find_mercator_interval (const std::string& genome, const std::string& chromosome,
+					     const unsigned start, const unsigned end,
+					     const bool strict /* = true */) const {
+
+  // initialize dummy object for comparison
+  Mercator_interval m;
+  m.genome = genome;
+  m.chromosome = chromosome;
+  Util::strip_leading_chr (m.chromosome);
+  m.start = start;
+  m.end = end;
+
+  std::vector<Mercator_interval>::const_iterator mercator = std::upper_bound (__intervals.begin(),
+									      __intervals.end(),
+									      m,
+									      Genomic_interval::Genomic_interval_less());
+
+  // decrement element to try to get to the Mercator object
+  // which (possibly) contains data for pos
+  // (if element is at beginning, then we have no complete map for sequence,
+  // but we may have a partial map)
+  if (mercator != __intervals.begin())
+    --mercator;
+
+  // now check that we're on the correct genome & chromosome
+  if (mercator->genome != m.genome || mercator->chromosome != m.chromosome)
+    return __intervals.size();
+
+  bool mapped = false;
+
+  // does the complete interval [start, end] fall outside the found mapping?
+  if (start > mercator->end || end < mercator->start)
+    mapped = false;
+
+  // does the complete interval [start, end] fall into the found mapping?
+  else if (start >= mercator->start && end <= mercator->end)
+    mapped = true;
+
+  // if we don't require complete coverage, then look for partial coverage
+  else if (!strict) {
+    if ((start <= mercator->start && end >= mercator->end)
+	|| (start >= mercator->start)
+	|| (end <= mercator->end))
+      mapped = true;
+  }
+
+  if (mapped)
+    return mercator - __intervals.begin();
+
+  // else couldn't map successfully
+  return __intervals.size();
+
+}
+
+std::vector<Genomic_interval> Mercator_map::choose_random_intervals (const std::string& genome,
+								     const size_t length, const size_t num) const {
+
+  // create lists of all intervals for the requested genome
+  std::vector<double> interval_lengths; // weight intervals for genome according to the sequence contained therein
+  std::vector<size_t> interval_indices; // indices for intervals in *this
+  for (size_t i = 0; i < size(); ++i) {
+    if (get_interval (i).genome == genome) {
+      interval_lengths.push_back (get_interval (i).length());
+      interval_indices.push_back (i);
+    }
+  }
+
+  // now normalize properly to get a probability distribution
+  const double norm = accumulate (interval_lengths.begin(), interval_lengths.end(),
+				  0.);
+  for (size_t i = 0; i < interval_lengths.size(); ++i)
+    interval_lengths[i] /= norm;
+
+  // choose intervals!
+  std::vector<Genomic_interval> random_intervals;
+  while (random_intervals.size() < num) {
+
+    // choose a Mercator_interval according to the length of sequence it has for genome
+    const Mercator_interval& interval = get_interval (interval_indices[Util::choose_from_distribution (interval_lengths)]);
+    
+    // choose a point within the Mercator_interval
+    const unsigned centroid = interval.start + Util::rand (interval.length() - 1);
+
+    unsigned random_start = centroid > static_cast<size_t> (length / 2) ? centroid - static_cast<size_t> (length / 2) : 0;
+    if (random_start < interval.start)
+      random_start = interval.start;
+    const unsigned random_end = centroid + static_cast<size_t> (length / 2);
+
+    // use this point as a centroid for a Genomic_interval
+    random_intervals.push_back (Genomic_interval (genome, interval.chromosome,
+						  random_start, random_end, interval.strand));
+
+  }
+
+  return random_intervals;
+
+}
+
+Mercator_alignment::Mercator_alignment (const std::string& map_dir,
+					const std::string& alignments_dir)
+  : Mercator_map (map_dir),
+    __alignments_dir (alignments_dir) {
+
+  __suffixes_stockholm.push_back ("stock");
+  __suffixes_stockholm.push_back ("stk");
+  __suffixes_mfa.push_back ("mfa");
+  __suffixes_mfa.push_back ("fasta");
+  __suffixes_mfa.push_back ("fa");
+  __suffixes_mfa.push_back ("fas");
+
+}
+
+void Mercator_alignment::read_bin_alignment (const unsigned bin,
+					     Stockholm& stockholm_bin,
+					     const bool verbose /* = true */) const {
+
+  std::string filename;
+
+  // look for Stockholm files
+  for (std::vector<std::string>::const_iterator suffix = __suffixes_stockholm.begin(); suffix != __suffixes_stockholm.end(); ++suffix) {
+    filename = __alignments_dir + '/' + Util::to_string (bin) + '.' + *suffix;
+    if (Util::exists_file (filename)) {
+      stockholm_bin.read_stockholm (filename, true, // strict = true
+				    verbose);
+      return;
+    }
+  }
+
+  // look for MFA files
+  for (std::vector<std::string>::const_iterator suffix = __suffixes_mfa.begin(); suffix != __suffixes_mfa.end(); ++suffix) {
+    filename = __alignments_dir + '/' + Util::to_string (bin) + '.' + *suffix;
+    if (Util::exists_file (filename)) {
+      stockholm_bin.read_mfa (filename, true, // strict = true
+			      verbose);
+      return;
+    }
+  }
+
+  // if we're here, then we didn't locate an alignment file
+  cerr << "ERROR: Couldn't locate alignment file of the form '"
+       << bin << ".{stock,stk,mfa,fasta,fa,fas}' in directory '" << __alignments_dir << "/'." << endl;
+  exit (1);
+
+}
+
+Stockholm* Mercator_alignment::slice
+(Sequence_database& seq_db_subalign,
+ const std::string& genome, const std::string& chromosome,
+ char strand,
+ const unsigned start, const unsigned end,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool annotate_homology_information /* = false */,
+ const bool verbose /* = true */) const {
+
+
+  Sequence_database seq_db_bin;
+  Stockholm stockholm_bin (seq_db_bin);
+  unsigned bin;
+
+  return slice (seq_db_subalign,
+		bin,
+		stockholm_bin,
+		genome, chromosome,
+		strand,
+		start, end,
+		lazy, truncate_ok,
+		annotate_homology_information,
+		verbose);
+
+}
+
+Stockholm* Mercator_alignment::slice
+(Sequence_database& seq_db_subalign,
+ unsigned& bin,
+ Stockholm& stockholm_bin,
+ const std::string& genome, const std::string& chromosome,
+ char strand,
+ const unsigned start, const unsigned end,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool annotate_homology_information /* = false */,
+ const bool verbose /* = true */) const {
+
+  // sanity check on strand
+  if (strand != '+' && strand != '-' && verbose) {
+    cerr << "WARNING: Unknown strand '" << strand << "'; assuming + strand." << endl;
+    strand = '+';
+  }
+
+  // map from genomic to alignment coordinates
+  const Interval align_interval = map_genomic_to_align (genome, chromosome,
+							start, end,
+							bin,
+							stockholm_bin,
+							lazy, truncate_ok,
+							verbose);
+  // catch the case of an empty interval, meaning that no mapping could be found
+  if (align_interval.length() == 0) {
+    seq_db_subalign.clear();
+    return new Stockholm (seq_db_subalign);
+  }  
+
+  const unsigned start_align = align_interval.start;
+  const unsigned end_align = align_interval.end;
+
+  // pull out the subalignment
+  Stockholm* subalignment = stockholm_bin.subalignment (seq_db_subalign,
+							start_align, end_align);
+
+  // revcomp if necessary
+  const size_t idx = find_mercator_interval (genome, chromosome,
+					     start, end,
+					     !truncate_ok); // not strict if truncate_ok
+  const Mercator_interval& interval = get_interval (idx);
+  if (strand != interval.strand)
+    subalignment->revcomp (Mercator_alignment::alphabet);
+
+  // show homology information for all seqs if desired
+  // (i.e., what subsequences are in the subalignment)
+  if (annotate_homology_information) {
+
+    // has the subaligment been reverse-complemented w.r.t. the raw Mercator mapping?
+    const bool was_rc = (strand != interval.strand);
+
+    for (size_t r = 0; r < stockholm_bin.rows(); ++r) {
+
+      const std::string& genome2 = stockholm_bin.get_row_name (r);
+      
+      GFF gff;
+
+      // if "source" genome, annotate directly
+      if (genome2 == genome) {
+
+	gff.seqid = chromosome;
+	Util::strip_leading_chr (gff.seqid); // for consistency with rest of sequences
+	gff.start = start + 1;               // convert to 1-based coordinates (b/c GFF)
+	gff.end = end + 1;
+	gff.strand = strand;
+
+      }
+
+      // else find the homologous sequence to annotate with
+      else {
+
+	// find homologous interval
+	Genomic_interval interval2 = find_homologous_interval (bin,
+							       stockholm_bin,
+							       genome, chromosome,
+							       start, end,
+							       genome2,
+							       lazy, truncate_ok,
+							       verbose);
+
+	// figure out what strand genome2 is on in the subalignment
+	if (was_rc)
+	  Sequence::complement_strand (interval2.strand);
+
+	// annotate
+	gff.seqid = interval2.chromosome;
+	gff.start = interval2.start + 1; // convert to 1-based coordinates (b/c GFF)
+	gff.end = interval2.end + 1;
+	gff.strand = interval2.strand;
+
+      }
+      
+      // annotate!
+      subalignment->set_gs_annot (genome2, Stockholm::gff_annotation, gff.to_string());
+
+    }
+
+  }
+
+  return subalignment;
+
+}
+
+
+Genomic_interval Mercator_alignment::find_homologous_interval
+(const std::string& genome_from, const std::string& chromosome_from,
+ const unsigned start_from, const unsigned end_from,
+ const std::string& genome_to,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool verbose /* = true */) const {
+
+  Sequence_database seq_db_bin;
+  Stockholm stockholm_bin (seq_db_bin);
+  unsigned bin;
+
+  return find_homologous_interval (bin,
+				   stockholm_bin,
+				   genome_from, chromosome_from,
+				   start_from, end_from,
+				   genome_to,
+				   lazy, truncate_ok,
+				   verbose);  
+
+}
+
+Genomic_interval Mercator_alignment::find_homologous_interval 
+(unsigned& bin,
+ Stockholm& stockholm_bin,
+ const std::string& genome_from, const std::string& chromosome_from,
+ const unsigned start_from, const unsigned end_from,
+ const std::string& genome_to,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool verbose /* = true */) const {
+
+  // check that these are valid genomes
+  if (!exists_genome (genome_from)) {
+    cerr << "ERROR: No information for genome '" << genome_from << "'; valid genomes are:" << endl
+	 << get_genomes_string() << endl;
+    exit (1);
+  }
+  if (!exists_genome (genome_to)) {
+    cerr << "ERROR: No information for genome '" << genome_to << "'; valid genomes are:" << endl
+	 << get_genomes_string() << endl;
+    exit (1);
+  }
+
+  // try to map the interval
+  const size_t idx_from = find_mercator_interval (genome_from, chromosome_from,
+						  start_from, end_from,
+						  !truncate_ok);
+  if (idx_from == size()) {
+    if (!lazy) {
+      cerr << "ERROR: No mapping exists for: " << genome_from << '\t' << chromosome_from << '\t'
+	   << start_from << '\t' << end_from << endl;
+      exit (1);
+    } else {
+      cerr << "WARNING: No mapping exists for: " << genome_from << '\t' << chromosome_from << '\t'
+	   << start_from << '\t' << end_from << endl;
+      return Genomic_interval();
+    }
+  }
+  const Mercator_interval& interval_from = get_interval (idx_from);
+  const unsigned this_bin = interval_from.bin;
+
+  // find the bin for genome_map_to
+  Mercator_interval mercator_interval_to = get_interval_by_bin (this_bin, genome_to);
+
+  // now extract the homologous interval using the base-level alignment
+
+  // if this_bin isn't the passed alignment,
+  // then find and open the appropriate bin
+  if (bin != this_bin) {
+    // find & read alignment
+    read_bin_alignment (this_bin, stockholm_bin, verbose);
+    // record current bin
+    bin = this_bin;
+  }
+
+
+  // map the sequence interval using the alignment
+  // (remember to convert coordinates w.r.t. Mercator_interval)
+
+  // first calculate the sequence coordinate offsets w.r.t. the interval_from alignment
+  // the conditionals truncate the requested sequence as appropriate if it's not entirely
+  // contained within the interval_from alignment
+  unsigned start_from_seq, end_from_seq;
+  // if Mercator_interval is on - strand, then need to flip the interval and calculate w.r.t.
+  // the end of the mapped Mercator_interval (because the sequence in the alignment has
+  // been reverse-complemented, so it "begins" at the end of the Mercator_interval)
+  if (interval_from.strand == '-') {
+    start_from_seq = static_cast<int> (interval_from.end - end_from) >= 0
+      ? interval_from.end - end_from
+      : 0;
+    end_from_seq = static_cast<int> (interval_from.end - start_from) >= 0
+      ? interval_from.end - start_from
+      : interval_from.end - interval_from.start;
+  }
+  // if Mercator_interval is on + strand, then just subtract offsets
+  else {
+    start_from_seq = static_cast<int> (start_from - interval_from.start) >= 0
+      ? start_from - interval_from.start
+      : 0;
+    end_from_seq = static_cast<int> (interval_from.end - end_from) >= 0
+      ? end_from - interval_from.start
+      : interval_from.end - interval_from.start;
+  }
+
+  // warn if we've truncated
+  if (static_cast<int> (start_from - interval_from.start) < 0 || static_cast<int> (interval_from.end - end_from) < 0
+      || static_cast<int> (interval_from.end - end_from) < 0 || static_cast<int> (interval_from.end - start_from) < 0)
+    cerr << "WARNING: Truncating alignment slice to mapped sequence: " << genome_from << '\t' << chromosome_from << '\t'
+	 << start_from << '\t' << end_from << '\t' << interval_from.strand << endl;
+
+  // now map to coordinates in the other sequence
+  const Interval interval_to = stockholm_bin.map_seq_to_seq (genome_from, start_from_seq, end_from_seq,
+							     genome_to);
+
+  // check for the case of no sequence (empty interval) in the "to" genome subsequence
+  // Alignment::map_seq_to_seq returns (1, 0) if no sequence
+  if (interval_to.end < interval_to.start)
+    return Genomic_interval();
+
+  // now convert mercator_interval_to to hold the base-level mapping
+  // else add offsets w.r.t. end of the Mercator_interval
+  if (mercator_interval_to.strand == '-') {
+    mercator_interval_to.start = mercator_interval_to.end - interval_to.end;
+    mercator_interval_to.end = mercator_interval_to.end - interval_to.start;
+  }
+  // if Mercator_interval is on + strand, then just add offsets back on
+  else {
+    mercator_interval_to.end = mercator_interval_to.start + interval_to.end;
+    mercator_interval_to.start += interval_to.start;
+  }
+  // (NB: both of these transformations are derived by 
+  // inverting the ones used above to set {start,end}_from_seq)
+
+  return mercator_interval_to;
+
+}
+
+GFF_database Mercator_alignment::map_gff_database
+(const std::string& genome_from, const std::string& genome_to,
+ const GFF_database& gff_db_from,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool verbose /* = true */,
+ const bool force_entry /* = false */) const {
+
+  GFF_database gff_db_to;
+
+  // initialize persistent sequence & alignment information for current bin
+  Sequence_database seq_db_bin;
+  Stockholm stockholm_bin (seq_db_bin);
+  unsigned bin = 0; // initialize to dummy 0 value
+
+  // iterate through GFF
+  for (std::vector<GFF>::const_iterator gff_from = gff_db_from.begin(); gff_from != gff_db_from.end(); ++gff_from) {
+    
+    // use the alignment to find the homologous interval
+    Genomic_interval region_target = find_homologous_interval (bin,
+							       stockholm_bin,
+							       genome_from, gff_from->seqid,
+							       gff_from->start - 1, gff_from->end - 1, // convert to 0-based coordinates
+							       genome_to,
+							       lazy, truncate_ok,
+							       verbose);
+
+    // check that it was mapped successfully
+    // (Mercator_alignment::find_homologous_interval returns an empty value
+    // if it wasn't or if homologous subsequence is empty)
+    // NB no need to enforce lazy here, b/c find_homologous_interval does this for us
+    if (region_target.genome == "") {
+      cerr << "WARNING: No homologous sequence found (all gaps) in " << genome_to << " for: " << genome_from << '\t' << gff_from->seqid << '\t'
+	   << gff_from->start - 1 << '\t' << gff_from->end - 1 << '\t' << gff_from->strand << endl;
+      // store an empty entry if requested
+      if (force_entry) {
+	GFF gff_to;
+	gff_to.source = std::string (PACKAGE) + '\\' + gff_from->source;
+	gff_to.type = gff_from->type;
+	gff_to.start = 1; // nonsense values for start and end: [1, 0]
+	gff_to.end = 0;
+	gff_db_to.store_entry (gff_to);
+      }
+      continue;
+    }
+
+    // get the Mercator_interval for the source
+    const size_t idx_source = find_mercator_interval (genome_from, gff_from->seqid,
+						      gff_from->start - 1, gff_from->end - 1, // convert to 0-based coordinates
+						      !truncate_ok);
+    assert (idx_source < size());
+    const Mercator_interval& interval_source = get_interval (idx_source);
+
+    // use the source interval to determine whether the source feature was 
+    // reverse-complemented w.r.t. the strand in the Mercator_interval
+    // if it was, then the target feature will also be reverse-complemented
+    // w.r.t. the strand in the Mercator_interval
+    const bool is_rc = (interval_source.strand != gff_from->strand);
+
+    GFF gff_to;
+    gff_to.seqid = region_target.chromosome;
+    gff_to.source = std::string (PACKAGE) + '\\' +  gff_from->source;
+    gff_to.type = gff_from->type;
+    gff_to.start = region_target.start + 1; // convert back to 1-based coordinates
+    gff_to.end = region_target.end + 1;
+    if (gff_from->strand == GFF::unknown_strand)   // if the source feature had no annotated strand, then do the same for the target feature
+      gff_to.strand = GFF::unknown_strand;
+    else {                           // otherwise set the target strand appropriately using the homology mapping implied by the alignment
+      gff_to.strand = region_target.strand;
+      if (is_rc)
+	Sequence::complement_strand (gff_to.strand);
+    }
+    for (std::vector<std::string>::const_iterator key = gff_from->attributes_ordering.begin(); key != gff_from->attributes_ordering.end(); ++key) {
+      const std::vector<std::string>& values = gff_from->attributes_map.find (*key)->second;
+      for (std::vector<std::string>::const_iterator value = values.begin(); value != values.end(); ++value) {
+	// watch for case of quoted fields
+	if ((*value)[0] == '\"' && (*value)[value->length() - 1] == '\"') {
+	  gff_to.add_value (*key, '\"' + genome_to + '\\'+ std::string (*value, 1, value->length() - 1));
+	} else if ((*value)[0] == '\'' && (*value)[value->length() - 1] == '\'') {
+	  gff_to.add_value (*key, '\'' + genome_to + '\\'+ std::string (*value, 1, value->length() - 1));
+	} else {
+	  gff_to.add_value (*key, genome_to + '\\'+ *value);
+	}
+      }
+    }
+
+    gff_db_to.store_entry (gff_to);
+
+  }
+
+  return gff_db_to;
+
+}
+
+Genomic_interval Mercator_alignment::map_align_to_genomic
+(const unsigned bin,
+ const Stockholm& stockholm_bin,
+ const std::string& genome,
+ const unsigned start, const unsigned end,
+ const bool rc /* = false */) const {
+
+  // check sane
+  assert (start <= end);
+  assert (end < stockholm_bin.columns());
+  assert (exists_genome (genome));
+
+  // find the Mercator_interval describing the sequence for genome in this bin
+  // check whether the passed alignment of the bin sequence has been reverse-complemented:
+  // if so, then we need to flip the strand of Mercator_interval for this bin
+  Mercator_interval mercator_interval = get_interval_by_bin (bin, genome);
+  if (rc)
+    Sequence::complement_strand (mercator_interval.strand);
+
+  // map column indices to sequence coordinates (w.r.t. stockholm_bin)
+  const Interval align_seq_coords = stockholm_bin.map_align_to_seq (genome,
+								    start, end);
+
+  // now map from sequence coordinates within the alignment of the bin to genomic coordinates
+  Genomic_interval genomic_interval;
+  genomic_interval.genome = genome;
+  genomic_interval.chromosome = mercator_interval.chromosome;
+  genomic_interval.strand = mercator_interval.strand;
+
+  // check for the case of an empty interval
+  if (align_seq_coords.start > align_seq_coords.end) {
+    genomic_interval.start = 1;
+    genomic_interval.end = 0;
+    return genomic_interval;
+  }
+
+  // tricky if on the - strand
+  // (sequence has been reversed, so we need to count from right to left)
+  if (genomic_interval.strand == '-') {
+    genomic_interval.start = mercator_interval.end - align_seq_coords.end;
+    genomic_interval.end = mercator_interval.end - align_seq_coords.start;
+  }
+  // ...easier if aligned sequence is on the + strand
+  else {
+    genomic_interval.start = mercator_interval.start + align_seq_coords.start;
+    genomic_interval.end = mercator_interval.start + align_seq_coords.end;
+  }
+  // Note that the above calculations for the - strand are equivalent to:
+  //	genomic_coords.start = (seqlength - 1) - align_seq_coords.end + mercator_interval.start;
+  //	genomic_coords.end = (seqlength - 1) - align_seq_coords.start + mercator_interval.start;
+  // where seqlength is the ungapped sequence length of the bin.
+
+  return genomic_interval;
+
+}
+
+Interval Mercator_alignment::map_genomic_to_align
+(const std::string& genome, const std::string& chromosome,
+ const unsigned start, const unsigned end,
+ unsigned& bin,
+ Stockholm& stockholm_bin,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool verbose /* = true */) const {
+
+  // map to sequence coordinates within the bin
+  const Interval bin_seq_coords = map_genomic_to_bin_seq (genome, chromosome,
+							  start, end,
+							  bin,
+							  stockholm_bin,
+							  lazy, truncate_ok,
+							  verbose);
+
+  // catch the case of a 0-lenth interval
+  if (bin_seq_coords.length() == 0)
+    return Interval (1, 0);
+
+  // then map to alignment coordinates
+  const unsigned start_align = stockholm_bin.map_seq_to_align (genome, bin_seq_coords.start);
+  const unsigned end_align = stockholm_bin.map_seq_to_align (genome, bin_seq_coords.end);
+
+  return Interval (start_align, end_align);
+
+}
+
+Interval Mercator_alignment::map_genomic_to_bin_seq
+(const std::string& genome, const std::string& chromosome,
+ const unsigned start, const unsigned end,
+ unsigned& bin,
+ Stockholm& stockholm_bin,
+ const bool lazy /* = false */, const bool truncate_ok /* = false */,
+ const bool verbose /* = true */) const {
+
+  // check that this is a valid genome
+  if (!exists_genome (genome)) {
+    cerr << "ERROR: No information for genome '" << genome << "'; valid genomes are:" << endl
+	 << get_genomes_string() << endl;
+    exit (1);
+  }
+
+  // try to map the interval
+  const size_t idx = find_mercator_interval (genome, chromosome,
+					     start, end,
+					     !truncate_ok); // not strict if truncate_ok
+  if (idx == size()) {
+    if (!lazy) {
+      cerr << "ERROR: No mapping exists for: " << genome << '\t' << chromosome << '\t'
+	   << start << '\t' << end << endl;
+      exit (1);
+    } else {
+      cerr << "WARNING: No mapping exists for: " << genome << '\t' << chromosome << '\t'
+	   << start << '\t' << end << endl;
+      return Interval (1, 0);
+    }
+  }
+  const Mercator_interval& interval = get_interval (idx);
+  const unsigned this_bin = interval.bin;
+
+  // if this_bin isn't the passed alignment,
+  // then find and open the appropriate bin
+  if (bin != this_bin) {
+    // find & read alignment
+    read_bin_alignment (this_bin, stockholm_bin, verbose);
+    // record current bin
+    bin = this_bin;
+  }
+
+  // map sequence to alignment coordinates
+
+  // first calculate the sequence coordinates within the interval alignment
+  // (i.e., subtract off the offsets for the mapped Mercator_interval)
+  // the conditionals truncate the requested sequence as appropriate if it's not entirely
+  // contained within the interval alignment
+  unsigned start_seq, end_seq;
+
+  // if Mercator_interval is on - strand, then need to flip the interval and calculate w.r.t.
+  // the end of the mapped Mercator_interval (because the sequence in the alignment has
+  // been reverse-complemented, so it "begins" at the end of the Mercator_interval)
+  // (very tricky...)
+  if (interval.strand == '-') {
+    start_seq = static_cast<int> (interval.end - end) >= 0
+      ? interval.end - end
+      : 0;
+    end_seq = static_cast<int> (interval.end - start) >= 0
+      ? interval.end - start
+      : interval.end - interval.start;
+  }
+  // if Mercator_interval is on + strand, then just subtract offsets
+  else {
+    start_seq = static_cast<int> (start - interval.start) >= 0
+      ? start - interval.start
+      : 0;
+    end_seq = static_cast<int> (interval.end - end) >= 0
+      ? end - interval.start
+      : interval.end - interval.start;
+  }
+  
+  // warn if we've truncated
+  if (static_cast<int> (start - interval.start) < 0 || static_cast<int> (interval.end - end) < 0
+      || static_cast<int> (interval.end - end) < 0 || static_cast<int> (interval.end - start) < 0)
+    cerr << "WARNING: Truncating alignment slice to mapped sequence: " << genome << '\t' << chromosome << '\t'
+	 << start << '\t' << end << endl;
+  
+  return Interval (start_seq, end_seq);
+
+}
diff --git a/src/seq/mercator.h b/src/seq/mercator.h
new file mode 100644
index 0000000..318854f
--- /dev/null
+++ b/src/seq/mercator.h
@@ -0,0 +1,465 @@
+
+/**
+ * \file mercator.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef SEQ_MERCATOR_INCLUDED
+#define SEQ_MERCATOR_INCLUDED
+
+#include "config.h"
+#include "util/regexp.h"
+#include "seq/alignment.h"
+#include "seq/gff.h"
+#include "seq/interval.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a single genomic interval in a mapping.
+   *
+   * Uses 0-based, fully-closed coordinates.
+   * Note that this is NOT the same as Mercator itself,
+   * which uses 0-based, half-open [start, end) coordinates.
+   * \see Mercator_map
+   */
+  struct Mercator_interval : public Genomic_interval {
+
+  public:
+
+    Mercator_interval() { }
+
+    /**
+     * \brief Constructor.
+     */
+    Mercator_interval (unsigned bin,
+		       const std::string& genome, const std::string& chromosome,
+		       const unsigned start, const unsigned end, char strand)
+      : Genomic_interval (genome, chromosome,
+			  start, end, strand),
+      bin (bin)
+    { }
+
+    unsigned bin;   ///< Mercator bin number
+
+    /**
+     * \brief Write in Mercator format.
+     */
+    std::string to_string() const {
+      std::string str;
+      str = chromosome + '\t'
+	+ Util::to_string (start) + '\t' + Util::to_string (end) + '\t'
+	+ strand;
+      return str;
+    }
+
+    /**
+     * \brief Output operator.
+     */
+    friend std::ostream& operator<< (std::ostream& o, const Mercator_interval& interval) {
+      o << interval.bin << '\t'
+<< interval.genome << '\t'
+	<< interval.to_string() << endl;
+      return o;
+    }
+
+    // explicitly import less_than
+    using Genomic_interval::operator<;
+
+  };
+
+  /**
+   * \brief Represent a Mercator mapping between genomes.
+   *
+   * Uses 0-based, fully-closed coordinates.
+   * Mercator uses 0-based, half-open [start, end)
+   * coordinates; the conversion is done internally by this class.
+   * If present, strips off the leading 'chr' frequently prepended 
+   * to chromosome names (this helps to prevent frustrations due
+   * to, e.g., having 'chr' prepended to the chromosomes in the map
+   * file but not when calling slice.
+   */
+  struct Mercator_map {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     * \param map_dir directory for Mercator genomes and map files
+     */
+    Mercator_map (const std::string& map_dir);
+
+    /**
+     * \brief Find the Mercator_interval for a particular genomic sequence.
+     *
+     * Require that the sequence is completely or partially contained
+     * in interval.
+     * Uses a binary search over all Mercator_interval objects.
+     * \param strict interval must be completely contained within Mercator_interval
+     * \return index of Mercator_interval in __intervals, or size() if it can't be found
+     */
+    size_t find_mercator_interval (const std::string& genome, const std::string& chromosome,
+				   const unsigned start, const unsigned end,
+				   const bool strict = true) const;
+
+    /**
+     * \brief Choose random Genomic_intervals from sequence in a Mercator_map.
+     *
+     * Chosen according to a uniform distribution over sequences:
+     * - choose a Mercator_interval according to the length of sequence it has for genome
+     * - choose a point within the Mercator_interval
+     * - use this point as a centroid for a Genomic_interval
+     *   (note that the Genomic_interval will NOT be truncated, even if it does not
+     *   fit within the containing Mercator_interval)
+     * \param genome genome to select intervals for
+     * \param length length of desired intervals
+     * \param num number of intervals desired
+     */
+    std::vector<Genomic_interval> choose_random_intervals (const std::string& genome,
+							   const size_t length, const size_t num) const;
+
+    /**
+     * \brief Get a Mercator_interval by its index.
+     * \see find_mercator_interval
+     */
+    const Mercator_interval& get_interval (const size_t idx) const {
+      return __intervals[idx];
+    }
+
+    /**
+     * \brief Number of intervals.
+     * 
+     * This is equal to (# of bins) * (# of genomes).
+     */
+    size_t size() const { return __intervals.size(); }
+
+    /**
+     * \brief Number of bins.
+     */
+    size_t bins() const { return __num_bins; }
+
+    /**
+     * \brief Get all Mercator_intervals for a particular genome.
+     */
+    std::vector<Mercator_interval> get_mercator_intervals (const std::string& genome) const;
+
+    /**
+     * \brief Do we have information for a particular genome?
+     */
+    bool exists_genome (const std::string& genome) const {
+      return __genome_index.find (genome) != __genome_index.end();
+    }
+
+    /**
+     * \brief Get the list of genomes in the Mercator file format.
+     */
+    std::string get_genomes_string() const;
+
+    /**
+     * \brief Get the Mercator_interval for a particular bin and genome.     
+     */
+    inline const Mercator_interval& get_interval_by_bin (const unsigned bin, const std::string& genome) const;
+
+
+  protected:
+
+    /**
+     * \brief Get indices in __intervals for all Mercator_interval objects for a particular bin.
+     */
+    inline const std::vector<size_t>& get_intervals_by_bin (const unsigned bin) const;
+
+    /**
+     * \brief Get iterator to start of __intervals.
+     */
+    std::vector<Mercator_interval>::const_iterator begin() const {
+      return __intervals.begin();
+    }
+
+    /**
+     * \brief Get iterator to end of __intervals.
+     */
+    std::vector<Mercator_interval>::const_iterator end() const {
+      return __intervals.end();
+    }
+
+
+  private:
+
+    /**
+     * \brief Initialize from Mercator file.
+     * \see parse_line
+     */
+    void from_file (const std::string& genomes_filename,
+		    const std::string& map_filename);
+
+    /**
+     * \brief Initialize map from bins to Mercator_interval objects.
+     *
+     * Must be called after from_file.
+     */
+    void init_bin_index();
+
+    /**
+     * \brief Parse single line of Mercator map file.
+     */
+    void parse_line (const std::string& line);
+
+
+    std::vector<std::string> __genomes;             ///< map from numeric genome index to name (ordered list of genomes)
+    std::map<std::string, size_t> __genome_index;   ///< map from a genome to its numeric index in the map file
+
+    size_t __num_bins;                              ///< number of bins in the map
+    std::vector<Mercator_interval> __intervals;     ///< Mercator_interval entries
+
+    /**
+     * \brief Map from a bin and genome to the index for the corresponding Mercator_interval objects in __intervals.
+     * The appropriate index in __intervals is accessed as __bin_index[bin][__genome_index[genome]].
+     * If there is no such index (i.e., for a particular bin there is no associated interval for some genome,
+     * then the index will be the nonsense index size().
+     */
+    std::vector<std::vector<size_t> > __bin_index;
+
+  private:
+
+    static const std::string mercator_empty_interval; ///< string designating no information for a particular genome in a map file
+
+  };
+
+  /**
+   * \brief 
+   *
+   * Assumes a DNA alphabet, but DOES NOT check or enforce this!
+   */
+  struct Mercator_alignment : public Mercator_map {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     * \param map_dir directory for Mercator genomes and map files
+     * \param alignments_dir directory for alignment files
+     */
+    Mercator_alignment (const std::string& map_dir,
+			const std::string& alignments_dir);
+
+    /**
+     * \brief Find and read the alignment file for a particular bin.
+     * \param bin Mercator bin
+     * \param stockholm_bin read alignment into this
+     */
+    void read_bin_alignment (const unsigned bin,
+			     Stockholm& stockholm_bin,
+			     const bool verbose = true) const;
+
+    /**
+     * \brief Get the subalignment for a particular genomic sequence.
+     *
+     * If requested, will return a truncated subalignment if only
+     * part of the sequence can be mapped (rather than returning nothing).
+     * If the strand is -, then the returned subalignment
+     * will be reverse-complemented.
+     * \param seq_db_subalign Sequence_database hold subalignment sequences
+     * \param lazy warn, instead of die, if the interval can't be mapped
+     * \param truncate_ok if the sequence can't all be mapped, then return a truncated subalignment
+     * \param annotate_homology_information mark up alignment with homology information for sequences (in GFF format)
+     * \return subalignment, or empty alignment if can't be found
+     * \see subalignment
+     */
+    Stockholm* slice (Sequence_database& seq_db_subalign,
+		      const std::string& genome, const std::string& chromosome,
+		      char strand,
+		      const unsigned start, const unsigned end,
+		      const bool lazy = false, const bool truncate_ok = false,
+		      const bool annotate_homology_information = false,
+		      const bool verbose = true) const;
+
+    /**
+     * \brief Get the subalignment for a particular genomic sequence.
+     *
+     * If requested, will return a truncated subalignment if only
+     * part of the sequence can be mapped (rather than returning nothing).
+     * If the strand is -, then the returned subalignment
+     * will be reverse-complemented (i.e., if the requested strand differs from
+     * the strand specified in the Mercator mapping, then the alignment will 
+     * be reverse-complemented w.r.t. the Mercator multiple alignment).
+     * If the strand is unknown, then the + strand is assumed.
+     * Looks for an alignment of the form 'bin.{stock,stk,mfa,fasta,fa,fas}'
+     * in __alignments_dir.
+     * This method populates Sequence_database and Stockholm objects
+     * for both the entire bin alignment as well as the requested subalignment.
+     * Saving on overhead associated with reading in the bin alignment,
+     * this allows for efficient extraction of multiple sequences
+     * from the same bin.
+     * \param subalign_seq_db hold subalignment sequences
+     * \param bin Mercator bin which stockholm_bin holds the alignment for (set to 0 for dummy/unknown value)
+     * \param stockholm_bin hold Stockholm alignment for bin
+     * \param lazy warn, instead of die, if the interval can't be mapped
+     * \param truncate if the sequence can't all be mapped, then return a truncated subalignment
+     * \param annotate_homology_information mark up alignment with homology information for sequences (in GFF format)
+     * \see map_genomic_to_align
+     * \return subalignment, or empty alignment if can't be found
+     */
+    Stockholm* slice (Sequence_database& seq_db_subalign,
+		      unsigned& bin,
+		      Stockholm& stockholm_bin,
+		      const std::string& genome, const std::string& chromosome,
+		      char strand,
+		      const unsigned start, const unsigned end,
+		      const bool lazy = false, const bool truncate_ok = false,
+		      const bool annotate_homology_information = false,
+		      const bool verbose = true) const;
+
+    /**
+     * \brief Find the homologous interval according to the Mercator mapping and corresponding multiple alignment.
+     *
+     * The returned Mercator_interval DOES NOT correspond to an actual entry
+     * in the Mercator map file, but rather a sub-interval thereof.
+     * Maps genome_from -> genome_to.
+     * As always, coordinates are 0-based and fully-closed.
+     * \param genome_from genome with the specified sequence interval
+     * \param genome_to genome to find the homologous interval in
+     * \param lazy warn, instead of die, if the interval can't be mapped
+     * \param truncate if the sequence can't all be mapped, then use a truncated subalignment
+     * \return Mercator_interval specifying the homologous interval; returned value is empty if it can't be mapped or if empty subsequence (all gaps in alignment)
+     */
+    Genomic_interval find_homologous_interval
+      (const std::string& genome_from, const std::string& chromosome_from,
+       const unsigned start_from, const unsigned end_from,
+       const std::string& genome_to,
+       const bool lazy = false, const bool truncate_ok = false,
+       const bool verbose = true) const;
+
+    /**
+     * \brief Find the homologous interval according to the Mercator mapping and corresponding multiple alignment.
+     *
+     * The returned Mercator_interval DOES NOT correspond to an actual entry
+     * in the Mercator map file, but rather a sub-interval thereof.
+     * Maps genome_from -> genome_to.
+     * This method populates Sequence_database and Stockholm objects
+     * for the entire bin alignment.
+     * Saving on overhead associated with reading in the bin alignment,
+     * this allows for efficient multiple queries from the same bin.
+     * As always, coordinates are 0-based and fully-closed.
+     * \param genome_from genome with the specified sequence interval
+     * \param genome_to genome to find the homologous interval in
+     * \param lazy warn, instead of die, if the interval can't be mapped
+     * \param truncate if the sequence can't all be mapped, then use a truncated subalignment
+     * \return Mercator_interval specifying the homologous interval; returned value is empty if it can't be mapped or if empty subsequence (all gaps in alignment)
+     */
+    Genomic_interval find_homologous_interval
+      (unsigned& bin,
+       Stockholm& stockholm_bin,
+       const std::string& genome_from, const std::string& chromosome_from,
+       const unsigned start_from, const unsigned end_from,
+       const std::string& genome_to,
+       const bool lazy = false, const bool truncate_ok = false,
+       const bool verbose = true) const;
+
+    /**
+     * \brief Map the features in a GFF database to another genome.
+     *
+     * \param lazy warn, instead of die, if the interval can't be mapped
+     * \param truncate_ok if the sequence can't all be mapped, then return a truncated subalignment
+     * \param force_entry if a feature can't be mapped, then add an empty entry to the GFF file (rather than skipping it entirely)
+     */
+    GFF_database map_gff_database
+      (const std::string& genome_from, const std::string& genome_to,
+       const GFF_database& gff_db_from,
+       const bool lazy = false, const bool truncate_ok = false,
+       const bool verbose = true,
+       const bool force_entry = false) const;
+
+    /**
+     * \brief Map alignment coordinates (w.r.t. the alignment of a particular Mercator bin)
+     * to genomic coordinates for a genome.
+     *
+     * \param bin bin which we have the alignment for
+     * \param stockholm_bin the alignment of the bin
+     * \param genome genome to map coordinates for
+     * \param start 0-based column start coordinate
+     * \param end 0-based column end coordinate
+     * \param rc has the passed alignment of the bin been reverse-complemented?  (if so,
+     * then appropriately deals with the necessary coordinate conversions)
+     * \return Genomic_interval representing the appropriate genomic sequence for genome,
+     * with nonsense coordinates [1, 0] if the interval is empty (no ungapped sequence).
+     */
+    Genomic_interval map_align_to_genomic
+      (const unsigned bin,
+       const Stockholm& stockholm_bin,
+       const std::string& genome,
+       const unsigned start, const unsigned end,
+       const bool rc = false) const;
+
+    /**
+     * \brief Map genomic coordinates to alignment coordinates for a particular bin.
+     *
+     * \param start 0-based genomic start coordinate
+     * \param end 0-based genomic end coordinate
+     * \param bin Mercator bin which stockholm holds the alignment for (set to 0 for dummy/unknown value)
+     if reading in a new alignment is necessary, then this function sets bin appropriately
+     * \param stockholm_bin hold Stockholm alignment for bin
+     * \return alignment column coordinates or nonsense coordinates [1, 0] if no mapping
+     */
+    Interval map_genomic_to_align
+      (const std::string& genome, const std::string& chromosome,
+       const unsigned start, const unsigned end,
+       unsigned& bin,
+       Stockholm& stockholm_bin,
+       const bool lazy = false, const bool truncate_ok = false,
+       const bool verbose = true) const;
+
+    /**
+     * \brief Map genomic coordinates to sequence coordinates within a particular bin.
+     * \param start 0-based genomic start coordinate
+     * \param end 0-based genomic end coordinate
+     * \param bin Mercator bin which stockholm holds the alignment for (set to 0 for dummy/unknown value)
+     if reading in a new alignment is necessary, then this function sets bin appropriately
+     * \param stockholm_bin hold Stockholm alignment for bin
+     * \return alignment column coordinates or nonsense coordinates [1, 0] if no mapping
+     */
+    Interval map_genomic_to_bin_seq
+      (const std::string& genome, const std::string& chromosome,
+       const unsigned start, const unsigned end,
+       unsigned& bin,
+       Stockholm& stockholm_bin,
+       const bool lazy = false, const bool truncate_ok = false,
+       const bool verbose = true) const;
+    
+
+  private:
+
+    std::string __alignments_dir;                   ///< directory to search for alignments
+    static const Alphabet alphabet;                 ///< DNA alphabet
+    std::vector<std::string> __suffixes_mfa;        ///< file suffixes to search for alignments
+    std::vector<std::string> __suffixes_stockholm;  ///< file suffixes to search for alignments
+
+  };
+
+  inline const std::vector<size_t>& Mercator_map::get_intervals_by_bin (const unsigned bin) const {
+    return __bin_index[bin];
+  }
+
+  inline const Mercator_interval& Mercator_map::get_interval_by_bin (const unsigned bin, const std::string& genome) const {
+
+    // check sane
+    assert (exists_genome (genome));
+    assert (bin <= bins()); // remember that the numbering of Mercator bins is 1-based
+                            // and that we preserve the 1-based indexing in __bin_index
+                            // (see init_bin_index)
+
+    const size_t index = __bin_index[bin][__genome_index.find (genome)->second];
+
+    // make sure that we have a valid Mercator_interval for this (bin, genome) pair
+    assert (index < size());
+
+    // make sure that we found it
+    assert ((get_interval (index).bin == bin) && (get_interval (index).genome == genome));
+
+    return get_interval (index);
+
+  }
+
+}
+
+#endif /* SEQ_MERCATOR_INCLUDED */
diff --git a/src/seq/sequence.cc b/src/seq/sequence.cc
new file mode 100644
index 0000000..7d46264
--- /dev/null
+++ b/src/seq/sequence.cc
@@ -0,0 +1,587 @@
+
+/**
+ * \file sequence.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <algorithm>
+
+#include "util/regexp.h"
+#include "math/mathematics.h"
+#include "seq/sequence.h"
+
+using namespace fsa;
+
+const std::string Sequence::fasta_seq_start = ">";
+
+// Mapping from codons to amino acids.
+// This really should be a static member variable,
+// but I kept getting annoying linker errors, so here it is.
+// Nucleotide->integer mapping is e.g. AGC => [0][3][2].
+// Stop codons are 'X'.
+const char Translated_sequence::__codon_map[4][4][4] = {
+  { { 'K', 'N', 'K', 'N' },
+    { 'T', 'T', 'T', 'T' },
+    { 'R', 'S', 'R', 'S' },
+    { 'I', 'I', 'M', 'I' } },
+  { { 'Q', 'H', 'Q', 'H' },
+    { 'P', 'P', 'P', 'P' },
+    { 'R', 'R', 'R', 'R' },
+    { 'L', 'L', 'L', 'L' } },
+  { { 'E', 'D', 'E', 'D' },
+    { 'A', 'A', 'A', 'A' },
+    { 'G', 'G', 'G', 'G' },
+    { 'V', 'V', 'V', 'V' } },
+  { { 'X', 'Y', 'X', 'Y' },
+    { 'S', 'S', 'S', 'S' },
+    { 'X', 'C', 'W', 'C' },
+    { 'L', 'F', 'L', 'F' } },
+};
+
+
+
+Sequence::Sequence (const std::string& name, const std::string& seq)
+  : name (name), seq (seq)
+{ }
+
+Sequence::Sequence (const std::string& name, const std::string& seq,
+		    const std::string& info)
+  : name (name), seq (seq), info (info)
+{ }
+
+bool Sequence::detect_fasta (const std::string& filename) {
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  Regexp re_name ("^[ \t]*" + fasta_seq_start + "([^ \t]*)[ \t]*(.*)");
+
+  std::string line;
+  while (!filestream.eof()) {
+
+    getline (filestream, line);
+    if (re_name.Match (line.c_str())) {
+      filestream.close();
+      return true;
+    }
+
+  }
+  filestream.close();
+
+  return false;  
+
+}
+
+Sequence* Sequence::subsequence (const unsigned start, const unsigned end) const {
+
+  assert (!length() || (end < length()));
+  Sequence* sequence = NULL;
+  if (end < start)
+    sequence = new Sequence (name, "");
+  else
+    sequence = new Sequence (name, seq.substr (start, end - start + 1), info);
+
+  return sequence;
+
+}
+
+void Sequence::revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) /* = NULL */) {
+
+  alphabet.revcomp (seq, is_gap_char);
+
+}
+
+Sequence Sequence::revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) /* = NULL */) const {
+
+  Sequence sequence = *this;
+  sequence.revcomp (alphabet, is_gap_char);
+  return sequence;
+
+}
+
+Translated_sequence::Translated_sequence (const Sequence& orig_seq)
+  : orig_seq (orig_seq),
+    __alphabet (DNA_alphabet()) {             // impose DNA alphabet
+
+  __forward.resize (3);
+  __reverse.resize (3);
+
+  // size strings for all reading frames for speed
+  const unsigned rem = orig_seq.length() % 3;
+  const unsigned len = (orig_seq.length() - rem) / 3;
+  for (size_t frame = 0; frame < 3; ++frame) {
+    // calculate length for this frame
+    const size_t l = len - ((static_cast<int> (rem) - static_cast<int> (frame)) >= 0 ? 0 : 1); // remember possibility of overhang at end
+    __forward[frame].reserve (l);
+    __reverse[frame].reserve (l);
+  }
+  
+  // forward strand
+  unsigned zero;
+  unsigned one = __alphabet.get_char_index (orig_seq.seq[0]);  // initialize to "previous" values from fake last frame
+  unsigned two = __alphabet.get_char_index (orig_seq.seq[1]);
+  for (size_t i = 2; i < orig_seq.length(); ++i) {
+
+    // get amino acid
+    zero = one;                                            // increment frame
+    one = two;
+    two = __alphabet.get_char_index (orig_seq.seq[i]);     // and get new character
+    const char ch = __codon_map[zero][one][two];
+
+    // get frame and position in translated sequence
+    const unsigned frame = (i - 2) % 3; // because we begin at frame 0 but i = 2
+
+    // store character
+    __forward[frame] += ch;
+
+  }
+
+  // reverse strand
+  std::string orig_seq_revcomp = __alphabet.revcomp (orig_seq.seq);
+
+  one = __alphabet.get_char_index (orig_seq_revcomp[0]);  // initialize to "previous" values from fake last frame
+  two = __alphabet.get_char_index (orig_seq_revcomp[1]);
+  for (size_t i = 2; i < orig_seq.length(); ++i) {
+
+    // get amino acid
+    zero = one;                                                // increment frame
+    one = two;
+    two = __alphabet.get_char_index (orig_seq_revcomp[i]);     // and get new character
+    const char ch = __codon_map[zero][one][two];
+
+    // get frame and position in translated sequence
+    const unsigned frame = (i - 2) % 3; // because we begin at frame 0 but i = 2
+
+    // store character
+    __reverse[frame] += ch;
+
+  }
+
+}
+
+void Sequence::init_hardmasking (size_t min_hardmask_length, bool (*is_hardmask_char) (char)) {
+
+  // mark sequence as hardmasked
+  __is_hardmasked = true;
+
+  // find hardmasked intervals
+  bool in_run = false;
+  size_t start = 0;
+  size_t len = 0;
+  for (size_t i = 0; i < seq.length(); ++i) {
+    if (is_hardmask_char (seq[i])) {
+      // if just started a run of hardmasked characters
+      if (!in_run) {
+	start = i;
+	len = 0;
+	in_run = true;
+      }
+      // increment length of run
+      ++len;
+    }
+    else {
+      // if just ended a run
+      if (in_run) {
+	// store if meets length criteria
+	if (len >= min_hardmask_length)
+	  __masked_intervals.push_back (Interval (start, i - 1)); // -1 b/c now outside of run
+	in_run = false;
+      }
+    }
+  }
+
+  // check for case of ending in a run
+  if (in_run) {
+    // store if meets length criteria
+    if (len >= min_hardmask_length)
+      __masked_intervals.push_back (Interval (start, seq.length()));
+  }  
+
+}
+
+Sequence Sequence::get_stripped_sequence() const {
+
+  if (!__is_hardmasked) {
+    cerr << "ERROR: Sequence isn't hardmasked." << endl;
+    exit (1);
+  }
+
+  // handle case of no masked intervals
+  if (!__masked_intervals.size())
+    return *this;
+
+  std::string stripped;
+
+  // iterate over masked intervals, avoiding them as we go  
+  size_t start = 0;
+  for (std::vector<Interval>::const_iterator iter = __masked_intervals.begin(); iter != __masked_intervals.end(); ++iter) {
+    for (size_t i = start; i < iter->start; ++i)
+      stripped += seq[i];
+    start = iter->end + 1;
+  }
+  // catch the sequence past the last interval
+  for (size_t i = __masked_intervals.back().end + 1; i < seq.length(); ++i)
+    stripped += seq[i];
+
+  return Sequence (name, stripped, info);
+
+}
+
+bool Sequence::is_pos_hardmasked (const unsigned orig_pos) const {
+
+  if (!__is_hardmasked) {
+    cerr << "ERROR: Sequence isn't hardmasked." << endl;
+    exit (1);
+  }
+
+  for (std::vector<Interval>::const_iterator iter = __masked_intervals.begin(); iter != __masked_intervals.end(); ++iter) {
+    if ((orig_pos >= iter->start) && (orig_pos <= iter->end))
+      return true;
+  }
+
+  return false;
+}
+
+unsigned Sequence::map_stripped_to_orig (const unsigned pos) const {
+
+  if (!__is_hardmasked) {
+    cerr << "ERROR: Sequence isn't hardmasked." << endl;
+    exit (1);
+  }
+
+  size_t orig_pos = pos;
+  for (std::vector<Interval>::const_iterator iter = __masked_intervals.begin(); iter != __masked_intervals.end(); ++iter) {
+    
+    // have we found it?
+    // (is it before this interval begins?)
+    if (orig_pos < iter->start)
+      return orig_pos;
+    
+    // if position is past this masked interval,
+    // increment offset appropriately
+    if (orig_pos >= iter->start)
+      orig_pos += iter->end - iter->start + 1;
+    
+  }
+
+  // check sane
+  if (orig_pos >= seq.length()) {
+    cerr << "map_stripped_to_orig: mapped " << pos << " -> " << orig_pos << "; seqlen = " << seq.length() << endl;
+  }
+  assert (orig_pos < seq.length());
+
+  return orig_pos;
+
+}
+
+unsigned Sequence::map_orig_to_stripped (const unsigned orig_pos) const {
+
+  if (!__is_hardmasked) {
+    cerr << "ERROR: Sequence isn't hardmasked." << endl;
+    exit (1);
+  }
+
+  // sanity check  
+  assert (orig_pos < (*this).length());
+
+  // loop over the masked intervals,
+  // subtracting their length as we go
+  size_t pos = orig_pos;
+  for (std::vector<Interval>::const_iterator iter = __masked_intervals.begin(); iter != __masked_intervals.end(); ++iter) {
+
+    // return out-of-bounds answer if original coordinate
+    // falls within a masked interval
+    if ((orig_pos >= iter->start) && (orig_pos <= iter->end))
+      return seq.length();
+
+    // have we reached the original coordinate?
+    if (orig_pos < iter->start)
+      return pos;
+
+    pos -= iter->length();
+    
+  }
+
+  return pos;
+
+}
+
+void Sequence::write_fasta (std::ostream& o) const {
+
+  o << fasta_seq_start << name
+    << (info.length() ? (' ' + info) : "") << endl
+    << seq << endl;
+
+}
+
+Sequence_database::Sequence_database (const Sequence_database& parent) {
+
+  // deep copy
+  for (std::vector<Sequence*>::const_iterator sequence = parent.__sequences.begin(); sequence != parent.__sequences.end(); ++sequence) {
+    Sequence* s = new Sequence (**sequence);
+    __sequences.push_back (s);
+  }
+
+  __sequence_index = parent.__sequence_index;
+
+}
+
+Sequence_database& Sequence_database::operator= (const Sequence_database& parent) {
+
+  // check for self-assignment
+  if (this == &parent)
+    return *this;
+
+  // clear old memory
+  this->clear();
+
+  // perform deep copy
+  for (std::vector<Sequence*>::const_iterator sequence = parent.__sequences.begin(); sequence != parent.__sequences.end(); ++sequence) {
+    Sequence* s = new Sequence (**sequence);
+    __sequences.push_back (s);
+  }
+
+  __sequence_index = parent.__sequence_index;
+
+  return *this;
+
+}
+
+Sequence_database::~Sequence_database() {
+
+  for (std::vector<Sequence*>::iterator sequence = __sequences.begin(); sequence != __sequences.end(); ++sequence)
+    delete *sequence;
+
+}
+
+void Sequence_database::read_fasta (const std::string& filename, bool (*is_gap_char) (char) /* = NULL */,
+				    const bool strip_leading_chr /* = true */,
+				    const bool verbose /* = true */) {
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  if (verbose)
+    cerr << "Reading FASTA-format sequence file '" << filename << "'...";
+
+  Regexp re_name ("^[ \t]*" + Sequence::fasta_seq_start + "([^ \t]*)[ \t]*(.*)");
+
+  std::string line;
+
+  std::vector<std::string> seqs_names;
+  std::vector<std::string> seqs;
+  std::vector<std::string> seqs_info;
+
+  bool in_seq_body = false;
+  size_t curr_idx = 0; // dummy value to prevent compiler warnings
+  while (!filestream.eof()) {
+
+    getline (filestream, line);
+
+    // are we at a name line?
+    if (re_name.Match (line.c_str())) {
+      if (re_name.SubStrings() < 1) { continue; }
+      // store name
+      const std::string name = re_name[1];
+      curr_idx = seqs_names.size();
+      seqs_names.push_back (name);
+      // store info following name, if present
+      std::string info;
+      if (re_name.SubStrings() >= 2)
+	info = re_name[2];
+      seqs_info.push_back (info);
+      // store empty sequence
+      seqs.push_back ("");
+      in_seq_body = true;
+    }
+    // if not, then we must be reading sequence data
+    else if (in_seq_body) {
+      // if this is the first line of data for this sequence
+      if (seqs.size() < seqs_names.size())
+	seqs.push_back (line);
+      else
+	seqs[curr_idx] += line;
+    }
+
+  }
+  filestream.close();
+
+  // assert sane
+  if (seqs.size() != seqs_names.size()) {
+    cerr << "ERROR: Sequence names and data don't match up.  Is your FASTA file improperly formatted?" << endl;
+    exit (1);
+  }
+  assert (seqs_names.size() == seqs_info.size());
+
+  // now store
+  for (size_t i = 0; i < seqs_names.size(); ++i) {
+
+    std::string& name = seqs_names[i];
+    std::string& seq = seqs[i];
+    std::string& info = seqs_info[i];
+
+    // remove leading chr if requested and present
+    if (strip_leading_chr)
+      Util::strip_leading_chr (name);
+
+    // strip out whitespace
+    std::string::iterator last_pos = std::remove_if (seq.begin(), seq.end(),
+						     isspace);
+    seq.erase (last_pos, seq.end());
+
+    // strip out gaps if requested
+    if (is_gap_char != 0) {
+      last_pos = std::remove_if (seq.begin(), seq.end(),
+				 is_gap_char);
+      seq.erase (last_pos, seq.end());
+    }
+
+    // remove newline from info, if present
+    Util::chomp (info);
+
+    // store sequence
+    Sequence* sequence = new Sequence (name, seq, info);
+    add_seq (sequence);
+  }
+
+  if (verbose)
+    cerr << "done." << endl;
+
+}
+
+void Sequence_database::write_fasta (std::ostream& o) const {
+
+  for (std::vector<Sequence*>::const_iterator seq = this->begin(); seq != this->end(); ++seq)
+    (*seq)->write_fasta (o);
+
+}
+
+void Sequence_database::add_seq (Sequence* sequence) {
+
+  if (exists_seq (sequence->name)) {
+    cerr << "ERROR: Duplicate sequence name '" << sequence->name << "'; this is forbidden." << endl
+	 << "Note that descriptions following the sequence names are not considered part of the names themselves." << endl;
+    exit (1);
+  }
+  __sequences.push_back (sequence);
+  __sequence_index.insert (std::make_pair (sequence->name, __sequences.size() - 1));
+
+}
+
+void Sequence_database::add_seq (const Sequence& sequence) {
+
+  if (exists_seq (sequence.name)) {
+    cerr << "ERROR: Duplicate sequence name '" << sequence.name << "'; this is forbidden." << endl
+	 << "Note that descriptions following the sequence names are not considered part of the names themselves." << endl;
+    exit (1);
+  }
+
+  Sequence* sequence_p = new Sequence (sequence);
+  __sequences.push_back (sequence_p);
+  __sequence_index.insert (std::make_pair (sequence.name, __sequences.size() - 1));
+
+}
+
+void Sequence_database::revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) /* = NULL */) {
+
+  for (std::vector<Sequence*>::iterator seq = this->begin(); seq != this->end(); ++seq)
+    (*seq)->revcomp (alphabet, is_gap_char);
+
+}
+
+bool Sequence_database::matches_alphabet (const Alphabet& alphabet, const double threshold /* = 0.95 */) const {
+
+  size_t matches = 0;
+  size_t total = 0;
+
+  for (size_t i = 0; i < size(); ++i) {
+    const Sequence& sequence = get_seq (i);
+    total += sequence.length();
+
+    for (std::string::const_iterator s = sequence.seq.begin(); s != sequence.seq.end(); ++s) {
+      if (alphabet.is_nondegen_char (*s) || alphabet.is_unknown_char (*s))
+	++matches;
+    }
+
+  }
+
+  // catch case of no sequence
+  if (total == 0)
+    return true;
+
+  const double frac =  static_cast<double> (matches) / total;
+
+  if (frac >= threshold) {
+    cerr << "Sequences match a " << alphabet.name() << " alphabet." << endl;
+    return true;
+  }
+
+  return false;
+}
+
+void Sequence_database::clear() {
+
+  for (std::vector<Sequence*>::iterator sequence = __sequences.begin(); sequence != __sequences.end(); ++sequence)
+    delete *sequence;
+  __sequences.clear();
+
+  __sequence_index.clear();
+
+}
+
+size_t Sequence_database::meanlength() const {
+
+  size_t total = 0;
+  for (size_t i = 0; i < size(); ++i) {
+    const Sequence& sequence = get_seq (i);
+    total += sequence.length();
+  }
+  
+  return static_cast<size_t> (total / size());
+
+}
+
+size_t Sequence_database::median_length() const {
+
+  std::vector<size_t> lengths (size());
+  for (size_t i = 0; i < size(); ++i)
+    lengths[i] = get_seq (i).length();
+  
+  return Mathematics::median (lengths);
+
+}
+
+std::vector<std::string> Sequence_database::get_sequence_list() const {
+
+  std::vector<std::string> names;
+  for (std::vector<Sequence*>::const_iterator sequence = begin(); sequence != end(); ++sequence)
+    names.push_back ((*sequence)->name);
+
+  return names;
+
+}
+
+Sequence_database Sequence_database::translate() const {
+
+  Sequence_database tr_db;
+
+  // store first reading frame of forward strand
+  for (size_t i = 0; i < this->size(); ++i) {
+    const Sequence& sequence = get_seq (i);
+    Translated_sequence tr (sequence);
+    Sequence* forward = new Sequence (tr.get_forward (0));
+    tr_db.add_seq (forward);
+  }
+
+  return tr_db;
+
+}
diff --git a/src/seq/sequence.h b/src/seq/sequence.h
new file mode 100644
index 0000000..6d623b5
--- /dev/null
+++ b/src/seq/sequence.h
@@ -0,0 +1,506 @@
+
+/**
+ * \file sequence.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef SEQ_SEQUENCE_INCLUDED
+#define SEQ_SEQUENCE_INCLUDED
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <map>
+
+#include "util/misc.h"
+#include "seq/alphabet.h"
+#include "seq/interval.h"
+
+namespace fsa {
+
+  /**
+   * \brief Represent a single named sequence.
+   *
+   * Coordinates are 0-based.
+   * Interavls are always fully-closed, [start, end].
+   */
+  struct Sequence {
+
+  public:
+
+    std::string name;   ///< sequence name
+    std::string seq;    ///< sequence itself
+    std::string info;   ///< free-form information which comes after the name in a FASTA file
+
+    /**
+     * \brief Default constructor.
+     */
+    Sequence() { }
+
+    /**
+     * \brief Constructor.
+     */
+    Sequence (const std::string& name, const std::string& seq);
+
+    /**
+     * \brief Constructor.
+     */
+    Sequence (const std::string& name, const std::string& seq,
+	      const std::string& info);
+
+    /**
+     * \brief Detect whether a file seems to be in FASTA format.
+     */
+    static bool detect_fasta (const std::string& filename);
+
+    /**
+     * \brief Write sequence in FASTA format.
+     */
+    void write_fasta (std::ostream& o) const;
+
+    /**
+     * \brief Get sequence length.
+     */
+    inline size_t length() const { return seq.length(); }
+
+    /**
+     * \brief Append sequence data.
+     */
+    inline void append (const std::string& s) { seq += s; }
+
+    /**
+     * \brief Get subsequence.
+     *
+     */
+    Sequence* subsequence (const unsigned start, const unsigned end) const;
+
+    /**
+     * \brief Reverse-complement sequence under the passed alphabet.
+     *
+     * If requested, ignores gap characters as defined by the passed function.
+     * \param alphabet Alphabet to reverse-complement under
+     * \param is_gap_char function pointer defining a gap character
+     */
+    void revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) = NULL);
+
+    /**
+     * \brief Reverse-complement sequence under the passed alphabet.
+     */
+    Sequence revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) = NULL) const;
+
+    /**
+     * \brief Complement a strand.
+     */
+    inline static void complement_strand (char& strand);
+
+    /**
+     * \brief Initialize hardmasking by finding hardmasked intervals in original sequence.
+     *
+     * \param min_hardmask_length minimum length of hardmasked sequence to strip out
+     * \param is_hardmask_char function pointer defining a hardmasked character
+     */
+     void init_hardmasking (size_t min_hardmask_length, bool (*is_hardmask_char) (char));
+
+    /**
+     * \brief Is the sequence at a position hardmasked?
+     */
+    bool is_pos_hardmasked (const unsigned orig_pos) const;
+
+    /**
+     * \brief Map coordinates from stripped sequence back to original sequence.
+     *
+     * Uses a linear-time search over the masked intervals.
+     * NB: The coordinate mappings could be made faster with a binary search.
+     */
+    unsigned map_stripped_to_orig (const unsigned pos) const;
+
+    /**
+     * \brief Map coordinates from original sequence to stripped sequence.
+     *
+     * Uses a linear-time search over the masked intervals.
+     * Returns sequence length (out of bounds)
+     * if the coordinate falls in a masked interval.
+     */
+    unsigned map_orig_to_stripped (const unsigned pos) const;
+
+    /**
+     * \brief Strip out hardmasked sequence.
+     */
+    Sequence get_stripped_sequence() const;
+
+
+
+    static const std::string fasta_seq_start;   ///< designate sequence name in FASTA files
+
+
+  private:
+
+    bool __is_hardmasked;  ///< is this sequence hardmasked?
+
+    /**
+     * \brief coordinates of hardmasked intervals
+     *
+     * 0-based, fully-closed coordinates [start, end].
+     */
+    std::vector<Interval> __masked_intervals;
+
+
+  };
+
+  /**
+   * \brief Represent a translated nucleotide sequence.
+   *
+   * Assumes and enforces a non-degenerate DNA alphabet:
+   * Degenerate characters are randomized and a DNA alphabet is imposed.
+   */
+  struct Translated_sequence {
+
+  public:
+
+    /**
+     * \brief constructor
+     */
+    Translated_sequence (const Sequence& orig_seq);
+
+    /**
+     * \brief Get translated sequence on forward strand.
+     * \param frame reading frame 0, 1, 2
+     */
+    inline Sequence get_forward (const unsigned frame) const {
+      assert (frame < 3);
+      return Sequence (orig_seq.name, __forward[frame], orig_seq.info);
+    }
+
+    /**
+     * \brief Get translated sequence on reverse strand.
+     */
+    inline Sequence get_reverse (const unsigned frame) const {
+      assert (frame < 3);
+      return Sequence (orig_seq.name, __reverse[frame], orig_seq.info);
+    }
+
+    /**
+     * \brief Map a coordinate in a translated sequence back to the position in the original sequence.
+     *
+     * All coordinates are assumed to be 0-based.
+     * Maps back to the first nucleotide of the corresponding codon.
+     * \param forward true for forward strand, false for reverse
+     * \param frame reading frame (0, 1 or 2)
+     * \param pos position in translated sequence
+     * \return position in original sequence
+     */
+    inline unsigned map_coords_to_orig (const bool forward, const unsigned frame, const unsigned pos) const;
+
+    /**
+     * \brief Map an interval in a translated sequence back to the interval in the original sequence.
+     *
+     * All coordinates are assumed to be 0-based.
+     * Maps back to the first nucleotide of first corresponding codon and last nucleotide of the last codon.
+     * \param forward true for forward strand, false for reverse
+     * \param frame reading frame (0, 1 or 2)
+     * \param interval position in translated sequence
+     * \return interval in original sequence
+     */
+    inline Interval map_interval_to_orig (const bool forward, const unsigned frame, const Interval& interval) const;
+
+  private:
+
+    static const char __codon_map[4][4][4];   ///< map from codons to amino acids
+
+    const Sequence& orig_seq;                 ///< original sequence
+    const Alphabet __alphabet;                ///< DNA alphabet
+
+    std::vector<std::string> __forward;       ///< 3 reading frames of forward strand
+    std::vector<std::string> __reverse;       ///< 3 reading frames of reverse strand
+
+  };
+
+  /**
+   * \brief Represent a set of sequences.
+   *
+   * This container holds all sequence data,
+   * and as such should be instantiated at the "top" of a program.
+   */
+  struct Sequence_database {
+
+  public:
+
+    /**
+     * \brief Constructor.
+     */
+    Sequence_database() { }
+    Sequence_database (const Sequence_database& parent);
+    Sequence_database& operator= (const Sequence_database& parent);
+
+    /**
+     * \brief Destructor.
+     */
+    ~Sequence_database();
+
+    /**
+     * \brief Read a FASTA-format file.
+     *
+     * Strips out whitespace. Strips out gaps if requested with, e.g.,
+     * seq_db.read_fasta ("rob.fasta", Alignment::is_gap_char)
+     * Does NOT clear sequence data; this method can therefore be
+     * used to read a series of different files into the same Sequence_database.
+     * \param is_gap_char function pointer defining a gap character
+     * \param strip_leading_chr strips the leading 'chr', if present, from the sequence names
+     */
+    void read_fasta (const std::string& filename, bool (*is_gap_char) (char) = NULL,
+		     const bool strip_leading_chr = true,
+		     const bool verbose = true);
+
+    /**
+     * \brief Write in FASTA format.
+     */
+    void write_fasta (std::ostream& o) const;
+
+    /**
+     * \brief Add sequence to database.
+     */
+    void add_seq (Sequence* sequence);
+
+    /**
+     * \brief Add sequence to database.
+     * 
+     * Note that this method creates a copy of the passed sequence!
+     */
+    void add_seq (const Sequence& sequence);
+
+    /**
+     * \brief Append sequence data.
+     * \param name sequence name
+     * \param seq sequence data to append
+     */
+    inline void append_seq (const std::string& name, const std::string& seq);
+
+    /**
+     * \brief Does a sequence exist in the database?
+     */
+    inline bool exists_seq (const std::string& name) const;
+
+    /**
+     * \brief Get sequence from database.
+     */
+    inline const Sequence& get_seq (const std::string& name) const;
+
+    /**
+     * \brief Get sequence from database.
+     */
+    inline Sequence& get_seq (const std::string& name);
+
+    /**
+     * \brief Get sequence from database.
+     * \param i index of sequence in database
+     */
+    inline const Sequence& get_seq (const size_t i) const;
+
+    /**
+     * \brief Get sequence from database.
+     * \param i index of sequence in database
+     */
+    inline Sequence& get_seq (const size_t i);
+
+    /**
+     * \brief Get index of sequence in database.
+     * 
+     * Sequences are indexed according to the order in which they were first stored.
+     */
+    inline size_t get_seq_index (const std::string& name) const;
+
+    /**
+     * \brief Reverse-complement sequences under the passed alphabet.
+     *
+     * If requested, ignores gap characters as defined by the passed function.
+     * \param alphabet Alphabet to reverse-complement under
+     * \param is_gap_char function pointer defining a gap character
+     */
+    void revcomp (const Alphabet& alphabet, bool (*is_gap_char) (char) = NULL);
+
+    /**
+     * \brief Do the sequences appear to match a particular alphabet?
+     * \param alphabet alphabet to match against
+     * \param threshold fraction of sequence characters required to match alphabet
+     * \return match >= 0.95 to alphabet, or true if Sequence_database is empty
+     */
+    bool matches_alphabet (const Alphabet& alphabet, const double threshold = 0.95) const;
+
+    /**
+     * \brief Number of sequences in database.
+     */
+    size_t size() const { return __sequences.size(); }
+
+    /**
+     * \brief Average length of sequences in database.
+     */
+    size_t meanlength() const;
+
+    /**
+     * \brief Median length of sequences in database.
+     */
+    size_t median_length() const;
+
+    /**
+     * \brief Clear all sequence data.
+     */
+    void clear();
+
+    /**
+     * \brief Get list of names of all sequences in database.
+     */
+    std::vector<std::string> get_sequence_list() const;
+
+    /**
+     * \brief Translate all sequences.
+     *
+     * "Overhangs" (incomplete codons at the end of the sequence) are dropped.
+     * \return the translated database
+     */
+    Sequence_database translate() const;
+
+    /**
+     * \brief Get iterator to start of __sequences.
+     */
+    std::vector<Sequence*>::iterator begin() {
+      return __sequences.begin();
+    }
+
+    /**
+     * \brief Get iterator to start of __sequences.
+     */
+    std::vector<Sequence*>::const_iterator begin() const {
+      return __sequences.begin();
+    }
+
+    /**
+     * \brief Get iterator to end of __sequences.
+     */
+    std::vector<Sequence*>::iterator end() {
+      return __sequences.end();
+    }
+
+    /**
+     * \brief Get iterator to end of __sequences.
+     */
+    std::vector<Sequence*>::const_iterator end() const {
+      return __sequences.end();
+    }
+
+
+  private:
+
+    std::vector<Sequence*> __sequences;               ///< sequences
+    std::map<std::string, size_t> __sequence_index;   ///< lookup index in *this from sequence name
+
+  };
+
+
+
+
+  /****************************************
+   * Function definitions.
+   ****************************************/
+
+  inline void Sequence::complement_strand (char& strand) {
+
+    if (strand == '+')
+      strand = '-';
+    else if (strand == '-')
+      strand = '+';
+
+  }
+
+  inline unsigned Translated_sequence::map_coords_to_orig (const bool forward, const unsigned frame, const unsigned pos) const {
+
+    unsigned orig_pos;
+    if (forward)
+      orig_pos = (3 * pos + frame);
+    else
+      orig_pos = (orig_seq.length() - 1) - (3 * pos + frame); // - 1 because 0-based coordinates
+
+    assert (orig_pos < orig_seq.length());
+
+    return orig_pos;
+
+  }
+
+  inline Interval Translated_sequence::map_interval_to_orig (const bool forward, const unsigned frame, const Interval& interval) const {
+
+    assert (interval.start <= interval.end);
+
+    Interval orig_interval;
+    if (forward) {
+      orig_interval.start = map_coords_to_orig (forward, frame, interval.start);  // first nt of first codon
+      orig_interval.end = map_coords_to_orig (forward, frame, interval.end) + 2;  // last nt of last codon
+    }
+    else {
+      // for reverse strand:
+      // first nt of first codon on forward strand is last nt of last codon in revcomp'ed sequence
+      orig_interval.start = map_coords_to_orig (forward, frame, interval.end) - 2;
+      orig_interval.end = orig_interval.start + 3 * (interval.end - interval.start + 1) - 1; // remember 0-based coordinates
+    }
+
+    assert (orig_interval.start <= orig_interval.end);
+    assert (orig_interval.end < orig_seq.length());
+
+    return orig_interval;
+  }
+
+
+  inline bool Sequence_database::exists_seq (const std::string& name) const {
+
+    return (__sequence_index.find (name) != __sequence_index.end());
+
+  }
+
+  inline size_t Sequence_database::get_seq_index (const std::string& name) const {
+    assert (exists_seq (name));
+    return __sequence_index.find (name)->second;
+  }
+
+  inline const Sequence& Sequence_database::get_seq (const std::string& name) const {
+
+    assert (exists_seq (name));
+    return *__sequences[__sequence_index.find (name)->second];
+
+  }
+
+  inline Sequence& Sequence_database::get_seq (const std::string& name) {
+
+    assert (exists_seq (name));
+    return *__sequences[__sequence_index.find (name)->second];
+
+  }
+
+  inline const Sequence& Sequence_database::get_seq (const size_t i) const {
+
+    assert (i < __sequences.size());
+    return *__sequences[i];
+
+  }
+
+  inline Sequence& Sequence_database::get_seq (const size_t i) {
+
+    assert (i < __sequences.size());
+    return *__sequences[i];
+
+  }
+
+  inline void Sequence_database::append_seq (const std::string& name, const std::string& seq) {
+    if (!exists_seq (name)) {
+      Sequence* sequence = new Sequence (name, seq);
+      add_seq (sequence);
+    }
+    else
+      get_seq (name).append (seq);
+    return;
+  }
+
+}
+
+#endif /* SEQ_SEQUENCE_INCLUDED */
diff --git a/src/seq/similarity_matrix.cc b/src/seq/similarity_matrix.cc
new file mode 100644
index 0000000..0d6be11
--- /dev/null
+++ b/src/seq/similarity_matrix.cc
@@ -0,0 +1,204 @@
+
+/**
+ * \file similarity_matrix.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include <iostream>
+#include <iomanip>
+
+#include "math/mathematics.h"
+#include "seq/similarity_matrix.h"
+
+using namespace fsa;
+
+Sequence_kmer_counts::Sequence_kmer_counts (const Alphabet& alphabet,
+			  const size_t k)
+  : __alphabet (alphabet),
+    __k (k),
+    __num_words (fsa::Mathematics::power_of_integer (__alphabet.size(), __k)) {
+
+  // pre-compute necessary powers of alphabet size
+  __powers_of_alphabet_size.resize (__k);
+  for (size_t i = 0; i < k; ++i)
+    __powers_of_alphabet_size[i] = Mathematics::power_of_integer (__alphabet.size(), i);
+
+}
+
+Sequence_kmer_counts::Kmer_counts Sequence_kmer_counts::compute_counts (const Sequence& sequence) const {
+
+  Sequence_kmer_counts::Kmer_counts kmer_counts;
+
+  // if the sequence is shorter than k, then return
+  if (sequence.length() < k())
+    return kmer_counts;
+
+  // iterate over positions in the sequence, storing counts as we go
+  for (size_t i = 0; i <= sequence.length() - k() + 1; ++i) {
+
+    const Sequence_kmer_counts::Kmer_index index = kmer_to_index (sequence.seq, i);
+
+    // if this word contains a character which isn't in the alphabet,
+    // then don't store any information
+    if (index == num_words())
+      continue;
+
+    // else store count
+    else
+      ++kmer_counts[index];
+
+  }
+  
+  return kmer_counts;
+
+}
+
+size_t Sequence_kmer_counts::choose_minimum_word_length (const Sequence_database& seq_db,
+							 const Alphabet& alphabet) {
+  
+  const size_t medianlen = seq_db.median_length();
+  const size_t bestk = 1 + static_cast<size_t> (std::log (static_cast<double> (medianlen))
+						/ std::log (static_cast<double> (alphabet.size())));
+
+  if (bestk > 0)
+    return bestk;
+  else
+    return 1;
+
+}
+
+Sequence_similarity_matrix::Sequence_similarity_matrix (const Sequence_database& seq_db,
+							const Alphabet& alphabet,
+							const size_t k)
+  : __seq_db (seq_db),
+    __similarities (seq_db.size(), std::vector<double> (seq_db.size(), 0.)) {
+
+  compute_kmer_similarity_matrix (seq_db,
+				  alphabet,
+				  k);
+
+}
+
+size_t Sequence_similarity_matrix::compute_kmer_similarity (const Sequence_kmer_counts::Kmer_counts& counts_x, const Sequence_kmer_counts::Kmer_counts& counts_y) {
+
+  size_t count = 0;
+
+  // for speed, loop over the smaller set of k-mers
+  if (counts_x.size() < counts_y.size()) {
+
+    // for each k-mer in X
+    for (Sequence_kmer_counts::Kmer_counts::const_iterator kmer_count_x = counts_x.begin(); kmer_count_x != counts_x.end(); ++kmer_count_x) {
+      Sequence_kmer_counts::Kmer_counts::const_iterator kmer_count_y = counts_y.find (kmer_count_x->first);
+      if (kmer_count_y != counts_y.end())
+	count += std::min (kmer_count_x->second, kmer_count_y->second);
+    }
+
+  }
+
+  else {
+
+    // for each k-mer in Y
+    for (Sequence_kmer_counts::Kmer_counts::const_iterator kmer_count_y = counts_y.begin(); kmer_count_y != counts_y.end(); ++kmer_count_y) {
+      Sequence_kmer_counts::Kmer_counts::const_iterator kmer_count_x = counts_x.find (kmer_count_y->first);
+      if (kmer_count_x != counts_x.end())
+	count += std::min (kmer_count_x->second, kmer_count_y->second);
+    }
+
+  }
+
+  return count;
+
+}
+
+void Sequence_similarity_matrix::write (std::ostream& o) const {
+
+  // figure out an appropriate width based on the longest sequence name
+  size_t width = 8;
+  for (size_t i = 0; i < __seq_db.size(); ++i)
+    width = std::max (width, __seq_db.get_seq (i).name.length() + 2);
+
+  // precision of floating-point output
+  const size_t precision = 3;
+
+  // write header
+  o.width (width); o << "";
+  for (size_t i = 0; i < __similarities.size(); ++i) {
+    o.width (width);
+    o << __seq_db.get_seq (i).name;
+  }
+  o << endl;
+
+  // matrix itself
+  for (size_t i = 0; i < __similarities.size(); ++i) {
+    o.width (width);
+    o << __seq_db.get_seq (i).name;
+    for (size_t j = 0; j < __similarities.size(); ++j) {
+      o.width (width);
+      if (i == j)
+	o << "";
+      else
+	o << std::setprecision (precision) << get_similarity (i, j);
+    }
+    o << endl;
+  }
+  
+}
+
+void Sequence_similarity_matrix::compute_kmer_similarity_matrix (const Sequence_database& seq_db,
+								 const Alphabet& alphabet,
+								 const size_t k) {
+
+  // check sane
+  assert (seq_db.size() > 1);
+  assert (seq_db.matches_alphabet (alphabet));
+
+  // initialize appropriate Sequence_kmer_counts object
+  const Sequence_kmer_counts counter (alphabet, k);
+
+  // accumulate k-mer counts for each sequence
+  std::vector<Sequence_kmer_counts::Kmer_counts> kmer_counts_db (seq_db.size());
+  for (size_t i = 0; i < seq_db.size(); ++i)
+    kmer_counts_db[i] = counter.compute_counts (seq_db.get_seq (i));
+
+  // compute similarities
+  assert (__similarities.size() == seq_db.size());
+  for (size_t i = 0; i < seq_db.size(); ++i) {
+
+    // check sane
+    assert (__similarities[i].size() == seq_db.size());
+
+    // set diagonal entries to one
+    __similarities[i][i] = 1;
+
+    // catch the case of a 0-length sequence
+    if (seq_db.get_seq (i).length() == 0)
+      continue;
+
+    for (size_t j = i + 1; j < seq_db.size(); ++j) {
+
+      // catch the case of a 0-length sequence
+      if (seq_db.get_seq (j).length() == 0)
+	continue;
+
+      // compute k-mer similarity and normalize with the length of the shorter sequence
+      __similarities[i][j] = static_cast<double> (compute_kmer_similarity (kmer_counts_db[i], kmer_counts_db[j]));
+      __similarities[i][j] /=
+	(std::min (seq_db.get_seq (i).length(), seq_db.get_seq (j).length()) >= k)
+	? std::min (seq_db.get_seq (i).length(), seq_db.get_seq (j).length()) - (k - 1)
+	: std::min (seq_db.get_seq (i).length(), seq_db.get_seq (j).length());
+
+      // matrix is symmetric
+      __similarities[j][i] = __similarities[i][j];
+
+      // check sane
+      if (__similarities[i][j] < 0.)
+	cerr << __similarities[i][j] << endl;
+      assert (__similarities[i][j] >= 0.);
+      assert (__similarities[i][j] <= 1. + Mathematics::double_very_tiny);
+
+    }
+
+  }
+
+}
diff --git a/src/seq/similarity_matrix.h b/src/seq/similarity_matrix.h
new file mode 100644
index 0000000..9746c8e
--- /dev/null
+++ b/src/seq/similarity_matrix.h
@@ -0,0 +1,198 @@
+
+/**
+ * \file similarity_matrix.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef SEQ_SIMILARITY_MATRIX_INCLUDED
+#define SEQ_SIMILARITY_MATRIX_INCLUDED
+
+#include "util/misc.h"
+#include "seq/alphabet.h"
+#include "seq/sequence.h"
+
+namespace fsa {
+
+  /**
+   * \brief Compute k-mer statistics of sequences.
+   */
+  struct Sequence_kmer_counts {
+    
+  public:
+
+    typedef uintmax_t Kmer_index;                      ///< numerical index of a k-mer
+    typedef std::map<Kmer_index, size_t> Kmer_counts;  ///< k-mer counts for a sequence
+
+    /**
+     * Constructor.
+     * \param k word length
+     */
+    Sequence_kmer_counts (const Alphabet& alphabet,
+			  const size_t k);
+
+    /**
+     * \brief Compute the k-mer counts of a sequence.
+     */
+    Kmer_counts compute_counts (const Sequence& sequence) const;
+    
+    /**
+     * \brief Compute the minimum word length (>= 1) appropriate for computing distances.
+     *
+     * Given a uniform distribution over characters of the alphabet, compute
+     *  k = log_|A| (L) + 1,  |A| = alphabet size
+     * the minimum word length such that the expected number of occurrences
+     * of a particular k-mer is < 1.
+     * The length L is the median length of the sequences.
+     */
+    static size_t choose_minimum_word_length (const Sequence_database& seq_db,
+					      const Alphabet& alphabet);
+
+    /**
+     * \brief Get number of possible words.
+     * 
+     * Note that this corresponds to 1 + the maximum index, e.g., a nonsense k-mer.
+     * \see kmer_to_index
+     */
+    Kmer_index num_words() const { return __num_words; }
+
+    /**
+     * \brief Length of words.
+     */
+    size_t k() const { return __k; }
+
+  private:
+
+    /**
+     * \brief Convert a substring of the passed string to the corresponding k-mer integral index.
+     *
+     * Considers the k-mer str.substr (start, __k).
+     * It is the responsibility of the calling function to ensure that the
+     * string boundaries are not overrun.
+     *
+     * \param str string to take a substring of
+     * \param start position (0-based) of the k-mer
+     * \return index or num_words() if the k-mer contains a character which is either degenerate or not in the alphabet
+     */
+    Kmer_index kmer_to_index (const std::string& str, const unsigned start) const;
+
+    Alphabet __alphabet;              ///< alphabet which the k-mer are defined over
+    unsigned short __k;               ///< word length
+    Kmer_index __num_words;           ///< \see num_words
+
+    std::vector<size_t> __powers_of_alphabet_size;  ///< \see kmer_to_index
+
+  };
+
+  /**
+   * \brief Represent a matrix of similarities between pairs of sequences based on k-mer counts.
+   */
+  struct Sequence_similarity_matrix {
+
+  public:
+    
+    /**
+     * \brief Constructor.
+     */
+    Sequence_similarity_matrix (const Sequence_database& seq_db,
+				const Alphabet& alphabet,
+				const size_t k);
+
+    /**
+     * \brief Get the similarity between two sequences.
+     */
+    double get_similarity (const size_t i, const size_t j) const;
+
+    /**
+     * \brief Output method.
+     */
+    void write (std::ostream& o) const;
+
+  private:
+
+    /**
+     * \brief Compute the k-mer similarity between two sequences.
+     *
+     * Computed as:
+     * counts <- 0
+     * For each k-mer w in X
+     *   counts += min (# instances of w in X, # instances of w in Y)
+     * (the outer loop is over k-mers of X or Y, depending upon which is the smaller set)
+     *
+     * \param counts_x k-mer counts for sequence X
+     * \param counts_y k-mer counts for sequence Y
+     */
+    static size_t compute_kmer_similarity (const Sequence_kmer_counts::Kmer_counts& counts_x, const Sequence_kmer_counts::Kmer_counts& counts_y);
+
+    /**
+     * \brief Compute the k-mer similarity matrix between all pairs of sequences.
+     *
+     * The similarity between two sequences is defined as the
+     * total number of shared k-mers divided by the length of the
+     * shortest sequence.  We divide by the length of the shortest
+     * sequence to avoid a systematic bias towards longer sequences.
+     * Each entry in the similarity matrix therefore falls in the interval [0, 1].
+     * Sets diagonal entries (the similarities of sequences with themselves) to 1.
+     *
+     * \param seq_db sequences to consider
+     * \param alphabet alphabet over which sequences are defined
+     * \param k word length to use
+     * \see compute_kmer_similarity
+     */
+    void compute_kmer_similarity_matrix (const Sequence_database& seq_db,
+					 const Alphabet& alphabet,
+					 const size_t k);
+
+    const Sequence_database& __seq_db;                  ///< sequence data
+    std::vector<std::vector<double> > __similarities;   ///< sequence similarity matrix
+
+  };
+
+  inline Sequence_kmer_counts::Kmer_index Sequence_kmer_counts::kmer_to_index (const std::string& str, const unsigned start) const {
+
+    // catch case of k = 0
+    if (k() == 0)
+      return 0;
+
+    // assert sane
+    assert (start + k() - 1 <= str.length());
+
+    Sequence_kmer_counts::Kmer_index index = 0;
+    for (size_t i = 0; i < k(); ++i) {
+
+      const char ch = str[start + i];
+
+      if (!__alphabet.is_nondegen_char (ch))
+	return num_words();
+
+      // exploit 2-bit representation of a DNA alphabet if possible (the hare)
+      if (__alphabet.size() == 4) {
+	index <<= 2; // because 2 bits per character
+	index |= __alphabet.get_char_index (ch);
+      }
+
+      // else do it with multiplication (the tortoise)
+      // (but not too slow, since we've hardcoded in powers of the alphabet size)
+      // note that the "backwards" vector indexing is so that the leftmost character,
+      // which we see first, corresponds to the largest power of the alphabet size
+      // (which is how the above bit-shifting works)
+      else
+	index += __alphabet.get_char_index (ch) * __powers_of_alphabet_size[k() - i - 1];
+
+    }
+
+    assert (index < num_words());
+
+    return index;
+
+  }
+
+  inline double Sequence_similarity_matrix::get_similarity (const size_t i, const size_t j) const {
+    assert (i < __similarities.size());
+    assert (j < __similarities.size());
+    return __similarities[i][j];
+  }
+
+}
+
+#endif /* SEQ_SIMILARITY_MATRIX_INCLUDED */
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
new file mode 100644
index 0000000..74948eb
--- /dev/null
+++ b/src/util/Makefile.am
@@ -0,0 +1,24 @@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+
+noinst_LIBRARIES = libutil.a
+libutil_a_SOURCES = \
+	dexception.cc \
+	logfile.cc \
+	memcheck.cc \
+	misc.cc \
+	opts_list.cc \
+	regexp.cc \
+	sstring.cc
+
+noinst_HEADERS = \
+	array2d.h \
+	dexception.h \
+	hash_fcn.h \
+	logfile.h \
+	logtags.h \
+	macros.h \
+	memcheck.h \
+	misc.h \
+	opts_list.h \
+	regexp.h \
+	sstring.h
diff --git a/src/util/Makefile.in b/src/util/Makefile.in
new file mode 100644
index 0000000..adde048
--- /dev/null
+++ b/src/util/Makefile.in
@@ -0,0 +1,570 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = src/util
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+AM_V_AR = $(am__v_AR_ at AM_V@)
+am__v_AR_ = $(am__v_AR_ at AM_DEFAULT_V@)
+am__v_AR_0 = @echo "  AR      " $@;
+am__v_AR_1 = 
+libutil_a_AR = $(AR) $(ARFLAGS)
+libutil_a_LIBADD =
+am_libutil_a_OBJECTS = dexception.$(OBJEXT) logfile.$(OBJEXT) \
+	memcheck.$(OBJEXT) misc.$(OBJEXT) opts_list.$(OBJEXT) \
+	regexp.$(OBJEXT) sstring.$(OBJEXT)
+libutil_a_OBJECTS = $(am_libutil_a_OBJECTS)
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+AM_V_CXX = $(am__v_CXX_ at AM_V@)
+am__v_CXX_ = $(am__v_CXX_ at AM_DEFAULT_V@)
+am__v_CXX_0 = @echo "  CXX     " $@;
+am__v_CXX_1 = 
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
+AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
+am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
+am__v_CXXLD_0 = @echo "  CXXLD   " $@;
+am__v_CXXLD_1 = 
+SOURCES = $(libutil_a_SOURCES)
+DIST_SOURCES = $(libutil_a_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+HEADERS = $(noinst_HEADERS)
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+# Read a list of newline-separated strings from the standard input,
+# and print each of them once, without duplicates.  Input order is
+# *not* preserved.
+am__uniquify_input = $(AWK) '\
+  BEGIN { nonempty = 0; } \
+  { items[$$0] = 1; nonempty = 1; } \
+  END { if (nonempty) { for (i in items) print i; }; } \
+'
+# Make sure the list of sources is unique.  This is necessary because,
+# e.g., the same source file might be shared among _SOURCES variables
+# for different programs/libraries.
+am__define_uniq_tagged_files = \
+  list='$(am__tagged_files)'; \
+  unique=`for i in $$list; do \
+    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+  done | $(am__uniquify_input)`
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I$(top_srcdir)/src
+noinst_LIBRARIES = libutil.a
+libutil_a_SOURCES = \
+	dexception.cc \
+	logfile.cc \
+	memcheck.cc \
+	misc.cc \
+	opts_list.cc \
+	regexp.cc \
+	sstring.cc
+
+noinst_HEADERS = \
+	array2d.h \
+	dexception.h \
+	hash_fcn.h \
+	logfile.h \
+	logtags.h \
+	macros.h \
+	memcheck.h \
+	misc.h \
+	opts_list.h \
+	regexp.h \
+	sstring.h
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/util/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign src/util/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+libutil.a: $(libutil_a_OBJECTS) $(libutil_a_DEPENDENCIES) $(EXTRA_libutil_a_DEPENDENCIES) 
+	$(AM_V_at)-rm -f libutil.a
+	$(AM_V_AR)$(libutil_a_AR) libutil.a $(libutil_a_OBJECTS) $(libutil_a_LIBADD)
+	$(AM_V_at)$(RANLIB) libutil.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dexception.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/logfile.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/memcheck.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/misc.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/opts_list.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regexp.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sstring.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(AM_V_CXX at am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+ID: $(am__tagged_files)
+	$(am__define_uniq_tagged_files); mkid -fID $$unique
+tags: tags-am
+TAGS: tags
+
+tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	set x; \
+	here=`pwd`; \
+	$(am__define_uniq_tagged_files); \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: ctags-am
+
+CTAGS: ctags
+ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
+	$(am__define_uniq_tagged_files); \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+cscopelist: cscopelist-am
+
+cscopelist-am: $(am__tagged_files)
+	list='$(am__tagged_files)'; \
+	case "$(srcdir)" in \
+	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
+	  *) sdir=$(subdir)/$(srcdir) ;; \
+	esac; \
+	for i in $$list; do \
+	  if test -f "$$i"; then \
+	    echo "$(subdir)/$$i"; \
+	  else \
+	    echo "$$sdir/$$i"; \
+	  fi; \
+	done >> $(top_builddir)/cscope.files
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES) $(HEADERS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
+	uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/util/array2d.h b/src/util/array2d.h
new file mode 100644
index 0000000..e6991a4
--- /dev/null
+++ b/src/util/array2d.h
@@ -0,0 +1,421 @@
+#ifndef ARRAY2D_INCLUDED
+#define ARRAY2D_INCLUDED
+
+#include <cstddef>
+#include <vector>
+#include <functional>
+#include <algorithm>
+#include "util/dexception.h"
+#include "util/logfile.h"
+
+namespace fsa {
+
+  // xy_container's must implement the following
+  //   operator==
+  //   swap (xy_container_type)
+  //   default, copy constructors
+  //  ...plus the following xy constructor...
+  //   xy_container_type (int xsize, int ysize, const_reference default_val)
+  //  ...and the following xy accessors...
+  //   inline const_reference get_xy_or_default (int x, int y, int xsize, int ysize) const    [nonperturbative]
+  //   inline reference get_xy (int x, int y, int xsize, int ysize)  [creates (x,y) entry if it does not exist]
+
+  template<class T>
+    struct array2d_dense_vector : std::vector<T>
+    {
+      inline array2d_dense_vector() : std::vector<T>() { }
+      inline array2d_dense_vector (const array2d_dense_vector<T>& a) : std::vector<T> (a) { }
+      inline array2d_dense_vector (int xsize, int ysize, const T& default_val) : std::vector<T> (xsize*ysize, default_val) { }
+      inline const T& get_xy_or_default (int x, int y, int xsize, int ysize) const { return (*this) [x + y * xsize]; }
+      inline T& get_xy (int x, int y, int xsize, int ysize) { return (*this) [x + y * xsize]; }
+    };
+
+  template<class T>
+    struct array2d_sparse_vector : std::vector< std::map<int,T> >
+    {
+      // typedefs
+      typedef typename std::map<int,T>::iterator map_iterator;
+      typedef typename std::map<int,T>::const_iterator const_map_iterator;
+
+      // data: default value
+      T default_val;
+
+      // methods
+      inline array2d_sparse_vector() : std::vector< std::map<int,T> >() { }
+      inline array2d_sparse_vector (const array2d_sparse_vector<T>& a) : std::vector< std::map<int,T> > (a) { }
+      inline array2d_sparse_vector (int xsize, int ysize, const T& default_val)
+	: std::vector< std::map<int,T> > (ysize),
+	default_val (default_val)
+	{ }
+
+      inline const T& get_xy_or_default (int x, int y, int xsize, int ysize) const {
+	const std::map<int,T>& col = (*this)[y];
+	const_map_iterator i = col.find (x);
+	if (i == col.end())
+	  return default_val;
+	return (*i).second;
+      }
+
+      inline T& get_xy (int x, int y, int xsize, int ysize) {
+	std::map<int,T>& col = (*this)[y];
+	map_iterator i = col.find (x);
+	if (i == col.end())
+	  return col[x] = default_val;
+	return (*i).second;
+      }
+    };
+
+  // array2d class
+
+  /* Problems: confusingly, operator<< and operator>> output the transpose of the array, i.e. rows become columns
+     This confusion arises from the (x,y) indexing convention of arrays and the (row,col) indexing of matrices.
+     As a workaround, use write_rowcol() and read_rowcol() methods.
+  */
+
+  template <class T, class xy_container_type = array2d_dense_vector<T> >
+    class array2d
+    {
+    public:
+    typedef T          value_type;
+    typedef T&         reference;
+    typedef const T&   const_reference;
+    typedef T*         pointer;
+  
+    typedef ptrdiff_t  difference_type;
+    typedef size_t     size_type;
+
+    typedef array2d <value_type, xy_container_type> array2d_type;
+
+    private:
+    int _xsize, _ysize;
+    xy_container_type _data;
+  
+    public:
+  
+    std::vector<int> dim() const { std::vector<int> d(2); d[0] = _xsize; d[1] = _ysize; return d; }
+    int xsize() const { return _xsize; }
+    int ysize() const { return _ysize; }
+    int columns() const { return _xsize; }
+    int rows() const { return _ysize; }
+    int rank() const { return 2; }
+
+    bool operator== (const array2d_type& a) const
+    { return _xsize == a._xsize && _ysize == a._ysize && _data == a._data; }
+
+    // NB row/column addressing is opposite to matrices:
+    // matrices use (row,column), we use (x,y)=(column,row)
+    //
+
+    reference operator()(int x, int y)
+    {
+#ifdef DART_DEBUG
+      if (x < 0 || x >= _xsize || y < 0 || y >= _ysize)
+	DART_DEBUG_ERROR ("array2d overflow");
+#endif
+      return _data.get_xy (x, y, _xsize, _ysize);
+    }
+    const_reference operator()(int x, int y) const
+    {
+#ifdef DART_DEBUG
+      if (x < 0 || x >= _xsize || y < 0 || y >= _ysize)
+	DART_DEBUG_ERROR ("array2d overflow");
+#endif
+      return _data.get_xy_or_default (x, y, _xsize, _ysize);
+    }
+
+    reference operator[](const std::vector<int>& k) { return (*this) (k[0], k[1]); }
+    const_reference operator[](const std::vector<int>& k) const { return (*this) (k[0], k[1]); }
+
+    reference operator[](const std::pair<int, int>& k) { return (*this) (k.first, k.second); }
+    const_reference operator[](const std::pair<int, int>& k) const { return (*this) (k.first, k.second); }
+
+    reference entry (int x, int y) { return (*this) (x, y); }
+    const_reference entry (int x, int y) const { return (*this) (x, y); }
+
+    void fill (const value_type& fill_value)
+    {
+      for (int x = 0; x < xsize(); ++x)
+	for (int y = 0; y < ysize(); ++y)
+	  (*this)(x,y) = fill_value;
+    }
+
+    void resize (int new_xsize, int new_ysize, const value_type& default_value)
+    {
+      array2d_type new_array (new_xsize, new_ysize, default_value);
+      for (int x = 0; x < std::min (_xsize, new_xsize); ++x)
+	for (int y = 0; y < std::min (_ysize, new_ysize); ++y)
+	  new_array (x, y) = entry (x, y);
+      swap (new_array);
+    }
+
+    void swap (array2d_type& a)
+    {
+      std::swap (_xsize, a._xsize);
+      std::swap (_ysize, a._ysize);
+      _data.swap (a._data);
+    }
+
+    // iterators
+    struct xy_iterator : public std::iterator <std::forward_iterator_tag, T>
+    {
+      // data
+      int x, y;
+      array2d_type* a;
+      // methods
+    xy_iterator() : x(0), y(0), a(0) { }
+      xy_iterator (int x, int y, array2d_type* a) : x(x), y(y), a(a) { }
+      T& operator*() { return (*a)(x,y); }
+      const T& operator*() const { return (*a)(x,y); }
+      bool operator== (const xy_iterator& i) const { return y==i.y && x==i.x && a==i.a; }
+      bool operator!= (const xy_iterator& i) const { return !(*this==i); }
+      xy_iterator& operator++() { if (++x >= a->xsize()) { x = 0; ++y; } return *this; }
+    };
+
+    typedef xy_iterator iterator;
+    typedef xy_iterator const_iterator;
+
+    iterator begin() { return xy_iterator (0, 0, this); }
+    iterator end() { return xy_iterator (0, ysize(), this); }
+    const_iterator begin() const { return xy_iterator (0, 0, (array2d_type*) this); }
+    const_iterator end() const { return xy_iterator (0, ysize(), (array2d_type*) this); }
+
+    // row & column iterators
+    class Row_iterator
+    {
+      // iterator typedefs (inheriting from iterator seems to crash the compiler)
+    public:
+    typedef std::random_access_iterator_tag iterator_category;
+    typedef T value_type;
+    typedef ptrdiff_t difference_type;
+    typedef T* pointer;
+    typedef T& reference;
+
+    // the real stuff
+    private:
+    array2d_type* _array;
+    int _row;
+    int _col_offset;
+    bool _same_row (const Row_iterator& i) const { return _array==i._array && _row==i._row; }
+    public:
+    Row_iterator (array2d_type& a, int row, int col_offset = 0) : _array(&a), _row(row), _col_offset(col_offset) { }
+    reference operator[] (int col) { return (*_array) (_row, col + _col_offset); }
+    const_reference operator[] (int col) const { return (*_array) (_row, col + _col_offset); }
+    reference operator*() { return (*this)[0]; }
+    const_reference operator*() const { return (*this)[0]; }
+    bool operator== (const Row_iterator& i) const { return _same_row(i) && _col_offset==i._col_offset; }
+    Row_iterator& operator++() { ++_col_offset; return *this; }
+    Row_iterator operator++ (int) { Row_iterator tmp = *this; ++_col_offset; return tmp; }
+    Row_iterator& operator--() { --_col_offset; return *this; }
+    Row_iterator operator-- (int) { Row_iterator tmp = *this; --_col_offset; return tmp; }
+    Row_iterator& operator+= (ptrdiff_t d) { _col_offset += d; return *this; }
+    Row_iterator& operator-= (ptrdiff_t d) { _col_offset -= d; return *this; }
+    friend Row_iterator operator+ (const Row_iterator& l, ptrdiff_t d) { Row_iterator res = l; res += d; return res; }
+    friend Row_iterator operator- (const Row_iterator& l, ptrdiff_t d) { Row_iterator res = l; res -= d; return res; }
+    ptrdiff_t operator- (const Row_iterator& i) const
+    {
+      if (!_same_row(i)) THROW fsa::Standard_exception ("Can't subtract array2d<>::Row_iterator's of different types");
+      return _col_offset - i._col_offset;
+    }
+    };
+
+    class Column_iterator
+    {
+      // iterator typedefs (inheriting from iterator seems to crash the compiler)
+    public:
+      typedef std::random_access_iterator_tag iterator_category;
+      typedef T value_type;
+      typedef ptrdiff_t difference_type;
+      typedef T* pointer;
+      typedef T& reference;
+
+      // the real stuff
+    private:
+      array2d_type* _array;
+      int _col;
+      int _row_offset;
+      bool _same_col (const Column_iterator& i) const { return _array==i._array && _col==i._col; }
+    public:
+      Column_iterator (array2d_type& a, int col, int row_offset = 0) : _array(&a), _col(col), _row_offset(row_offset) { }
+      reference operator[] (int row) { return (*_array) (row + _row_offset, _col); }
+      const_reference operator[] (int row) const { return (*_array) (row + _row_offset, _col); }
+      reference operator*() { return (*this)[0]; }
+      const_reference operator*() const { return (*this)[0]; }
+      bool operator== (const Column_iterator& i) const { return _same_col(i) && _row_offset==i._row_offset; }
+      Column_iterator& operator++() { ++_row_offset; return *this; }
+      Column_iterator operator++ (int) { Column_iterator tmp = *this; ++_row_offset; return tmp; }
+      Column_iterator& operator--() { --_row_offset; return *this; }
+      Column_iterator operator-- (int) { Column_iterator tmp = *this; --_row_offset; return tmp; }
+      Column_iterator& operator+= (ptrdiff_t d) { _row_offset += d; return *this; }
+      Column_iterator& operator-= (ptrdiff_t d) { _row_offset -= d; return *this; }
+      friend Column_iterator operator+ (const Column_iterator& l, ptrdiff_t d) { Column_iterator res = l; res += d; return res; }
+      friend Column_iterator operator- (const Column_iterator& l, ptrdiff_t d) { Column_iterator res = l; res -= d; return res; }
+      ptrdiff_t operator- (const Column_iterator& i) const
+      {
+	if (!_same_col(i)) THROW Standard_exception ("Can't subtract array2d::Column_iterator's of different types");
+	return _row_offset - i._row_offset;
+      }
+      Column_iterator begin() const { return *this; }
+      Column_iterator end() const { return Column_iterator (_array, _col, _array->rows()); }
+    };
+
+    // row & column views
+    class Row_view
+    {
+    private:
+      Row_iterator _begin;
+      Row_iterator _end;
+    public:
+      Row_view (array2d_type& a, int row)
+	: _begin (a, row, 0), _end (a, row, a.columns())
+	{ }
+
+      Row_view (array2d_type& a, int row, int begin_col, int end_col)
+	: _begin (a, row, begin_col), _end (a, row, end_col)
+	{ }
+
+      const Row_iterator& begin() const { return _begin; }
+      const Row_iterator& end() const { return _end; }
+      // override operator[] to do range checking for debug compilation
+      reference operator[] (int col)
+      {
+#ifdef DART_DEBUG
+	if (col < 0 || col >= _end - _begin) DART_DEBUG_ERROR ("Row_view overflow");
+#endif /* DART_DEBUG */
+	return _begin[col];
+      }
+      const_reference operator[] (int col) const
+      {
+#ifdef DART_DEBUG
+	if (col < 0 || col >= _end - _begin) DART_DEBUG_ERROR ("Row_view overflow");
+#endif /* DART_DEBUG */
+	return _begin[col];
+      }
+    };
+
+    class Column_view
+    {
+    private:
+      Column_iterator _begin;
+      Column_iterator _end;
+    public:
+      Column_view (array2d_type& a, int col)
+	: _begin (a, col, 0), _end (a, col, a.columns())
+	{ }
+
+      Column_view (array2d_type& a, int col, int begin_row, int end_row)
+	: _begin (a, col, begin_row), _end (a, col, end_row)
+	{ }
+
+      const Column_iterator& begin() const { return _begin; }
+      const Column_iterator& end() const { return _end; }
+      // override operator[] to do range checking for debug compilation
+      reference operator[] (int col)
+      {
+#ifdef DART_DEBUG
+	if (col < 0 || col >= _end - _begin) DART_DEBUG_ERROR ("Column_view overflow");
+#endif /* DART_DEBUG */
+	return _begin[col];
+      }
+      const_reference operator[] (int col) const
+      {
+#ifdef DART_DEBUG
+	if (col < 0 || col >= _end - _begin) DART_DEBUG_ERROR ("Column_view overflow");
+#endif /* DART_DEBUG */
+	return _begin[col];
+      }
+    };
+
+    // row & column accessors
+
+    const Row_view row (int row) const { return Row_view (*this, row); }
+    const Row_view row (int row, int begin_col, int end_col) const { return Row_view (*this, row, begin_col, end_col); }
+
+    Row_view row (int row) { return Row_view (*this, row); }
+    Row_view row (int row, int begin_col, int end_col) { return Row_view (*this, row, begin_col, end_col); }
+
+    const Column_view column (int col) const { return Column_view (*this, col); }
+    const Column_view column (int col, int begin_row, int end_row) const { return Column_view (*this, col, begin_row, end_row); }
+  
+    Column_view column (int col) { return Column_view (*this, col); }
+    Column_view column (int col, int begin_row, int end_row) { return Column_view (*this, col, begin_row, end_row); }
+
+    // misc get & set methods
+
+    void set_row (int row, const std::vector<value_type>& v)
+    {
+      for (int x = 0; x < xsize(); x++) (*this)(x,row) = v[x];
+    }
+
+    void set_column (int col, const std::vector<value_type>& v)
+    {
+      for (int y = 0; y < ysize(); y++) (*this)(col,y) = v[y];
+    }
+
+    std::vector<std::vector<value_type> > all_columns() const
+    {
+      std::vector<std::vector<value_type> > v (ysize(), std::vector<value_type> (xsize(), (value_type) 0));
+      for (int x = 0; x < xsize(); x++)
+	for (int y = 0; y < ysize(); y++)
+	  v[x][y] = ((array2d_type&) *this)(x,y);
+      return v;
+    }
+
+    array2d_type transpose() const
+    {
+      array2d_type tmp (ysize(), xsize());
+      for (int x = 0; x < xsize(); x++)
+	for (int y = 0; y < ysize(); y++)
+	  tmp(y,x) = (*this)(x,y);
+      return tmp;
+    }
+
+    // constructors
+    array2d() : _xsize(0), _ysize(0), _data() {}
+
+    array2d (const array2d_type& a) :
+    _xsize(a._xsize), _ysize(a._ysize), _data(a._data) {}
+  
+    array2d (int xsize, int ysize, const value_type& t) :
+    _xsize(xsize), _ysize(ysize), _data(xsize, ysize, t)
+    {}
+  
+    array2d (int xsize, int ysize) :
+    _xsize(xsize), _ysize(ysize), _data(xsize, ysize, value_type())
+    {}
+
+    // i/o methods
+    void write_rowcol (std::ostream& out) const
+    {
+      for (int x = 0; x < xsize(); x++)
+	for (int y = 0; y < ysize(); y++)
+	  out << ((array2d_type&) *this) (x, y) << (y < ysize()-1 ? " " : "\n");
+    }
+    void read_rowcol (std::istream& in)
+    {
+      for (int x = 0; x < xsize(); x++)
+	for (int y = 0; y < ysize(); y++)
+	  in >> (*this) (x, y);
+    }
+    };
+
+  template <class T, class xy_container_type>
+    std::ostream& operator<< (std::ostream& out, const array2d<T,xy_container_type>& a)
+  {
+    for (int y = 0; y < a.ysize(); y++)
+      for (int x = 0; x < a.xsize(); x++)
+	out << ((array2d<T,xy_container_type>&) a) (x, y) << (x < a.xsize()-1 ? " " : "\n");
+    return out;
+  }
+
+  template <class T, class xy_container_type>
+    std::istream& operator>> (std::istream& in, array2d<T,xy_container_type>& a)
+  {
+    for (int y = 0; y < a.ysize(); y++)
+      for (int x = 0; x < a.xsize(); x++)
+	in >> a (x, y);
+    return in;
+  }
+
+}
+
+#endif
diff --git a/src/util/dexception.cc b/src/util/dexception.cc
new file mode 100644
index 0000000..f1af7b0
--- /dev/null
+++ b/src/util/dexception.cc
@@ -0,0 +1,120 @@
+
+#include <cstdio>
+
+#include "util/dexception.h"
+#include "util/logfile.h"
+
+// uncomment the following #define to allow debugging display of the function stack
+// (finally decided against leaving this as the default behaviour: it garbled the error message too many times - ihh, 8/15/03)
+// #define __SHOW_FUNCTION_STACK__
+
+using namespace fsa;
+
+Dart_exception::Dart_exception()
+{
+  stack_trace.clear();  // dummy, redundant line of code just so we have some place to set a breakpoint
+#ifdef __SHOW_FUNCTION_STACK__
+#ifdef __GNUC__
+  // this code is VERY messy and doesn't work right, but a stack trace is a nice thing to have, even a half-working one
+  void* ret_addr[20];
+  int d = 0;
+  void* fa;
+  fa = __builtin_frame_address(0);
+  if (fa) { ret_addr[d++] = __builtin_return_address(0); fa = __builtin_frame_address(1); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(1); fa = __builtin_frame_address(2); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(2); fa = __builtin_frame_address(3); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(3); fa = __builtin_frame_address(4); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(4); fa = __builtin_frame_address(5); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(5); fa = __builtin_frame_address(6); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(6); fa = __builtin_frame_address(7); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(7); fa = __builtin_frame_address(8); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(8); fa = __builtin_frame_address(9); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(9); fa = __builtin_frame_address(10); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(10); fa = __builtin_frame_address(11); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(11); fa = __builtin_frame_address(12); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(12); fa = __builtin_frame_address(13); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(13); fa = __builtin_frame_address(14); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(14); fa = __builtin_frame_address(15); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(15); fa = __builtin_frame_address(16); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(16); fa = __builtin_frame_address(17); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(17); fa = __builtin_frame_address(18); }
+  if (fa) { ret_addr[d++] = __builtin_return_address(18); fa = __builtin_frame_address(19); }
+  if (fa) ret_addr[d++] = __builtin_return_address(19);
+  // the following line was added to work around mysterious, intermittent corruption of stack_trace...
+  // this now seems to have disappeared, but it did that once before and came back... perhaps the code is haunted?
+  stack_trace << "*** exception *** exception *** exception *** exception *** exception *** exception *** exception *** exception ***\n";
+  stack_trace << "Function stack (depth=" << d;
+  if (d == 20) stack_trace << '+';
+  stack_trace << "):";
+  for (int level = 0; level < d; ++level)
+    {
+      char hex[100];   // i assume this will never run on a >400-bit machine
+      sprintf (hex, "%.8x", ret_addr[level]);
+      stack_trace << " *0x" << hex;
+    }
+  if (d == 20) stack_trace << " ...";
+  stack_trace << '\n';
+  stack_trace << "*** exception *** exception *** exception *** exception *** exception *** exception *** exception *** exception ***\n";
+  stack_trace << '\n';
+#endif  /* __GNUC__ */  
+#endif  /* __SHOW_FUNCTION_STACK__ */
+}
+
+Dart_exception::~Dart_exception() { }
+
+const char* Dart_exception::what() const
+{
+  sstring& what = (sstring&) _what;  // cast away const
+  what.clear();
+  what << stack_trace;
+  what << details();
+  return what.c_str();
+}
+
+const char* Dart_exception::details() const
+{
+  return "unknown exception\n";
+}
+
+Standard_exception::Standard_exception (const char* m) : Dart_exception(), msg(m)
+{
+  msg.append("\n");
+}
+
+Standard_exception::Standard_exception (const sstring& m) : Dart_exception(), msg(m)
+{
+  msg.append("\n");
+}
+
+const char* Standard_exception::details() const
+{
+  return msg.c_str();
+}
+
+Format_exception::Format_exception (std::istream& in) : Dart_exception() { info = ""; setup_info (in); }
+Format_exception::Format_exception (std::istream& in, const char* prefix) : Dart_exception() { info << prefix << '\n'; setup_info (in); }
+Format_exception::Format_exception (std::istream& in, const sstring& prefix) : Dart_exception() { info << prefix << '\n'; setup_info (in); }
+
+void Format_exception::setup_info (std::istream& in)
+{
+  info << "Bad input format, somewhere before ";
+  if (in.eof()) info.append("EOF\n");
+  else
+    {
+      info.append("'");
+      char c;
+      for (int i = 0; i < 20 && !in.eof(); i++)
+	if ((c = in.get()) != '\n') { if (!in.eof()) info.push_back(c); } else info.append("\\n");
+      info.append("'\n");
+    }
+}
+
+const char* Format_exception::details() const
+{
+  return info.c_str();
+}
+
+const char* String_exception::details() const
+{
+  return msg.c_str();
+}
diff --git a/src/util/dexception.h b/src/util/dexception.h
new file mode 100644
index 0000000..a0e3e1f
--- /dev/null
+++ b/src/util/dexception.h
@@ -0,0 +1,58 @@
+// my exception class
+
+#ifndef DART_EXCEPTION_INCLUDED
+#define DART_EXCEPTION_INCLUDED
+
+#include "util/sstring.h"
+
+namespace fsa {
+
+  struct Dart_exception
+  {
+    sstring stack_trace, _what;
+
+    Dart_exception();
+    virtual ~Dart_exception();
+
+    virtual const char* details() const;
+    const char* what() const;
+  };
+
+  class Standard_exception : public Dart_exception
+  {
+  protected:
+    sstring msg;
+
+  public:
+    Standard_exception (const char* m);
+    Standard_exception (const sstring& m);
+    const char* details() const;
+  };
+
+  class Format_exception : public Dart_exception
+  {
+  protected:
+    sstring info;
+    void setup_info (std::istream& in);
+
+  public:
+    Format_exception (std::istream& in);
+    Format_exception (std::istream& in, const char* prefix);
+    Format_exception (std::istream& in, const sstring& prefix);
+    const char* details() const;
+  };
+
+  class String_exception : public Dart_exception
+  {
+  protected:
+    sstring msg;
+
+  public:
+    String_exception (const char* m, const char* arg) : Dart_exception(), msg(m) { msg.append(arg).append("\n"); }
+    String_exception (const char* m, const sstring& arg) : Dart_exception(), msg(m) { msg.append(arg).append("\n"); }
+    const char* details() const;
+  };
+
+}
+
+#endif
diff --git a/src/util/hash_fcn.h b/src/util/hash_fcn.h
new file mode 100644
index 0000000..360e1d7
--- /dev/null
+++ b/src/util/hash_fcn.h
@@ -0,0 +1,200 @@
+
+/**
+ * \file hash_fcn.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file implements Paul Hsieh's hash function,
+ *  found at http://www.azillionmonkeys.com/qed/hash.html.
+ */
+
+#ifndef HASH_FCN_INCLUDED
+#define HASH_FCN_INCLUDED
+
+#include <cstring>
+#include <config.h>
+#include <stdint.h>
+
+#undef get16bits
+#if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__)	\
+  || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
+#define get16bits(d) (*((const uint16_t *) (d)))
+#endif
+
+#if !defined (get16bits)
+#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)	\
+		      +(uint32_t)(((const uint8_t *)(d))[0]) )
+#endif
+
+namespace fsa {
+
+  typedef unsigned short bit16_t;
+  typedef unsigned int bit32_t;
+  typedef unsigned long long bit64_t;
+
+  /// Assorted hash functions.
+  // NB: Who knows why, but I get "duplicate symbol" errors
+  // if these functions aren't wrapped up in a struct.
+  struct Hash_functions {
+
+    /// Hash for 16-bit integer.
+    /*
+     * \param key int to hash
+     */
+    static inline bit32_t bit16_t_hash (const bit16_t key) {
+      return __lh3_Wang_hash_int (bit32_t (key));
+    }
+
+    /// Hash for 32-bit integer.
+    /*
+     * \param key int to hash
+     */
+    static inline bit32_t bit32_t_hash (const bit32_t key) {
+      return __lh3_Wang_hash_int (key);
+    }
+
+    /// Hash for 64-bit integer.
+    /*
+     * \param key int to hash
+     */
+    static inline bit32_t bit64_t_hash (const bit64_t key) {
+      return bit32_t (__lh3_Jenkins_hash_64 (key));
+    }
+
+    /// Hash for two 64-bit integers.
+    /*
+     * \param first first int to hash
+     * \param second second int to hash
+     *
+     * XORs the two integers, then uses the Jenkins hash.
+     */
+    static inline bit32_t bit64_t_pair_hash (const bit64_t first, const bit64_t second) {
+      return bit32_t (__lh3_Jenkins_hash_64 (first ^ second));
+    }
+
+    /// Wang's hash function for 32-bit integers.
+    static inline bit32_t __lh3_Wang_hash_int (bit32_t key) {
+      key += ~(key << 15);
+      key ^=  (key >> 10);
+      key +=  (key << 3);
+      key ^=  (key >> 6);
+      key += ~(key << 11);
+      key ^=  (key >> 16);
+      return key;
+    }
+
+    /// Jenkins' hash function for 64-bit integers.
+    static inline bit64_t __lh3_Jenkins_hash_64 (bit64_t key) {
+      key += ~(key << 32);
+      key ^= (key >> 22);
+      key += ~(key << 13);
+      key ^= (key >> 8);
+      key += (key << 3);
+      key ^= (key >> 15);
+      key += ~(key << 27);
+      key ^= (key >> 31);
+      return key;
+    }
+
+    /// Hsieh's hash.
+    /*
+     * \param data char array to hash
+     * \param len length of char array
+     * \see hsieh_hash_incr
+     */
+    static inline uint32_t hsieh_hash (const char* data, int len) {
+      return hsieh_hash_incr (data, len, len);
+    }
+
+    /// Hsieh's hash.
+    /*
+     * \param data char array to hash
+     * \see hsieh_hash_incr
+     */
+    static inline uint32_t hsieh_hash (const char* data) {
+      int len = std::strlen (data);
+      return hsieh_hash_incr (data, len, len);
+    }
+
+    /// Hsieh's hash for pairs.
+    /*
+     * \param first first element (char array) to hash
+     * \param second second element (char array) to hash
+     * \param len length of char array
+     * Hash first, then use that to hash second.
+     * Assumes that both first and second have identical lengths.
+     * \see hsieh_hash_incr
+     */
+    static inline uint32_t hsieh_hash_pair (const char* first, const char* second, int len) {
+      return hsieh_hash_incr (second, len, hsieh_hash_incr (first, len, 0));
+    }
+
+    /// Hsieh's hash for pairs.
+    /*
+     * \param first first element (char array) to hash
+     * \param second second element (char array) to hash
+     * Hash first, then use that to hash second.
+     * Assumes that both first and second have identical lengths.
+     * \see hsieh_hash_incr
+     */
+    static inline uint32_t hsieh_hash_pair (const char* first, const char* second) {
+      return hsieh_hash_incr (second, std::strlen (second), hsieh_hash_incr (first, std::strlen (first), 0));
+    }
+
+    /// Incremental version of Hsieh's hash.
+    /*
+     * \param data char array to hash
+     * \param len length of char array
+     * \param hash some constant
+     */
+    static inline uint32_t hsieh_hash_incr (const char* data, int len, uint32_t hash) {
+      uint32_t tmp;
+      int rem;
+
+      // the below previously was
+      //   if (len <= 0 || data == NULL) return 0;
+      // -- RKB 9/27/08
+      if (len <= 0 || data == 0) return 0;
+
+      rem = len & 3;
+      len >>= 2;
+
+      /* Main loop */
+      for (;len > 0; len--) {
+	hash  += get16bits (data);
+	tmp    = (get16bits (data+2) << 11) ^ hash;
+	hash   = (hash << 16) ^ tmp;
+	data  += 2*sizeof (uint16_t);
+	hash  += hash >> 11;
+      }
+
+      /* Handle end cases */
+      switch (rem) {
+      case 3: hash += get16bits (data);
+	hash ^= hash << 16;
+	hash ^= data[sizeof (uint16_t)] << 18;
+	hash += hash >> 11;
+	break;
+      case 2: hash += get16bits (data);
+	hash ^= hash << 11;
+	hash += hash >> 17;
+	break;
+      case 1: hash += *data;
+	hash ^= hash << 10;
+	hash += hash >> 1;
+      }
+
+      /* Force "avalanching" of final 127 bits */
+      hash ^= hash << 3;
+      hash += hash >> 5;
+      hash ^= hash << 4;
+      hash += hash >> 17;
+      hash ^= hash << 25;
+      hash += hash >> 6;
+
+      return hash;
+    }
+
+  };
+
+}
+
+#endif /* HASH_FCN_INCLUDED */
diff --git a/src/util/logfile.cc b/src/util/logfile.cc
new file mode 100644
index 0000000..167390b
--- /dev/null
+++ b/src/util/logfile.cc
@@ -0,0 +1,337 @@
+#include "util/logfile.h"
+#include "util/logtags.h"
+
+using namespace fsa;
+
+namespace fsa {
+  Log_streambuf clog_streambuf;
+  Log_stream    clog_stream (clog_streambuf, 9);
+  sstring       ERRSTR;   /* used as a temporary variable by THROWEXPR() macro */
+}
+
+Log_streambuf::Log_streambuf()
+  : std::streambuf()
+{
+  bare_newline = true;
+  verbose_on_stderr = false;
+  log_to_stderr = true;
+  log_to_file = false;
+  
+  datebuf = new char[TBUF_MAX_SZ + 1];
+  timebuf = new char[TBUF_MAX_SZ + 1];
+}
+
+Log_streambuf::~Log_streambuf()
+{
+  delete[] datebuf;
+  delete[] timebuf;
+}
+
+int Log_streambuf::overflow (int c)
+{
+  // print tags
+  if (bare_newline)
+    {
+      if (log_in_XML)
+	if (last_file_tag != file_tag)
+	  print_long_XML_tag();
+	else
+	  print_short_XML_tag();
+      else
+	print_tabbed_tag();
+      last_file_tag = file_tag;
+    }
+  // log the character
+  if (log_to_stdout) cout.put(c);
+  if (log_to_stderr) cerr.put(c);
+  if (log_to_file && logfile_open) logfile_stream.put(c);
+  // set (or unset) bare_newline flag
+  if (c == '\n')
+    {
+      bare_newline = TRUE;
+      if (log_to_stdout) cout.flush();
+      if (log_to_stderr) cerr.flush();
+      if (log_to_file && logfile_open) logfile_stream.flush();
+    }
+  else
+    bare_newline = FALSE;
+  // return
+  return 0;
+}
+
+void Log_streambuf::save_logfile_state()
+{
+  saved_logfile_state.push (Log_streambuf_vars (*this));
+}
+
+void Log_streambuf::restore_logfile_state()
+{
+  ((Log_streambuf_vars&) *this) = saved_logfile_state.top();
+  saved_logfile_state.pop();
+}
+
+void Log_streambuf::print_long_XML_tag()
+{
+  prepare_date_and_time();
+  newtag_buf.clear();
+  newtag_buf << '<' << CLOGXMLTAGNAME;
+  newtag_buf << " date=\"" << datebuf << "\" time=\"" << timebuf << "\" " << file_tag << "/>\n";
+  print_newtag_buf();
+}
+
+void Log_streambuf::print_short_XML_tag()
+{
+  const sstring old_datebuf (datebuf);
+  const sstring old_timebuf (timebuf);
+  prepare_date_and_time();
+  const bool date_changed = strcmp (datebuf, old_datebuf.c_str()) != 0;
+  const bool time_changed = strcmp (timebuf, old_timebuf.c_str()) != 0;
+  if (date_changed || time_changed)
+    {
+      newtag_buf.clear();
+      newtag_buf << '<' << CLOGXMLTAGNAME;
+      if (date_changed) newtag_buf << " date=\"" << datebuf << "\"";
+      if (time_changed) newtag_buf << " time=\"" << timebuf << "\"";
+      newtag_buf << "/>\n";
+      print_newtag_buf();
+    }
+}
+
+void Log_streambuf::print_tabbed_tag()
+{
+  prepare_date_and_time();
+  newtag_buf.clear();
+  newtag_buf << '[' << datebuf << ',' << timebuf << "] " << file_tag << "\t";
+  print_newtag_buf();
+}
+
+void Log_streambuf::print_newtag_buf()
+{
+  if (log_to_file && logfile_open) logfile_stream << newtag_buf;
+  if (log_to_stderr && verbose_on_stderr) cerr << newtag_buf;
+}
+
+Regexp stream_qualifier_re ("^(.*);([^;]*)$");
+Regexp bad_re ("[!#,:;]");
+Regexp level_range_re ("^(.*),([^,]*)$");
+Regexp range_re ("^(-?[0123456789]+):(-?[0123456789]+)$");
+Regexp above_re ("^(-?[0123456789]+)$");
+Regexp below_re ("^:(-?[0123456789]+)$");
+Regexp line_range_re ("^(.*)#([0123456789]+)-([0123456789]+)$");
+Regexp single_line_re ("^(.*)#([0123456789]+)$");
+Regexp pling_re ("^!(.*)$");
+Regexp filename_re ("^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_]+\\.[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]+$");
+Regexp tag_re ("^[ABCDEFGHIJKLMNOPQRSTUVWXYZ][ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789]+$");
+
+Log_stream::Log_directive::Log_directive (const sstring& directive_string)
+{
+  sstring d = directive_string;
+
+  // chop off the ';f' or the ';e'
+  //
+  if (stream_qualifier_re.Match (d.c_str()))
+    {
+      d = stream_qualifier_re[1];
+      const sstring qualifier = stream_qualifier_re[2];
+      if (qualifier.size() != 1) THROWEXPR ("ERROR: Bad qualifier char: '" << qualifier << "' in '" << d << "'.");
+      const char q = qualifier[0];
+      if (q != 'f' && q != 'e') { syntax_help(0); THROW Standard_exception ("ERROR: Syntax error in logging directive."); }
+      stderr_or_logfile = q == 'e' ? 1 : 2;
+    }
+  else
+    stderr_or_logfile = 3;
+
+ // chop off the ',x:y' log-level range
+  //
+  if (level_range_re.Match (d.c_str()))
+    {
+      d = level_range_re[1];
+      const sstring level_range = level_range_re[2];
+      if (range_re.Match (level_range.c_str())) { sstring l = range_re[1]; sstring h = range_re[2]; lowest_level = atoi(l.c_str()); highest_level = atoi(h.c_str()); }
+      else if (above_re.Match (level_range.c_str())) { sstring l = above_re[1]; lowest_level = atoi(l.c_str()); highest_level = +123456789; }
+      else if (below_re.Match (level_range.c_str())) { sstring h = below_re[1]; lowest_level = -123456789; highest_level = atoi(h.c_str()); }
+      else { syntax_help(0); THROW Standard_exception ("ERROR: Syntax error in logging directive."); }
+    }
+  else
+    {
+      lowest_level  = -123456789;
+      highest_level = +123456789;
+    }
+  if (lowest_level > highest_level) { syntax_help(0); THROW Standard_exception ("ERROR: Syntax error in logging directive."); }
+
+  // chop off the '#x-y' line-number range
+  //
+  if (line_range_re.Match (d.c_str())) { d = line_range_re[1]; sstring s = line_range_re[2]; start_line = atoi(s.c_str()); sstring e = line_range_re[3]; end_line = atoi(e.c_str()); }
+  else if (single_line_re.Match (d.c_str())) { d = single_line_re[1]; sstring s = single_line_re[2]; start_line = end_line = atoi(s.c_str()); }
+  else { start_line = 0; end_line = +123456789; }
+  if (start_line > end_line) { syntax_help(0); THROW Standard_exception ("ERROR: Syntax error in logging directive."); }
+
+  // strip the '!' off the front
+  //
+  if (pling_re.Match (d.c_str())) { d = pling_re[1]; on = 0; }
+  else on = 1;
+
+  // if any special characters remain, then something's wrong
+  //
+  if (bad_re.Match (d.c_str())) { syntax_help(0); THROW Standard_exception ("ERROR: Syntax error in logging directive."); }
+
+  // convert '^' and '$' to whitespace
+  for_contents (sstring, d, c) if (*c == '^' || *c == '$') *c = ' ';
+
+  // if the remaining pattern fits
+  //      /^[A-Za-z_]+\.[A-Za-z]+$/ (has a dot suffix => is a filename)
+  //   or /^[A-Z][A-Z_0-9]+$/       (upper case variable name => is a tag),
+  // then add a space to the start and the end, to force a complete match
+  // (or in the case of filenames, add a '^' to the start and a space to the end)
+  //
+  // also add parentheses at this stage
+  //
+  const char* dc = d.c_str();
+  if (filename_re.Match(dc)) { d.insert ((sstring::size_type) 0, "^()"); d.append (" "); }
+  else if (tag_re.Match(dc)) { d.insert ((sstring::size_type) 0, " ("); d.append (") "); }
+  else                       { d.insert ((sstring::size_type) 0, "()"); }
+
+  filename_pattern = Regexp (d.c_str());
+}
+
+bool Log_stream::Log_directive::syntax_help (Opts_list* ol)
+{
+  cerr << "\nLogging directives have a flexible syntax. The simplest kind of directive is a tag in upper-case,\nsuch as '-log INIT', or a priority level, e.g. '-log 6'; but you can also turn on (or off) messages\nby source file, by line, and by combinations of these.\n\n";
+  cerr << "Examples include:\n\n";
+  cerr << "-log JAM               turns on logging for all messages with tag 'JAM' (see -logtags or -logtaginfo for list)\n";
+  cerr << "-log 3                 turns on logging for messages of priority level 3 or higher\n";
+  cerr << "-log cabin,3           turns on logging for messages of priority level 3 or higher in source files matching '*cabin*' (eg cabin.h, mycabin.cc)\n";
+  cerr << "-log cabin.h,3         turns on logging for messages of priority level 3 or higher in source file 'cabin.h' only\n";
+  cerr << "-log 'lady,3:6'        turns on logging for messages from priority levels 3 to 6 in source files '*lady*'\n";
+  cerr << "                        (NB excluding high log levels may have the side-effect of blocking lower ones due to nested 'if' clauses in C++ code)";
+  cerr << "\n-log 'lady#1-100,3:6'  turns on logging for messages from levels 3 to 6 for first 100 lines of files '*lady*'";
+  cerr << "\n-log 'lady,3:6;f'      turns on logging for messages from levels 3 to 6 in files '*lady*' for logfile only\n";
+  cerr << "                        (suffix ';e' applies to standard error only)\n";
+  cerr << "-log '!^fire'          turns off logging for all messages in source files starting with 'fire' (eg firefight.f77, fired.exe)\n";
+  cerr << "-nolog fire            same as -log '!fire'\n\n";
+  exit(0);
+  return 0;
+}
+
+bool Log_stream::Log_directive::tags_help (Opts_list* ol)
+{
+  cout << all_log_tags;
+  exit(0);
+  return 1;
+}
+
+bool Log_stream::Log_directive::tags_long_help (Opts_list* ol)
+{
+  cout << all_log_tag_info;
+  exit(0);
+  return 1;
+}
+
+bool Log_stream::Log_directive::process (int level, const char* src_file, int src_line, int& stderr_ret, int& file_ret)
+{
+  if (filename_pattern.Match (src_file) && level >= lowest_level && level <= highest_level && src_line >= start_line && src_line <= end_line)
+    {
+      if (((stderr_or_logfile & 1) == 1) && stderr_ret == -1) stderr_ret = on ? 1 : 0;
+      if (((stderr_or_logfile & 2) == 2) && file_ret == -1) file_ret = on ? 1 : 0;
+      dirstr_match = filename_pattern[1];
+      return stderr_or_logfile ? 1 : 0;
+    }
+  return 0;
+}
+
+void Log_stream::add_new_directive (const char* dir)
+{
+  sstring d (dir);
+  directives.push_back (Log_directive (d));
+}
+
+void Log_stream::save_logfile_state()
+{
+  saved_logfile_state.push (Log_stream_vars (*this));
+  log_streambuf.save_logfile_state();
+}
+
+void Log_stream::restore_logfile_state()
+{
+  ((Log_stream_vars&) *this) = saved_logfile_state.top();
+  saved_logfile_state.pop();
+  log_streambuf.restore_logfile_state();
+}
+
+Log_stream::Log_stream (Log_streambuf& log_streambuf, int log_level) :
+  std::ostream (&log_streambuf),
+  log_streambuf (log_streambuf)
+{
+  log_to_stderr_mask = true;
+  log_to_file_mask = false;
+  lowest_log_level = log_level;
+  current_log_level = INITIAL_LOG_LEVEL;
+
+  file_tag_buf = new char[FILETAG_MAX_SZ + 1];
+  this->request_logging(0,__FILE__,__LINE__).CLOG_FILE_LINE << "Log opened\n";
+}
+
+Log_stream::~Log_stream()
+{
+  this->request_logging(0,__FILE__,__LINE__).CLOG_FILE_LINE << "Log closed\n";
+  clog_streambuf.close_logfile();
+  delete[] file_tag_buf;
+}
+
+
+bool Log_stream::clog_to_file (Opts_list* ol)
+{
+  sstring filename = ol->next_string();
+  clog_streambuf.open_logfile (filename);
+  clog_stream.log_to_file_only();
+  CLOG(0) << "Opened logfile " << filename << "\n";
+  return 1;
+}
+
+bool Log_stream::clog_to_stderr (Opts_list* ol)
+{
+  clog_stream.log_to_stderr_only();
+  return 1;
+}
+
+bool Log_stream::clog_everywhere (Opts_list* ol)
+{
+  sstring filename = ol->next_string();
+  clog_streambuf.open_logfile (filename);
+  clog_stream.log_everywhere();
+  CLOG(0) << "Opened logfile " << filename << "\0";
+  return 1;
+}
+
+bool Log_stream::clog_directive (Opts_list* ol)
+{
+  sstring directive_string (ol->next_string());
+  Regexp numeric_re ("^-?[0123456789]+$");
+  if (numeric_re.Match (directive_string.c_str())) clog_stream.lowest_log_level = atoi (directive_string.c_str());
+  else clog_stream.directives.push_back (Log_directive (directive_string));
+  return 1;
+}
+
+bool Log_stream::clog_negated_directive (Opts_list* ol)
+{
+  sstring directive_string (ol->next_string());
+  clog_stream.directives.push_back (Log_directive (directive_string));
+  clog_stream.directives.back().on = !clog_stream.directives.back().on;
+  return 1;
+}
+
+void Log_stream::add_opts (Opts_list& ol)
+{
+  ol.print_title ("Logging options");
+  ol.add ("-log", &Log_stream::clog_directive, " <string>\tturn on diagnostic logging (-loghelp shows syntax)");
+  ol.add ("-logfile", &Log_stream::clog_to_file, " <file>\tlog to file");
+  ol.add ("-logcopy", &Log_stream::clog_everywhere, " <file>\tlog to file and standard error");
+  ol.add ("-logtime", clog_streambuf.verbose_on_stderr = 0, "timestamp standard error (logfile stamped automatically)");
+  ol.add ("-logxml",  clog_streambuf.log_in_XML = TRUE, "add XML timestamps");
+  ol.add ("-logerr",  &Log_stream::clog_to_stderr, "\tlog on standard error (default)");
+  ol.add ("-nolog",   &Log_stream::clog_negated_directive);
+  ol.add ("-loghelp", &Log_stream::Log_directive::syntax_help);
+  ol.add ("-logtags", &Log_stream::Log_directive::tags_help);
+  ol.add ("-logtaginfo", &Log_stream::Log_directive::tags_long_help);
+  ol.newline();
+}
diff --git a/src/util/logfile.h b/src/util/logfile.h
new file mode 100644
index 0000000..86c3f15
--- /dev/null
+++ b/src/util/logfile.h
@@ -0,0 +1,277 @@
+#ifndef LOGFILE_INCLUDED
+#define LOGFILE_INCLUDED
+
+#include <cstring>
+#include <cstdio>
+#include <ctype.h>
+#include <time.h>
+#include <fstream>
+#include <list>
+#include <map>
+#include <stack>
+
+#include "util/misc.h"
+#include "util/sstring.h"
+#include "util/macros.h"
+#include "util/opts_list.h"
+#include "util/regexp.h"
+
+#define CLOGXMLTAGNAME    "log"
+#define INITIAL_LOG_LEVEL 9
+#define ERROR_LOG_LEVEL   10
+#define ERROR_TAG         "ERROR"
+
+#define CLOGSTREAM             clog_stream
+#define CLOGSTREAMBUF          clog_streambuf
+#define CLOG_FILE_LINE         file_tag(__FILE__,__LINE__,"")
+#define CLOG_FILE_LINE_TAGS(T) file_tag(__FILE__,__LINE__,"" #T "")
+
+#define CLOGREQUEST(n,STDOUT_FLAG)      CLOGSTREAM.request_logging(n,__FILE__ " ",__LINE__,STDOUT_FLAG)
+#define CTAGREQUEST(n,TAGS,STDOUT_FLAG) CLOGSTREAM.request_logging(n,__FILE__ " " #TAGS " ",__LINE__,STDOUT_FLAG)
+
+#define CLOG(n)          CLOGREQUEST(n,0).CLOG_FILE_LINE
+#define CTAG(n,TAGS)     CTAGREQUEST(n,TAGS,0).CLOG_FILE_LINE_TAGS(TAGS)
+#define CLOGERR          CLOGREQUEST(ERROR_LOG_LEVEL,0).CLOG_FILE_LINE_TAGS(ERROR_TAG)
+#define CLOGOUT          CLOGREQUEST(ERROR_LOG_LEVEL,1).CLOG_FILE_LINE
+#define CL               CLOGSTREAM
+#define CLOGGING(n)      (CLOGREQUEST(n,0).logging() ? CLOGSTREAM.CLOG_FILE_LINE.logging() : 0)
+#define CTAGGING(n,TAGS) (CTAGREQUEST(n,TAGS,0).logging() ? CLOGSTREAM.CLOG_FILE_LINE_TAGS(TAGS).logging() : 0)
+
+// max buffer sizes
+#define TBUF_MAX_SZ 60
+#define FILETAG_MAX_SZ 400
+
+// helpful exception stuff
+
+#define THROW              CLOG(7) << "Exception thrown\n", throw
+#define THROWSTR           "", THROW Standard_exception (ERRSTR.c_str())
+#define THROWEXPR(EXPR)    { ERRSTR.clear(); ERRSTR << EXPR; THROW Standard_exception (ERRSTR.c_str()); }
+#define THROWIFTRUE(EXPR)  { if (EXPR) { ERRSTR.clear(); ERRSTR << #EXPR; THROW Standard_exception (ERRSTR.c_str()); } }
+#define THROWASSERT(EXPR)  { if (!(EXPR)) { ERRSTR.clear(); ERRSTR << "ERROR: Failed assertion '" << #EXPR << "'"; THROW Standard_exception (ERRSTR.c_str()); } }
+
+namespace fsa {
+
+  // Logfile system variables
+  class Log_streambuf_vars
+  {
+  protected:
+    bool     logfile_open;
+    sstring  last_filename;
+    bool     bare_newline;
+    sstring  file_tag;
+    sstring  last_file_tag;
+
+  public:
+    bool     verbose_on_stderr;
+    bool     log_to_stderr;
+    bool     log_to_stdout;
+    bool     log_to_file;
+    bool     log_in_XML;
+  };
+
+  // streambuf class
+  class Log_streambuf : public std::streambuf, public Log_streambuf_vars
+  {
+  protected:
+    int overflow(int c);
+
+  private:
+
+    std::ofstream logfile_stream;
+    char*    datebuf;  // date string buffer
+    char*    timebuf;  // time string buffer
+    sstring  newtag_buf;
+
+    std::stack<Log_streambuf_vars> saved_logfile_state;
+
+    inline void prepare_date_and_time()
+    {
+      const time_t t = time(NULL);
+      strftime (datebuf, TBUF_MAX_SZ, "%Y/%d/%m", localtime(&t));
+      strftime (timebuf, TBUF_MAX_SZ, "%H:%M:%S", localtime(&t));
+    }
+  
+  public:
+
+    void save_logfile_state();
+    void restore_logfile_state();
+
+    inline void new_file_tag (const char* s)
+    {
+      // print a newline
+      if (!bare_newline)
+	{
+	  if (log_to_file && logfile_open) logfile_stream << '\n';
+	  if (log_to_stderr) cerr << '\n';
+	  if (log_to_stdout) cout << '\n';
+	}
+      // update vars
+      file_tag = s;
+      bare_newline = TRUE;
+    }
+
+    void print_long_XML_tag();
+    void print_short_XML_tag();
+    void print_tabbed_tag();
+    void print_newtag_buf();
+
+    inline void close_logfile()
+    {
+      if (logfile_open)
+	logfile_stream.close();
+      logfile_open = FALSE;
+    }
+
+    inline void open_logfile(const sstring& filename)
+    {
+      if (filename != last_filename)
+	{
+	  close_logfile();
+	  logfile_stream.open (filename.c_str(), std::ios_base::app);
+	  logfile_open = 1;
+	  last_filename = filename;
+	}
+    }
+
+    Log_streambuf();
+    ~Log_streambuf();
+  };
+
+  // vars for Log_stream
+  struct Log_stream_vars
+  {
+    bool log_to_stderr_mask;
+    bool log_to_file_mask;
+    int  lowest_log_level;
+    int  current_log_level;
+  };
+
+  // ostream class
+  class Log_stream : public std::ostream, public Log_stream_vars
+  {
+  private:
+    Log_streambuf& log_streambuf;
+
+    char* file_tag_buf;
+
+  public:
+
+    std::stack<Log_stream_vars> saved_logfile_state;
+
+    struct Log_directive
+    {
+      sstring dirstr_match;
+      Regexp  filename_pattern;
+      int     start_line;
+      int     end_line;
+      int     lowest_level;
+      int     highest_level;
+      int     stderr_or_logfile;   // 1 means directive applies to stderr, 2 means it applies to logfile, 3 means both
+      bool    on;                  // true if this directive turns logging on & not off
+      bool    process (int level, const char* src_file, int src_line, int& stderr_ret, int& file_ret);
+      Log_directive (const sstring& directive_string);
+
+      static bool syntax_help (Opts_list* ol);
+      static bool tags_help (Opts_list* ol);
+      static bool tags_long_help (Opts_list* ol);
+    };
+  
+    std::list<Log_directive> directives;
+
+    void add_new_directive (const char* dir);       // can be called from the debugger
+
+    void save_logfile_state();
+    void restore_logfile_state();
+  
+    void log_to_stderr_only() { log_to_stderr_mask = 1; log_to_file_mask = 0; }
+    void log_to_file_only() { log_to_stderr_mask = 0; log_to_file_mask = 1; }
+    void log_everywhere() { log_to_stderr_mask = log_to_file_mask = 1; }
+
+    inline Log_stream& request_logging (int level, const char* src_file, int src_line, bool log_to_stdout = 0)
+    {
+      if (directives.empty())
+	{
+	  log_streambuf.log_to_stderr = log_to_stderr_mask && level >= lowest_log_level && !log_to_stdout;
+	  log_streambuf.log_to_file   = log_to_file_mask   && level >= lowest_log_level;
+	  log_streambuf.log_to_stdout = log_to_stdout;
+	}
+      else
+	{
+	  src_file = strip_path (src_file);
+	  int stderr_flag = -1;
+	  int file_flag = -1;
+	  for_iterator (std::list<Log_directive>::reverse_iterator, dir, directives.rbegin(), directives.rend())     // loop backwards through directives list
+	    {
+	      dir->process (level, src_file, src_line, stderr_flag, file_flag);
+	      if (stderr_flag != -1 && file_flag != -1)
+		{
+		  if (dir->dirstr_match.size())
+		    {
+		      for_const_contents (sstring, dir->dirstr_match, c)
+			if (*c == ' ' || *c == '\t')  // chop off whitespace
+			  break;
+		    }
+		  break;
+		}
+	    }
+	  log_streambuf.log_to_stderr = log_to_stderr_mask && (stderr_flag == -1 ? level >= lowest_log_level : stderr_flag) && !log_to_stdout;
+	  log_streambuf.log_to_file   = log_to_file_mask   && (file_flag == -1   ? level >= lowest_log_level : file_flag);
+	  log_streambuf.log_to_stdout = log_to_stdout;
+	}
+      current_log_level = level;
+      return *this;
+    }
+  
+    inline bool logging() { return log_streambuf.log_to_stderr || log_streambuf.log_to_file || log_streambuf.log_to_stdout; }
+
+    static inline const char* strip_path (const char* file_with_path)
+    {
+      const char* s;
+      while ((s = std::strchr (file_with_path, DIR_SEP_CHAR)) != NULL) file_with_path = s + 1;
+      return file_with_path;
+    }
+
+    inline Log_stream& file_tag (const char* src_file, int src_line, const char* tags)
+    {
+      if (log_streambuf.log_in_XML)
+	{
+	  if (tags ? (std::strlen(tags) > 0) : false)
+	    sprintf (file_tag_buf, "file=\"%s\" line=%d level=%d tags=\"%s\"", strip_path (src_file), src_line, current_log_level, tags);
+	  else
+	    sprintf (file_tag_buf, "file=\"%s\" line=%d level=%d", strip_path (src_file), src_line, current_log_level);
+	}
+      else
+	{
+	  if (tags ? (std::strlen(tags) > 0) : false)
+	    sprintf (file_tag_buf, "<%s#%d> <%d %s>", strip_path (src_file), src_line, current_log_level, tags);
+	  else
+	    sprintf (file_tag_buf, "<%s#%d> <%d>", strip_path (src_file), src_line, current_log_level);
+	}
+      log_streambuf.new_file_tag (file_tag_buf);
+      return *this;
+    }
+
+    // constructor
+    Log_stream (Log_streambuf& log_streambuf, int log_level);
+
+    // destructor
+    ~Log_stream();
+
+    static bool clog_to_file (Opts_list* ol);
+    static bool clog_to_stderr (Opts_list* ol);
+    static bool clog_everywhere (Opts_list* ol);
+    static bool clog_directive (Opts_list* ol);
+    static bool clog_negated_directive (Opts_list* ol);
+
+    static void add_opts (Opts_list& ol);
+  };
+
+  extern Log_streambuf clog_streambuf;
+  extern Log_stream    clog_stream;
+
+  // the following string does nothing special except serve as a buffer for exception-throwing via the THROWSTR macro:
+  extern sstring ERRSTR;
+
+}
+
+#endif
diff --git a/src/util/logtags.h b/src/util/logtags.h
new file mode 100644
index 0000000..ec9c9d1
--- /dev/null
+++ b/src/util/logtags.h
@@ -0,0 +1,13 @@
+/* This file automatically generated by make-logtags.pl. DO NOT EDIT */
+
+#ifndef UTIL_LOGTAGS_INCLUDED
+#define UTIL_LOGTAGS_INCLUDED
+
+namespace fsa {
+
+  const char* all_log_tags = "\nANCHORING                 CONSTRAINTS               MANAGER                   \nANCHORING_VERBOSE         CONSTRAINTS_VERBOSE       MW                        \nANCHORING_VERBOSE_VERBOSE DAG                       OPTS                      \nANNEALING                 DB                        REFINEMENT                \nANNEALING_VERBOSE         FSA                       SPARSEMATRIX              \nANNEALING_VERBOSEs        FSAEM                     \n";
+  const char* all_log_tag_info = "\nTag                       Level Module    File#line\n---                       ----- ------    ---------\n<none>                      0   util      logfile.cc#285\n                            0   util      logfile.cc#300\nANCHORING                   9   fsa       anchors.cc#934\n                            9   fsa       anchors.cc#936\n                            9   fsa       anchors.cc#938\n                            9   fsa       anchors.cc#1140\n  [...]
+
+}
+
+#endif /* UTIL_LOGTAGS_INCLUDED */
diff --git a/src/util/macros.h b/src/util/macros.h
new file mode 100644
index 0000000..2f49d67
--- /dev/null
+++ b/src/util/macros.h
@@ -0,0 +1,84 @@
+// miscellaneous useful macros
+
+#ifndef MACROS_INCLUDED
+#define MACROS_INCLUDED
+
+#include <ctype.h>
+#include <iostream>
+
+// TRUE and FALSE
+#define TRUE 1
+#define FALSE 0
+
+// conditional char and string macros for true and false
+#define YES_OR_NO(X) ((X) ? "yes" : "no")
+#define TRUE_OR_FALSE(X) ((X) ? "true" : "false")
+#define Y_OR_N(X) ((X) ? 'y' : 'n')
+#define T_OR_F(X) ((X) ? 't' : 'f')
+
+// Container iterator macros. There are two kinds:
+// (1) template iterator macros, using "typename";
+// (2) nontemplate iterator macros, using typedefs without "typename".
+
+// Prefixes used by the iterator macros
+#define DART_ITER_TYPE _type_
+#define DART_END_ITER  _end_
+#define DART_TMP_CNTNR _cntnr_
+
+// (1) template iterator macros, using "typename"
+#define template_for_contents(ContainerType, Container, Iterator) for ( typename ContainerType ::iterator Iterator = ( Container ).begin(), DART_END_ITER ## Iterator = ( Container ).end(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define template_for_const_contents(ContainerType, Container, Iterator) for ( typename ContainerType ::const_iterator Iterator = ( Container ).begin(), DART_END_ITER ## Iterator = ( Container ).end(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define template_for_reverse_contents(ContainerType, Container, Iterator) for ( typename ContainerType ::reverse_iterator Iterator = ( Container ).rbegin(), DART_END_ITER ## Iterator = ( Container ).rend(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define template_for_const_reverse_contents(ContainerType, Container, Iterator) for ( typename ContainerType ::const_reverse_iterator Iterator = ( Container ).rbegin(), DART_END_ITER ## Iterator = ( Container ).rend(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+
+// (2) nontemplate iterator macros, using typedefs without "typename"
+#define for_contents(ContainerType, Container, Iterator) for ( ContainerType ::iterator Iterator = ( Container ).begin(), DART_END_ITER ## Iterator = ( Container ).end(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define for_const_contents(ContainerType, Container, Iterator) for ( ContainerType ::const_iterator Iterator = ( Container ).begin(), DART_END_ITER ## Iterator = ( Container ).end(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define for_tmp_contents(ContainerType, ContainerExpr, Iterator) ContainerType DART_TMP_CNTNR ## Iterator = ContainerExpr; for ( ContainerType ::iterator Iterator = DART_TMP_CNTNR ## Iterator .begin(), DART_END_ITER ## Iterator = DART_TMP_CNTNR ## Iterator .end(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define for_reverse_contents(ContainerType, Container, Iterator) for ( ContainerType ::reverse_iterator Iterator = ( Container ).rbegin(), DART_END_ITER ## Iterator = ( Container ).rend(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define for_const_reverse_contents(ContainerType, Container, Iterator) for ( ContainerType ::const_reverse_iterator Iterator = ( Container ).rbegin(), DART_END_ITER ## Iterator = ( Container ).rend(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+#define for_tmp_reverse_contents(ContainerType, ContainerExpr, Iterator) ContainerType DART_TMP_CNTNR ## Iterator = ContainerExpr; for ( ContainerType ::reverse_iterator Iterator = DART_TMP_CNTNR ## Iterator .rbegin(), DART_END_ITER ## Iterator = DART_TMP_CNTNR ## Iterator .rend(); !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+// for_iterator macro
+#define for_iterator(IteratorType, Iterator, Begin, End) for ( IteratorType Iterator = Begin, DART_END_ITER ## Iterator = End; !(Iterator == DART_END_ITER ## Iterator); ++ Iterator )
+
+// "begin, end" iterator macro
+#define begin_end(Container) ( Container ).begin(), ( Container ).end()
+
+// Directory separator
+#define DIR_SEP_CHAR '/'
+
+
+// Stream tricks -- rarely if ever used
+struct Eat_white_type
+{
+  friend std::istream& operator>> (std::istream& is, Eat_white_type)
+    {
+      char c;
+      while (is.get(c)) if (!isspace (c)) { is.putback(c); break; }
+      return is;
+    }
+};
+
+#define EAT_WHITE Eat_white_type()
+
+struct Flush_type { friend std::ostream& operator<< (std::ostream& o, Flush_type) { return flush(o); } };
+
+#define FLUSH Flush_type()
+
+#ifdef DART_DEBUG
+#define DART_DEBUG_MODE_STRING "debug"
+#else
+#define DART_DEBUG_MODE_STRING "release"
+#endif
+
+#endif
diff --git a/src/util/memcheck.cc b/src/util/memcheck.cc
new file mode 100644
index 0000000..0286c34
--- /dev/null
+++ b/src/util/memcheck.cc
@@ -0,0 +1,51 @@
+
+/**
+ * \file memcheck.cc
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Colin Dewey.
+ */
+
+#include "config.h"
+#include "memcheck.h"
+
+#ifdef HAVE_STRUCT_SYSINFO_TOTALRAM
+// Memory check for Linux systems
+#include <sys/sysinfo.h>
+int total_ram() {
+	struct sysinfo info;
+	if (sysinfo(&info) == 0) {
+		unsigned long totalram = info.totalram;
+#ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT
+		// info.totalram is in units of info.mem_unit bytes
+		totalram *= info.mem_unit;
+#endif
+		// Return total RAM in megabytes
+		return totalram >> 20;
+	} else {
+		return -1;
+	}
+}
+#elif HAVE_DECL_SYSCTL && HAVE_DECL_CTL_HW && HAVE_DECL_HW_PHYSMEM
+// Memory check for BSD/Darwin systems
+#include <sys/sysctl.h>
+int total_ram() {
+	// Management Information Base (MIB) codes for physical memory
+	static int mib[] = {CTL_HW, HW_PHYSMEM};
+
+	// Variable for result of physical memory query and its size
+	size_t physmem;
+	size_t len = sizeof(physmem);
+
+	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &physmem, &len, NULL, 0) == 0
+		and len == sizeof(physmem)) {
+		// sysctl returns total RAM in bytes
+		return physmem >> 20;
+	} else {
+		return -1;
+	}
+}
+#else
+int total_ram() {
+	return -1;
+}
+#endif
diff --git a/src/util/memcheck.h b/src/util/memcheck.h
new file mode 100644
index 0000000..4a0b282
--- /dev/null
+++ b/src/util/memcheck.h
@@ -0,0 +1,17 @@
+
+/**
+ * \file memcheck.h
+ * This file is part of FSA, a sequence alignment algorithm.
+ * \author Source code in this file was written by Colin Dewey.
+ */
+
+#ifndef MEMCHECK_INCLUDED
+#define MEMCHECK_INCLUDED
+
+/**
+ * \brief Returns the total system memory size in megabytes,
+ * or -1 if it cannot be determined.
+ */
+int total_ram();
+
+#endif // MEMCHECK_INCLUDED
diff --git a/src/util/misc.cc b/src/util/misc.cc
new file mode 100644
index 0000000..056975f
--- /dev/null
+++ b/src/util/misc.cc
@@ -0,0 +1,90 @@
+
+/**
+ * \file misc.cc
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#include "util/misc.h"
+#include <algorithm>
+#include <fstream>
+
+using namespace fsa;
+
+
+Regexp Util::re_chr_stripper = Regexp ("^(chr)?(.+)");
+Regexp Util::re_basename = Regexp ("^.*\\/([^\\/]+)$");
+Regexp Util::re_basename_extension = Regexp ("^(.+)\\.[^\\.]+$");
+
+bool Util::exists_file (const std::string& filename) {
+
+  struct stat fileinfo;
+  bool gotattr;
+
+  // Attempt to get the file attributes
+  int statresults = stat (filename.c_str(), &fileinfo);
+
+  if (statresults == 0) {
+    // We were able to get the file attributes
+    // so the file obviously exists.
+    gotattr = true;
+  } else {
+    // We were not able to get the file attributes.
+    // This may mean that we don't have permission to
+    // access the folder which contains this file. If you
+    // need to do that level of checking, lookup the
+    // return values of stat which will give you
+    // more details on why stat failed.
+    gotattr = false;
+
+  }
+  
+  return gotattr; 
+
+}
+
+size_t Util::count_newlines (const std::string& filename) {
+
+  std::ifstream filestream;
+  filestream.open (filename.c_str(), std::ios::in);
+  if (!filestream.is_open()) {
+    cerr << "ERROR: Couldn't open file '" << filename << "' for reading." << endl;
+    exit (1);
+  }
+
+  size_t num = std::count (std::istreambuf_iterator<char> (filestream), std::istreambuf_iterator<char>(),
+			   '\n');
+
+  return num;
+
+}
+
+void Util::strip_leading_chr (std::string& chromosome) {
+
+  if (re_chr_stripper.Match (chromosome.c_str())) // strip off leading 'chr' if present
+    chromosome = std::string (re_chr_stripper[2]);
+
+}
+
+void Util::basename (std::string& filename,
+		     const bool strip_extension /* = false */) {
+
+  // remove directory information
+  if (re_basename.Match (filename.c_str()))
+    filename = std::string (re_basename[1]);
+
+  // remove filename extension
+  if (strip_extension && re_basename_extension.Match (filename.c_str()))
+    filename = re_basename_extension[1];
+
+}
+
+bool Util::String_equal_ci::operator() (const std::string& s1, const std::string& s2) const {
+
+    return std::lexicographical_compare (s1.begin(),
+					 s1.end(),
+					 s2.begin(),
+					 s2.end(),
+					 Util::char_less_ci);
+
+}
diff --git a/src/util/misc.h b/src/util/misc.h
new file mode 100644
index 0000000..a2063f2
--- /dev/null
+++ b/src/util/misc.h
@@ -0,0 +1,390 @@
+
+/**
+ * \file misc.h
+ * This file is part of FSA.
+ * \author Source code in this file was written by Robert Bradley.
+ */
+
+#ifndef UTIL_MISC_INCLUDED
+#define UTIL_MISC_INCLUDED
+
+#include <cassert>
+#include <cstdlib>
+#include <ctime>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <sys/stat.h>
+#include <map>
+
+#include "config.h"
+#include "util/regexp.h"
+
+using std::cerr;
+using std::cout;
+using std::endl;
+
+namespace fsa {
+
+  struct Util {
+
+  public:
+
+    /**
+     * \brief Convert to a string.
+     */
+    template<typename T>
+    static std::string to_string (const T& t);
+
+    /**
+     * \brief Remove newline character, if it exists, from the end of a string.
+     */
+    static void chomp (std::string& str);
+
+    /**
+     * \brief Convert a string to upper-case.
+     */
+    static void toupper (std::string& str);
+
+    /**
+     * \brief Convert a string to lower-case.
+     */
+    static void tolower (std::string& str);
+
+    /**
+     * \brief Tokenize a string according to the specified delimiters.
+     *
+     * Code from:
+     * http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
+     */
+    static std::vector<std::string> split (const std::string& str,
+					   const std::string& delimiters = " ");
+
+    /**
+     * \brief Join strings into a single string separated by delimiter.
+     */
+    template<typename T>
+    static std::string join (const std::vector<T>& items,
+			     const std::string& delimiter = "");
+
+    /**
+     * \brief Search for an instance of a specified item in a vector of items.
+     * \param item list of items to search through
+     * \param query item to search for
+     */
+    template<typename T>
+    static bool contains (const std::vector<T>& items,
+			  const T query);
+
+    /**
+     * \brief Add prefix to all strings in vector.
+     */
+    static std::vector<std::string> addprefix (const std::vector<std::string>& items,
+					       const std::string prefix);
+
+    /**
+     * \brief Add suffix to all strings in vector.
+     */
+    static std::vector<std::string> addsuffix (const std::vector<std::string>& items,
+					       const std::string suffix);
+
+    /**
+     * \brief Get keys in a map or multimap.
+     *
+     * Returns possibly-duplicate key values if T is a multimap.
+     * \param container map or multimap
+     */
+    template<typename T>
+    static std::vector<typename T::key_type> keys (const T& container);
+
+    /**
+     * \brief Get values in a map or multimap.
+     * \param container map or multimap
+     */
+    template<typename T>
+    static std::vector<typename T::mapped_type> values (const T& container);
+
+    /**
+     * \brief Strip leading 'chr' (if present) from the passed chromosome name.
+     */
+    static void strip_leading_chr (std::string& chromosome);
+
+    /**
+     * \brief Return a random number in [0, max].
+     */
+    static unsigned rand (const unsigned max);
+
+    /**
+     * \brief Return a random probability (double in [0, 1]).
+     */
+    static double prob();
+
+    /**
+     * \brief Seed random number generator.
+     */
+    static void seed_rand (const unsigned seed);
+
+    /**
+     * \brief Seed random number generate on current time.
+     */
+    static void seed_rand_on_time();
+
+    /**
+     * \brief Choose from a probability vector.
+     * 
+     * Assumes that the distribution is properly normalized.
+     */
+    static size_t choose_from_distribution (const std::vector<double>& dist);
+
+    /**
+     * \brief Does a file exist?
+     *
+     * Uses stat to see if we can get the file attributes.
+     * From http://www.techbytes.ca/techbyte103.html.
+     */
+    static bool exists_file (const std::string& filename);
+
+    /**
+     * \brief Counts the number of newlines in a file.
+     * \param filename name of file
+     */
+    static size_t count_newlines (const std::string& filename);
+
+    /**
+     * \brief Remove directory information from filename.
+     *
+     * Converts, e.g., '/tmp/rob.data' to 'rob.data' or 'rob'.
+     * \param strip_extension remove extension from filename as well
+     */
+    static void basename (std::string& filename,
+			  const bool strip_extension = false);
+
+    /**
+     * \brief Case-insensitive character comparison.
+     * \see String_equal_ci
+     */
+    static bool char_less_ci (const char c1, const char c2) {
+      return std::tolower (static_cast<unsigned char> (c1)) < std::tolower (static_cast<unsigned char> (c2));
+    }
+
+    /**
+     * \brief Case-insensitive string comparison.
+     * 
+     * Taken from Meyers, "Effective C++" 3rd ed.
+     */
+    struct String_equal_ci {
+    public:
+      bool operator() (const std::string& s1, const std::string& s2) const;
+    };
+
+    /**
+     * \brief Function object for comparing duples.
+     *
+     * Orders by first coordinate, then second coordinate.
+     */
+    template<typename T1, typename T2>
+    struct Duple_less : std::binary_function<T1, T2, bool> {
+    public:
+      bool operator() (const std::pair<T1, T2> l, const std::pair<T1, T2> r) const {
+	if (l.first == r.first)
+	  return (l.second < r.second);
+	else
+	  return (l.first < r.first);
+      }
+    };
+
+    /**
+     * \brief Function object for comparing map entries based on their values.
+     *
+     * T might be, e.g., std::map<char, size_t>
+     */
+    template<typename T>
+    struct Map_value_less : std::binary_function<T, T, bool> {
+    public:
+      bool operator() (const typename T::value_type& l, const typename T::value_type& r) const {
+	return l.second < r.second;
+      }
+    };
+
+
+  private:
+
+    static Regexp re_chr_stripper;                  ///< \see strip_leading_chr
+    static Regexp re_basename;                      ///< \see basename
+    static Regexp re_basename_extension;            ///< \see basename
+    
+  };
+
+
+  template<typename T>
+    std::string Util::to_string (const T& t) {
+
+    std::stringstream ss;
+    ss << t;
+
+    return ss.str();
+
+  }
+
+  template<typename T>
+    std::string Util::join (const std::vector<T>& items,
+			    const std::string& delimiter /* = "" */) {
+    
+    std::stringstream joined;
+
+    // case the catch of no items
+    if (!items.size())
+      return joined.str();
+
+    // awkward loop structure is to avoid adding the delimiter onto the end of the string
+    typename std::vector<T>::const_iterator item;
+    for (item = items.begin(); (item + 1) != items.end(); ++item)
+      joined << *item << delimiter;
+    joined << *item;
+
+    return joined.str();
+
+  }
+
+  inline std::vector<std::string> Util::addprefix (const std::vector<std::string>& items,
+						   const std::string prefix) {
+
+    std::vector<std::string> modified;
+    if (!items.size())
+      return modified;
+
+    for (std::vector<std::string>::const_iterator item = items.begin(); item != items.end(); ++item)
+      modified.push_back (prefix + *item);
+
+    return modified;
+
+  }
+
+  inline std::vector<std::string> Util::addsuffix (const std::vector<std::string>& items,
+						   const std::string suffix) {
+
+    std::vector<std::string> modified;
+    if (!items.size())
+      return modified;
+
+    for (std::vector<std::string>::const_iterator item = items.begin(); item != items.end(); ++item)
+      modified.push_back (*item + suffix);
+
+    return modified;
+
+  }
+
+  template<typename T>
+    bool Util::contains (const std::vector<T>& items,
+			 const T query) {
+
+    for (typename std::vector<T>::const_iterator item = items.begin(); item != items.end(); ++item) {
+      if (*item == query)
+	return true;
+    }
+
+    return false;
+
+  }
+
+  template<typename T>
+    std::vector<typename T::key_type> Util::keys (const T& container) {
+
+    std::vector<typename T::key_type> keys;
+    for (typename T::const_iterator item = container.begin(); item != container.end(); ++item)
+      keys.push_back (item->first);
+
+    return keys;
+
+  }
+
+  template<typename T>
+    std::vector<typename T::mapped_type> Util::values (const T& container) {
+
+    std::vector<typename T::mapped_type> values;
+    for (typename T::const_iterator item = container.begin(); item != container.end(); ++item)
+      values.push_back (item->second);
+
+    return values;
+
+  }
+
+  inline void Util::chomp (std::string& str) {
+
+    const int end = str.length() - 1;
+    if (end >= 0 && str[end] == '\n')
+      str.erase (end);
+
+  }
+
+  inline void Util::toupper (std::string& str) {
+
+    for (std::string::iterator s = str.begin(); s != str.end(); ++s)
+      *s = std::toupper (*s);
+
+  }
+
+  inline void Util::tolower (std::string& str) {
+
+    for (std::string::iterator s = str.begin(); s != str.end(); ++s)
+      *s = std::tolower (*s);
+
+  }
+
+  inline std::vector<std::string> Util::split (const std::string& str,
+					       const std::string& delimiters /* = " " */) {
+
+    std::vector<std::string> tokens;
+
+    // Skip delimiters at beginning.
+    std::string::size_type lastpos = str.find_first_not_of (delimiters, 0);
+    // Find first "non-delimiter".
+    std::string::size_type pos = str.find_first_of (delimiters, lastpos);
+
+    while (std::string::npos != pos || std::string::npos != lastpos) {
+      // Found a token, add it to the vector.
+      tokens.push_back (str.substr (lastpos, pos - lastpos));
+      // Skip delimiters.  Note the "not_of"
+      lastpos = str.find_first_not_of (delimiters, pos);
+      // Find next "non-delimiter"
+      pos = str.find_first_of (delimiters, lastpos);
+    }
+
+    return tokens;
+
+  }
+
+  inline unsigned Util::rand (const unsigned max) {
+    assert (max < RAND_MAX);
+    return std::rand() % (max + 1);
+  }
+
+  inline double Util::prob() {
+    return static_cast<double> (std::rand()) / RAND_MAX;
+  }
+
+  inline void Util::seed_rand (const unsigned seed) {
+    std::srand (seed);
+  }
+
+  inline void Util::seed_rand_on_time() {
+    std::srand (std::time (NULL));
+  }
+
+  inline size_t Util::choose_from_distribution (const std::vector<double>& dist) {
+    double prob = Util::prob();
+    for (size_t i = 0; i < dist.size() - 1; ++i) {
+      prob -= dist[i];
+      if (prob <= 0.)
+	return i;
+    }
+    
+    // handle last case separately to accomodate floating-point error
+    return dist.size() - 1;
+
+  }
+
+}
+
+#endif /* UTIL_MISC_INCLUDED */
diff --git a/src/util/opts_list.cc b/src/util/opts_list.cc
new file mode 100755
index 0000000..458cd7a
--- /dev/null
+++ b/src/util/opts_list.cc
@@ -0,0 +1,433 @@
+#include <ctype.h>
+#include "util/opts_list.h"
+#include "util/macros.h"
+#include "util/logfile.h"
+
+using namespace fsa;
+
+void Opts_list::print (const char* text)
+{ options_help_text.append (text); }
+
+void Opts_list::newline()
+{ print ("\n"); }
+
+void Opts_list::print_title (const char* text)
+{
+  sstring underline (std::strlen(text), '-');
+  options_help_text << text << "\n" << underline << "\n";
+}
+
+sstring Opts_list::short_help() const
+{
+  sstring h = program_name;
+  if (short_description.size()) h << " - " << short_description << '\n';
+  if (syntax.size()) h << "\nUsage: " << program_name << " " << syntax << '\n';
+  if (short_help_text.size()) h << short_help_text << '\n';
+  return h;
+}
+
+Regexp help_tab_re ("^([^\t]+)\t+([^\t].*)$");
+sstring Opts_list::help() const
+{
+  sstring h = program_name;
+  if (short_description.size()) h << " - " << short_description << '\n';
+  if (syntax.size()) h << "Usage: " << program_name << " " << syntax << '\n';
+  if (options_help_text.size())
+    {
+      h << "\n";
+      h << "Command-line options (righthandmost options take precedence)\n";
+      h << "------------------------------------------------------------\n";
+      // split up the options_help_text by lines
+      const std::vector<sstring> help_lines = options_help_text.split ("\n", FALSE);
+      // split at tab, find max width of LHS
+      int max_lhs_width = 0;
+      for_const_contents (std::vector<sstring>, help_lines, line)
+	if (help_tab_re.Match (line->c_str()))
+	  max_lhs_width = std::max (max_lhs_width, (int) help_tab_re[1].size());
+      // print out each line, again splitting tabs & aligning LHS
+      for_const_contents (std::vector<sstring>, help_lines, line)
+	if (help_tab_re.Match (line->c_str()))
+	  {
+	    const sstring lhs = help_tab_re[1];
+	    const sstring rhs = help_tab_re[2];
+	    h << lhs;
+	    for (int i = (int) lhs.size(); i < max_lhs_width + 1; ++i)
+	      h << ' ';
+	    h << rhs << '\n';
+	  }
+	else
+	  h << *line << '\n';
+      h << "\n";
+    }
+  return h;
+}
+
+bool Opts_list::display_help (Opts_list* ol)
+{ cout << ol->help(); exit(0); return 1; }
+
+bool Opts_list::display_version (Opts_list* ol)
+{
+  cout << ol->program_name << ":\n" << ol->version_info;
+  exit(0);
+  return 1;
+}
+
+void Opts_list::set_expect_flag (Expect_flag& flag, const char* value_str)
+{
+  sstring value (value_str);
+  value.to_lower();
+  if (value == sstring("yes") || value == sstring("y")) flag = YES;
+  else if (value == sstring("no") || value == sstring("n")) flag = NO;
+  else if (value == sstring("auto") || value == sstring("a")) flag = AUTO;
+  else THROW Syntax_exception (*this, "expected 'yes', 'no' or 'auto'");
+}
+
+Opts_list::Opts_list (int argc, char** argv)
+  : argc(argc),
+    argv(argv),
+    alias_args(),
+    next_alias_arg (alias_args.end()),
+    init_argc(argc),
+    init_argv(argv),
+    expect_args(-1)
+{
+  program_name = next_string();
+  add ("h help -help", &display_help, "\tdisplay this message");
+  add ("v -version", &display_version, "\tdisplay version");
+  short_help_text.clear();
+  short_help_text << "Type \'" << program_name << " " << "--help\' for command-line options.";
+  SET_VERSION_INFO(*this);
+}
+
+Opts_list::~Opts_list()
+{ }
+
+bool Opts_list::more_args() const
+{
+  return next_alias_arg != alias_args.begin() || argc > 0;
+}
+
+double Opts_list::next_double()
+{
+  if (next_alias_arg != alias_args.begin())
+    {
+      const sstring& next_arg = *--next_alias_arg;
+      return next_arg.to_double();
+    }
+  if (--argc < 0) THROW Syntax_exception (*this, "missing floating-point argument");
+  return atof(*argv++);
+}
+
+int Opts_list::next_int()
+{
+  if (next_alias_arg != alias_args.begin())
+    {
+      const sstring& next_arg = *--next_alias_arg;
+      return next_arg.to_int();
+    }
+  if (--argc < 0) THROW Syntax_exception (*this, "missing integer argument");
+  return atoi(*argv++);
+}
+
+char* Opts_list::next_string()
+{
+  if (next_alias_arg != alias_args.begin())
+    {
+      const sstring& next_arg = *--next_alias_arg;
+      return (char*) next_arg.c_str();  // cast away const... hacky
+    }
+  if (--argc < 0) THROW Syntax_exception (*this, "missing string argument");
+  return *argv++;
+}
+
+void Opts_list::new_opt (const sstring& s)
+{
+  if (all_opts.find(s) != all_opts.end())
+    {
+      // print directly to cerr, as this exception is often thrown outside a clean handler
+      cerr << "Duplicate option: -" << s << "; about to throw an exception...\n";
+      cerr.flush();
+      THROWEXPR ("ERROR: Duplicate option: -" << s);
+    }
+  all_opts.insert(s);
+}
+
+sstring Opts_list::neg_opt (const sstring& s)
+{
+  sstring neg;
+  sstring::const_iterator i = s.begin();
+  while (i < s.end())
+    {
+      if (*i == '-') { neg << *i++; continue; }
+      neg << "no";
+      neg.append (i, s.end());
+      break;
+    }
+  return neg;
+}
+
+void Opts_list::add(const char*opt,bool&var,const char*desc, bool show_default, const char* negopt, const char* negdesc)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  std::vector<sstring> negv;
+  if (negopt)
+    {
+      tmp = negopt;
+      negv = tmp.split();
+    }
+  else
+    for_contents (std::vector<sstring>, v, s)
+      negv.push_back (neg_opt (*s));
+  if (desc)
+    {
+      options_help_text << "-" << sstring::join (v,",-") << "\t";
+      int i = 0;
+      int desc_len = std::strlen(desc);
+      while (i < desc_len) if (isspace(desc[i])) options_help_text << desc[i++]; else break;
+      if (show_default && var) options_help_text << "(default) ";
+      while (i < desc_len) options_help_text << desc[i++];
+      const sstring& neg = negv.back();
+      if (show_default && var) options_help_text << " (-" << neg << " to disable)";
+      else if (negdesc) options_help_text << " (opposite of -" << neg << ")";
+      options_help_text << "\n";
+    }
+  if (negdesc)
+    {
+      options_help_text << " -" << sstring::join (negv,",-") << "\t ";
+      int i = 0;
+      int desc_len = std::strlen(negdesc);
+      while (i < desc_len) if (isspace(negdesc[i])) options_help_text << negdesc[i++]; else break;
+      if (show_default && !var) options_help_text << "(default) ";
+      while (i < desc_len) options_help_text << negdesc[i++];
+      const sstring& pos = v.back();
+      if (show_default && !var) options_help_text << " (-" << pos << " to disable)";
+      else if (desc) options_help_text << " (opposite of -" << pos << ")";
+      options_help_text << "\n";
+    }
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      bool_opts[*i] = &var;
+    }
+  for_contents (std::vector<sstring>, negv, i)
+    {
+      new_opt (*i);
+      bool_no_opts[*i] = &var;
+    }
+}
+
+void Opts_list::add(const char*opt,int&var,const char*desc, bool show_default)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  if (desc)
+    {
+      options_help_text << "-" << sstring::join (v,",-") << " <integer>\t" << desc;
+      if (show_default)
+	{
+	  char buf[100];
+	  sprintf (buf, "%d", var);
+	  options_help_text << " (default is " << buf << ")";
+	}
+      options_help_text << "\n";
+    }
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      int_opts[*i] = &var;
+    }
+}
+
+void Opts_list::add(const char*opt,double&var,const char*desc, bool show_default)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  if (desc)
+    {
+      options_help_text << "-" << sstring::join (v,",-") << " <real>\t" << desc;
+      if (show_default)
+	{
+	  char buf[100];
+	  sprintf (buf, "%g", var);
+	  options_help_text << " (default is " << buf << ")";
+	}
+      options_help_text << "\n";
+    }
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      double_opts[*i] = &var;
+    }
+}
+
+void Opts_list::add (const char* opt, const char* alias, const char* desc, bool show_alias)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  const sstring alias_str (alias);
+  if (desc)
+    {
+      options_help_text << '-' << sstring::join (v,",-") << '\t' << desc;
+      if (show_alias)
+	options_help_text << " (same as '" << alias << "')";
+      options_help_text << '\n';
+    }
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      alias_opts[*i] = alias_str;
+    }
+}
+
+void Opts_list::add(const char*opt,Option_handler callback,const char*desc)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  if (desc)
+    options_help_text << "-" << sstring::join (v,",-") << desc << "\n";
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      callback_opts[*i] = callback;
+    }
+}
+
+void Opts_list::add(const char*opt,sstring&var,const char*desc, bool show_default)
+{
+  sstring tmp (opt);
+  std::vector<sstring> v = tmp.split();
+  if (desc)
+    {
+      options_help_text << "-" << sstring::join (v,",-") << " <string>\t" << desc;
+      if (show_default) options_help_text << " (default is \"" << var << "\")";
+      options_help_text << "\n";
+    }
+  for_contents (std::vector<sstring>, v, i)
+    {
+      new_opt (*i);
+      string_opts[*i] = &var;
+    }
+}
+
+std::vector<sstring> Opts_list::get_not_opts()
+{
+  std::vector<sstring> not_opts;
+  while (more_args())
+    {
+      sstring opt = next_string();
+      if (opt[0] != '-')
+	not_opts.push_back (opt);
+      else
+	{
+	  opt.erase (opt.begin());
+	  opt.to_lower();
+
+	  if (int_opts.find(opt) != int_opts.end())
+	    next_int();
+	  else if (double_opts.find(opt) != double_opts.end())
+	    next_double();
+	  else if (string_opts.find(opt) != string_opts.end())
+	    next_string();
+	  else if (alias_opts.find(opt) != alias_opts.end())
+	    {
+	      const std::vector<sstring> alias_opts_vec = alias_opts[opt].split();
+	      alias_args.insert (alias_args.begin(), alias_opts_vec.rbegin(), alias_opts_vec.rend());
+	    }
+	  else if (callback_opts.find(opt) != callback_opts.end())
+	    {
+	      (*callback_opts[opt]) (this);
+	    }
+	}
+    }
+
+  // reset pointers
+  argc = init_argc;
+  argv = init_argv;
+  
+  return not_opts;
+}
+
+bool Opts_list::parse()
+{
+  args.clear();
+  while (more_args())
+    {
+      sstring opt = next_string();
+
+      if (opt[0] != '-')
+	args.push_back (opt);
+      else
+	{
+	  opt.erase (opt.begin());
+	  opt.to_lower();
+
+	  const Parse_status stat = parse_opt (opt);
+	  if (stat == PARSE_OK || stat == PARSE_NOT_OK)
+	    return stat == PARSE_OK;
+
+	  else if (bool_opts.find(opt) != bool_opts.end())
+	    *bool_opts[opt] = 1;
+	  
+	  else if (bool_no_opts.find(opt) != bool_no_opts.end())
+	      *bool_no_opts[opt] = 0;
+	  
+	  else if (int_opts.find(opt) != int_opts.end())
+	    *int_opts[opt] = next_int();
+	  
+	  else if (double_opts.find(opt) != double_opts.end())
+	    *double_opts[opt] = next_double();
+	  
+	  else if (string_opts.find(opt) != string_opts.end())
+	    *string_opts[opt] = next_string();
+	  
+	  else if (alias_opts.find(opt) != alias_opts.end())
+	    {
+	      const std::vector<sstring> alias_opts_vec = alias_opts[opt].split();
+	      alias_args.insert (alias_args.begin(), alias_opts_vec.rbegin(), alias_opts_vec.rend());
+	    }
+	  
+	  else if (callback_opts.find(opt) != callback_opts.end())
+	    {
+	      if (!(*callback_opts[opt]) (this))
+		return 0;
+	    }
+	  
+	  else
+	    {
+	      THROW Syntax_exception (*this, "unknown option: -", opt.c_str());
+	      return 0;
+	    }
+	}
+    }
+
+  if (expect_args >= 0 && (int) args.size() != expect_args)
+    THROWEXPR ("ERROR: Expected " << expect_args << " arguments, got " << args.size());
+
+  CTAG(5,OPTS) << "Parsed command line: ";
+  for (int i = 0; i < init_argc; i++) clog_stream << init_argv[i] << (i < init_argc - 1 ? " " : "\n");
+
+  bool parsed_ok = 1;
+  for_contents (std::vector<Option_handler>, post_parse_callback, callback) parsed_ok &= (*callback) (this);
+  
+  return parsed_ok;
+}
+
+void Opts_list::parse_or_die()
+{
+  try
+    {
+      if (!parse()) { CLOGERR << short_help(); exit(1); }
+    }
+  catch (const Dart_exception& e)
+    {
+      cerr << short_help();
+      cerr << e.what();
+      exit(1);
+    }
+}
+
+Opts_list::Parse_status Opts_list::parse_opt (const sstring& opt)
+{
+  return UNPARSED;
+}
diff --git a/src/util/opts_list.h b/src/util/opts_list.h
new file mode 100755
index 0000000..9a1c637
--- /dev/null
+++ b/src/util/opts_list.h
@@ -0,0 +1,160 @@
+#ifndef OPTS_LIST_INCLUDED
+#define OPTS_LIST_INCLUDED
+
+#include <iostream>
+#include <cmath>
+#include <set>
+#include <map>
+#include <list>
+
+#include "util/dexception.h"
+#include "util/sstring.h"
+#include "config.h"
+
+namespace fsa {
+
+  // parser class for command line options & arguments of an executable
+  struct Opts_list {
+
+    // syntax error exception class... this is really archaic stuff
+    struct Syntax_exception : Dart_exception
+    {
+      const Opts_list&  opts;  // pointer to parent class
+      sstring           temp;  // temporary variable used by Dart_exception method
+      sstring           info;  // used to hold the error message
+
+      Syntax_exception (const Opts_list& opts, const char* msg) :
+      Dart_exception(), opts(opts), info(msg) {}
+      Syntax_exception (const Opts_list& opts, const char* msg1, const char* msg2) :
+      Dart_exception(), opts(opts), info(msg1) { info.append(msg2); }
+
+      // overrides Dart_exception method
+      const char* details() const
+      {
+	(sstring&) temp = "";
+	((sstring&) temp).append("While parsing command line: ").append(info).append(".\n");
+	return temp.c_str();
+      }
+    };
+
+    // typedef for "option handlers" (callback member functions)
+    typedef bool (*Option_handler) (Opts_list*);  // returns TRUE if parsed OK, FALSE if error
+
+    // type of option taking values "yes", "no" and "auto" (used in one piece of code dating from 1999, AFAIK...)
+    enum Expect_flag { YES, NO, AUTO };
+    void set_expect_flag (Expect_flag& flag, const char* value_str);
+
+    // member variables
+
+    // "current" argc and argv - these are used as pointers and are changed by the option parse code
+    int    argc;
+    char** argv;
+
+    // aliased arguments
+    std::list<sstring> alias_args;
+    std::list<sstring>::iterator next_alias_arg;
+
+    // method to check if there are more args remaining
+    bool more_args() const;
+
+    // initial values of argc and argv
+    int    init_argc;
+    char** init_argv;
+
+    int expect_args;   // expected number of args: -1 for "any", otherwise will complain if not equal to this
+
+    // all options
+    std::set<sstring> all_opts;
+    void new_opt (const sstring& s);
+    static sstring neg_opt (const sstring& s);  // puts a "no" in front of an option
+
+    // options by type
+    std::map <sstring, bool*>          bool_opts;
+    std::map <sstring, bool*>          bool_no_opts;
+    std::map <sstring, int*>           int_opts;
+    std::map <sstring, double*>        double_opts;
+    std::map <sstring, sstring*>       string_opts;
+    std::map <sstring, Option_handler> callback_opts;
+    std::map <sstring, sstring>        alias_opts;
+
+    // post-parse callback hooks
+    std::vector <Option_handler>       post_parse_callback;
+
+    // various bits of help text
+    sstring program_name;
+    sstring short_description;
+    sstring version_info;
+    sstring syntax;
+    sstring short_help_text;
+    sstring options_help_text;
+
+    // arguments (extracted from the command line & stuck into this vector by the option-parsing code)
+    std::vector<sstring> args;
+  
+    // member functions
+
+    // constructor
+    Opts_list (int argc, char** argv);
+
+    // virtual destructor
+    virtual ~Opts_list();
+
+    // builder methods to add options, with comments in help text
+    void add (const char* opt, bool& var, const char* desc = 0, bool show_default = 1, const char* negopt = 0, const char* negdesc = 0);
+    void add (const char* opt, int& var, const char* desc = 0, bool show_default = true);
+    void add (const char* opt, double& var, const char* desc = 0, bool show_default = true);
+    void add (const char* opt, sstring& var, const char* desc = 0, bool show_default = true);
+    void add (const char* opt, const char* alias, const char* desc = 0, bool show_alias = true);
+    void add (const char* opt, Option_handler callback, const char* desc = 0);
+
+    // builder methods to add comments to help text
+    void print (const char* text);
+    void newline();
+    void print_title (const char* text);
+
+    // parser methods
+    bool parse();  // returns TRUE if parsed OK
+    void parse_or_die();
+
+    // Get everything which doesn't begin with '-'
+    // (for collecting e.g. sequence filenames without parsing options).
+    // This is basically a hacked version of parse() which doesn't store
+    // bool, int, double or string option values
+    // (but alias and callback options /do/ get parsed).
+    // Pointers are reset afterwards for regular parsing with parse().
+    std::vector<sstring> get_not_opts();
+
+    // virtual parse method
+    enum Parse_status { UNPARSED = 0, PARSE_OK = 1, PARSE_NOT_OK = 2 };
+    virtual Parse_status parse_opt (const sstring& opt);
+
+    // parser helper methods
+    double next_double();
+    int    next_int();
+    char*  next_string();
+
+    // help text accessors
+    virtual sstring short_help() const;  // prints program_name/short_description/syntax, short_help_text
+    virtual sstring help() const;  // prints program_name/short_description/syntax, options_help_text
+
+    // option handler functions to display various bits of help text
+    static bool display_help (Opts_list* ol);
+    static bool display_version (Opts_list* ol);
+  };
+
+  // build macros
+#define SET_VERSION_INFO(OPTS) (OPTS).version_info.clear(); (OPTS).version_info << PACKAGE_STRING << " (" << DART_DEBUG_MODE_STRING << ") compiled " << __DATE__ << " " << __TIME__ << "\n";
+
+  //#define INIT_CONSTRUCTED_OPTS_LIST(OPTS,ARGS,SYNTAX,SHORTDESC) OPTS.short_description = (SHORTDESC); OPTS.syntax = (SYNTAX); OPTS.expect_args = (ARGS); SET_VERSION_INFO(OPTS); Rnd::add_opts(OPTS); OPTS.newline(); Log_stream::add_opts(OPTS);
+
+  // Rnd library removed 12/19/08
+  // -- RKB
+#define INIT_CONSTRUCTED_OPTS_LIST(OPTS,ARGS,SYNTAX,SHORTDESC) OPTS.short_description = (SHORTDESC); OPTS.syntax = (SYNTAX); OPTS.expect_args = (ARGS); SET_VERSION_INFO(OPTS); Log_stream::add_opts(OPTS);
+
+#define INIT_TYPED_OPTS_LIST(OPTS_TYPE,OPTS,ARGC,ARGV,ARGS,SYNTAX,SHORTDESC) OPTS_TYPE OPTS(ARGC,ARGV); INIT_CONSTRUCTED_OPTS_LIST(OPTS,ARGS,SYNTAX,SHORTDESC)
+
+#define INIT_OPTS_LIST(OPTS,ARGC,ARGV,ARGS,SYNTAX,SHORTDESC) INIT_TYPED_OPTS_LIST(Opts_list,OPTS,ARGC,ARGV,ARGS,SYNTAX,SHORTDESC)
+
+}
+
+#endif
diff --git a/src/util/regexp.cc b/src/util/regexp.cc
new file mode 100644
index 0000000..678f8c7
--- /dev/null
+++ b/src/util/regexp.cc
@@ -0,0 +1,1758 @@
+// See http://www.codeguru.com/Cpp/Cpp/string/regex/article.php/c2779/
+// for information on how to use this code.
+// -- RKB
+
+// Regexp.cc - regular expression class based on Henry Spencer's regexp code.
+// Adapted for Windows by Guy Gascoigne (see notes below)
+// Made unix-friendly by Ian Holmes ihh at lanl.gov April 30, 1999
+
+// In case this isn't obvious from the later comments this is an ALTERED
+// version of the software. If you like my changes then cool, but nearly
+// all of the functionality here is derived from Henry Spencer's original
+// work.
+//
+// This code should work correctly under both _SBCS and _UNICODE, I did
+// start working on making it work with _MBCS but gave up after a while
+// since I don't need this particular port and it's not going to be as
+// straight forward as the other two.
+//
+// The problem stems from the compiled program being stored as chars,
+// the individual items need to be wide enough to hold whatever character
+// is thrown at them, but currently they are accessed as an array of
+// whatever size integral type is appropriate.  _MBCS would cause this
+// to be char, but at times it would need to be larger.  This would
+// require making the program be an array of short with the appropriate
+// conversions used everywhere.  Certainly it's doable, but it's a pain.
+// What's worse is that the current code will compile and run under _MBCS,
+// only breaking when it gets wide characters thrown against it.
+//
+// I've marked at least one bit of code with #pragma messages, I may not
+// get all of them, but they should be a start
+//
+// Guy Gascoigne - Piggford (ggp at bigfoot.com) Friday, February 27, 1998
+
+// EAT MY SHORTS - I took out all the casts to shorts cos they made my
+// SparcStation unhappy. ihh at lanl.gov April 30, 1999
+
+// regcomp and regexec -- regsub and regerror are elsewhere
+// @(#)regexp.c	1.3 of 18 April 87
+//
+//	Copyright (c) 1986 by University of Toronto.
+//	Written by Henry Spencer.  Not derived from licensed software.
+//
+//	Permission is granted to anyone to use this software for any
+//	purpose on any computer system, and to redistribute it freely,
+//	subject to the following restrictions:
+//
+//	1. The author is not responsible for the consequences of use of
+//		this software, no matter how awful, even if they arise
+//		from defects in it.
+//
+//	2. The origin of this software must not be misrepresented, either
+//		by explicit claim or by omission.
+//
+//	3. Altered versions must be plainly marked as such, and must not
+//		be misrepresented as being the original software.
+// *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
+// *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
+// *** as in BSD grep and ex.
+// *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
+// *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
+// *** THIS IS AN ALTERED VERSION.  It was altered by James A. Woods,
+// *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
+// *** THIS IS AN ALTERED VERSION.  It was altered by Geoffrey Noer,
+// *** THIS IS AN ALTERED VERSION.  It was altered by Guy Gascoigne - Piggford
+// *** guy at wyrdrune.com, on 15 March 1998, porting it to C++ and converting
+// *** it to be the engine for the Regexp class
+// *** THIS IS AN ALTERED VERSION.  It was altered by Ian Holmes,
+// *** ihh at fruitfly.org, on Jan 28 2000, porting it to gcc and DART's string
+// *** class (sstring)
+// *** THIS IS AN ALTERED VERSION.  It was altered by Robert Bradley,
+// *** Dec 4 2008, changing the string class: sstring -> std::string.
+//
+// Beware that some of this code is subtly aware of the way operator
+// precedence is structured in regular expressions.  Serious changes in
+// regular-expression syntax might require a total rethink.
+
+#include <cassert>
+#include <iostream>
+#include <string.h>
+
+#include "util/regexp.h"
+
+// The first byte of the regexp internal "program" is actually this magic
+// number; the start node begins in the second byte.
+
+const char	MAGIC = ((char)'\234');
+
+// #define new DEBUG_NEW
+
+// following line commented out by ihh, December 14 2003, because gcc doesn't care for it
+// #pragma warning( disable : 4711 )	// automatic inline selected
+
+// The "internal use only" fields in regexp.h are present to pass info from
+// compile to execute that permits the execute phase to run lots faster on
+// simple cases.  They are:
+//
+// regstart	char that must begin a match; '\0' if none obvious
+// reganch	is the match anchored (at beginning-of-line only)?
+// regmust	string (pointer into program) that match must include, or NULL
+// regmlen	length of regmust string
+//
+// Regstart and reganch permit very fast decisions on suitable starting
+// points for a match, cutting down the work a lot.  Regmust permits fast
+// rejection of lines that cannot possibly match.  The regmust tests are
+// costly enough that regcomp() supplies a regmust only if the
+// r.e. contains something potentially expensive (at present, the only
+// such thing detected is * or + at the start of the r.e., which can
+// involve a lot of backup).  Regmlen is supplied because the test in
+// regexec() needs it and regcomp() is computing it anyway.
+
+// Structure for regexp "program".  This is essentially a linear encoding
+// of a nondeterministic finite-state machine (aka syntax charts or
+// "railroad normal form" in parsing technology).  Each node is an opcode
+// plus a "next" pointer, possibly plus an operand.  "Next" pointers of
+// all nodes except BRANCH implement concatenation; a "next" pointer with
+// a BRANCH on both ends of it is connecting two alternatives.  (Here we
+// have one of the subtle syntax dependencies: an individual BRANCH (as
+// opposed to a collection of them) is never concatenated with anything
+// because of operator precedence.)  The operand of some types of node is
+// a literal string; for others, it is a node leading into a sub-FSM.  In
+// particular, the operand of a BRANCH node is the first node of the
+// branch.  (NB this is *not* a tree structure: the tail of the branch
+// connects to the thing following the set of BRANCHes.)  The opcodes
+// are:
+
+enum {
+//  definition	number		opnd?	meaning
+	END		=	0,		//	no		End of program.
+	BOL		=	1,		//	no		Match beginning of line.
+	EOL		=	2,		//	no		Match end of line.
+	ANY		=	3,		//	no		Match any character.
+	ANYOF	=	4,		//	str		Match any of these.
+	ANYBUT	=	5,		//	str		Match any but one of these.
+	BRANCH	=	6,		//	node	Match this, or the next..\&.
+	BACK	=	7,		//	no		"next" ptr points backward.
+	EXACTLY	=	8,		//	str		Match this string.
+	NOTHING	=	9,		//	no		Match empty string.
+	STAR	=	10,		//	node	Match this 0 or more times.
+	PLUS	=	11,		//	node	Match this 1 or more times.
+	WORDA	=	12,		//	no		Match "" at wordchar, where prev is nonword
+	WORDZ	=	13,		//	no		Match "" at nonwordchar, where prev is word
+	OPEN	=	20,		//	no		Sub-RE starts here.
+						//			OPEN+1 is number 1, etc.
+	CLOSE	=	30		//	no		Analogous to OPEN.
+};
+
+// Opcode notes:
+//
+// BRANCH	The set of branches constituting a single choice are hooked
+//		together with their "next" pointers, since precedence prevents
+//		anything being concatenated to any individual branch.  The
+//		"next" pointer of the last BRANCH in a choice points to the
+//		thing following the whole choice.  This is also where the
+//		final "next" pointer of each individual branch points; each
+//		branch starts with the operand node of a BRANCH node.
+//
+// BACK		Normal "next" pointers all implicitly point forward; BACK
+//		exists to make loop structures possible.
+//
+// STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
+//		BRANCH structures using BACK.  Simple cases (one character
+//		per match) are implemented with STAR and PLUS for speed
+//		and to minimize recursive plunges.
+//
+// OPEN,CLOSE	...are numbered at compile time.
+
+// A node is one char of opcode followed by two chars of "next" pointer.
+// "Next" pointers are stored as two 8-bit pieces, high order first.  The
+// value is a positive offset from the opcode of the node containing it.
+// An operand, if any, simply follows the node.  (Note that much of the
+// code generation knows about this implicit relationship.)
+//
+// Using two bytes for the "next" pointer is vast overkill for most things,
+// but allows patterns to get big without disasters.
+
+
+enum
+{
+	REGERR_SENTINEL_VALUE = 0,
+	REGERR_NULLARG = 1, REGERR_CORRUPTED, REGERR_CORRUPTION, REGERR_CORRUPTED_POINTERS,
+	REGERR_BAD_REGREPEAT, REGERR_CORRUPTED_OPCODE, REGERR_NULL_TO_REGSUB,
+	REGERR_DAMAGED_REGEXP_REGSUB, REGERR_DAMAGED_MATCH_STRING, REGERR_NULL_TO_REGCOMP,
+	REGERR_TO_BIG, REGERR_TO_MANY_PAREN, REGERR_UNTERMINATED_PAREN, REGERR_UNMATCHED_PAREN,
+	REGERR_INTERNAL_ERROR_JUNK, REGERR_OP_COULD_BE_EMPTY, REGERR_NESTED_OP, REGERR_INVALID_RANGE,
+	REGERR_UNMATCHED_BRACE, REGERR_INTERNAL_UNEXPECTED_CHAR, REGERR_OP_FOLLOWS_NOTHING,
+	REGERR_TRAILING_ESC, REGERR_INTERNAL_STRSCSPN, REGERR_NO_REGEXP
+};
+
+struct regErr
+{
+	int m_id;
+	const char* m_err;
+} errors[] = {
+	{ REGERR_NULLARG,					"NULL argument to regexec" },
+	{ REGERR_CORRUPTED,					"corrupted regexp" },
+	{ REGERR_CORRUPTION,				"regexp corruption" },
+	{ REGERR_CORRUPTED_POINTERS,		"corrupted pointers" },
+	{ REGERR_BAD_REGREPEAT,				"internal error: bad call of regrepeat" },
+	{ REGERR_CORRUPTED_OPCODE,			"corrupted opcode" },
+	{ REGERR_NULL_TO_REGSUB,			"NULL parm to regsub" },
+	{ REGERR_DAMAGED_REGEXP_REGSUB,		"damaged regexp fed to regsub" },
+	{ REGERR_DAMAGED_MATCH_STRING,		"damaged match string" },
+	{ REGERR_NULL_TO_REGCOMP,			"NULL argument to regcomp" },
+	{ REGERR_TO_BIG,					"regexp too big" },
+	{ REGERR_TO_MANY_PAREN,				"too many ()" },
+	{ REGERR_UNTERMINATED_PAREN,		"unterminated ()" },
+	{ REGERR_UNMATCHED_PAREN,			"unmatched ()" },
+	{ REGERR_INTERNAL_ERROR_JUNK,		"internal error: junk on end" },
+	{ REGERR_OP_COULD_BE_EMPTY,			"*+ operand could be empty" },
+	{ REGERR_NESTED_OP,					"nested *?+" },
+	{ REGERR_INVALID_RANGE,				"invalid [] range" },
+	{ REGERR_UNMATCHED_BRACE,			"unmatched []" },
+	{ REGERR_INTERNAL_UNEXPECTED_CHAR,	"internal error: \\0|) unexpected" },
+	{ REGERR_OP_FOLLOWS_NOTHING,		"?+* follows nothing" },
+	{ REGERR_TRAILING_ESC,				"trailing \\" },
+	{ REGERR_INTERNAL_STRSCSPN,			"internal error: strcspn 0" },
+	{ REGERR_NO_REGEXP,					"NULL regexp" },
+	{ REGERR_SENTINEL_VALUE,			"Unknown error" }							// must be last value
+};
+
+// Flags to be passed up and down.
+
+enum {
+	HASWIDTH	=	01,	// Known never to match null string.
+	SIMPLE		=	02,	// Simple enough to be STAR/PLUS operand.
+	SPSTART		=	04,	// Starts with * or +.
+	WORST		=	0	// Worst case.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class CRegErrorHandler
+{
+	friend class Regexp;
+	mutable std::string m_szError;
+	static const char* FindErr( int id );
+protected:
+	void ClearErrorString() const;
+	void regerror( const char* s ) const;
+	void regerror( int id ) const;
+public:
+	CRegErrorHandler() { }
+	CRegErrorHandler( const CRegErrorHandler & reh ) : m_szError( reh.m_szError ) {}
+
+	const std::string & GetErrorString() const;
+};
+
+void CRegErrorHandler::regerror( const char* s ) const
+{
+  std::cerr << "ERROR: regerror: " << s << "\n";
+  m_szError = s;
+}
+
+void CRegErrorHandler::regerror( int id ) const
+{
+	regerror( FindErr( id ) );
+}
+
+const std::string & CRegErrorHandler::GetErrorString() const
+{
+	return m_szError;
+}
+
+void CRegErrorHandler::ClearErrorString() const
+{
+	m_szError.clear();
+}
+
+const char* CRegErrorHandler::FindErr( int id )
+{
+  struct regErr * perr;
+  for (perr = errors; perr->m_id != REGERR_SENTINEL_VALUE; perr++ )
+    if ( perr->m_id == id )
+      return perr->m_err;
+  
+  return perr->m_err;		// since we've fallen off the array, perr->m_id == 0
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+// All of the functions required to directly access the 'program'
+class CRegProgramAccessor : public CRegErrorHandler
+{
+public:
+	static inline char OP( char* p )
+	{
+		return (*(p));
+	}
+	static inline char* OPERAND( char* p )
+	{
+		return p + 3;
+	}
+	static inline char* regnext( char* p )
+	{
+	  const int offset = (((unsigned char*)p)[1] << 8) + ((unsigned char*)p)[2];
+	  
+		if (offset == 0)
+			return(NULL);
+		
+		return((OP(p) == BACK) ? p-offset : p+offset);
+	}
+#ifdef _RE_DEBUG
+	char* CRegProgramAccessor::regprop( char* op );
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// The internal interface to the regexp, wrapping the compilation as well as the
+// execution of the regexp (matching)
+
+class regexp_internal : public CRegProgramAccessor
+{
+	friend class CRegExecutor;
+	friend class Regexp;
+	
+	int m_programSize;
+	char* startp[Regexp::NSUBEXP];
+	char* endp[Regexp::NSUBEXP];
+	char regstart;		// Internal use only.
+	char reganch;		// Internal use only.
+	char* regmust;		// Internal use only.
+	int regmlen;		// Internal use only.
+	char* program;
+	
+	bool status;
+	int count;			// used by Regexp to manage the reference counting of regexps
+	int numSubs;
+public:
+	
+	regexp_internal( const char* exp, bool iCase );
+	regexp_internal( const regexp_internal & r );
+	~regexp_internal();
+	
+	void ignoreCase( const char * in, char * out );
+	
+	bool regcomp( const char* exp );
+	bool regexec( char* str );
+	bool Status() const { return status; }
+
+	std::string GetReplaceString( const char* sReplaceExp ) const;
+
+	regexp_internal * getCopy();
+
+#ifdef _RE_DEBUG
+	void  regdump();
+#endif
+	
+#ifdef _DEBUG
+	std::string m_originalPattern;
+	std::string m_modifiedPattern;
+#endif
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Compile / Validate the regular expression - ADT
+
+class CRegCompilerBase : public CRegProgramAccessor
+{
+public:
+	CRegCompilerBase( const char* parse );
+
+	char* reg(int paren, int *flagp);
+protected:
+	char* regparse;	// Input-scan pointer. 
+	int regnpar;		// () count. 
+
+	char* regbranch(int *flagp);
+	char* regpiece(int *flagp);
+	char* regatom(int *flagp);
+	inline bool ISREPN( char c )	{ return ((c) == '*' || (c) == '+' || (c) == '?'); }
+
+	virtual void regc(int c) = 0;
+	virtual char* regnode(int op) = 0;
+	virtual void reginsert(char op, char* opnd) = 0;
+	virtual void regtail(char* p, char* val) = 0;
+	virtual void regoptail(char* p, char* val) = 0;
+
+  // virtual destructor, to keep gcc happy -- added by ihh, December 14, 2003
+  virtual ~CRegCompilerBase() { }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// First pass over the expression, testing for validity and returning the 
+// program size
+
+class CRegValidator : public CRegCompilerBase
+{
+public:
+	CRegValidator( const char* parse );
+
+	inline long Size() const { return regsize; }
+private:
+	long regsize;		// Code size. 
+	char regdummy[3];	// NOTHING, 0 next ptr 
+protected:
+	char* regnode(int) { regsize += 3; return regdummy; }
+	void regc(int) { regsize++; }
+	void reginsert(char, char*) { regsize += 3; }
+	void regtail(char*, char*) { return; }
+	void regoptail(char*, char*) { return; }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// Second pass, actually generating the program
+
+class CRegCompiler : public CRegCompilerBase
+{
+public:
+	CRegCompiler( const char* parse, char* prog );
+private:
+	char* regcode;
+protected:
+	// regc - emit (if appropriate) a byte of code
+	void regc(int b)
+	{
+		*regcode++ = (char)b;
+	}
+	char* regnode(int op);
+	void reginsert(char op, char* opnd);
+	void regtail(char* p, char* val);
+	void regoptail(char* p, char* val);
+};
+
+// regnode - emit a node
+char* CRegCompiler::regnode(int op)
+{
+	char* const ret = regcode;
+
+	char* ptr = ret;
+	*ptr++ = (char)op;
+	*ptr++ = '\0';		// Null next pointer. 
+	*ptr++ = '\0';
+	regcode = ptr;
+
+	return(ret);
+}
+
+// reginsert - insert an operator in front of already-emitted operand
+//
+// Means relocating the operand.
+void CRegCompiler::reginsert(char op, char* opnd)
+{
+	char* place;
+
+	(void) memmove(opnd+3, opnd, (size_t)((regcode - opnd)*sizeof(char)));
+	regcode += 3;
+
+	place = opnd;		// Op node, where operand used to be.
+	*place++ = op;
+	*place++ = '\0';
+	*place++ = '\0';
+}
+
+// regtail - set the next-pointer at the end of a node chain
+void CRegCompiler::regtail(char* p, char* val)
+{
+	char* scan;
+	char* temp;
+
+	// Find last node. 
+	for (scan = p; (temp = regnext(scan)) != NULL; scan = temp)
+		continue;
+
+	int next_ptr = (OP(scan) == BACK) ? scan - val : val - scan;
+	((unsigned char*)scan)[1] = (unsigned char) (next_ptr >> 8);
+	((unsigned char*)scan)[2] = (unsigned char) (next_ptr & 0xff);
+
+	// debugging assertion added by ihh -- December 5, 2003
+	if (regnext(scan) != val)
+	  regerror( REGERR_CORRUPTED );
+}
+
+// regoptail - regtail on operand of first argument; nop if operandless
+void CRegCompiler::regoptail(char* p, char* val)
+{
+	// "Operandless" and "op != BRANCH" are synonymous in practice. 
+	if (OP(p) == BRANCH)
+		regtail(OPERAND(p), val);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+CRegCompilerBase::CRegCompilerBase( const char* parse )
+	: regparse( (char*)parse ),
+	regnpar(1)
+{
+}
+
+CRegValidator::CRegValidator( const char* parse )
+	: CRegCompilerBase( parse ),
+	regsize(0)
+{
+	regc(MAGIC);
+	regdummy[0] = NOTHING;
+	regdummy[1] = regdummy[2] = 0;
+}
+
+CRegCompiler::CRegCompiler( const char* parse, char* prog )
+	: CRegCompilerBase( parse ),
+	regcode(prog)
+{
+	regc(MAGIC);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+regexp_internal::regexp_internal( const char* exp, bool iCase )
+  : m_programSize(0),
+    regstart(0),
+    reganch(0),
+    regmust(0),
+    regmlen(0),
+    program(0)
+{
+#if _DEBUG
+	m_originalPattern = exp;		// keep a version of the pattern for debugging
+#endif
+
+	if ( iCase )
+	{
+		char * out = new char[(strlen( exp ) * 4) + 1];
+		ignoreCase( exp, out );
+
+#if _DEBUG
+		m_modifiedPattern = out;	// and the modified version if there is one
+#endif
+		status = regcomp( out );
+		delete [] out;
+	}
+	else
+		status = regcomp( exp );
+
+	count = numSubs = 0;
+}
+
+regexp_internal::regexp_internal( const regexp_internal & orig )
+	: m_programSize(orig.m_programSize),
+	  regstart(orig.regstart),
+	  reganch(orig.reganch),
+	  regmust(0),
+	  regmlen(orig.regmlen),
+	  numSubs(orig.numSubs)
+{
+#if _DEBUG
+	m_originalPattern = orig.m_originalPattern;
+	m_modifiedPattern = orig.m_modifiedPattern;
+#endif
+	status = orig.status;
+	count = 0;
+	program = new char[m_programSize];
+	memcpy( program, orig.program, m_programSize * sizeof( char ) );
+	if ( orig.regmust )
+		regmust = program + ( orig.regmust - orig.program );
+
+	for ( int i = Regexp::NSUBEXP; i > 0; i--)
+	{
+		startp[i] = orig.startp[i];
+		endp[i] = orig.endp[i];
+	}
+}
+
+regexp_internal::~regexp_internal()
+{
+	delete [] program;
+}
+
+
+// regcomp - compile a regular expression into internal code
+//
+// We can't allocate space until we know how big the compiled form will
+// be, but we can't compile it (and thus know how big it is) until we've
+// got a place to put the code.  So we cheat: we compile it twice, once
+// with code generation turned off and size counting turned on, and once
+// "for real".  This also means that we don't allocate space until we are
+// sure that the thing really will compile successfully, and we never
+// have to move the code and thus invalidate pointers into it.  (Note
+// that it has to be in one piece because free() must be able to free it
+// all.)
+//
+// Beware that the optimization-preparation code in here knows about some
+// of the structure of the compiled regexp.
+
+bool regexp_internal::regcomp(const char* exp)
+{
+	char* scan;
+	int flags;
+
+	if (exp == NULL)
+	{
+		regerror( REGERR_NULL_TO_REGCOMP );
+		return 0;
+	}
+
+	// First pass: determine size, legality.
+	CRegValidator tester( exp );
+
+	if (tester.reg(0, &flags) == NULL)
+		return false;
+
+	// Small enough for pointer-storage convention? 
+	if (tester.Size() >= 0x7fffL)	// Probably could be 0xffffL. 
+	{
+		regerror(REGERR_TO_BIG);
+		return 0;
+	}
+
+	m_programSize = tester.Size();
+	// Allocate space. 
+	program = new char[m_programSize];
+
+	CRegCompiler comp( exp, program );
+	// Second pass: emit code. 
+	if (comp.reg(0, &flags) == NULL)
+		return false;
+
+	scan = program + 1;			// First BRANCH. 
+	if (OP(regnext(scan)) == END)
+	{		// Only one top-level choice. 
+		scan = OPERAND(scan);
+
+		// Starting-point info. 
+		if (OP(scan) == EXACTLY)
+			regstart = *OPERAND(scan);
+		else if (OP(scan) == BOL)
+			reganch = 1;
+
+		// If there's something expensive in the r.e., find the
+		// longest literal string that must appear and make it the
+		// regmust.  Resolve ties in favor of later strings, since
+		// the regstart check works with the beginning of the r.e.
+		// and avoiding duplication strengthens checking.  Not a
+		// strong reason, but sufficient in the absence of others.
+		 
+		if (flags&SPSTART) 
+		{
+			char* longest = NULL;
+			size_t len = 0;
+
+			for (; scan != NULL; scan = regnext(scan))
+				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len)
+				{
+					longest = OPERAND(scan);
+					len = strlen(OPERAND(scan));
+				}
+			regmust = longest;
+			regmlen = (int)len;
+		}
+	}
+
+	return true;
+}
+
+regexp_internal * regexp_internal::getCopy()
+{
+	return new regexp_internal( *this );
+}
+
+// reg - regular expression, i.e. main body or parenthesized thing
+//
+// Caller must absorb opening parenthesis.
+//
+// Combining parenthesis handling with the base level of regular expression
+// is a trifle forced, but the need to tie the tails of the branches to what
+// follows makes it hard to avoid.
+
+char* CRegCompilerBase::reg( int paren, int *flagp )
+{
+	char* ret = 0;
+	char* br;
+	char* ender;
+	int parno = 0;
+	int flags;
+
+	*flagp = HASWIDTH;	// Tentatively. 
+
+	if (paren)
+	{
+		// Make an OPEN node. 
+		if (regnpar >= Regexp::NSUBEXP)
+		{
+			regerror(REGERR_TO_MANY_PAREN);
+			return NULL;
+		}
+		parno = regnpar;
+		regnpar++;
+		ret = regnode(OPEN+parno);
+	}
+
+	// Pick up the branches, linking them together. 
+	br = regbranch(&flags);
+	if (br == NULL)
+		return(NULL);
+	if (paren)
+		regtail(ret, br);	// OPEN -> first. 
+	else
+		ret = br;
+	*flagp &= ~(~flags&HASWIDTH);	// Clear bit if bit 0. 
+	*flagp |= flags&SPSTART;
+	while (*regparse == '|')
+	{
+		regparse++;
+		br = regbranch(&flags);
+		if (br == NULL)
+			return(NULL);
+		regtail(ret, br);	// BRANCH -> BRANCH. 
+		*flagp &= ~(~flags&HASWIDTH);
+		*flagp |= flags&SPSTART;
+	}
+
+	// Make a closing node, and hook it on the end. 
+	ender = regnode((paren) ? CLOSE+parno : END);
+	regtail(ret, ender);
+
+	// Hook the tails of the branches to the closing node. 
+	for (br = ret; br != NULL; br = regnext(br))
+		regoptail(br, ender);
+
+	// Check for proper termination. 
+	if (paren && *regparse++ != ')')
+	{
+		regerror( REGERR_UNTERMINATED_PAREN );
+		return NULL;
+	}
+	else if (!paren && *regparse != '\0')
+	{
+		if (*regparse == ')')
+		{
+			regerror( REGERR_UNMATCHED_PAREN );
+			return NULL;
+		}
+		else
+		{
+			regerror( REGERR_INTERNAL_ERROR_JUNK );
+			return NULL;
+		}
+		// NOTREACHED 
+	}
+
+	return(ret);
+}
+
+// regbranch - one alternative of an | operator
+//
+// Implements the concatenation operator.
+
+char* CRegCompilerBase::regbranch(int *flagp)
+{
+	char* ret;
+	char* chain;
+	char* latest;
+	int flags;
+	int c;
+
+	*flagp = WORST;				// Tentatively. 
+
+	ret = regnode(BRANCH);
+	chain = NULL;
+	while ((c = *regparse) != '\0' && c != '|' && c != ')')
+	{
+		latest = regpiece(&flags);
+		if (latest == NULL)
+			return(NULL);
+		*flagp |= flags&HASWIDTH;
+		if (chain == NULL)		// First piece. 
+			*flagp |= flags&SPSTART;
+		else
+			regtail(chain, latest);
+		chain = latest;
+	}
+	if (chain == NULL)			// Loop ran zero times. 
+		(void) regnode(NOTHING);
+
+	return(ret);
+}
+
+// regpiece - something followed by possible [*+?]
+//
+// Note that the branching code sequences used for ? and the general cases
+// of * and + are somewhat optimized:  they use the same NOTHING node as
+// both the endmarker for their branch list and the body of the last branch.
+// It might seem that this node could be dispensed with entirely, but the
+// endmarker role is not redundant.
+
+char* CRegCompilerBase::regpiece(int *flagp)
+{
+	char* ret;
+	char op;
+	char* next;
+	int flags;
+
+	ret = regatom(&flags);
+	if (ret == NULL)
+		return(NULL);
+
+	op = *regparse;
+	if (!ISREPN(op))
+	{
+		*flagp = flags;
+		return(ret);
+	}
+
+	if (!(flags&HASWIDTH) && op != '?' )
+	{
+		regerror( REGERR_OP_COULD_BE_EMPTY );
+		return NULL;
+	}
+	switch (op)
+	{
+		case '*':	*flagp = WORST|SPSTART;				break;
+		case '+':	*flagp = WORST|SPSTART|HASWIDTH;	break;
+		case '?':	*flagp = WORST;						break;
+	}
+
+	if (op == '*' && (flags&SIMPLE))
+		reginsert(STAR, ret);
+	else if (op == '*')
+	{
+		// Emit x* as (x&|), where & means "self". 
+		reginsert(BRANCH, ret);				// Either x 
+		regoptail(ret, regnode(BACK));		// and loop 
+		regoptail(ret, ret);				// back 
+		regtail(ret, regnode(BRANCH));		// or 
+		regtail(ret, regnode(NOTHING));		// null. 
+	}
+	else if (op == '+' && (flags&SIMPLE))
+		reginsert(PLUS, ret);
+	else if (op == '+' )
+	{
+		// Emit x+ as x(&|), where & means "self". 
+		next = regnode(BRANCH);				// Either 
+		regtail(ret, next);
+		regtail(regnode(BACK), ret);		// loop back 
+		regtail(next, regnode(BRANCH));		// or 
+		regtail(ret, regnode(NOTHING));		// null. 
+	}
+	else if (op == '?' )
+	{
+		// Emit x? as (x|) 
+		reginsert(BRANCH, ret);				// Either x 
+		regtail(ret, regnode(BRANCH));		// or 
+		next = regnode(NOTHING);			// null. 
+		regtail(ret, next);
+		regoptail(ret, next);
+	}
+	regparse++;
+	if (ISREPN(*regparse))
+	{
+		regerror( REGERR_NESTED_OP );
+		return NULL;
+	}
+
+	return(ret);
+}
+
+// regatom - the lowest level
+//
+// Optimization:  gobbles an entire sequence of ordinary characters so that
+// it can turn them into a single node, which is smaller to store and
+// faster to run.  Backslashed characters are exceptions, each becoming a
+// separate node; the code is simpler that way and it's not worth fixing.
+
+char* CRegCompilerBase::regatom(int * flagp)
+{
+	char* ret;
+	int flags;
+
+	*flagp = WORST;		// Tentatively. 
+
+	switch ( *regparse++ )
+	{
+		// FIXME: these chars only have meaning at beg/end of pat?
+		case '^':
+			ret = regnode(BOL);
+			break;
+		case '$':
+			ret = regnode(EOL);
+			break;
+		case '.':
+			ret = regnode(ANY);
+			*flagp |= HASWIDTH|SIMPLE;
+			break;
+		case '[':
+		{
+			int range;
+			int rangeend;
+			int c;
+
+			if (*regparse == '^')
+			{	// Complement of range. 
+				ret = regnode(ANYBUT);
+				regparse++;
+			}
+			else
+				ret = regnode(ANYOF);
+			if ((c = *regparse) == ']' || c == '-')
+			{
+				regc(c);
+				regparse++;
+			}
+			while ((c = *regparse++ ) != '\0' && c != ']')
+			{
+				if (c != '-')
+					regc(c);
+				else if ((c = *regparse) == ']' || c == '\0')
+					regc('-');
+				else
+				{
+					range = (char)*(regparse-2);
+					rangeend = (char)c;
+					if (range > rangeend)
+					{
+						regerror( REGERR_INVALID_RANGE );
+						return NULL;
+					}
+					for (range++; range <= rangeend; range++)
+						regc(range);
+					regparse++;
+				}
+			}
+			regc('\0');
+			if (c != ']')
+			{
+				regerror( REGERR_UNMATCHED_BRACE );
+				return NULL;
+			}
+			*flagp |= HASWIDTH|SIMPLE;
+			break;
+		}
+		case '(':
+			ret = reg(1, &flags);
+			if (ret == NULL)
+				return(NULL);
+			*flagp |= flags&(HASWIDTH|SPSTART);
+			break;
+		case '\0':
+		case '|':
+		case ')':
+			// supposed to be caught earlier 
+			regerror( REGERR_INTERNAL_UNEXPECTED_CHAR );
+			return NULL;
+		case '?':
+		case '+':
+		case '*':
+			{
+				regerror( REGERR_OP_FOLLOWS_NOTHING );
+				return NULL;
+			}
+		case '\\':
+			switch (*regparse++)
+			{
+				case '\0':
+				{
+					regerror( REGERR_TRAILING_ESC );
+					return NULL;
+				}
+				case '<':
+					ret = regnode(WORDA);
+					break;
+				case '>':
+					ret = regnode(WORDZ);
+					break;
+				/* FIXME: Someday handle \1, \2, ... */
+				default:
+					/* Handle general quoted chars in exact-match routine */
+					goto de_fault;
+			}
+			break;
+	de_fault:
+	default:
+		// Encode a string of characters to be matched exactly.
+		//
+		// This is a bit tricky due to quoted chars and due to
+		// '*', '+', and '?' taking the SINGLE char previous
+		// as their operand.
+		//
+		// On entry, the char at regparse[-1] is going to go
+		// into the string, no matter what it is.  (It could be
+		// following a \ if we are entered from the '\' case.)
+		// 
+		// Basic idea is to pick up a good char in  ch  and
+		// examine the next char.  If it's *+? then we twiddle.
+		// If it's \ then we frozzle.  If it's other magic char
+		// we push  ch  and terminate the string.  If none of the
+		// above, we push  ch  on the string and go around again.
+		//
+		//  regprev  is used to remember where "the current char"
+		// starts in the string, if due to a *+? we need to back
+		// up and put the current char in a separate, 1-char, string.
+		// When  regprev  is NULL,  ch  is the only char in the
+		// string; this is used in *+? handling, and in setting
+		// flags |= SIMPLE at the end.
+		{
+			char *regprev;
+			register char ch;
+
+			regparse--;			/* Look at cur char */
+			ret = regnode(EXACTLY);
+			for ( regprev = 0 ; ; ) {
+				ch = *regparse++;	/* Get current char */
+				switch (*regparse) {	/* look at next one */
+
+				default:
+					regc(ch);	/* Add cur to string */
+					break;
+
+				case '.': case '[': case '(':
+				case ')': case '|': case '\n':
+				case '$': case '^':
+				case '\0':
+				/* FIXME, $ and ^ should not always be magic */
+				magic:
+					regc(ch);	/* dump cur char */
+					goto done;	/* and we are done */
+
+				case '?': case '+': case '*':
+					if (!regprev) 	/* If just ch in str, */
+						goto magic;	/* use it */
+					/* End mult-char string one early */
+					regparse = regprev; /* Back up parse */
+					goto done;
+
+				case '\\':
+					regc(ch);	/* Cur char OK */
+					switch (regparse[1]){ /* Look after \ */
+					case '\0':
+					case '<':
+					case '>':
+					/* FIXME: Someday handle \1, \2, ... */
+						goto done; /* Not quoted */
+					default:
+						/* Backup point is \, scan							 * point is after it. */
+						regprev = regparse;
+						regparse++; 
+						continue;	/* NOT break; */
+					}
+				}
+				regprev = regparse;	/* Set backup point */
+			}
+		done:
+			regc('\0');
+			*flagp |= HASWIDTH;
+			if (!regprev)		/* One char? */
+				*flagp |= SIMPLE;
+		}
+		break;
+	}
+
+	return(ret);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// regexec and friends
+
+// Work-variable struct for regexec().
+
+class CRegExecutor : public CRegProgramAccessor
+{
+	friend bool regexp_internal::regexec( char* str );
+
+	char* reginput;		// String-input pointer. 
+	char* regbol;			// Beginning of input, for ^ check. 
+	char* * regstartp;		// Pointer to startp array. 
+	char* * regendp;		// Ditto for endp.
+
+	regexp_internal * prog;
+public:
+	CRegExecutor( regexp_internal * prog, char* str );
+protected:
+	bool regtry( char* str );
+	bool regmatch( char* prog );
+	size_t regrepeat( char* node );
+};
+
+CRegExecutor::CRegExecutor( regexp_internal * p, char* str )
+	: regbol( str ),
+	regstartp( p->startp ),
+	regendp( p->endp ),
+	prog(p)
+{
+}
+
+#ifdef _RE_DEBUG
+int regnarrate = 0;
+#endif
+
+// regexec - match a regexp against a string
+
+bool regexp_internal::regexec( char* str )
+{
+	// Be paranoid. 
+	if ( str == NULL )
+	{
+		regerror( REGERR_NULLARG );
+		return false;
+	}
+
+	// Check validity of program. 
+	if (*program != MAGIC)
+	{
+		regerror( REGERR_CORRUPTED );
+		return false;
+	}
+
+	// If there is a "must appear" string, look for it. 
+	if ( regmust != NULL && strstr( str, regmust ) == NULL )
+		return false;
+
+	CRegExecutor executor( this, str );
+
+	// Simplest case:  anchored match need be tried only once. 
+	if ( reganch )
+		return( executor.regtry( str ) );
+
+	// Messy cases:  unanchored match. 
+	if ( regstart != '\0' )
+	{
+		// We know what char it must start with. 
+		for ( char* s = str; s != NULL; s = strchr( s+1 , regstart ) )
+			if ( executor.regtry( s) )
+				return true;
+		return false;
+	}
+	else
+	{
+		// We don't -- general case. 
+		for ( char* s = str; ! executor.regtry( s ); s++ )
+			if (*s == '\0')
+				return false;
+	}
+	return true;
+}
+
+// regtry - try match at specific point
+bool CRegExecutor::regtry( char* str )
+{
+	int i;
+	char* * stp;
+	char* * enp;
+
+	reginput = str;
+
+	stp = prog->startp;
+	enp = prog->endp;
+	for (i = Regexp::NSUBEXP; i > 0; i--)
+	{
+		*stp++ = NULL;
+		*enp++ = NULL;
+	}
+	if ( regmatch( prog->program + 1 ) )
+	{
+		prog->startp[0] = str;
+		prog->endp[0] = reginput;
+		return true;
+	}
+	else
+		return false;
+}
+
+// regmatch - main matching routine
+//
+// Conceptually the strategy is simple:  check to see whether the current
+// node matches, call self recursively to see whether the rest matches,
+// and then act accordingly.  In practice we make some effort to avoid
+// recursion, in particular by going through "ordinary" nodes (that don't
+// need to know whether the rest of the match failed) by a loop instead of
+// by recursion.
+
+bool CRegExecutor::regmatch( char* prog )
+{
+	char* scan;	// Current node. 
+	char* next;		// Next node. 
+
+#ifdef _RE_DEBUG
+	if (prog != NULL && regnarrate)
+		_ftprintf(stderr, "%s(\n", regprop(prog));
+#endif
+	for (scan = prog; scan != NULL; scan = next)
+	{
+#ifdef _RE_DEBUG
+		if (regnarrate)
+			_ftprintf(stderr, "%s...\n", regprop(scan));
+#endif
+		next = regnext(scan);
+
+		switch (OP(scan))
+		{
+			case BOL:
+				if (reginput != regbol)
+					return false;
+				break;
+			case EOL:
+				if (*reginput != '\0')
+					return false;
+				break;
+			case WORDA:
+				/* Must be looking at a letter, digit, or _ */
+				if ((!isalnum(*reginput)) && *reginput != '_')
+					return(0);
+				/* Prev must be BOL or nonword */
+				if (reginput > regbol &&
+					(isalnum(reginput[-1]) || reginput[-1] == '_'))
+					return(0);
+				break;
+			case WORDZ:
+				/* Must be looking at non letter, digit, or _ */
+				if (isalnum(*reginput) || *reginput == '_')
+					return(0);
+				/* We don't care what the previous char was */
+				break;
+			case ANY:
+				if (*reginput == '\0')
+					return false;
+				reginput++;
+				break;
+			case EXACTLY:
+			{
+				size_t len;
+				char* const opnd = OPERAND(scan);
+
+				// Inline the first character, for speed. 
+				if (*opnd != *reginput)
+					return false;
+				len = strlen(opnd);
+				if (len > 1 && strncmp(opnd, reginput, len) != 0)
+					return false;
+				reginput += len;
+
+				break;
+			}
+			case ANYOF:
+				if (*reginput == '\0' ||
+						strchr(OPERAND(scan), *reginput) == NULL)
+					return false;
+				reginput++;
+				break;
+			case ANYBUT:
+				if (*reginput == '\0' ||
+						strchr(OPERAND(scan), *reginput) != NULL)
+					return false;
+				reginput++;
+				break;
+			case NOTHING:
+				break;
+			case BACK:
+				break;
+			case OPEN+1: case OPEN+2: case OPEN+3:
+			case OPEN+4: case OPEN+5: case OPEN+6:
+			case OPEN+7: case OPEN+8: case OPEN+9:
+			{
+				const int no = OP(scan) - OPEN;
+				char* const input = reginput;
+
+				if (regmatch(next))
+				{
+					// Don't set startp if some later
+					// invocation of the same parentheses
+					// already has.
+					 
+					if (regstartp[no] == NULL)
+						regstartp[no] = input;
+					return true;
+				}
+				else
+					return false;
+				break;
+			}
+			case CLOSE+1: case CLOSE+2: case CLOSE+3:
+			case CLOSE+4: case CLOSE+5: case CLOSE+6:
+			case CLOSE+7: case CLOSE+8: case CLOSE+9:
+			{
+				const int no = OP(scan) - CLOSE;
+				char* const input = reginput;
+
+				if (regmatch(next))
+				{
+					// Don't set endp if some later
+					// invocation of the same parentheses
+					// already has.
+					 
+					if (regendp[no] == NULL)
+						regendp[no] = input;
+					return true;
+				}
+				else
+					return false;
+				break;
+			}
+			case BRANCH:
+			{
+				char* const save = reginput;
+
+				if (OP(next) != BRANCH)		// No choice. 
+					next = OPERAND(scan);	// Avoid recursion. 
+				else
+				{
+					while (OP(scan) == BRANCH)
+					{
+						if (regmatch(OPERAND(scan)))
+							return true;
+						reginput = save;
+						scan = regnext(scan);
+					}
+					return false;
+					// NOTREACHED 
+				}
+				break;
+			}
+			case STAR: case PLUS:
+			{
+				const char nextch = (OP(next) == EXACTLY) ? *OPERAND(next) : '\0';
+				size_t no;
+				char* const save = reginput;
+				const size_t min = (OP(scan) == STAR) ? 0 : 1;
+
+				for (no = regrepeat(OPERAND(scan)) + 1; no > min; no--)
+				{
+					reginput = save + no - 1;
+					// If it could work, try it. 
+					if (nextch == '\0' || *reginput == nextch)
+						if (regmatch(next))
+							return true;
+				}
+				return false;
+				break;
+			}
+			case END:
+				return true;	// Success! 
+				break;
+			default:
+				regerror( REGERR_CORRUPTION );
+				return false;
+				break;
+		}
+	}
+
+	// We get here only if there's trouble -- normally "case END" is
+	// the terminating point.
+
+	regerror( REGERR_CORRUPTED_POINTERS );
+	return false;
+}
+
+// regrepeat - report how many times something simple would match
+
+size_t CRegExecutor::regrepeat( char* node )
+{
+	size_t count;
+	char* scan;
+	char ch;
+
+	switch (OP(node))
+	{
+		case ANY:
+			return(strlen(reginput));
+			break;
+		case EXACTLY:
+			ch = *OPERAND(node);
+			count = 0;
+			for (scan = reginput; *scan == ch; scan++)
+				count++;
+			return(count);
+			break;
+		case ANYOF:
+			return(strspn(reginput, OPERAND(node)));
+			break;
+		case ANYBUT:
+			return(strcspn(reginput, OPERAND(node)));
+			break;
+		default:		// Oh dear.  Called inappropriately. 
+			regerror( REGERR_BAD_REGREPEAT );
+			return(0);	// Best compromise. 
+			break;
+	}
+	// NOTREACHED 
+}
+
+#ifdef _RE_DEBUG
+
+// regdump - dump a regexp onto stdout in vaguely comprehensible form
+
+void regexp_internal::regdump()
+{
+	char* s;
+	char op = EXACTLY;	// Arbitrary non-END op. 
+	char* next;
+
+	s = strinc(program);
+	while (op != END)
+	{	// While that wasn't END last time... 
+		op = OP(s);
+		_tprintf("%2d%s", s-program, regprop(s));	// Where, what. 
+		next = regnext(s);
+		if (next == NULL)		// Next ptr. 
+			_tprintf("(0)");
+		else 
+			_tprintf("(%d)", (s-program)+(next-s));
+		s += 3;
+		if (op == ANYOF || op == ANYBUT || op == EXACTLY)
+		{
+			// Literal string, where present. 
+			while (*s != '\0')
+			{
+				_putchar(*s);
+				s = strinc(s);
+			}
+			s = strinc(s);
+		}
+		_putchar('\n');
+	}
+
+	// Header fields of interest. 
+	if (regstart != '\0')
+		_tprintf("start `%c' ", regstart);
+	if (reganch)
+		_tprintf("anchored ");
+	if (regmust != NULL)
+		_tprintf("must have \"%s\"", regmust);
+	_tprintf("\n");
+}
+
+// regprop - printable representation of opcode
+
+#define OUTPUT(s) case s: p = s; break
+char* CRegProgramAccessor::regprop( char* op )
+{
+	char* p;
+	static char buf[50];
+
+	(void) strcpy(buf, ":");
+
+	switch (OP(op))
+	{
+	OUTPUT( BOL );
+	OUTPUT( EOL );
+	OUTPUT( ANY );
+	OUTPUT( ANYOF );
+	OUTPUT( ANYBUT );
+	OUTPUT( BRANCH );
+	OUTPUT( EXACTLY );
+	OUTPUT( NOTHING );
+	OUTPUT( BACK );
+	OUTPUT( END );
+	OUTPUT( STAR );
+	OUTPUT( PLUS );
+	OUTPUT( WORDA );
+	OUTPUT( WORDZ );
+	case OPEN+1: case OPEN+2: case OPEN+3:
+	case OPEN+4: case OPEN+5: case OPEN+6:
+	case OPEN+7: case OPEN+8: case OPEN+9:
+		_stprintf(buf+strlen(buf), "OPEN%d", OP(op)-OPEN);
+		p = NULL;
+		break;
+	case CLOSE+1: case CLOSE+2: case CLOSE+3:
+	case CLOSE+4: case CLOSE+5: case CLOSE+6:
+	case CLOSE+7: case CLOSE+8: case CLOSE+9:
+		_stprintf(buf+strlen(buf), "CLOSE%d", OP(op)-CLOSE);
+		p = NULL;
+		break;
+	default:
+		regerror( REGERR_CORRUPTED_OPCODE );
+		break;
+	}
+	if (p != NULL)
+		(void) strcat(buf, p);
+	return(buf);
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+
+// constructor
+Regexp::Regexp()
+	: str(0),
+	  rc(0)
+{ }
+
+Regexp::Regexp( const char* exp, bool iCase )
+	: str( 0 ),
+	  rc( new regexp_internal( exp, iCase ) )
+{ }
+
+Regexp::Regexp( const std::string& exp, bool iCase )
+	: str( 0 ),
+	  rc( new regexp_internal( exp.c_str(), iCase ) )
+{ }
+
+Regexp::Regexp( const Regexp &r )
+  : str(r.str),
+    m_szError(r.m_szError),
+    rc( r.rc )
+{
+	if ( rc )
+		rc->count++;
+}
+
+const Regexp & Regexp::operator=( const Regexp & r )
+{
+	if ( this != &r )
+	{
+		if ( rc && rc->count-- == 0 )
+			delete rc;
+
+		rc = r.rc;
+		if ( rc )
+			rc->count++;
+
+		str = r.str;
+		m_szError = r.m_szError;
+	}	
+	return *this;
+}
+
+Regexp::~Regexp()
+{
+	if ( rc && rc->count-- == 0 )
+		delete rc;
+}
+
+bool Regexp::Match( const char * s )
+{
+	ClearErrorString();
+	str = s;
+	bool ret = false;
+	if ( rc )
+	{
+		// copy on write !
+
+		if ( rc->count )
+		{
+			rc->count--;
+			rc = rc->getCopy();
+		}
+
+		ret = rc->regexec( (char*) s );
+		int i = 0;
+		if ( ret )
+			for ( i = 0; i < Regexp::NSUBEXP && rc->startp[i] ; i++ )
+				;
+		rc->numSubs = i - 1;
+	}
+	else
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+	return ret;
+}
+
+std::string Regexp::GetReplaceString( char* source ) const
+{
+	ClearErrorString();
+	if ( rc )
+		return rc->GetReplaceString( source );
+	else
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+	return "";
+}
+
+int Regexp::SubStrings() const
+{
+	ClearErrorString();
+	int ret = -1;
+	if ( rc )
+		ret = rc->numSubs;
+	else
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+	return ret;
+}
+
+int Regexp::SubStart( unsigned int i ) const
+{
+	ClearErrorString();
+	int ret = -1;
+	if ( rc )
+		ret = rc->startp[safeIndex(i)] - str;
+	else
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+	return ret;
+}
+
+int Regexp::SubLength( unsigned int i ) const
+{
+	ClearErrorString();
+	int ret = -1;
+	if ( rc )
+	{
+		i = safeIndex(i);
+		ret = rc->endp[i] - rc->startp[i];
+	}
+	else
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+	return ret;
+}
+
+bool Regexp::CompiledOK() const
+{
+	return rc ? rc->Status() : false;
+}
+
+#ifdef _RE_DEBUG
+void Regexp::Dump()
+{
+	if ( rc )
+		rc->regdump();
+#if defined( _DEBUG )
+	else
+		TRACE0( "No regexp to dump out\n" );
+#endif
+}
+#endif
+
+int Regexp::safeIndex( unsigned int i ) const
+{
+	return i < Regexp::NSUBEXP ? i : Regexp::NSUBEXP;
+}
+
+const std::string Regexp::operator[]( unsigned int i ) const
+{
+	ClearErrorString();
+	assert( rc );
+	if ( rc )
+	{
+		int len = SubLength(i);
+		std::string buffer (rc->startp[i], len);
+		return buffer;
+	}
+	else
+	{
+		m_szError = CRegErrorHandler::FindErr( REGERR_NO_REGEXP );
+		return "";
+	}
+}
+
+void regexp_internal::ignoreCase( const char * in, char * out )
+{
+	// copy in to out making every top level character a [Aa] set
+	bool inRange = 0;
+	while( *in )
+	{
+		if ( *in == '[' )
+			inRange = 1;
+		if ( *in == ']' )
+			inRange = 0;
+		if ( ! inRange && isalpha( *in ) )
+		{
+			*out++ = '[';
+			*out++ = (char)toupper( *in );
+			*out++ = (char)tolower( *in );
+			*out++ = ']';
+		}
+		else
+			*out++ = *in;
+		in++;
+	}
+	*out = 0;
+}
+
+// GetReplaceString	- Converts a replace expression to a string
+//					- perform substitutions after a regexp match
+// Returns			- The resultant string
+std::string regexp_internal::GetReplaceString( const char* sReplaceExp ) const
+{
+	std::string szEmpty;
+
+	char *src = (char *)sReplaceExp;
+	char *buf = 0;
+	char c;
+	int no;
+	size_t len;
+
+	if( sReplaceExp == NULL )
+	{
+		regerror( REGERR_NULL_TO_REGSUB  );
+		return szEmpty;
+	}
+	if ( *program != MAGIC)
+	{
+		regerror( REGERR_DAMAGED_REGEXP_REGSUB );
+		return szEmpty;
+	}
+
+	// First compute the length of the string
+	int replacelen = 0;
+	while ((c = *src++) != '\0') 
+	{
+		if (c == '&')
+			no = 0;
+		else if (c == '\\' && isdigit(*src))
+			no = *src++ - '0';
+		else
+			no = -1;
+
+		if (no < 0) 
+		{	
+			// Ordinary character. 
+			if (c == '\\' && (*src == '\\' || *src == '&'))
+				c = *src++;
+			replacelen++;
+		} 
+		else if (startp[no] != NULL && endp[no] != NULL &&
+					endp[no] > startp[no]) 
+		{
+			// Get tagged expression
+			len = endp[no] - startp[no];
+			replacelen += len;
+		}
+	}
+
+	std::string szReplace (replacelen, '\0');
+
+	// Now we can create the string
+	src = (char *)sReplaceExp;
+	while ((c = *src++) != '\0') 
+	{
+		if (c == '&')
+			no = 0;
+		else if (c == '\\' && isdigit(*src))
+			no = *src++ - '0';
+		else
+			no = -1;
+
+		if (no < 0) 
+		{	
+			// Ordinary character. 
+			if (c == '\\' && (*src == '\\' || *src == '&'))
+				c = *src++;
+			szReplace.push_back(c);
+		} 
+		else if (startp[no] != NULL && endp[no] != NULL &&
+					endp[no] > startp[no]) 
+		{
+			// Get tagged expression
+			len = endp[no] - startp[no];
+			strncpy(buf, startp[no], len);
+			buf += len;
+			if (len != 0 && *(buf-1) == '\0')
+			{	/* strncpy hit NUL. */
+				regerror( REGERR_DAMAGED_MATCH_STRING );
+				return szEmpty;
+			}
+		}
+	}
+
+	return szReplace;
+}
+
+std::string Regexp::GetErrorString() const
+{
+	// make sure that if status == 0 that we have an error string
+	assert( ( ! CompiledOK() ) ? ( rc ? rc->GetErrorString() : m_szError).size() != 0 : 1 );
+	return rc ? rc->GetErrorString() : m_szError ;
+}
+
+void Regexp::ClearErrorString() const
+{
+	if ( rc )
+		rc->ClearErrorString();
+	m_szError.clear();
+}
+
diff --git a/src/util/regexp.h b/src/util/regexp.h
new file mode 100644
index 0000000..b00e53d
--- /dev/null
+++ b/src/util/regexp.h
@@ -0,0 +1,49 @@
+// Regexp.h - regular expression class based on Henry Spencer's regexp code.
+// Adapted for Windows by Guy Gascoigne (see notes in Regexp.cc)
+// Made unix-friendly by Ian Holmes ihh at lanl.gov April 30, 1999
+
+#ifndef UTIL_REGEXP_INCLUDED
+#define UTIL_REGEXP_INCLUDED
+
+#include <string>
+
+class regexp_internal;       //  internal interface to the regexp
+
+class Regexp                 //  main regular expression class
+{
+public:
+	enum { NSUBEXP = 10 };
+
+	Regexp();
+	Regexp( const char* exp, bool iCase = false );
+	Regexp( const std::string& exp, bool iCase = false );  // added by Robert Bradley
+	Regexp( const Regexp &r );
+	~Regexp();
+	const Regexp & operator=( const Regexp & r );
+
+	bool Match( const char * s );
+	int SubStrings() const;
+	
+	const std::string operator[]( unsigned int i ) const;
+	int SubStart( unsigned int i ) const;
+	int SubLength( unsigned int i ) const;
+
+	std::string GetReplaceString( char* source ) const;
+
+	std::string GetErrorString() const;
+	bool CompiledOK() const;
+
+#if defined( _RE_DEBUG )
+	void Dump();
+#endif
+private:
+	const char * str;	/* used to return substring offsets only */
+	mutable std::string m_szError;
+	regexp_internal * rc;
+
+	void ClearErrorString() const;
+	int safeIndex( unsigned int i ) const;
+
+};
+
+#endif /* UTIL_REGEXP_INCLUDED */
diff --git a/src/util/sstring.cc b/src/util/sstring.cc
new file mode 100644
index 0000000..2005a96
--- /dev/null
+++ b/src/util/sstring.cc
@@ -0,0 +1,159 @@
+
+#include <cstring>
+#include <algorithm>
+
+#include "util/sstring.h"
+#include "util/regexp.h"
+#include "util/macros.h"
+#include "util/logfile.h"
+
+#include "math/mathematics.h"
+
+// minimum buffer size for sstring::getline()
+#define DART_GETLINE_BUF_SIZE 100
+
+using namespace fsa;
+
+int string_with_streambuf::DART_string_streambuf::overflow(int c) { owner.push_back ((char) c); return c; }
+
+void sstring::to_lower()
+{
+  for_contents (sstring, *this, c)
+    if (*c >= 'A' && *c <= 'Z') *c += 'a' - 'A';
+}
+
+void sstring::to_upper()
+{
+  for_contents (sstring, *this, c)
+    if (*c >= 'a' && *c <= 'z') *c += 'A' - 'a';
+}
+
+std::vector<sstring> sstring::split (const char* split_chars, bool skip_empty_fields, int max_fields) const
+{
+  sstring expr;
+  expr << "^([^" << split_chars << "]*)([" << split_chars << "])(.*)";
+  Regexp parser (expr.c_str());
+  
+  std::vector<sstring> result;
+  sstring tmp = *this;
+  while (--max_fields != 0 && parser.Match (tmp.c_str()))
+    {
+      if (parser[1].size() || !skip_empty_fields) result.push_back (parser[1]);
+      tmp = parser[3];
+    }
+  if (tmp.size() || !skip_empty_fields) result.push_back(tmp);
+  
+  return result;
+}
+
+sstring sstring::join (const std::vector<sstring>& v, const char* sep)
+{
+  sstring result;
+  for (int i = 0; i+1 < (int) v.size(); i++) result.append(v[i]).append(sep);
+  if (v.size()) result.append(v.back());
+  return result;
+}
+
+sstring& sstring::getline (std::istream& is, size_type max_size)
+{
+  clear();
+  size_type buf_sz = std::max ((size_t) capacity(), (size_t) DART_GETLINE_BUF_SIZE);
+  const char term = '\n';
+  while (1)
+    {
+      // read from the stream, until we reach the delimiter character, or fill the buffer.
+      char buf [buf_sz];
+      is.get (buf, buf_sz, term);
+      append (buf);
+      if (is.eof())
+	break;
+      is.clear();
+      if (is.fail()) THROWEXPR ("ERROR: Couldn't clear fail bit.");
+      // read next character. If it's the delimiter, stop; otherwise, enlarge the buffer.
+      char c = '\0';
+      is.get (c);
+      push_back (c);
+      if (is.fail()) THROW Format_exception (is, "ERROR: Read failure\n");
+      if (is.eof())
+	break;
+      if (c == term)
+	{
+	  is.clear();
+	  break;
+	}
+      if (buf_sz >= max_size) THROW Format_exception (is, "ERROR: Line too long\n");
+      buf_sz = std::min (buf_sz * 2, max_size);
+    }
+  return *this;
+}
+
+Regexp int_regexp ("^\\-?[0-9]+$");
+int sstring::to_int_strict (const char* err_prefix) const
+{
+  if (!int_regexp.Match (c_str()))
+    THROWEXPR (err_prefix << ": " << *this);
+  return to_int();
+}
+
+Regexp nonneg_int_regexp ("^[0-9]+$");
+int sstring::to_nonneg_int_strict (const char* err_prefix) const
+{
+  if (!nonneg_int_regexp.Match (c_str()))
+    THROWEXPR (err_prefix << ": " << *this);
+  return to_int();
+}
+
+Regexp double_regexp ("^\\-?([0-9]*\\.)?[0-9]+([eE][\\+\\-]?[0-9]+)?$");
+double sstring::to_double_strict (const char* err_prefix) const
+{
+  if (!double_regexp.Match (c_str()))
+    THROWEXPR (err_prefix << ": " << *this);
+  return to_double();
+}
+
+Regexp nonneg_double_regexp ("^([0-9]*\\.)?[0-9]+([eE][\\+\\-]?[0-9]+)?$");
+double sstring::to_nonneg_double_strict (const char* err_prefix) const
+{
+  if (!nonneg_double_regexp.Match (c_str()))
+    THROWEXPR (err_prefix << ": " << *this);
+  return to_double();
+}
+
+sstring sstring::substr (int start, int len) const
+{
+  const int real_start = Mathematics::bounded_value (start, 0, (int) size());
+  const int real_end = Mathematics::bounded_value (start + len, real_start, (int) size());
+  sstring sub (begin() + real_start, begin() + real_end);
+  return sub;
+}
+
+char_string::char_string (char c) : sstring()
+{
+  add_char(c);
+}
+
+
+char_string::char_string (const char* s) : sstring()
+{
+  reserve (std::strlen (s));
+  for (; *s != '\0'; ++s) add_char(*s);
+}
+
+void char_string::add_char (char c)
+{
+  if (isprint(c))
+    *this << c;
+  else
+    {
+      char cstr[12];
+      sprintf (cstr, "\\%.3o", c);
+      *this << cstr;
+    }
+}
+
+void sstring::read_entire_file (const char* filename)
+{
+  std::ifstream sstring_stream (filename);
+  if (!sstring_stream) THROWEXPR ("ERROR: File '" << filename << "' not found.");
+  std::copy (std::istream_iterator<char> (sstring_stream), std::istream_iterator<char>(), back_inserter (*this));
+}
diff --git a/src/util/sstring.h b/src/util/sstring.h
new file mode 100644
index 0000000..355f7e5
--- /dev/null
+++ b/src/util/sstring.h
@@ -0,0 +1,131 @@
+#ifndef SSTRING_INCLUDED
+#define SSTRING_INCLUDED
+
+#include <cstdio>
+#include <string>
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <vector>
+
+// RKB -- 5/29/08
+#include <iterator>
+
+#include "util/misc.h"
+
+// default maximum length for sstring::getline
+#define DART_MAX_LINE_SIZE 12345678
+
+namespace fsa {
+
+  // base class for sstring
+  class string_with_streambuf : public std::basic_string<char>
+    {
+    protected:
+      // streambuf prototype
+      class DART_string_streambuf : public std::streambuf
+	{
+	protected:
+	  int overflow(int c);
+	public:
+	  string_with_streambuf& owner;
+	  DART_string_streambuf (string_with_streambuf& s) : owner(s) { }
+	};
+  
+      // streambuf member
+      DART_string_streambuf sbuf;
+
+    public:
+      // constructors
+    string_with_streambuf() : std::basic_string<char>(), sbuf(*this) { }
+      string_with_streambuf (long n, const char value) : std::basic_string<char>(n,value), sbuf(*this) { }
+      string_with_streambuf (const std::basic_string<char>& x) : std::basic_string<char>(x), sbuf(*this) { }
+      string_with_streambuf (const string_with_streambuf& x) : std::basic_string<char>(x), sbuf(*this) { }
+#ifdef __STL_MEMBER_TEMPLATES
+      template <class InputIterator>
+	string_with_streambuf(InputIterator first, InputIterator last) : std::basic_string<char>(first, last), sbuf(*this) { }
+#else /* __STL_MEMBER_TEMPLATES */
+    string_with_streambuf(const_iterator first, const_iterator last) : std::basic_string<char>(first, last), sbuf(*this) { }
+#endif /* __STL_MEMBER_TEMPLATES */
+      string_with_streambuf (const char* x) : std::basic_string<char>(x), sbuf(*this) { }
+      string_with_streambuf (const char* x, size_type n) : std::basic_string<char>(x,n), sbuf(*this) { }
+    };
+
+  // sstring: DART string class
+  class sstring : public string_with_streambuf, public std::ostream
+  {
+  public:
+  sstring() : string_with_streambuf(), std::ostream(&sbuf) {}
+    sstring (size_type n, const char value = '\0') : string_with_streambuf(n,value), std::ostream(&sbuf) {}
+    sstring (int n, const char value = '\0') : string_with_streambuf(n,value), std::ostream(&sbuf) {}
+    sstring (long n, const char value = '\0') : string_with_streambuf(n,value), std::ostream(&sbuf) {}
+    sstring (const std::basic_string<char>& x) : string_with_streambuf(x), std::ostream(&sbuf) {}
+    sstring (const sstring& x) : string_with_streambuf(x), std::ostream(&sbuf) {}
+
+#ifdef __STL_MEMBER_TEMPLATES
+    template <class InputIterator>
+      sstring(InputIterator first, InputIterator last) : string_with_streambuf(first, last), std::ostream(&sbuf) {}
+#else /* __STL_MEMBER_TEMPLATES */
+  sstring(const_iterator first, const_iterator last) : string_with_streambuf(first, last), std::ostream(&sbuf) {}
+#endif /* __STL_MEMBER_TEMPLATES */
+
+    sstring (const char* x) : string_with_streambuf(x), std::ostream(&sbuf) {}
+    sstring (const char* x, size_type n) : string_with_streambuf(x,n), std::ostream(&sbuf) {}
+
+    void read_entire_file (const char* filename);
+
+    iterator end() { return ((std::basic_string<char>*) this) -> end(); }
+    const_iterator end() const { return ((const std::basic_string<char>*) this) -> end(); }
+
+    bool operator==(const std::basic_string<char>& x) const { return ((const std::basic_string<char>&) *this) == x; }
+    bool operator==(const char* x) const { return ((const std::basic_string<char>&) *this) == std::basic_string<char> (x); }
+
+    bool operator<(const std::basic_string<char>& x) const { return ((const std::basic_string<char>&) *this) < x; }
+
+    sstring& operator=(const sstring& x) { ((std::basic_string<char>&) *this) = (const std::basic_string<char>&) x; return *this; }
+    sstring& operator=(const std::basic_string<char>& x) { ((std::basic_string<char>&) *this) = x; return *this; }
+    sstring& operator=(const char* x) { ((std::basic_string<char>&) *this) = x; return *this; }
+
+    void push_back (char c) { append (1, c); }
+    void clear() { erase(); }
+    void to_lower();
+    void to_upper();
+
+    std::vector<sstring> split (const char* split_chars = " \t\n", bool skip_empty_fields = 1, int max_fields = 0) const;
+    static sstring join (const std::vector<sstring>& v, const char* sep = " ");
+
+    friend std::ostream& operator<<(std::ostream&o, const sstring& s) { return o << s.c_str(); }
+
+    sstring& getline (std::istream& is, size_type max_size = DART_MAX_LINE_SIZE);
+  
+    char front() { char c = '\0'; if (size() > 0) c = *begin(); return c; }
+    char back() { char c = '\0'; if (size() > 0) c = *(end()-1); return c; }
+    char chop() { char c = '\0'; if (size() > 0) { c = back(); erase (end() - 1); } return c; }
+    char chomp (const char chomp_char = '\n') { return back() == chomp_char ? chop() : '\0'; }
+
+    int to_int() const { return atoi (c_str()); }
+    double to_double() const { return atof (c_str()); }
+
+    // strict versions of to_int() and to_double(), that do checking
+    int to_int_strict (const char* err_prefix = "Not an integer constant") const;
+    int to_nonneg_int_strict (const char* err_prefix = "Not a non-negative integer constant") const;
+    double to_double_strict (const char* err_prefix = "Not a numeric constant") const;
+    double to_nonneg_double_strict (const char* err_prefix = "Not a non-negative numeric constant") const;
+
+    sstring substr (int start, int len) const;
+
+  };
+
+  // char_string converts non-printable chars into octal
+  class char_string : public sstring
+  {
+  private:
+    void add_char (char c);
+  public:
+    char_string (char c);     
+    char_string (const char* s);
+  };
+
+}
+
+#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..284b32e
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,3 @@
+AM_COLOR_TESTS=always
+TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
+TESTS = apps/isect_d.unmappable.bash apps/isect_eve.bash apps/isect_hairy.bash apps/map_eve.bash apps/map_hairy.bash apps/slice_eve.bash apps/slice_hairy.bash RV11.BBS11011.default.bash RV11.BBS11011.noindel2.bash RV11.BBS11011.nolearngap.bash RV11.BBS11011.nolearnemit-bypair.bash RV11.BBS11011.nolearnemit-all.bash RV11.BBS11011.nolearn.bash RV11.BBS11011.noregularize.bash RV11.BBS11011.refinement0.bash RV11.BBS11011.refinement1.bash RV11.BBS11011.maxsn.bash RV11.BBS11011.gapfactor0.bash [...]
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..d213950
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,1198 @@
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2013 Free Software Foundation, Inc.
+
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+VPATH = @srcdir@
+am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
+am__make_running_with_option = \
+  case $${target_option-} in \
+      ?) ;; \
+      *) echo "am__make_running_with_option: internal error: invalid" \
+              "target option '$${target_option-}' specified" >&2; \
+         exit 1;; \
+  esac; \
+  has_opt=no; \
+  sane_makeflags=$$MAKEFLAGS; \
+  if $(am__is_gnu_make); then \
+    sane_makeflags=$$MFLAGS; \
+  else \
+    case $$MAKEFLAGS in \
+      *\\[\ \	]*) \
+        bs=\\; \
+        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
+          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \
+    esac; \
+  fi; \
+  skip_next=no; \
+  strip_trailopt () \
+  { \
+    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
+  }; \
+  for flg in $$sane_makeflags; do \
+    test $$skip_next = yes && { skip_next=no; continue; }; \
+    case $$flg in \
+      *=*|--*) continue;; \
+        -*I) strip_trailopt 'I'; skip_next=yes;; \
+      -*I?*) strip_trailopt 'I';; \
+        -*O) strip_trailopt 'O'; skip_next=yes;; \
+      -*O?*) strip_trailopt 'O';; \
+        -*l) strip_trailopt 'l'; skip_next=yes;; \
+      -*l?*) strip_trailopt 'l';; \
+      -[dEDm]) skip_next=yes;; \
+      -[JT]) skip_next=yes;; \
+    esac; \
+    case $$flg in \
+      *$$target_option*) has_opt=yes; break;; \
+    esac; \
+  done; \
+  test $$has_opt = yes
+am__make_dryrun = (target_option=n; $(am__make_running_with_option))
+am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = tests
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+	$(top_srcdir)/build-aux/test-driver
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/version.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+AM_V_P = $(am__v_P_ at AM_V@)
+am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
+am__v_P_0 = false
+am__v_P_1 = :
+AM_V_GEN = $(am__v_GEN_ at AM_V@)
+am__v_GEN_ = $(am__v_GEN_ at AM_DEFAULT_V@)
+am__v_GEN_0 = @echo "  GEN     " $@;
+am__v_GEN_1 = 
+AM_V_at = $(am__v_at_ at AM_V@)
+am__v_at_ = $(am__v_at_ at AM_DEFAULT_V@)
+am__v_at_0 = @
+am__v_at_1 = 
+SOURCES =
+DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
+am__tty_colors_dummy = \
+  mgn= red= grn= lgn= blu= brg= std=; \
+  am__color_tests=no
+am__tty_colors = { \
+  $(am__tty_colors_dummy); \
+  if test "X$(AM_COLOR_TESTS)" = Xno; then \
+    am__color_tests=no; \
+  elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
+    am__color_tests=yes; \
+  elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
+    am__color_tests=yes; \
+  fi; \
+  if test $$am__color_tests = yes; then \
+    red=''; \
+    grn=''; \
+    lgn=''; \
+    blu=''; \
+    mgn=''; \
+    brg=''; \
+    std=''; \
+  fi; \
+}
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+am__recheck_rx = ^[ 	]*:recheck:[ 	]*
+am__global_test_result_rx = ^[ 	]*:global-test-result:[ 	]*
+am__copy_in_global_log_rx = ^[ 	]*:copy-in-global-log:[ 	]*
+# A command that, given a newline-separated list of test names on the
+# standard input, print the name of the tests that are to be re-run
+# upon "make recheck".
+am__list_recheck_tests = $(AWK) '{ \
+  recheck = 1; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+        { \
+          if ((getline line2 < ($$0 ".log")) < 0) \
+	    recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
+        { \
+          recheck = 0; \
+          break; \
+        } \
+      else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
+        { \
+          break; \
+        } \
+    }; \
+  if (recheck) \
+    print $$0; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# A command that, given a newline-separated list of test names on the
+# standard input, create the global log from their .trs and .log files.
+am__create_global_log = $(AWK) ' \
+function fatal(msg) \
+{ \
+  print "fatal: making $@: " msg | "cat >&2"; \
+  exit 1; \
+} \
+function rst_section(header) \
+{ \
+  print header; \
+  len = length(header); \
+  for (i = 1; i <= len; i = i + 1) \
+    printf "="; \
+  printf "\n\n"; \
+} \
+{ \
+  copy_in_global_log = 1; \
+  global_test_result = "RUN"; \
+  while ((rc = (getline line < ($$0 ".trs"))) != 0) \
+    { \
+      if (rc < 0) \
+         fatal("failed to read from " $$0 ".trs"); \
+      if (line ~ /$(am__global_test_result_rx)/) \
+        { \
+          sub("$(am__global_test_result_rx)", "", line); \
+          sub("[ 	]*$$", "", line); \
+          global_test_result = line; \
+        } \
+      else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
+        copy_in_global_log = 0; \
+    }; \
+  if (copy_in_global_log) \
+    { \
+      rst_section(global_test_result ": " $$0); \
+      while ((rc = (getline line < ($$0 ".log"))) != 0) \
+      { \
+        if (rc < 0) \
+          fatal("failed to read from " $$0 ".log"); \
+        print line; \
+      }; \
+      printf "\n"; \
+    }; \
+  close ($$0 ".trs"); \
+  close ($$0 ".log"); \
+}'
+# Restructured Text title.
+am__rst_title = { sed 's/.*/   &   /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
+# Solaris 10 'make', and several other traditional 'make' implementations,
+# pass "-e" to $(SHELL), and POSIX 2008 even requires this.  Work around it
+# by disabling -e (using the XSI extension "set +e") if it's set.
+am__sh_e_setup = case $$- in *e*) set +e;; esac
+# Default flags passed to test drivers.
+am__common_driver_flags = \
+  --color-tests "$$am__color_tests" \
+  --enable-hard-errors "$$am__enable_hard_errors" \
+  --expect-failure "$$am__expect_failure"
+# To be inserted before the command running the test.  Creates the
+# directory for the log if needed.  Stores in $dir the directory
+# containing $f, in $tst the test, in $log the log.  Executes the
+# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
+# passes TESTS_ENVIRONMENT.  Set up options for the wrapper that
+# will run the test scripts (or their associated LOG_COMPILER, if
+# thy have one).
+am__check_pre = \
+$(am__sh_e_setup);					\
+$(am__vpath_adj_setup) $(am__vpath_adj)			\
+$(am__tty_colors);					\
+srcdir=$(srcdir); export srcdir;			\
+case "$@" in						\
+  */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;;	\
+    *) am__odir=.;; 					\
+esac;							\
+test "x$$am__odir" = x"." || test -d "$$am__odir" 	\
+  || $(MKDIR_P) "$$am__odir" || exit $$?;		\
+if test -f "./$$f"; then dir=./;			\
+elif test -f "$$f"; then dir=;				\
+else dir="$(srcdir)/"; fi;				\
+tst=$$dir$$f; log='$@'; 				\
+if test -n '$(DISABLE_HARD_ERRORS)'; then		\
+  am__enable_hard_errors=no; 				\
+else							\
+  am__enable_hard_errors=yes; 				\
+fi; 							\
+case " $(XFAIL_TESTS) " in				\
+  *[\ \	]$$f[\ \	]* | *[\ \	]$$dir$$f[\ \	]*) \
+    am__expect_failure=yes;;				\
+  *)							\
+    am__expect_failure=no;;				\
+esac; 							\
+$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
+# A shell command to get the names of the tests scripts with any registered
+# extension removed (i.e., equivalently, the names of the test logs, with
+# the '.log' extension removed).  The result is saved in the shell variable
+# '$bases'.  This honors runtime overriding of TESTS and TEST_LOGS.  Sadly,
+# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
+# since that might cause problem with VPATH rewrites for suffix-less tests.
+# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
+am__set_TESTS_bases = \
+  bases='$(TEST_LOGS)'; \
+  bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
+  bases=`echo $$bases`
+RECHECK_LOGS = $(TEST_LOGS)
+AM_RECURSIVE_TARGETS = check recheck
+TEST_SUITE_LOG = test-suite.log
+TEST_EXTENSIONS = @EXEEXT@ .test
+LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
+am__set_b = \
+  case '$@' in \
+    */*) \
+      case '$*' in \
+        */*) b='$*';; \
+          *) b=`echo '$@' | sed 's/\.log$$//'`; \
+       esac;; \
+    *) \
+      b='$*';; \
+  esac
+am__test_logs1 = $(TESTS:=.log)
+am__test_logs2 = $(am__test_logs1:@EXEEXT at .log=.log)
+TEST_LOGS = $(am__test_logs2:.test.log=.log)
+TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/build-aux/test-driver
+TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
+	$(TEST_LOG_FLAGS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXONERATE_EXEC = @EXONERATE_EXEC@
+GREP = @GREP@
+HAVE_CONDOR = @HAVE_CONDOR@
+HAVE_CONDOR_COMPILE = @HAVE_CONDOR_COMPILE@
+HAVE_JAVAC = @HAVE_JAVAC@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAD_MAIN_CLASS = @MAD_MAIN_CLASS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MUMMER_EXEC = @MUMMER_EXEC@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_COLOR_TESTS = always
+TESTS_ENVIRONMENT = top_builddir=$(top_builddir)
+TESTS = apps/isect_d.unmappable.bash apps/isect_eve.bash \
+	apps/isect_hairy.bash apps/map_eve.bash apps/map_hairy.bash \
+	apps/slice_eve.bash apps/slice_hairy.bash \
+	RV11.BBS11011.default.bash RV11.BBS11011.noindel2.bash \
+	RV11.BBS11011.nolearngap.bash \
+	RV11.BBS11011.nolearnemit-bypair.bash \
+	RV11.BBS11011.nolearnemit-all.bash RV11.BBS11011.nolearn.bash \
+	RV11.BBS11011.noregularize.bash RV11.BBS11011.refinement0.bash \
+	RV11.BBS11011.refinement1.bash RV11.BBS11011.maxsn.bash \
+	RV11.BBS11011.gapfactor0.bash RV11.BBS11011.gapfactor2.bash \
+	RV11.BBS11011.nodynamicweights.bash RV11.BBS11011.fast.bash \
+	RV11.BBS11011.refalign.bash RV11.BBS11011.bandwidth10.bash \
+	RV11.BBS11011.minprob0.1.bash mel-yak.11.bash all_empty.bash \
+	one_empty.bash length1.bash RV12.BBS12030.default.bash \
+	tRNA.aln1.default.bash mel-yak.233.aln1.default.bash \
+	RV12.BBS12030.noindel2.bash tRNA.aln1.nucprot.bash \
+	tRNA.aln1.loadprobs.bash RV12.BBS12030.nolearn.bash \
+	RV12.BBS12030.maxsn.bash RV12.BBS12030.refinement0.bash \
+	RV12.BBS12030.refinement1.bash \
+	RV12.BBS12030.nodynamicweights.bash tRNA.aln1.treeweights.bash \
+	mirna.refalign.bash mirna.fast.bash mirna.fast.maxsn.bash \
+	mirna.mst-min.bash mirna.mst-min.mst-max.bash \
+	mirna.mst-palm.degree.bash translated.anchored.bash \
+	RV12.BBS12030.nolearn.anchored.bash \
+	mel-yak.233.aln1.translated.bash \
+	mel-yak.233.aln1.exonerate.bash \
+	mel-yak.233.aln1.translated.exonerate.bash \
+	mel-yak.233.aln1.exonerate.mercator.bash \
+	mel-yak-sec.97.mercator.bash blanchette.seq00.exonerate.bash \
+	blanchette.seq00.exonerate.minscore50.bash \
+	blanchette.seq00.exonerate.bandwidth1000.bash
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .log .test .test$(EXEEXT) .trs
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+tags TAGS:
+
+ctags CTAGS:
+
+cscope cscopelist:
+
+
+# Recover from deleted '.trs' file; this should ensure that
+# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
+# both 'foo.log' and 'foo.trs'.  Break the recipe in two subshells
+# to avoid problems with "make -n".
+.log.trs:
+	rm -f $< $@
+	$(MAKE) $(AM_MAKEFLAGS) $<
+
+# Leading 'am--fnord' is there to ensure the list of targets does not
+# expand to empty, as could happen e.g. with make check TESTS=''.
+am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
+am--force-recheck:
+	@:
+
+$(TEST_SUITE_LOG): $(TEST_LOGS)
+	@$(am__set_TESTS_bases); \
+	am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
+	redo_bases=`for i in $$bases; do \
+	              am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
+	            done`; \
+	if test -n "$$redo_bases"; then \
+	  redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
+	  redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
+	  if $(am__make_dryrun); then :; else \
+	    rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
+	  fi; \
+	fi; \
+	if test -n "$$am__remaking_logs"; then \
+	  echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
+	       "recursion detected" >&2; \
+	else \
+	  am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
+	fi; \
+	if $(am__make_dryrun); then :; else \
+	  st=0;  \
+	  errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
+	  for i in $$redo_bases; do \
+	    test -f $$i.trs && test -r $$i.trs \
+	      || { echo "$$errmsg $$i.trs" >&2; st=1; }; \
+	    test -f $$i.log && test -r $$i.log \
+	      || { echo "$$errmsg $$i.log" >&2; st=1; }; \
+	  done; \
+	  test $$st -eq 0 || exit 1; \
+	fi
+	@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
+	ws='[ 	]'; \
+	results=`for b in $$bases; do echo $$b.trs; done`; \
+	test -n "$$results" || results=/dev/null; \
+	all=`  grep "^$$ws*:test-result:"           $$results | wc -l`; \
+	pass=` grep "^$$ws*:test-result:$$ws*PASS"  $$results | wc -l`; \
+	fail=` grep "^$$ws*:test-result:$$ws*FAIL"  $$results | wc -l`; \
+	skip=` grep "^$$ws*:test-result:$$ws*SKIP"  $$results | wc -l`; \
+	xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
+	xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
+	error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
+	if test `expr $$fail + $$xpass + $$error` -eq 0; then \
+	  success=true; \
+	else \
+	  success=false; \
+	fi; \
+	br='==================='; br=$$br$$br$$br$$br; \
+	result_count () \
+	{ \
+	    if test x"$$1" = x"--maybe-color"; then \
+	      maybe_colorize=yes; \
+	    elif test x"$$1" = x"--no-color"; then \
+	      maybe_colorize=no; \
+	    else \
+	      echo "$@: invalid 'result_count' usage" >&2; exit 4; \
+	    fi; \
+	    shift; \
+	    desc=$$1 count=$$2; \
+	    if test $$maybe_colorize = yes && test $$count -gt 0; then \
+	      color_start=$$3 color_end=$$std; \
+	    else \
+	      color_start= color_end=; \
+	    fi; \
+	    echo "$${color_start}# $$desc $$count$${color_end}"; \
+	}; \
+	create_testsuite_report () \
+	{ \
+	  result_count $$1 "TOTAL:" $$all   "$$brg"; \
+	  result_count $$1 "PASS: " $$pass  "$$grn"; \
+	  result_count $$1 "SKIP: " $$skip  "$$blu"; \
+	  result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
+	  result_count $$1 "FAIL: " $$fail  "$$red"; \
+	  result_count $$1 "XPASS:" $$xpass "$$red"; \
+	  result_count $$1 "ERROR:" $$error "$$mgn"; \
+	}; \
+	{								\
+	  echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" |	\
+	    $(am__rst_title);						\
+	  create_testsuite_report --no-color;				\
+	  echo;								\
+	  echo ".. contents:: :depth: 2";				\
+	  echo;								\
+	  for b in $$bases; do echo $$b; done				\
+	    | $(am__create_global_log);					\
+	} >$(TEST_SUITE_LOG).tmp || exit 1;				\
+	mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG);			\
+	if $$success; then						\
+	  col="$$grn";							\
+	 else								\
+	  col="$$red";							\
+	  test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG);		\
+	fi;								\
+	echo "$${col}$$br$${std}"; 					\
+	echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}";	\
+	echo "$${col}$$br$${std}"; 					\
+	create_testsuite_report --maybe-color;				\
+	echo "$$col$$br$$std";						\
+	if $$success; then :; else					\
+	  echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}";		\
+	  if test -n "$(PACKAGE_BUGREPORT)"; then			\
+	    echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}";	\
+	  fi;								\
+	  echo "$$col$$br$$std";					\
+	fi;								\
+	$$success || exit 1
+
+check-TESTS:
+	@list='$(RECHECK_LOGS)';           test -z "$$list" || rm -f $$list
+	@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	trs_list=`for i in $$bases; do echo $$i.trs; done`; \
+	log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
+	exit $$?;
+recheck: all 
+	@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+	@set +e; $(am__set_TESTS_bases); \
+	bases=`for i in $$bases; do echo $$i; done \
+	         | $(am__list_recheck_tests)` || exit 1; \
+	log_list=`for i in $$bases; do echo $$i.log; done`; \
+	log_list=`echo $$log_list`; \
+	$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
+	        am__force_recheck=am--force-recheck \
+	        TEST_LOGS="$$log_list"; \
+	exit $$?
+apps/isect_d.unmappable.bash.log: apps/isect_d.unmappable.bash
+	@p='apps/isect_d.unmappable.bash'; \
+	b='apps/isect_d.unmappable.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/isect_eve.bash.log: apps/isect_eve.bash
+	@p='apps/isect_eve.bash'; \
+	b='apps/isect_eve.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/isect_hairy.bash.log: apps/isect_hairy.bash
+	@p='apps/isect_hairy.bash'; \
+	b='apps/isect_hairy.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/map_eve.bash.log: apps/map_eve.bash
+	@p='apps/map_eve.bash'; \
+	b='apps/map_eve.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/map_hairy.bash.log: apps/map_hairy.bash
+	@p='apps/map_hairy.bash'; \
+	b='apps/map_hairy.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/slice_eve.bash.log: apps/slice_eve.bash
+	@p='apps/slice_eve.bash'; \
+	b='apps/slice_eve.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+apps/slice_hairy.bash.log: apps/slice_hairy.bash
+	@p='apps/slice_hairy.bash'; \
+	b='apps/slice_hairy.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.default.bash.log: RV11.BBS11011.default.bash
+	@p='RV11.BBS11011.default.bash'; \
+	b='RV11.BBS11011.default.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.noindel2.bash.log: RV11.BBS11011.noindel2.bash
+	@p='RV11.BBS11011.noindel2.bash'; \
+	b='RV11.BBS11011.noindel2.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.nolearngap.bash.log: RV11.BBS11011.nolearngap.bash
+	@p='RV11.BBS11011.nolearngap.bash'; \
+	b='RV11.BBS11011.nolearngap.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.nolearnemit-bypair.bash.log: RV11.BBS11011.nolearnemit-bypair.bash
+	@p='RV11.BBS11011.nolearnemit-bypair.bash'; \
+	b='RV11.BBS11011.nolearnemit-bypair.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.nolearnemit-all.bash.log: RV11.BBS11011.nolearnemit-all.bash
+	@p='RV11.BBS11011.nolearnemit-all.bash'; \
+	b='RV11.BBS11011.nolearnemit-all.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.nolearn.bash.log: RV11.BBS11011.nolearn.bash
+	@p='RV11.BBS11011.nolearn.bash'; \
+	b='RV11.BBS11011.nolearn.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.noregularize.bash.log: RV11.BBS11011.noregularize.bash
+	@p='RV11.BBS11011.noregularize.bash'; \
+	b='RV11.BBS11011.noregularize.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.refinement0.bash.log: RV11.BBS11011.refinement0.bash
+	@p='RV11.BBS11011.refinement0.bash'; \
+	b='RV11.BBS11011.refinement0.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.refinement1.bash.log: RV11.BBS11011.refinement1.bash
+	@p='RV11.BBS11011.refinement1.bash'; \
+	b='RV11.BBS11011.refinement1.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.maxsn.bash.log: RV11.BBS11011.maxsn.bash
+	@p='RV11.BBS11011.maxsn.bash'; \
+	b='RV11.BBS11011.maxsn.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.gapfactor0.bash.log: RV11.BBS11011.gapfactor0.bash
+	@p='RV11.BBS11011.gapfactor0.bash'; \
+	b='RV11.BBS11011.gapfactor0.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.gapfactor2.bash.log: RV11.BBS11011.gapfactor2.bash
+	@p='RV11.BBS11011.gapfactor2.bash'; \
+	b='RV11.BBS11011.gapfactor2.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.nodynamicweights.bash.log: RV11.BBS11011.nodynamicweights.bash
+	@p='RV11.BBS11011.nodynamicweights.bash'; \
+	b='RV11.BBS11011.nodynamicweights.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.fast.bash.log: RV11.BBS11011.fast.bash
+	@p='RV11.BBS11011.fast.bash'; \
+	b='RV11.BBS11011.fast.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.refalign.bash.log: RV11.BBS11011.refalign.bash
+	@p='RV11.BBS11011.refalign.bash'; \
+	b='RV11.BBS11011.refalign.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.bandwidth10.bash.log: RV11.BBS11011.bandwidth10.bash
+	@p='RV11.BBS11011.bandwidth10.bash'; \
+	b='RV11.BBS11011.bandwidth10.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV11.BBS11011.minprob0.1.bash.log: RV11.BBS11011.minprob0.1.bash
+	@p='RV11.BBS11011.minprob0.1.bash'; \
+	b='RV11.BBS11011.minprob0.1.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.11.bash.log: mel-yak.11.bash
+	@p='mel-yak.11.bash'; \
+	b='mel-yak.11.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+all_empty.bash.log: all_empty.bash
+	@p='all_empty.bash'; \
+	b='all_empty.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+one_empty.bash.log: one_empty.bash
+	@p='one_empty.bash'; \
+	b='one_empty.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+length1.bash.log: length1.bash
+	@p='length1.bash'; \
+	b='length1.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.default.bash.log: RV12.BBS12030.default.bash
+	@p='RV12.BBS12030.default.bash'; \
+	b='RV12.BBS12030.default.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tRNA.aln1.default.bash.log: tRNA.aln1.default.bash
+	@p='tRNA.aln1.default.bash'; \
+	b='tRNA.aln1.default.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.233.aln1.default.bash.log: mel-yak.233.aln1.default.bash
+	@p='mel-yak.233.aln1.default.bash'; \
+	b='mel-yak.233.aln1.default.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.noindel2.bash.log: RV12.BBS12030.noindel2.bash
+	@p='RV12.BBS12030.noindel2.bash'; \
+	b='RV12.BBS12030.noindel2.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tRNA.aln1.nucprot.bash.log: tRNA.aln1.nucprot.bash
+	@p='tRNA.aln1.nucprot.bash'; \
+	b='tRNA.aln1.nucprot.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tRNA.aln1.loadprobs.bash.log: tRNA.aln1.loadprobs.bash
+	@p='tRNA.aln1.loadprobs.bash'; \
+	b='tRNA.aln1.loadprobs.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.nolearn.bash.log: RV12.BBS12030.nolearn.bash
+	@p='RV12.BBS12030.nolearn.bash'; \
+	b='RV12.BBS12030.nolearn.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.maxsn.bash.log: RV12.BBS12030.maxsn.bash
+	@p='RV12.BBS12030.maxsn.bash'; \
+	b='RV12.BBS12030.maxsn.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.refinement0.bash.log: RV12.BBS12030.refinement0.bash
+	@p='RV12.BBS12030.refinement0.bash'; \
+	b='RV12.BBS12030.refinement0.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.refinement1.bash.log: RV12.BBS12030.refinement1.bash
+	@p='RV12.BBS12030.refinement1.bash'; \
+	b='RV12.BBS12030.refinement1.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.nodynamicweights.bash.log: RV12.BBS12030.nodynamicweights.bash
+	@p='RV12.BBS12030.nodynamicweights.bash'; \
+	b='RV12.BBS12030.nodynamicweights.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+tRNA.aln1.treeweights.bash.log: tRNA.aln1.treeweights.bash
+	@p='tRNA.aln1.treeweights.bash'; \
+	b='tRNA.aln1.treeweights.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.refalign.bash.log: mirna.refalign.bash
+	@p='mirna.refalign.bash'; \
+	b='mirna.refalign.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.fast.bash.log: mirna.fast.bash
+	@p='mirna.fast.bash'; \
+	b='mirna.fast.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.fast.maxsn.bash.log: mirna.fast.maxsn.bash
+	@p='mirna.fast.maxsn.bash'; \
+	b='mirna.fast.maxsn.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.mst-min.bash.log: mirna.mst-min.bash
+	@p='mirna.mst-min.bash'; \
+	b='mirna.mst-min.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.mst-min.mst-max.bash.log: mirna.mst-min.mst-max.bash
+	@p='mirna.mst-min.mst-max.bash'; \
+	b='mirna.mst-min.mst-max.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mirna.mst-palm.degree.bash.log: mirna.mst-palm.degree.bash
+	@p='mirna.mst-palm.degree.bash'; \
+	b='mirna.mst-palm.degree.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+translated.anchored.bash.log: translated.anchored.bash
+	@p='translated.anchored.bash'; \
+	b='translated.anchored.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+RV12.BBS12030.nolearn.anchored.bash.log: RV12.BBS12030.nolearn.anchored.bash
+	@p='RV12.BBS12030.nolearn.anchored.bash'; \
+	b='RV12.BBS12030.nolearn.anchored.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.233.aln1.translated.bash.log: mel-yak.233.aln1.translated.bash
+	@p='mel-yak.233.aln1.translated.bash'; \
+	b='mel-yak.233.aln1.translated.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.233.aln1.exonerate.bash.log: mel-yak.233.aln1.exonerate.bash
+	@p='mel-yak.233.aln1.exonerate.bash'; \
+	b='mel-yak.233.aln1.exonerate.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.233.aln1.translated.exonerate.bash.log: mel-yak.233.aln1.translated.exonerate.bash
+	@p='mel-yak.233.aln1.translated.exonerate.bash'; \
+	b='mel-yak.233.aln1.translated.exonerate.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak.233.aln1.exonerate.mercator.bash.log: mel-yak.233.aln1.exonerate.mercator.bash
+	@p='mel-yak.233.aln1.exonerate.mercator.bash'; \
+	b='mel-yak.233.aln1.exonerate.mercator.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+mel-yak-sec.97.mercator.bash.log: mel-yak-sec.97.mercator.bash
+	@p='mel-yak-sec.97.mercator.bash'; \
+	b='mel-yak-sec.97.mercator.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+blanchette.seq00.exonerate.bash.log: blanchette.seq00.exonerate.bash
+	@p='blanchette.seq00.exonerate.bash'; \
+	b='blanchette.seq00.exonerate.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+blanchette.seq00.exonerate.minscore50.bash.log: blanchette.seq00.exonerate.minscore50.bash
+	@p='blanchette.seq00.exonerate.minscore50.bash'; \
+	b='blanchette.seq00.exonerate.minscore50.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+blanchette.seq00.exonerate.bandwidth1000.bash.log: blanchette.seq00.exonerate.bandwidth1000.bash
+	@p='blanchette.seq00.exonerate.bandwidth1000.bash'; \
+	b='blanchette.seq00.exonerate.bandwidth1000.bash'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+.test.log:
+	@p='$<'; \
+	$(am__set_b); \
+	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+ at am__EXEEXT_TRUE@.test$(EXEEXT).log:
+ at am__EXEEXT_TRUE@	@p='$<'; \
+ at am__EXEEXT_TRUE@	$(am__set_b); \
+ at am__EXEEXT_TRUE@	$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
+ at am__EXEEXT_TRUE@	--log-file $$b.log --trs-file $$b.trs \
+ at am__EXEEXT_TRUE@	$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
+ at am__EXEEXT_TRUE@	"$$tst" $(AM_TESTS_FD_REDIRECT)
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
+mostlyclean-generic:
+	-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
+	-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
+	-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-TESTS check-am clean clean-generic \
+	cscopelist-am ctags-am distclean distclean-generic distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-html install-html-am \
+	install-info install-info-am install-man install-pdf \
+	install-pdf-am install-ps install-ps-am install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
+	pdf-am ps ps-am recheck tags-am uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/version.m4 b/version.m4
new file mode 100644
index 0000000..7fa52ad
--- /dev/null
+++ b/version.m4
@@ -0,0 +1 @@
+m4_define([VERSION_NUMBER], [1.15.9])

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



More information about the debian-med-commit mailing list