[med-svn] [abyss] 05/14: Imported Upstream version 1.3.5

Charles Plessy plessy at alioth.debian.org
Sun Sep 8 05:30:20 UTC 2013


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

plessy pushed a commit to branch master
in repository abyss.

commit e05ee57d70aa67ed2a019b0c9dca819cdfcdd38d
Author: Charles Plessy <plessy at debian.org>
Date:   Sun Sep 8 11:22:19 2013 +0900

    Imported Upstream version 1.3.5
---
 ._depcomp                              |  Bin 0 -> 368 bytes
 ABYSS/Makefile.in                      |    1 +
 AdjList/AdjList.cpp                    |    8 +-
 AdjList/Makefile.in                    |    1 +
 Align/Makefile.am                      |   17 +-
 Align/Makefile.in                      |   48 ++++-
 Align/Options.h                        |   11 ++
 Align/align.cc                         |    7 +-
 Align/mergepairs.cc                    |  333 ++++++++++++++++++++++++++++++++
 Align/smith_waterman.cpp               |   24 +--
 Assembly/Makefile.in                   |    1 +
 Assembly/Options.cpp                   |    4 +-
 COPYRIGHT                              |   12 +-
 ChangeLog                              |   60 ++++++
 Common/ContigProperties.h              |    4 +
 Common/Makefile.in                     |    1 +
 Common/SAM.h                           |   21 ++
 Common/SeqExt.h                        |   10 +-
 Common/Uncompress.cpp                  |   57 +++++-
 Consensus/Consensus.cpp                |    7 +-
 Consensus/Makefile.in                  |    1 +
 DAssembler/DAssembler.cpp              |    7 +-
 DAssembler/Makefile.in                 |    1 +
 DataLayer/FastaReader.cpp              |   25 ++-
 DataLayer/FastaReader.h                |    5 +-
 DataLayer/Makefile.in                  |    1 +
 DataLayer/abyss-tofastq.cc             |    4 +-
 DataLayer/fac.cc                       |    9 +-
 DistanceEst/DistanceEst.cpp            |   48 +++--
 DistanceEst/MLE.cpp                    |    2 +-
 DistanceEst/Makefile.in                |    1 +
 FMIndex/Makefile.in                    |    1 +
 FMIndex/abyss-dawg.cc                  |    4 +-
 FMIndex/count.cc                       |    4 +-
 FilterGraph/FilterGraph.cpp            |    7 +-
 FilterGraph/Makefile.in                |    1 +
 Graph/AdjIO.h                          |    5 +
 Graph/ContigGraphAlgorithms.h          |    2 +-
 Graph/GraphAlgorithms.h                |    6 +-
 Graph/Makefile.in                      |    1 +
 Graph/gc.cc                            |    4 +-
 Graph/todot.cc                         |    4 +-
 KAligner/KAligner.cpp                  |    6 +-
 KAligner/Makefile.in                   |    1 +
 LICENSE                                |    2 +-
 Layout/Makefile.am                     |    5 +
 {ABYSS => Layout}/Makefile.in          |   69 +++----
 Layout/layout.cc                       |  319 ++++++++++++++++++++++++++++++
 Makefile.am                            |    2 +
 Makefile.in                            |    8 +-
 Map/Makefile.in                        |    1 +
 Map/index.cc                           |    4 +-
 Map/map.cc                             |   20 +-
 Map/overlap.cc                         |   53 ++++-
 MergePaths/Makefile.in                 |    1 +
 MergePaths/MergeContigs.cpp            |   10 +-
 MergePaths/MergePaths.cpp              |    7 +-
 MergePaths/PathConsensus.cpp           |    6 +-
 Misc/Makefile.am                       |   12 ++
 {bin => Misc}/Makefile.in              |  166 +++++++---------
 Misc/samtobreak.hs                     |  327 +++++++++++++++++++++++++++++++
 Overlap/Makefile.in                    |    1 +
 Overlap/Overlap.cpp                    |    4 +-
 Parallel/Makefile.in                   |    1 +
 Parallel/NetworkSequenceCollection.cpp |   13 +-
 Parallel/parallelAbyss.cpp             |    4 +
 ParseAligns/Makefile.in                |    1 +
 ParseAligns/ParseAligns.cpp            |    4 +-
 ParseAligns/abyss-fixmate.cc           |   41 +++-
 PathOverlap/Makefile.in                |    1 +
 PathOverlap/PathOverlap.cpp            |    7 +-
 PopBubbles/Makefile.in                 |    1 +
 PopBubbles/PopBubbles.cpp              |    7 +-
 README.html                            |   19 +-
 README.md                              |   15 +-
 Scaffold/Makefile.in                   |    1 +
 Scaffold/drawgraph.cc                  |    7 +-
 Scaffold/junction.cc                   |    7 +-
 Scaffold/scaffold.cc                   |   31 ++-
 SimpleGraph/Makefile.in                |    1 +
 SimpleGraph/SimpleGraph.cpp            |    7 +-
 bin/Makefile.in                        |    1 +
 bin/abyss-pe                           |   31 +--
 configure                              |  137 +++++++++++--
 configure.ac                           |   12 +-
 depcomp                                |  189 ++++++++++++------
 dialign/Makefile.in                    |    1 +
 doc/ABYSS.1                            |   12 +-
 doc/Makefile.in                        |    1 +
 doc/abyss-pe.1                         |   16 +-
 doc/abyss-tofastq.1                    |    4 +-
 doc/flowchart.pdf                      |  Bin 77904 -> 165274 bytes
 install-sh                             |   35 ++--
 kmerprint/Makefile.in                  |    1 +
 kmerprint/kmerprint.cc                 |  103 +++++++---
 missing                                |  148 +++++---------
 96 files changed, 2176 insertions(+), 477 deletions(-)

diff --git a/._depcomp b/._depcomp
new file mode 100755
index 0000000..407412f
Binary files /dev/null and b/._depcomp differ
diff --git a/ABYSS/Makefile.in b/ABYSS/Makefile.in
index a5768e0..e09e003 100644
--- a/ABYSS/Makefile.in
+++ b/ABYSS/Makefile.in
@@ -111,6 +111,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/AdjList/AdjList.cpp b/AdjList/AdjList.cpp
index 95df027..795c7ab 100644
--- a/AdjList/AdjList.cpp
+++ b/AdjList/AdjList.cpp
@@ -31,7 +31,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FILE]...\n"
@@ -40,8 +40,10 @@ static const char USAGE_MESSAGE[] =
 "Overlaps of exactly k-1 bases are found using a hash table.\n"
 "Overlaps of fewer than k-1 bases are found using a suffix array.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=K          find overlaps of up to K-1 bases\n"
-"  -m, --min-overlap=M   require a minimum overlap of M bases [30]\n"
+"  -m, --min-overlap=M   require a minimum overlap of M bases [50]\n"
 "      --adj             output the results in adj format [default]\n"
 "      --dot             output the results in dot format\n"
 "      --sam             output the results in SAM format\n"
@@ -56,7 +58,7 @@ namespace opt {
 	int format; // used by GraphIO
 
 	/** The minimum required amount of overlap. */
-	static unsigned minOverlap = 30;
+	static unsigned minOverlap = 50;
 }
 
 static const char shortopts[] = "k:m:v";
diff --git a/AdjList/Makefile.in b/AdjList/Makefile.in
index 8f5b8d2..d083670 100644
--- a/AdjList/Makefile.in
+++ b/AdjList/Makefile.in
@@ -111,6 +111,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Align/Makefile.am b/Align/Makefile.am
index cab3d2f..ef99d42 100644
--- a/Align/Makefile.am
+++ b/Align/Makefile.am
@@ -5,9 +5,9 @@ libalign_a_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/Common
 libalign_a_SOURCES = \
 	alignGlobal.cc alignGlobal.h \
 	dialign.cpp dialign.h dna_diag_prob.cc \
-	smith_waterman.cpp smith_waterman.h
+	smith_waterman.cpp smith_waterman.h Options.h
 
-bin_PROGRAMS = abyss-align
+bin_PROGRAMS = abyss-align abyss-mergepairs
 
 abyss_align_CPPFLAGS = -I$(top_srcdir) \
 	-I$(top_srcdir)/Common \
@@ -21,3 +21,16 @@ abyss_align_LDADD = $(builddir)/libalign.a \
 	$(top_builddir)/Common/libcommon.a
 
 abyss_align_SOURCES = align.cc
+
+abyss_mergepairs_CPPFLAGS = -I$(top_srcdir) \
+	-I$(top_srcdir)/Common \
+	-I$(top_srcdir)/DataLayer
+
+abyss_mergepairs_CXXFLAGS = $(AM_CXXFLAGS) $(OPENMP_CXXFLAGS)
+
+abyss_mergepairs_LDADD = $(builddir)/libalign.a \
+	$(top_builddir)/dialign/libdialign.a \
+	$(top_builddir)/DataLayer/libdatalayer.a \
+	$(top_builddir)/Common/libcommon.a
+
+abyss_mergepairs_SOURCES = mergepairs.cc
diff --git a/Align/Makefile.in b/Align/Makefile.in
index 5e50d9a..d638430 100644
--- a/Align/Makefile.in
+++ b/Align/Makefile.in
@@ -50,7 +50,7 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
-bin_PROGRAMS = abyss-align$(EXEEXT)
+bin_PROGRAMS = abyss-align$(EXEEXT) abyss-mergepairs$(EXEEXT)
 subdir = Align
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/depcomp
@@ -82,6 +82,14 @@ abyss_align_DEPENDENCIES = $(builddir)/libalign.a \
 	$(top_builddir)/Common/libcommon.a
 abyss_align_LINK = $(CXXLD) $(abyss_align_CXXFLAGS) $(CXXFLAGS) \
 	$(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_abyss_mergepairs_OBJECTS = abyss_mergepairs-mergepairs.$(OBJEXT)
+abyss_mergepairs_OBJECTS = $(am_abyss_mergepairs_OBJECTS)
+abyss_mergepairs_DEPENDENCIES = $(builddir)/libalign.a \
+	$(top_builddir)/dialign/libdialign.a \
+	$(top_builddir)/DataLayer/libdatalayer.a \
+	$(top_builddir)/Common/libcommon.a
+abyss_mergepairs_LINK = $(CXXLD) $(abyss_mergepairs_CXXFLAGS) \
+	$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -95,8 +103,10 @@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libalign_a_SOURCES) $(abyss_align_SOURCES)
-DIST_SOURCES = $(libalign_a_SOURCES) $(abyss_align_SOURCES)
+SOURCES = $(libalign_a_SOURCES) $(abyss_align_SOURCES) \
+	$(abyss_mergepairs_SOURCES)
+DIST_SOURCES = $(libalign_a_SOURCES) $(abyss_align_SOURCES) \
+	$(abyss_mergepairs_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -129,6 +139,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -205,7 +216,7 @@ libalign_a_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/Common
 libalign_a_SOURCES = \
 	alignGlobal.cc alignGlobal.h \
 	dialign.cpp dialign.h dna_diag_prob.cc \
-	smith_waterman.cpp smith_waterman.h
+	smith_waterman.cpp smith_waterman.h Options.h
 
 abyss_align_CPPFLAGS = -I$(top_srcdir) \
 	-I$(top_srcdir)/Common \
@@ -218,6 +229,17 @@ abyss_align_LDADD = $(builddir)/libalign.a \
 	$(top_builddir)/Common/libcommon.a
 
 abyss_align_SOURCES = align.cc
+abyss_mergepairs_CPPFLAGS = -I$(top_srcdir) \
+	-I$(top_srcdir)/Common \
+	-I$(top_srcdir)/DataLayer
+
+abyss_mergepairs_CXXFLAGS = $(AM_CXXFLAGS) $(OPENMP_CXXFLAGS)
+abyss_mergepairs_LDADD = $(builddir)/libalign.a \
+	$(top_builddir)/dialign/libdialign.a \
+	$(top_builddir)/DataLayer/libdatalayer.a \
+	$(top_builddir)/Common/libcommon.a
+
+abyss_mergepairs_SOURCES = mergepairs.cc
 all: all-am
 
 .SUFFIXES:
@@ -302,6 +324,9 @@ clean-binPROGRAMS:
 abyss-align$(EXEEXT): $(abyss_align_OBJECTS) $(abyss_align_DEPENDENCIES) $(EXTRA_abyss_align_DEPENDENCIES) 
 	@rm -f abyss-align$(EXEEXT)
 	$(abyss_align_LINK) $(abyss_align_OBJECTS) $(abyss_align_LDADD) $(LIBS)
+abyss-mergepairs$(EXEEXT): $(abyss_mergepairs_OBJECTS) $(abyss_mergepairs_DEPENDENCIES) $(EXTRA_abyss_mergepairs_DEPENDENCIES) 
+	@rm -f abyss-mergepairs$(EXEEXT)
+	$(abyss_mergepairs_LINK) $(abyss_mergepairs_OBJECTS) $(abyss_mergepairs_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -310,6 +335,7 @@ distclean-compile:
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/abyss_align-align.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/abyss_mergepairs-mergepairs.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libalign_a-alignGlobal.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libalign_a-dialign.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libalign_a-dna_diag_prob.Po at am__quote@
@@ -399,6 +425,20 @@ abyss_align-align.obj: align.cc
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_align_CPPFLAGS) $(CPPFLAGS) $(abyss_align_CXXFLAGS) $(CXXFLAGS) -c -o abyss_align-align.obj `if test -f 'align.cc'; then $(CYGPATH_W) 'align.cc'; else $(CYGPATH_W) '$(srcdir)/align.cc'; fi`
 
+abyss_mergepairs-mergepairs.o: mergepairs.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_mergepairs_CPPFLAGS) $(CPPFLAGS) $(abyss_mergepairs_CXXFLAGS) $(CXXFLAGS) -MT abyss_mergepairs-mergepairs.o -MD -MP -MF $(DEPDIR)/abyss_mergepairs-mergepairs.Tpo -c -o abyss_mergepairs-mergepairs.o `test -f 'mergepairs.cc' || echo '$(srcdir)/'`mergepairs.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/abyss_mergepairs-mergepairs.Tpo $(DEPDIR)/abyss_mergepairs-mergepairs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mergepairs.cc' object='abyss_mergepairs-mergepairs.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_mergepairs_CPPFLAGS) $(CPPFLAGS) $(abyss_mergepairs_CXXFLAGS) $(CXXFLAGS) -c -o abyss_mergepairs-mergepairs.o `test -f 'mergepairs.cc' || echo '$(srcdir)/'`mergepairs.cc
+
+abyss_mergepairs-mergepairs.obj: mergepairs.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_mergepairs_CPPFLAGS) $(CPPFLAGS) $(abyss_mergepairs_CXXFLAGS) $(CXXFLAGS) -MT abyss_mergepairs-mergepairs.obj -MD -MP -MF $(DEPDIR)/abyss_mergepairs-mergepairs.Tpo -c -o abyss_mergepairs-mergepairs.obj `if test -f 'mergepairs.cc'; then $(CYGPATH_W) 'mergepairs.cc'; else $(CYGPATH_W) '$(srcdir)/mergepairs.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/abyss_mergepairs-mergepairs.Tpo $(DEPDIR)/abyss_mergepairs-mergepairs.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mergepairs.cc' object='abyss_mergepairs-mergepairs.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_mergepairs_CPPFLAGS) $(CPPFLAGS) $(abyss_mergepairs_CXXFLAGS) $(CXXFLAGS) -c -o abyss_mergepairs-mergepairs.obj `if test -f 'mergepairs.cc'; then $(CYGPATH_W) 'mergepairs.cc'; else $(CYGPATH_W) '$(srcdir)/mergepairs.cc'; fi`
+
 .cpp.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
diff --git a/Align/Options.h b/Align/Options.h
new file mode 100644
index 0000000..9d56c1c
--- /dev/null
+++ b/Align/Options.h
@@ -0,0 +1,11 @@
+#ifndef ALIGN_OPTIONS
+#define ALIGN_OPTIONS 1
+
+namespace opt {
+	extern int match;
+	extern int mismatch;
+	extern int gap_open;
+	extern int gap_extend;
+}
+
+#endif
diff --git a/Align/align.cc b/Align/align.cc
index e7164a5..faadf81 100644
--- a/Align/align.cc
+++ b/Align/align.cc
@@ -22,20 +22,25 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FASTA]...\n"
 "Align multiple sequences globally using either Needleman-Wunsch\n"
 "or DIALIGN-TX. Groups of sequences may be separated using `#.'\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA  sequences in FASTA format\n"
 "\n"
 " Options:\n"
+"\n"
 "  -v, --verbose         display verbose output\n"
 "      --help            display this help and exit\n"
 "      --version         output version information and exit\n"
 "\n"
 " DIALIGN-TX options:\n"
+"\n"
 "  -D, --dialign-d=N     dialign debug level, default: 0\n"
 "  -M, --dialign-m=FILE  score matrix, default: dna_matrix.scr\n"
 "  -P, --dialign-p=FILE  diagonal length probability distribution\n"
diff --git a/Align/mergepairs.cc b/Align/mergepairs.cc
new file mode 100644
index 0000000..971a37c
--- /dev/null
+++ b/Align/mergepairs.cc
@@ -0,0 +1,333 @@
+#include "smith_waterman.h"
+#include "config.h"
+#include "DataLayer/Options.h"
+#include "Align/Options.h"
+#include "Common/Options.h"
+#include "FastaReader.h"
+#include "IOUtil.h"
+#include "Uncompress.h"
+#include "alignGlobal.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <getopt.h>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+#define PROGRAM "abyss-align"
+
+static const char VERSION_MESSAGE[] =
+PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
+"Written by Anthony Raymond.\n"
+"\n"
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
+
+static const char USAGE_MESSAGE[] =
+"Usage: " PROGRAM " [OPTION]... READS1 READS2\n"
+"Attempt to merge reads in READS1 with reads in READS2\n"
+"\n"
+" Options:\n"
+"\n"
+"  -o, --prefix=PREFIX     the prefix of all output files [out]\n"
+"  -p, --identity=N        minimum overlap identity [0.9]\n"
+"  -m, --matches=N         minimum number of matches in overlap [10]\n"
+"  -1, --length1=N         trim bases from 3' end of first read\n"
+"                          down to a maximum of N bp long [inf]\n"
+"  -2, --length2=N         trim bases from 3' end of second read\n"
+"                          down to a maximum of N bp long [inf]\n"
+"      --chastity          discard unchaste reads [default]\n"
+"      --no-chastity       do not discard unchaste reads\n"
+"      --trim-masked       trim masked bases from the ends of reads\n"
+"      --no-trim-masked    do not trim masked bases from the ends\n"
+"                          of reads [default]\n"
+"  -q, --trim-quality=N    trim bases from the ends of reads whose\n"
+"                          quality is less than the threshold\n"
+"      --standard-quality  zero quality is `!' (33)\n"
+"                          default for FASTQ and SAM files\n"
+"      --illumina-quality  zero quality is `@' (64)\n"
+"                          default for qseq and export files\n"
+"  -v, --verbose           display verbose output\n"
+"      --help              display this help and exit\n"
+"      --version           output version information and exit\n"
+"\n"
+"Report bugs to <" PACKAGE_BUGREPORT ">.\n";
+
+namespace opt {
+	static string prefix = "out";
+	static float identity = 0.9;
+	static unsigned min_matches = 10;
+
+	/** Max length of read 1. */
+	static int max_len_1 = 0;
+
+	/** Max length of read 2. */
+	static int max_len_2 = 0;
+}
+
+static struct {
+	unsigned total_reads;
+	unsigned merged_reads;
+	unsigned unmerged_reads;
+	unsigned no_alignment;
+	unsigned too_many_aligns;
+	unsigned low_matches;
+	unsigned has_indel;
+	unsigned pid_low;
+} stats;
+
+static const char shortopts[] = "o:p:m:q:1:2:v";
+
+enum { OPT_HELP = 1, OPT_VERSION };
+
+static const struct option longopts[] = {
+	{ "prefix",           required_argument, NULL, 'o' },
+	{ "identity",         required_argument, NULL, 'p' },
+	{ "matches",          required_argument, NULL, 'm' },
+	{ "verbose",          no_argument,       NULL, 'v' },
+	{ "length1",          no_argument,       NULL, '1' },
+	{ "length2",          no_argument,       NULL, '2' },
+	{ "chastity",         no_argument,       &opt::chastityFilter, 1 },
+	{ "no-chastity",      no_argument,       &opt::chastityFilter, 0 },
+	{ "trim-masked",      no_argument,       &opt::trimMasked, 1 },
+	{ "no-trim-masked",   no_argument,       &opt::trimMasked, 0 },
+	{ "trim-quality",     required_argument, NULL, 'q' },
+	{ "standard-quality", no_argument,       &opt::qualityOffset, 33 },
+	{ "illumina-quality", no_argument,       &opt::qualityOffset, 64 },
+	{ "help",             no_argument,       NULL, OPT_HELP },
+	{ "version",          no_argument,       NULL, OPT_VERSION },
+	{ NULL, 0, NULL, 0 }
+};
+
+char bestBase(char a, char b, char qa, char qb) {
+	return qa > qb ? a : b;
+}
+
+/** Merge the read sequences taking the highest quality base when
+ * there is a dissagreement while reporting the lowest quality
+ * possible. */
+static void mergeReads(overlap_align& overlap, FastqRecord& rec1,
+		FastqRecord& rec2, FastqRecord& out)
+{
+	size_t ol = overlap.length();
+
+	Sequence seq1 = rec1.seq;
+	string qual1 = rec1.qual;
+
+	Sequence rc_seq2 = reverseComplement(rec2.seq);
+	string rc_qual2(rec2.qual);
+	reverse(rc_qual2.begin(), rc_qual2.end());
+
+	// Form overhanging portions of the reads.
+	size_t out_len = overlap.overlap_t_pos + ol + rc_seq2.length() -
+		overlap.overlap_h_pos - 1;
+	Sequence out_seq(out_len, 'N');
+	string out_qual(out_len, '#');
+	assert(out_seq.length() >= seq1.length() || out_seq.length() >=
+			rc_seq2.length());
+
+	copy(seq1.begin(), seq1.begin() + overlap.overlap_t_pos,
+			out_seq.begin());
+	copy(rc_seq2.begin() + overlap.overlap_h_pos + 1, rc_seq2.end(),
+			out_seq.begin() + overlap.overlap_t_pos + ol);
+	copy(qual1.begin(), qual1.begin() + overlap.overlap_t_pos,
+			out_qual.begin());
+	copy(rc_qual2.begin() + ol, rc_qual2.end(),
+			out_qual.begin() + seq1.length());
+
+	// Fix the sequence and quality inside the overlap.
+	for (unsigned i = 0; i < ol; i++) {
+		assert(int(seq1.length() - ol + i) >= 0);
+		unsigned pos = seq1.length() - ol + i;
+		assert(pos < seq1.length() && i < rc_seq2.length() &&
+				pos < out_seq.length());
+		if (seq1[pos] == rc_seq2[i]) {
+			out_seq[pos] = seq1[pos];
+			out_qual[pos] = max(qual1[pos], rc_qual2[i]);
+		} else {
+			out_seq[pos] = bestBase(seq1[pos], rc_seq2[i],
+					qual1[pos], rc_qual2[i]);
+			out_qual[pos] = min(qual1[pos], rc_qual2[i]);
+		}
+	}
+	//cout << seq1 << '\n' << rc_seq2 << '\n' << out_seq << '\n';
+	//cout << qual1 << '\n' << rc_qual2 << '\n' << out_qual << '\n';
+	out = FastqRecord(rec1.id, rec1.comment, out_seq, out_qual);
+}
+
+bool isGapless(overlap_align& o, Sequence& s) {
+	return o.length() == s.length() - o.overlap_t_pos &&
+		o.length() == o.overlap_h_pos + 1;
+}
+
+static void filterAlignments(vector<overlap_align>& overlaps,
+		FastaRecord& rec)
+{
+	if (overlaps.empty()) {
+		stats.no_alignment++;
+		return;
+	}
+
+	vector<overlap_align>::iterator it;
+	for (it = overlaps.begin(); it != overlaps.end(); it++ ) {
+		overlap_align o = *it;
+		if (o.overlap_match < opt::min_matches)
+			overlaps.erase(it--);
+	}
+	if (overlaps.empty()) {
+		stats.low_matches++;
+		return;
+	}
+
+	for (it = overlaps.begin(); it != overlaps.end(); it++ ) {
+		overlap_align o = *it;
+		if (o.pid() < opt::identity)
+			overlaps.erase(it--);
+	}
+	if (overlaps.empty()) {
+		stats.pid_low++;
+		return;
+	}
+
+	for (it = overlaps.begin(); it != overlaps.end(); it++ ) {
+		overlap_align o = *it;
+		if (!isGapless(o, rec.seq))
+			overlaps.erase(it--);
+	}
+	if (overlaps.empty()) {
+		stats.has_indel++;
+		return;
+	}
+}
+
+/** Align read pairs. */
+static void alignFiles(const char* reads1, const char* reads2)
+{
+	if (opt::verbose > 0)
+		cerr << "Merging `" << reads1 << "' with `" << reads2 << "'\n";
+	FastaReader r1(reads1, FastaReader::NO_FOLD_CASE, opt::max_len_1);
+	FastaReader r2(reads2, FastaReader::NO_FOLD_CASE, opt::max_len_2);
+
+	// Openning the output files
+	string name(opt::prefix);
+	name.append("_reads_1.fastq");
+	ofstream unmerged1(name.c_str());
+	name = string(opt::prefix);
+	name.append("_reads_2.fastq");
+	ofstream unmerged2(name.c_str());
+	name = string(opt::prefix);
+	name.append("_merged.fastq");
+	ofstream merged(name.c_str());
+
+	FastqRecord rec1, rec2;
+	int x = 0;
+	while (r1 >> rec1 && r2 >> rec2) {
+		stats.total_reads++;
+		string rc_qual2(rec2.qual);
+		reverse(rc_qual2.begin(), rc_qual2.end());
+		vector<overlap_align> overlaps;
+		alignOverlap(rec1.seq, reverseComplement(rec2.seq), 0, overlaps,
+				true, opt::verbose > 2);
+
+		filterAlignments(overlaps, rec1);
+
+		if (overlaps.size() == 1) {
+			// If there is only one good alignment, merge reads and
+			// print to merged file
+			stats.merged_reads++;
+			FastqRecord out;
+			mergeReads(overlaps[0], rec1, rec2, out);
+			merged << out;
+			cout << overlaps[0].length() << ' ' <<
+				overlaps[0].overlap_match << '\n';
+		} else {
+			// print reads to separate files
+			if (overlaps.size() > 1)
+				stats.too_many_aligns++;
+			stats.unmerged_reads++;
+			unmerged1 << rec1;
+			unmerged2 << rec2;
+		}
+		if (opt::verbose > 0 && ++x % 10000 == 0) {
+			cerr << "Aligned " << x << " reads.\n";
+		}
+	}
+	r2 >> rec2;
+	assert(r1.eof());
+	assert(r2.eof());
+	unmerged1.close();
+	unmerged2.close();
+	merged.close();
+}
+
+int main(int argc, char** argv)
+{
+	bool die = false;
+
+	//defaults for alignment parameters
+	opt::match = 1;
+	opt::mismatch = -2;
+	opt::gap_open = -10000;
+	opt::gap_extend = -10000;
+
+	for (int c; (c = getopt_long(argc, argv,
+					shortopts, longopts, NULL)) != -1;) {
+		istringstream arg(optarg != NULL ? optarg : "");
+		switch (c) {
+			case '?': die = true; break;
+			case 'o': arg >> opt::prefix; break;
+			case 'p': arg >> opt::identity; break;
+			case 'm': arg >> opt::min_matches; break;
+			case 'q': arg >> opt::qualityThreshold; break;
+			case '1': arg >> opt::max_len_1; break;
+			case '2': arg >> opt::max_len_2; break;
+			case 'v': opt::verbose++; break;
+			case OPT_HELP:
+					  cerr << USAGE_MESSAGE;
+					  exit(EXIT_SUCCESS);
+			case OPT_VERSION:
+					  cerr << VERSION_MESSAGE;
+					  exit(EXIT_SUCCESS);
+		}
+		if (optarg != NULL && !arg.eof()) {
+			cerr << PROGRAM ": invalid option: `-"
+				<< (char)c << optarg << "'\n";
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if (argc - optind < 2) {
+		cerr << PROGRAM ": missing arguments\n";
+		die = true;
+	}
+
+	if (argc - optind > 2) {
+		cerr << PROGRAM ": too many arguments\n";
+		die = true;
+	}
+
+	if (die) {
+		cerr << "Try `" << PROGRAM
+			<< " --help' for more information.\n";
+		exit(EXIT_FAILURE);
+	}
+
+	const char* reads1 = argv[optind++];
+	const char* reads2 = argv[optind++];
+
+	alignFiles(reads1, reads2);
+
+	cerr << "Read merging stats: total=" << stats.total_reads
+		<< " merged=" << stats.merged_reads
+		<< " unmerged=" << stats.unmerged_reads << '\n'
+		<< "no_alignment=" << stats.no_alignment
+		<< " too_many_aligns=" << stats.too_many_aligns
+		<< " too_few_matches=" << stats.low_matches
+		<< " has_indel=" << stats.has_indel
+		<< " low_pid=" << stats.pid_low << '\n';
+
+	return 0;
+}
diff --git a/Align/smith_waterman.cpp b/Align/smith_waterman.cpp
index 01349dc..f1356d0 100644
--- a/Align/smith_waterman.cpp
+++ b/Align/smith_waterman.cpp
@@ -7,6 +7,7 @@
 
 #include "smith_waterman.h"
 #include "Sequence.h"
+#include "Align/Options.h"
 #include <algorithm>
 #include <cassert>
 #include <cctype>
@@ -15,18 +16,19 @@
 
 using namespace std;
 
-/** The score of a match. */
-static const int MATCH_SCORE = 5;
+namespace opt {
+	/** The score of a match. */
+	int match = 5;
 
-/** The score of a mismatch. */
-static const int MISMATCH_SCORE = -4;
+	/** The score of a mismatch. */
+	int mismatch = -4;
 
-/** gap open penalty */
-static const int GAP_OPEN_SCORE = -12;
-
-/** gap extend penalty */
-static const int GAP_EXTEND_SCORE = -4;
+	/** gap open penalty */
+	int gap_open = -12;
 
+	/** gap extend penalty */
+	int gap_extend = -4;
+}
 /** Print the specified alignment. */
 static ostream& printAlignment(ostream& out,
 		const string& aseq, const string& bseq,
@@ -81,13 +83,13 @@ static bool isMatch(char a, char b, char& c)
 static int matchScore(const char a, const char b)
 {
 	char consensus;
-	return isMatch(a, b, consensus) ? MATCH_SCORE : MISMATCH_SCORE;
+	return isMatch(a, b, consensus) ? opt::match : opt::mismatch;
 }
 
 /** Return the score of a gap, either newly opened or extended. */
 static int gapScore(bool prev_is_gap)
 {
-	return prev_is_gap ? GAP_EXTEND_SCORE : GAP_OPEN_SCORE;
+	return prev_is_gap ? opt::gap_extend : opt::gap_open;
 }
 
 //the backtrack step in smith_waterman
diff --git a/Assembly/Makefile.in b/Assembly/Makefile.in
index 4f99958..af0de0d 100644
--- a/Assembly/Makefile.in
+++ b/Assembly/Makefile.in
@@ -119,6 +119,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Assembly/Options.cpp b/Assembly/Options.cpp
index 3ae935b..184e3be 100644
--- a/Assembly/Options.cpp
+++ b/Assembly/Options.cpp
@@ -22,13 +22,15 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FILE...\n"
 "Assemble the input files, FILE, which may be in FASTA, FASTQ,\n"
 "qseq, export, SAM or BAM format and compressed with gz, bz2 or xz.\n"
 "\n"
+" Options:\n"
+"\n"
 "      --chastity        discard unchaste reads [default]\n"
 "      --no-chastity     do not discard unchaste reads\n"
 "      --trim-masked     trim masked bases from the ends of reads\n"
diff --git a/COPYRIGHT b/COPYRIGHT
index 7188bbb..3d56d24 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,6 +1,6 @@
 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 Upstream-Name: ABySS
-Upstream-Contact: Shaun Jackman <sjackman at bcgsc.ca>
+Upstream-Contact: Shaun Jackman <sjackman at gmail.com>
 Source: http://www.bcgsc.ca/platform/bioinfo/software/abyss
 
 License: BCCA-Academic
@@ -235,11 +235,11 @@ License: BCCA-Academic
  its sole discretion may assign this Agreement without notice to You.
 
 Files: *
-Copyright: Copyright 2012 Genome Sciences Centre
+Copyright: Copyright 2013 Genome Sciences Centre
 License: BCCA-Academic
 
-Files: Common/* DistanceEst/* ParseAligns/*
-Copyright: Copyright 2012 Genome Sciences Centre
+Files: Common/* DataLayer/* DistanceEst/* FMIndex/* Map/* ParseAligns/*
+Copyright: Copyright 2013 Genome Sciences Centre
 License: BCCA-Academic or GPL-3+
 
 Files: Common/cholesky.hpp
@@ -250,6 +250,10 @@ Files: Common/city.cc Common/city.h
 Copyright: Copyright 2011 Google, Inc.
 License: Expat
 
+Files: Layout/*
+Copyright: Copyright 2012 Shaun Jackman
+License: BCCA-Academic or GPL-3+
+
 Files: dialign/*
 Copyright: Copyright 2008 Amarendran R. Subramanian
 License: LGPL-2.1+
diff --git a/ChangeLog b/ChangeLog
index 797617c..27be8e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,63 @@
+2013-03-04  Anthony Raymond  <traymond at bcgsc.ca>
+
+	* Release version 1.3.5
+	* Standardized --help message format.
+	* Improve documentation.
+	* Merge overlapping read pairs.
+	* Layout and merge contigs using sequence overlap graph.
+	* Attempt to fill scaffold gap with consensus of all paths between
+	contigs.
+
+	abyss-pe:
+	* Attempt to fill scaffold gap with consensus of all paths between
+	contigs. 
+
+	AdjList:
+	* Increase the default value of m from 30 to 50.
+
+	abyss-overlap:
+	* Increase the default value of m from 30 to 50.
+	* New options, --tred and --no-tred. Remove transitive edges.
+	Default --tred.
+
+	abyss-mergepairs:
+	* New program. Merges overlapping read pairs.
+
+	ABYSS-P:
+	* Bug fix. Exit when there is a problem reading a file.
+	* Don't store sequences in the rank 0 process when using at least
+	1000 cores. Improves memory distribution with large number of
+	cores.
+
+	abyss-fac:
+	* Increase the default value of t from 200 to 500.
+
+	DistanceEst:
+	* Bug fix. Exit with success if there is only one contig. Fixes
+	this error:
+	DistanceEst: DistanceEst.cpp:534: int main(int, char**): Assertion `in' failed.
+	* Bug fix. Fix the bug causing this error:
+	DistanceEst: error: The observed fragment of size 128 bp is shorter than 2*l (l=71). Decrease l to 64.
+	* Bug fix. Correctly estimate distance using MLE when l=0.
+
+	abyss-layout:
+	* New program. Layout contigs using the sequence overlap graph.
+
+	abyss-map:
+	* Return helpful error when query ID starts with '@`
+	* New options, --chastity and --no-chastity. Ignore chastity
+	failed reads. Default --no-chastity.
+
+	abyss-samtobreak:
+	* New script. Calculate contig and scaffold contiguity and
+	correctness metrics.
+
+	abyss-fixmate:
+	* New option, l. Minimum alignment length. Set unmapped flag if
+	the CIGAR match length is too small.
+	* Print all alignments when the histogram output file not given.
+	* Print SAM header to the same file when given.
+
 2012-05-30  Shaun Jackman  <sjackman at bcgsc.ca>
 
 	* Release version 1.3.4.
diff --git a/Common/ContigProperties.h b/Common/ContigProperties.h
index a2f4b9c..73fb0bd 100644
--- a/Common/ContigProperties.h
+++ b/Common/ContigProperties.h
@@ -220,6 +220,10 @@ struct EdgeWeightMap {
 	reference operator[](const key_type& e) const
 	{
 		int weight = m_g[e].distance + m_g[target(e, m_g)].length;
+		if (weight <= 0)
+			std::cerr << "error: invalid edge: "
+				<< get(edge_name, m_g, e)
+				<< " [" << get(edge_bundle, m_g, e) << "]\n";
 		assert(weight > 0);
 		return weight;
 	}
diff --git a/Common/Makefile.in b/Common/Makefile.in
index 0925a35..d6b9c98 100644
--- a/Common/Makefile.in
+++ b/Common/Makefile.in
@@ -121,6 +121,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Common/SAM.h b/Common/SAM.h
index f13d0e1..835ec3e 100644
--- a/Common/SAM.h
+++ b/Common/SAM.h
@@ -10,6 +10,11 @@
 #include <sstream>
 #include <string>
 
+namespace opt {
+	/** The minimal alignment size. */
+	static unsigned minAlign = 1;
+}
+
 /** A SAM alignment of a single query. */
 struct SAMAlignment {
 	std::string rname;
@@ -93,6 +98,8 @@ struct SAMAlignment {
 		CigarCoord(const std::string& cigar)
 			: qlen(0), qstart(0), qspan(0), tspan(0)
 		{
+			if (cigar == "*")
+				return;
 			std::istringstream in(cigar);
 			bool first = true;
 			unsigned len;
@@ -274,6 +281,15 @@ struct SAMRecord : SAMAlignment {
 		mpos = o.pos;
 		isize = isMateUnmapped() ? 0
 			: o.targetAtQueryStart() - targetAtQueryStart();
+
+		// Fix unaligned mates
+		if (!o.isUnmapped() && isUnmapped()) {
+			rname = o.rname;
+			pos = o.pos;
+		} else if (o.isUnmapped() && !isUnmapped()) {
+			mrnm = "=";
+			mpos = pos;
+		}
 	}
 
 	/**
@@ -333,6 +349,11 @@ struct SAMRecord : SAMAlignment {
 			o.qname.resize(l - 2);
 			assert(!o.qname.empty());
 		}
+
+		// Set the unmapped flag if the alignment is not long enough.
+		CigarCoord a(o.cigar);
+		if (a.qspan < opt::minAlign || a.tspan < opt::minAlign)
+			o.flag |= FUNMAP;
 		return in;
 	}
 };
diff --git a/Common/SeqExt.h b/Common/SeqExt.h
index 5990496..01c0a40 100644
--- a/Common/SeqExt.h
+++ b/Common/SeqExt.h
@@ -1,6 +1,7 @@
 #ifndef SEQEXT_H
 #define SEQEXT_H 1
 
+#include "Sequence.h" // for codeToBase
 #include <cassert>
 #include <ostream>
 #include <stdint.h>
@@ -84,11 +85,10 @@ class SeqExt
 				const SeqExt& o)
 		{
 			assert(o.m_record < 1<<NUM_BASES);
-			return out
-				<< (o.checkBase(0) ? 'A' : '-')
-				<< (o.checkBase(1) ? 'C' : '-')
-				<< (o.checkBase(2) ? 'G' : '-')
-				<< (o.checkBase(3) ? 'T' : '-');
+			for (unsigned i = 0; i < NUM_BASES; ++i)
+				if (o.checkBase(i))
+					out << codeToBase(i);
+			return out;
 		}
 
 	private:
diff --git a/Common/Uncompress.cpp b/Common/Uncompress.cpp
index fcbc4ed..476d1fb 100644
--- a/Common/Uncompress.cpp
+++ b/Common/Uncompress.cpp
@@ -22,12 +22,18 @@
 
 using namespace std;
 
-static const char* zcatExec(const string& path)
+static const char* wgetExec(const string& path)
 {
 	return
 		startsWith(path, "http://") ? "wget -O-" :
 		startsWith(path, "https://") ? "wget -O-" :
 		startsWith(path, "ftp://") ? "wget -O-" :
+		NULL;
+}
+
+static const char* zcatExec(const string& path)
+{
+	return
 		endsWith(path, ".ar") ? "ar -p" :
 		endsWith(path, ".tar") ? "tar -xOf" :
 		endsWith(path, ".tar.Z") ? "tar -zxOf" :
@@ -56,7 +62,8 @@ extern "C" {
  */
 static int uncompress(const char *path)
 {
-	const char *zcat = zcatExec(path);
+	const char *wget = wgetExec(path);
+	const char *zcat = wget != NULL ? wget : zcatExec(path);
 	assert(zcat != NULL);
 
 	int fd[2];
@@ -127,8 +134,19 @@ FILE *fopen(const char *path, const char *mode)
 		fprintf(stderr, "error: dlsym fopen: %s\n", dlerror());
 		exit(EXIT_FAILURE);
 	}
-	return zcatExec(path) == NULL ? real_fopen(path, mode)
-		: funcompress(path);
+
+	// open a web address
+	if (wgetExec(path) != NULL)
+		return funcompress(path);
+	
+	// to check if the file exists, we need to attempt to open it
+	FILE* stream = real_fopen(path, mode);
+	if (string(mode) != "r" || !stream || zcatExec(path) == NULL)
+		return stream;
+	else {
+		fclose(stream);
+		return funcompress(path);
+	}
 }
 
 /** If the specified file is compressed, return a pipe that
@@ -143,8 +161,19 @@ FILE *fopen64(const char *path, const char *mode)
 		fprintf(stderr, "error: dlsym fopen64: %s\n", dlerror());
 		exit(EXIT_FAILURE);
 	}
-	return zcatExec(path) == NULL ? real_fopen64(path, mode)
-		: funcompress(path);
+
+	// open a web address
+	if (wgetExec(path) != NULL)
+		return funcompress(path);
+	
+	// to check if the file exists, we need to attempt to open it
+	FILE* stream = real_fopen64(path, mode);
+	if (string(mode) != "r" || !stream || zcatExec(path) == NULL)
+		return stream;
+	else {
+		fclose(stream);
+		return funcompress(path);
+	}
 }
 
 typedef int (*open_t)(const char *path, int flags, mode_t mode);
@@ -161,8 +190,20 @@ int open(const char *path, int flags, mode_t mode)
 		fprintf(stderr, "error: dlsym open: %s\n", dlerror());
 		exit(EXIT_FAILURE);
 	}
-	return zcatExec(path) == NULL ? real_open(path, flags, mode)
-		: uncompress(path);
+
+	// open a web address
+	if (wgetExec(path) != NULL)
+		return uncompress(path);
+	
+	// to check if the file exists, we need to attempt to open it
+	int filedesc = real_open(path, flags, mode);
+	if (mode != ios_base::in || filedesc < 0
+			|| zcatExec(path) == NULL)
+		return filedesc;
+	else {
+		close(filedesc);
+		return uncompress(path);
+	}
 }
 
 } // extern "C"
diff --git a/Consensus/Consensus.cpp b/Consensus/Consensus.cpp
index a714528..669c2fa 100644
--- a/Consensus/Consensus.cpp
+++ b/Consensus/Consensus.cpp
@@ -22,7 +22,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Tony Raymond and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... CONTIG\n"
@@ -31,8 +31,13 @@ static const char USAGE_MESSAGE[] =
 "Ensure that the --seq option was used when running KAligner.\n"
 "Call a consensus at each position of each contig and write the\n"
 "consensus in FASTA format to OUTPUT.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  CONTIG  contigs in FASTA format\n"
 "\n"
+" Options:\n"
+"\n"
 "  -o, --out=OUTPUT      write the output FASTA file to OUTPUT\n"
 "  -p, --pileup=PILEUP   write the pileup to PILEUP\n"
 "      --nt              output nucleotide contigs [default]\n"
diff --git a/Consensus/Makefile.in b/Consensus/Makefile.in
index 38e8732..0d2558c 100644
--- a/Consensus/Makefile.in
+++ b/Consensus/Makefile.in
@@ -110,6 +110,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/DAssembler/DAssembler.cpp b/DAssembler/DAssembler.cpp
index 0ab0786..c4e6aa4 100644
--- a/DAssembler/DAssembler.cpp
+++ b/DAssembler/DAssembler.cpp
@@ -22,7 +22,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Rod Docking.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 namespace opt {
     static unsigned max_overlap = 10;
@@ -50,8 +50,13 @@ static const struct option longopts[] = {
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [READS]\n"
 "Assemble a single contig from reads in a single orientation.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  READS  fasta-formatted reads file: the first read is used as the seed.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -o, --max_overlap=INT            maximum tier overlap for consensus calling"
 " [10]\n"
 "  -m, --max_mismatch=INT           maximum mismatches allowed for consensus"
diff --git a/DAssembler/Makefile.in b/DAssembler/Makefile.in
index 9d1fd6c..99f6d40 100644
--- a/DAssembler/Makefile.in
+++ b/DAssembler/Makefile.in
@@ -115,6 +115,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/DataLayer/FastaReader.cpp b/DataLayer/FastaReader.cpp
index da11ef0..1138145 100644
--- a/DataLayer/FastaReader.cpp
+++ b/DataLayer/FastaReader.cpp
@@ -33,11 +33,12 @@ ostream& FastaReader::die()
 	return cerr << m_path << ':' << m_line << ": error: ";
 }
 
-FastaReader::FastaReader(const char* path, int flags)
+FastaReader::FastaReader(const char* path, int flags, int len)
 	: m_path(path), m_fin(path),
 	m_in(strcmp(path, "-") == 0 ? cin : m_fin),
 	m_flags(flags), m_line(0), m_unchaste(0),
-	m_end(numeric_limits<streamsize>::max())
+	m_end(numeric_limits<streamsize>::max()),
+	m_maxLength(len)
 {
 	if (strcmp(path, "-") != 0)
 		assert_good(m_fin, path);
@@ -119,6 +120,11 @@ Sequence FastaReader::read(string& id, string& comment,
 		char& anchor, string& q)
 {
 next_record:
+	id.clear();
+	comment.clear();
+	anchor = 0;
+	q.clear();
+
 	// Discard comments.
 	while (m_in.peek() == '#')
 		ignoreLines(1);
@@ -150,7 +156,13 @@ next_record:
 			// read, chastity, flags, index: 1:Y:0:AAAAAA
 			if (opt::chastityFilter && comment[2] == 'Y') {
 				m_unchaste++;
-				ignoreLines(recordType == '@' ? 3 : 1);
+				if (recordType == '@') {
+					ignoreLines(3);
+				} else {
+					while (m_in.peek() != '>' && m_in.peek() != '#'
+							&& ignoreLines(1))
+						;
+				}
 				goto next_record;
 			}
 			if (id.size() > 2 && id.rbegin()[1] != '/') {
@@ -317,6 +329,13 @@ next_record:
 	if (opt::qualityOffset > 0)
 		qualityOffset = opt::qualityOffset;
 
+	// Trim from the 3' end to the maximum length. Then, trim based on
+	// quality.
+	if (m_maxLength > 0) {
+		s.erase(m_maxLength);
+		q.erase(m_maxLength);
+	}
+
 	if (opt::qualityThreshold > 0 && !q.empty()) {
 		assert(s.length() == q.length());
 		static const char ASCII[] =
diff --git a/DataLayer/FastaReader.h b/DataLayer/FastaReader.h
index 782d41a..e097267 100644
--- a/DataLayer/FastaReader.h
+++ b/DataLayer/FastaReader.h
@@ -22,7 +22,7 @@ class FastaReader {
 		bool flagFoldCase() { return ~m_flags & NO_FOLD_CASE; }
 		bool flagConvertQual() { return m_flags & CONVERT_QUALITY; }
 
-		FastaReader(const char* path, int flags);
+		FastaReader(const char* path, int flags, int len = 0);
 
 		~FastaReader()
 		{
@@ -111,6 +111,9 @@ class FastaReader {
 
 		/** Position of the end of the current section. */
 		std::streampos m_end;
+
+		/** Trim sequences to this length. 0 is unlimited. */
+		const int m_maxLength;
 };
 
 /** A FASTA record. */
diff --git a/DataLayer/Makefile.in b/DataLayer/Makefile.in
index 9cf895e..1fe4fd3 100644
--- a/DataLayer/Makefile.in
+++ b/DataLayer/Makefile.in
@@ -129,6 +129,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/DataLayer/abyss-tofastq.cc b/DataLayer/abyss-tofastq.cc
index 4fb161b..547afd8 100644
--- a/DataLayer/abyss-tofastq.cc
+++ b/DataLayer/abyss-tofastq.cc
@@ -22,7 +22,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FILE]...\n"
@@ -30,6 +30,8 @@ static const char USAGE_MESSAGE[] =
 "qseq, export, SAM or BAM format and compressed with gz, bz2 or xz\n"
 "and may be tarred.\n"
 "\n"
+" Options:\n"
+"\n"
 "      --cat               concatenate the records [default]\n"
 "  -i, --interleave        interleave the records\n"
 "      --fastq             ouput FASTQ format [default]\n"
diff --git a/DataLayer/fac.cc b/DataLayer/fac.cc
index 472f667..4cf6764 100644
--- a/DataLayer/fac.cc
+++ b/DataLayer/fac.cc
@@ -7,6 +7,7 @@
 #include "Common/Sequence.h" // for isACGT
 #include "DataLayer/FastaReader.h"
 #include "DataLayer/Options.h"
+#include "Uncompress.h"
 #include <algorithm>
 #include <getopt.h>
 #include <iostream>
@@ -20,13 +21,15 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FILE]...\n"
 "Calculate assembly contiguity statistics.\n"
 "\n"
-"  -s, -t, --min-length=N  ignore sequences shorter than N bp [200]\n"
+" Options:\n"
+"\n"
+"  -s, -t, --min-length=N  ignore sequences shorter than N bp [500]\n"
 "  -d, --delimiter=S       use S for the field delimiter [\\t]\n"
 "  -j, --jira              output JIRA format\n"
 "  -m, --mmd               output MultiMarkdown format\n"
@@ -42,7 +45,7 @@ static const char USAGE_MESSAGE[] =
 "Report bugs to <" PACKAGE_BUGREPORT ">.\n";
 
 namespace opt {
-	static unsigned minLength = 200;
+	static unsigned minLength = 500;
 	static string delimiter = "\t";
 	static int format;
 	static int verbose;
diff --git a/DistanceEst/DistanceEst.cpp b/DistanceEst/DistanceEst.cpp
index 1c3c9ea..1603b6b 100644
--- a/DistanceEst/DistanceEst.cpp
+++ b/DistanceEst/DistanceEst.cpp
@@ -9,6 +9,7 @@
 #include <algorithm>
 #include <cassert>
 #include <climits>
+#include <cmath>
 #include <cstdlib>
 #include <fstream>
 #include <getopt.h>
@@ -31,14 +32,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... HIST [PAIR]\n"
 "Estimate distances between contigs using paired-end alignments.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  HIST  distribution of fragments size\n"
 "  PAIR  alignments between contigs\n"
 "\n"
+" Options:\n"
+"\n"
 "      --mind=N          minimum distance between contigs [-(k-1)]\n"
 "      --maxd=N          maximum distance between contigs\n"
 "      --fr              force the orientation to forward-reverse\n"
@@ -72,9 +78,6 @@ namespace opt {
 	/** Output graph format. */
 	int format = DIST;
 
-	/** The minimal alignment size. */
-	static int minAlign = 1;
-
 	/** Minimum distance between contigs. */
 	static int minDist = numeric_limits<int>::min();
 
@@ -138,7 +141,7 @@ static int estimateDistanceUsingMean(
 		unsigned& numPairs)
 {
 	Histogram h(samples.begin(), samples.end());
-	int d = pmf.mean() - h.mean();
+	int d = (int)round(pmf.mean() - h.mean());
 
 	// Count the number of samples that agree with the distribution.
 	unsigned n = 0;
@@ -151,6 +154,9 @@ static int estimateDistanceUsingMean(
 	return d;
 }
 
+/** Global variable to track a recommended minAlign parameter */
+unsigned g_recMA;
+
 /** Estimate the distance between two contigs.
  * @param numPairs [out] the number of pairs that agree with the
  * expected distribution
@@ -188,23 +194,29 @@ static int estimateDistance(unsigned len0, unsigned len1,
 
 	vector<int> fragmentSizes;
 	fragmentSizes.reserve(fragments.size());
+	unsigned ma = opt::minAlign;
 	for (Fragments::const_iterator it = fragments.begin();
 			it != fragments.end(); ++it) {
 		int x = it->second - it->first;
-		if (!opt::rf && x <= 2 * int(opt::minAlign - 1)) {
-			cerr << PROGRAM ": error: The observed fragment of size "
-				<< x << " bp is shorter than 2*l "
-				"(l=" << opt::minAlign << "). "
-				"Decrease l to " << x / 2 << ".\n";
-			exit(EXIT_FAILURE);
+		if (!opt::rf && opt::method == MLE 
+				&& x <= 2 * int(ma - 1)) {
+			unsigned align = x / 2;
+			if (opt::verbose > 0)
+#pragma omp critical(cerr)
+				cerr << PROGRAM ": warning: The observed fragment of "
+					"size " << x << " bp is shorter than 2*l "
+					"(l=" << opt::minAlign << ").\n";
+			ma = min(ma, align);
 		}
 		fragmentSizes.push_back(x);
 	}
 
+#pragma omp critical(g_recMA)
+	g_recMA = min(g_recMA, ma);
 	switch (opt::method) {
 	  case MLE:
 		// Use the maximum likelihood estimator.
-		return maximumLikelihoodEstimate(opt::minAlign,
+		return maximumLikelihoodEstimate(ma,
 				opt::minDist, opt::maxDist,
 				fragmentSizes, pmf, len0, len1, opt::rf, numPairs);
 	  case MEAN:
@@ -531,7 +543,15 @@ int main(int argc, char** argv)
 
 	// Estimate the distances between contigs.
 	istream_iterator<SAMRecord> it(in), last;
+	if (contigLens.size() == 1) {
+		// When mapping to a single contig, no alignments spanning
+		// contigs are expected.
+		assert(in.eof());
+		exit(EXIT_SUCCESS);
+	}
 	assert(in);
+
+	g_recMA = opt::minAlign;
 #pragma omp parallel
 	for (vector<SAMRecord> records;;) {
 		records.clear();
@@ -541,6 +561,10 @@ int main(int argc, char** argv)
 			break;
 		writeEstimates(out, records, contigLens, pmf);
 	}
+	if (opt::verbose > 0 && g_recMA != opt::minAlign)
+		cerr << PROGRAM << ": warning: MLE will be more accurate if "
+			"l is decreased to " << g_recMA << ".\n";
+
 	assert(in.eof());
 
 	if (opt::format == DOT)
diff --git a/DistanceEst/MLE.cpp b/DistanceEst/MLE.cpp
index d91e259..9898e2e 100644
--- a/DistanceEst/MLE.cpp
+++ b/DistanceEst/MLE.cpp
@@ -150,7 +150,7 @@ int maximumLikelihoodEstimate(unsigned l,
 		}
 		int d;
 		tie(d, n) = maximumLikelihoodEstimate(
-				0, last, h,
+				first, last, h,
 				pmf, len0, len1);
 		return max(first, d - 2 * (int)(l - 1));
 	}
diff --git a/DistanceEst/Makefile.in b/DistanceEst/Makefile.in
index 7807ed6..a1750c7 100644
--- a/DistanceEst/Makefile.in
+++ b/DistanceEst/Makefile.in
@@ -116,6 +116,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/FMIndex/Makefile.in b/FMIndex/Makefile.in
index bdd222e..49c0a76 100644
--- a/FMIndex/Makefile.in
+++ b/FMIndex/Makefile.in
@@ -127,6 +127,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/FMIndex/abyss-dawg.cc b/FMIndex/abyss-dawg.cc
index e8403b1..2343167 100644
--- a/FMIndex/abyss-dawg.cc
+++ b/FMIndex/abyss-dawg.cc
@@ -24,13 +24,15 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FASTA]\n"
 "Output a directed acyclic word graph (DAWG) of the specified file.\n"
 "The index file TARGET.fm will be used if present.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -v, --verbose           display verbose output\n"
 "      --help              display this help and exit\n"
 "      --version           output version information and exit\n"
diff --git a/FMIndex/count.cc b/FMIndex/count.cc
index 7be2384..9985247 100644
--- a/FMIndex/count.cc
+++ b/FMIndex/count.cc
@@ -22,13 +22,15 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FASTA]\n"
 "Count k-mer of the specified file.\n"
 "The index file TARGET.fm will be used if present.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer              the size of a k-mer\n"
 "  -v, --verbose           display verbose output\n"
 "      --help              display this help and exit\n"
diff --git a/FilterGraph/FilterGraph.cpp b/FilterGraph/FilterGraph.cpp
index e4b96a9..e285366 100644
--- a/FilterGraph/FilterGraph.cpp
+++ b/FilterGraph/FilterGraph.cpp
@@ -40,14 +40,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Tony Raymond.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... ADJ\n"
 "Remove short contigs that do not contribute any relevant\n"
 "information to the assembly.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  ADJ    contig adjacency graph\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=N          k-mer size\n"
 "  -T, --island=N        remove islands shorter than N [0]\n"
 "  -t, --tip=N           remove tips shorter than N [0]\n"
diff --git a/FilterGraph/Makefile.in b/FilterGraph/Makefile.in
index 6aed6e3..97d0ea9 100644
--- a/FilterGraph/Makefile.in
+++ b/FilterGraph/Makefile.in
@@ -114,6 +114,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Graph/AdjIO.h b/Graph/AdjIO.h
index 48f2cd9..3e98f50 100644
--- a/Graph/AdjIO.h
+++ b/Graph/AdjIO.h
@@ -101,6 +101,11 @@ template <typename Graph, typename BetterEP>
 std::istream& read_adj(std::istream& in, ContigGraph<Graph>& g,
 		BetterEP betterEP)
 {
+	if (in.eof()) {
+		// Allow reading an empty file if the graph is not empty.
+		assert(num_vertices(g) > 0);
+		return in;
+	}
 	assert(in);
 
 	typedef typename Graph::vertex_descriptor vertex_descriptor;
diff --git a/Graph/ContigGraphAlgorithms.h b/Graph/ContigGraphAlgorithms.h
index 023a898..0eac936 100644
--- a/Graph/ContigGraphAlgorithms.h
+++ b/Graph/ContigGraphAlgorithms.h
@@ -329,7 +329,7 @@ size_t addComplementaryEdges(ContigGraph<DG>& g)
 		if (!found) {
 			add_edge(vc, uc, g[e], static_cast<DG&>(g));
 			numAdded++;
-		} else if (g[e] != g[f]) {
+		} else if (!(g[e] == g[f])) {
 			// The edge properties do not agree. Select the better.
 			g[e] = g[f] = BetterDistanceEst()(g[e], g[f]);
 		}
diff --git a/Graph/GraphAlgorithms.h b/Graph/GraphAlgorithms.h
index 62f453b..8b745c5 100644
--- a/Graph/GraphAlgorithms.h
+++ b/Graph/GraphAlgorithms.h
@@ -44,13 +44,15 @@ void find_transitive_edges(const Graph& g, OutIt out)
 		for (adjacency_iterator vit = vrange.first;
 				vit != vrange.second; ++vit) {
 			vertex_descriptor v = *vit;
-			assert(u != v); // no self loops
+			if (u == v) // ignore self loops
+				continue;
 			std::pair<adjacency_iterator, adjacency_iterator>
 				wrange = adjacent_vertices(v, g);
 			for (adjacency_iterator wit = wrange.first;
 					wit != wrange.second; ++wit) {
 				vertex_descriptor w = *wit;
-				assert(v != w); // no self loops
+				if (v == w) // ignore self loops
+					continue;
 				seen[get(vertex_index, g, w)] = true;
 			}
 		}
diff --git a/Graph/Makefile.in b/Graph/Makefile.in
index 16c0741..16c083c 100644
--- a/Graph/Makefile.in
+++ b/Graph/Makefile.in
@@ -129,6 +129,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Graph/gc.cc b/Graph/gc.cc
index f27f915..dfa755b 100644
--- a/Graph/gc.cc
+++ b/Graph/gc.cc
@@ -19,12 +19,14 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [FILE]...\n"
 "Count the number of vertices and edges in a graph.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -v, --verbose  display verbose output\n"
 "      --help     display this help and exit\n"
 "      --version  output version information and exit\n"
diff --git a/Graph/todot.cc b/Graph/todot.cc
index 16a50b5..c6fe767 100644
--- a/Graph/todot.cc
+++ b/Graph/todot.cc
@@ -24,12 +24,14 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [FILE]...\n"
 "Convert the specified graph to dot format.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=N   report the mean k-mer coverage, otherwise\n"
 "                 the sum k-mer coverage is reported\n"
 "      --adj             output the graph in adj format\n"
diff --git a/KAligner/KAligner.cpp b/KAligner/KAligner.cpp
index 899765e..548fafb 100644
--- a/KAligner/KAligner.cpp
+++ b/KAligner/KAligner.cpp
@@ -34,15 +34,17 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... QUERY... TARGET\n"
 "Align the sequences of the files QUERY to those of TARGET.\n"
 "All perfect matches of at least k bases will be found.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, -l, --kmer=N      k-mer size and minimum alignment length\n"
-"  -s, --section=S/N     split the target into N sections and align"
+"  -s, --section=S/N     split the target into N sections and align\n"
 "                        reads to section S [1/1]\n"
 "  -i, --ignore-multimap ignore duplicate k-mer in the target\n"
 "                        [default]\n"
diff --git a/KAligner/Makefile.in b/KAligner/Makefile.in
index 1dfe4bd..be84430 100644
--- a/KAligner/Makefile.in
+++ b/KAligner/Makefile.in
@@ -117,6 +117,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/LICENSE b/LICENSE
index f640300..cb557ef 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
 ABySS
-Copyright 2012 Genome Sciences Centre
+Copyright 2013 Genome Sciences Centre
 
 BC CANCER AGENCY SOFTWARE LICENSE AGREEMENT (ACADEMIC USE)
 CAREFULLY READ THE FOLLOWING TERMS AND CONDITIONS. This License
diff --git a/Layout/Makefile.am b/Layout/Makefile.am
new file mode 100644
index 0000000..2cdda85
--- /dev/null
+++ b/Layout/Makefile.am
@@ -0,0 +1,5 @@
+bin_PROGRAMS = abyss-layout
+
+abyss_layout_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/Common
+abyss_layout_LDADD = $(top_builddir)/Common/libcommon.a
+abyss_layout_SOURCES = layout.cc
diff --git a/ABYSS/Makefile.in b/Layout/Makefile.in
similarity index 87%
copy from ABYSS/Makefile.in
copy to Layout/Makefile.in
index a5768e0..a51de8a 100644
--- a/ABYSS/Makefile.in
+++ b/Layout/Makefile.in
@@ -49,8 +49,8 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
-bin_PROGRAMS = ABYSS$(EXEEXT)
-subdir = ABYSS
+bin_PROGRAMS = abyss-layout$(EXEEXT)
+subdir = Layout
 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
 	$(top_srcdir)/depcomp
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -63,11 +63,9 @@ CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
-am_ABYSS_OBJECTS = ABYSS-Abyss.$(OBJEXT)
-ABYSS_OBJECTS = $(am_ABYSS_OBJECTS)
-ABYSS_DEPENDENCIES = $(top_builddir)/Assembly/libassembly.a \
-	$(top_builddir)/DataLayer/libdatalayer.a \
-	$(top_builddir)/Common/libcommon.a
+am_abyss_layout_OBJECTS = abyss_layout-layout.$(OBJEXT)
+abyss_layout_OBJECTS = $(am_abyss_layout_OBJECTS)
+abyss_layout_DEPENDENCIES = $(top_builddir)/Common/libcommon.a
 DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -77,8 +75,8 @@ CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 CXXLD = $(CXX)
 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
 	-o $@
-SOURCES = $(ABYSS_SOURCES)
-DIST_SOURCES = $(ABYSS_SOURCES)
+SOURCES = $(abyss_layout_SOURCES)
+DIST_SOURCES = $(abyss_layout_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -111,6 +109,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -182,21 +181,13 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-ABYSS_CPPFLAGS = -I$(top_srcdir) \
-	-I$(top_srcdir)/Assembly \
-	-I$(top_srcdir)/Common \
-	-I$(top_srcdir)/DataLayer
-
-ABYSS_LDADD = \
-	$(top_builddir)/Assembly/libassembly.a \
-	$(top_builddir)/DataLayer/libdatalayer.a \
-	$(top_builddir)/Common/libcommon.a
-
-ABYSS_SOURCES = Abyss.cpp
+abyss_layout_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/Common
+abyss_layout_LDADD = $(top_builddir)/Common/libcommon.a
+abyss_layout_SOURCES = layout.cc
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .cpp .o .obj
+.SUFFIXES: .cc .o .obj
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -206,9 +197,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ABYSS/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Layout/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign ABYSS/Makefile
+	  $(AUTOMAKE) --foreign Layout/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -267,9 +258,9 @@ uninstall-binPROGRAMS:
 
 clean-binPROGRAMS:
 	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-ABYSS$(EXEEXT): $(ABYSS_OBJECTS) $(ABYSS_DEPENDENCIES) $(EXTRA_ABYSS_DEPENDENCIES) 
-	@rm -f ABYSS$(EXEEXT)
-	$(CXXLINK) $(ABYSS_OBJECTS) $(ABYSS_LDADD) $(LIBS)
+abyss-layout$(EXEEXT): $(abyss_layout_OBJECTS) $(abyss_layout_DEPENDENCIES) $(EXTRA_abyss_layout_DEPENDENCIES) 
+	@rm -f abyss-layout$(EXEEXT)
+	$(CXXLINK) $(abyss_layout_OBJECTS) $(abyss_layout_LDADD) $(LIBS)
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -277,35 +268,35 @@ mostlyclean-compile:
 distclean-compile:
 	-rm -f *.tab.c
 
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ABYSS-Abyss.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/abyss_layout-layout.Po at am__quote@
 
-.cpp.o:
+.cc.o:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
 
-.cpp.obj:
+.cc.obj:
 @am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
 @am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-ABYSS-Abyss.o: Abyss.cpp
- at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ABYSS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ABYSS-Abyss.o -MD -MP -MF $(DEPDIR)/ABYSS-Abyss.Tpo -c -o ABYSS-Abyss.o `test -f 'Abyss.cpp' || echo '$(srcdir)/'`Abyss.cpp
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/ABYSS-Abyss.Tpo $(DEPDIR)/ABYSS-Abyss.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Abyss.cpp' object='ABYSS-Abyss.o' libtool=no @AMDEPBACKSLASH@
+abyss_layout-layout.o: layout.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_layout_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT abyss_layout-layout.o -MD -MP -MF $(DEPDIR)/abyss_layout-layout.Tpo -c -o abyss_layout-layout.o `test -f 'layout.cc' || echo '$(srcdir)/'`layout.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/abyss_layout-layout.Tpo $(DEPDIR)/abyss_layout-layout.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='layout.cc' object='abyss_layout-layout.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ABYSS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ABYSS-Abyss.o `test -f 'Abyss.cpp' || echo '$(srcdir)/'`Abyss.cpp
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_layout_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o abyss_layout-layout.o `test -f 'layout.cc' || echo '$(srcdir)/'`layout.cc
 
-ABYSS-Abyss.obj: Abyss.cpp
- at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ABYSS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT ABYSS-Abyss.obj -MD -MP -MF $(DEPDIR)/ABYSS-Abyss.Tpo -c -o ABYSS-Abyss.obj `if test -f 'Abyss.cpp'; then $(CYGPATH_W) 'Abyss.cpp'; else $(CYGPATH_W) '$(srcdir)/Abyss.cpp'; fi`
- at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/ABYSS-Abyss.Tpo $(DEPDIR)/ABYSS-Abyss.Po
- at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Abyss.cpp' object='ABYSS-Abyss.obj' libtool=no @AMDEPBACKSLASH@
+abyss_layout-layout.obj: layout.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_layout_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT abyss_layout-layout.obj -MD -MP -MF $(DEPDIR)/abyss_layout-layout.Tpo -c -o abyss_layout-layout.obj `if test -f 'layout.cc'; then $(CYGPATH_W) 'layout.cc'; else $(CYGPATH_W) '$(srcdir)/layout.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/abyss_layout-layout.Tpo $(DEPDIR)/abyss_layout-layout.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='layout.cc' object='abyss_layout-layout.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ABYSS_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o ABYSS-Abyss.obj `if test -f 'Abyss.cpp'; then $(CYGPATH_W) 'Abyss.cpp'; else $(CYGPATH_W) '$(srcdir)/Abyss.cpp'; fi`
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(abyss_layout_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o abyss_layout-layout.obj `if test -f 'layout.cc'; then $(CYGPATH_W) 'layout.cc'; else $(CYGPATH_W) '$(srcdir)/layout.cc'; fi`
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
 	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
diff --git a/Layout/layout.cc b/Layout/layout.cc
new file mode 100644
index 0000000..9e498be
--- /dev/null
+++ b/Layout/layout.cc
@@ -0,0 +1,319 @@
+#include "config.h"
+#include "ContigPath.h"
+#include "ContigProperties.h"
+#include "Uncompress.h"
+#include "Graph/Assemble.h"
+#include "Graph/ContigGraph.h"
+#include "Graph/ContigGraphAlgorithms.h"
+#include "Graph/DirectedGraph.h"
+#include "Graph/GraphAlgorithms.h"
+#include "Graph/GraphIO.h"
+#include "Graph/GraphUtil.h"
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <getopt.h>
+#include <iostream>
+#include <sstream>
+#include <string>
+#include <utility>
+
+using namespace std;
+using boost::tie;
+
+#define PROGRAM "abyss-layout"
+
+static const char VERSION_MESSAGE[] =
+PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
+"Written by Shaun Jackman.\n"
+"\n"
+"Copyright 2012 Shaun Jackman\n";
+
+static const char USAGE_MESSAGE[] =
+"Usage: " PROGRAM " [OPTION]... OVERLAP\n"
+"Layout contigs using the sequence overlap graph.\n"
+"Output sequence paths.\n"
+"\n"
+" Arguments:\n"
+"\n"
+"  OVERLAP  the sequence overlap graph\n"
+"\n"
+" Options:\n"
+"\n"
+"  -s, --min-length=N    minimum sequence length [0]\n"
+"  -m, --min-overlap=N   minimum overlap [0]\n"
+"  -k, --kmer=N          length of a k-mer\n"
+"  -o, --out=FILE        write the paths to FILE\n"
+"  -g, --graph=FILE      write the graph to FILE\n"
+"      --tred            remove transitive edges\n"
+"      --no-tred         do not remove transitive edges [default]\n"
+"  -v, --verbose         display verbose output\n"
+"      --help            display this help and exit\n"
+"      --version         output version information and exit\n"
+"\n"
+"Report bugs to <" PACKAGE_BUGREPORT ">.\n";
+
+namespace opt {
+	unsigned k; // used by ContigProperties
+
+	/** Minimum sequence length. */
+	static unsigned minLength;
+
+	/** Minimum overlap. */
+	static unsigned minOverlap;
+
+	/** Write the paths to this file. */
+	static string out;
+
+	/** Write the graph to this file. */
+	static string graphPath;
+
+	/** Remove transitive edges. */
+	static int tred;
+
+	/** Verbose output. */
+	int verbose; // used by PopBubbles
+
+	/** Output format */
+	int format = DOT;
+}
+
+static const char shortopts[] = "g:k:m:o:s:v";
+
+enum { OPT_HELP = 1, OPT_VERSION };
+
+static const struct option longopts[] = {
+	{ "graph",       required_argument, NULL, 'g' },
+	{ "kmer",        required_argument, NULL, 'k' },
+	{ "min-overlap", required_argument, NULL, 'm' },
+	{ "out",         required_argument, NULL, 'o' },
+	{ "min-length",  required_argument, NULL, 's' },
+	{ "tred",        no_argument, &opt::tred, true },
+	{ "no-tred",     no_argument, &opt::tred, false },
+	{ "verbose",     no_argument,       NULL, 'v' },
+	{ "help",        no_argument,       NULL, OPT_HELP },
+	{ "version",     no_argument,       NULL, OPT_VERSION },
+	{ NULL, 0, NULL, 0 }
+};
+
+/** An overlap graph. */
+typedef DirectedGraph<Length, Distance> DG;
+typedef ContigGraph<DG> Graph;
+
+/** Remove short vertices. */
+static void filterVertices(Graph& g, unsigned minLength)
+{
+	typedef graph_traits<Graph> GTraits;
+	typedef GTraits::vertex_descriptor V;
+	typedef GTraits::vertex_iterator Vit;
+
+	if (minLength == 0)
+		return;
+
+	// Remove short sequences.
+	unsigned numRemoved = 0;
+	std::pair<Vit, Vit> urange = vertices(g);
+	for (Vit uit = urange.first; uit != urange.second; ++uit) {
+		V u = *uit;
+		if (g[u].length < minLength)
+			clear_vertex(u, g);
+		if (out_degree(u, g) == 0 && in_degree(u, g) == 0) {
+			remove_vertex(u, g);
+			numRemoved++;
+		}
+	}
+
+	if (opt::verbose > 0) {
+		cerr << "Ignored " << numRemoved << " sequences shorter than "
+			<< minLength << " bp.\n";
+		printGraphStats(cerr, g);
+	}
+}
+
+/** Return true if the edge is a small overlap. */
+struct IsSmallOverlap {
+	IsSmallOverlap(Graph& g) : m_g(g) { }
+	bool operator()(graph_traits<Graph>::edge_descriptor e) const
+	{
+		int maxDistance = -opt::minOverlap;
+		return m_g[e].distance > maxDistance;
+	}
+	const Graph& m_g;
+};
+
+/** Remove small overlaps. */
+static void filterEdges(Graph& g, unsigned minOverlap)
+{
+	if (minOverlap == 0)
+		return;
+	unsigned numBefore = num_edges(g);
+	remove_edge_if(IsSmallOverlap(g), static_cast<DG&>(g));
+	unsigned numRemoved = numBefore - num_edges(g);
+	if (opt::verbose > 0) {
+		cerr << "Removed " << numRemoved << " small overlaps.\n";
+		printGraphStats(cerr, g);
+	}
+}
+
+/** Read a graph from the specified file. */
+static void readGraph(const string& path, Graph& g)
+{
+	if (opt::verbose > 0)
+		cerr << "Reading `" << path << "'...\n";
+	ifstream fin(path.c_str());
+	istream& in = path == "-" ? cin : fin;
+	assert_good(in, path);
+	in >> g;
+	assert(in.eof());
+	if (opt::verbose > 0)
+		printGraphStats(cerr, g);
+	g_contigNames.lock();
+}
+
+/** Return the length histogram. */
+static Histogram buildLengthHistogram(const Graph& g)
+{
+	typedef graph_traits<Graph>::vertex_descriptor V;
+	typedef graph_traits<Graph>::vertex_iterator Vit;
+	Histogram h;
+	Vit uit, ulast;
+	for (tie(uit, ulast) = vertices(g); uit != ulast; ++++uit) {
+		V u = *uit;
+		if (!get(vertex_removed, g, u))
+			h.insert(g[u].length);
+	}
+	return h;
+}
+
+/** Run abyss-layout. */
+int main(int argc, char** argv)
+{
+	bool die = false;
+	for (int c; (c = getopt_long(argc, argv,
+					shortopts, longopts, NULL)) != -1;) {
+		istringstream arg(optarg != NULL ? optarg : "");
+		switch (c) {
+		  case '?':
+			die = true;
+			break;
+		  case 'k':
+			arg >> opt::k;
+			break;
+		  case 'g':
+			arg >> opt::graphPath;
+			break;
+		  case 'm':
+			arg >> opt::minOverlap;
+			break;
+		  case 'o':
+			arg >> opt::out;
+			break;
+		  case 's':
+			arg >> opt::minLength;
+			break;
+		  case 'v':
+			opt::verbose++;
+			break;
+		  case OPT_HELP:
+			cout << USAGE_MESSAGE;
+			exit(EXIT_SUCCESS);
+		  case OPT_VERSION:
+			cout << VERSION_MESSAGE;
+			exit(EXIT_SUCCESS);
+		}
+		if (optarg != NULL && !arg.eof()) {
+			cerr << PROGRAM ": invalid option: `-"
+				<< (char)c << optarg << "'\n";
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	if (argc - optind < 1) {
+		cerr << PROGRAM ": missing arguments\n";
+		die = true;
+	}
+
+	if (die) {
+		cerr << "Try `" << PROGRAM
+			<< " --help' for more information.\n";
+		exit(EXIT_FAILURE);
+	}
+
+	Graph g;
+	if (optind < argc) {
+		for (; optind < argc; optind++)
+			readGraph(argv[optind], g);
+	} else
+		readGraph("-", g);
+
+	// Remove short sequences.
+	filterVertices(g, opt::minLength);
+
+	// Remove small overlaps.
+	filterEdges(g, opt::minOverlap);
+
+	// Remove transitive edges.
+	if (opt::tred) {
+		unsigned numTransitive = remove_transitive_edges(g);
+		if (opt::verbose > 0) {
+			cerr << "Removed " << numTransitive
+				<< " transitive edges.\n";
+			printGraphStats(cerr, g);
+		}
+	}
+
+	/** A container of contig paths. */
+	typedef vector<ContigPath> ContigPaths;
+
+	// Assemble the paths.
+	ContigPaths paths;
+	assembleDFS(g, back_inserter(paths));
+	sort(paths.begin(), paths.end());
+	if (opt::verbose > 0) {
+		unsigned n = 0;
+		for (ContigPaths::const_iterator it = paths.begin();
+				it != paths.end(); ++it)
+			n += it->size();
+		cerr << "Assembled " << n << " sequences in "
+			<< paths.size() << " contigs.\n";
+		printGraphStats(cerr, g);
+	}
+
+	// Output the paths.
+	ofstream fout(opt::out.c_str());
+	ostream& out = opt::out.empty() || opt::out == "-" ? cout : fout;
+	assert_good(out, opt::out);
+	g_contigNames.unlock();
+	for (vector<ContigPath>::const_iterator it = paths.begin();
+			it != paths.end(); ++it)
+		out << createContigName() << '\t' << *it << '\n';
+	assert_good(out, opt::out);
+
+	// Create the new vertices.
+	for (vector<ContigPath>::const_iterator it = paths.begin();
+			it != paths.end(); ++it) {
+		const ContigPath& path = *it;
+		merge(g, path.begin(), path.end());
+		remove_vertex_if(g, path.begin(), path.end(),
+				not1(std::mem_fun_ref(&ContigNode::ambiguous)));
+	}
+	if (opt::verbose > 0)
+		printGraphStats(cerr, g);
+
+	// Output the graph.
+	if (!opt::graphPath.empty()) {
+		ofstream out(opt::graphPath.c_str());
+		assert_good(out, opt::graphPath);
+		write_dot(out, g);
+		assert_good(out, opt::graphPath);
+	}
+
+	// Print assembly contiguity statistics.
+	if (opt::verbose > 0) {
+		Histogram h = buildLengthHistogram(g);
+		const unsigned STATS_MIN_LENGTH = 200; // bp
+		printContiguityStats(cerr, h, STATS_MIN_LENGTH) << '\n';
+	}
+
+	return 0;
+}
diff --git a/Makefile.am b/Makefile.am
index 19e84f9..6620981 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,8 +23,10 @@ SUBDIRS = \
 	DAssembler \
 	DistanceEst \
 	KAligner \
+	Layout \
 	Map \
 	MergePaths \
+	Misc \
 	Overlap \
 	ParseAligns \
 	PathOverlap \
diff --git a/Makefile.in b/Makefile.in
index a9a26fa..0e23a00 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -117,8 +117,9 @@ CTAGS = ctags
 CSCOPE = cscope
 DIST_SUBDIRS = bin doc Assembly Common DataLayer FMIndex Graph dialign \
 	Align ABYSS Parallel AdjList Consensus DAssembler DistanceEst \
-	KAligner Map MergePaths Overlap ParseAligns PathOverlap \
-	PopBubbles Scaffold SimpleGraph kmerprint FilterGraph
+	KAligner Layout Map MergePaths Misc Overlap ParseAligns \
+	PathOverlap PopBubbles Scaffold SimpleGraph kmerprint \
+	FilterGraph
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -185,6 +186,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -277,8 +279,10 @@ SUBDIRS = \
 	DAssembler \
 	DistanceEst \
 	KAligner \
+	Layout \
 	Map \
 	MergePaths \
+	Misc \
 	Overlap \
 	ParseAligns \
 	PathOverlap \
diff --git a/Map/Makefile.in b/Map/Makefile.in
index 00ece28..ba5dd10 100644
--- a/Map/Makefile.in
+++ b/Map/Makefile.in
@@ -128,6 +128,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Map/index.cc b/Map/index.cc
index ec041f0..66a3e11 100644
--- a/Map/index.cc
+++ b/Map/index.cc
@@ -23,12 +23,14 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FILE\n"
 "Build an FM-index of FILE and store it in FILE.fm.\n"
 "\n"
+" Options:\n"
+"\n"
 "      --both              build both FAI and FM indexes [default]\n"
 "      --fai               build a FAI index\n"
 "      --fm                build a FM index\n"
diff --git a/Map/map.cc b/Map/map.cc
index 6449aa6..ed67733 100644
--- a/Map/map.cc
+++ b/Map/map.cc
@@ -31,18 +31,22 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... QUERY... TARGET\n"
 "Map the sequences of the files QUERY to those of the file TARGET.\n"
 "The index files TARGET.fai and TARGET.fm will be used if present.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -l, --min-align=N       find matches at least N bp [1]\n"
 "  -j, --threads=N         use N parallel threads [1]\n"
 "  -s, --sample=N          sample the suffix array [1]\n"
 "  -d, --dup               identify and print duplicate sequence\n"
 "                          IDs between QUERY and TARGET\n"
+"      --chastity          discard unchaste reads\n"
+"      --no-chastity       do not discard unchaste reads [default]\n"
 "  -v, --verbose           display verbose output\n"
 "      --help              display this help and exit\n"
 "      --version           output version information and exit\n"
@@ -76,6 +80,8 @@ static const struct option longopts[] = {
 	{ "dup", no_argument, NULL, 'd' },
 	{ "threads", required_argument, NULL, 'j' },
 	{ "verbose", no_argument, NULL, 'v' },
+	{ "chastity", no_argument, &opt::chastityFilter, 1 },
+	{ "no-chastity", no_argument, &opt::chastityFilter, 0 },
 	{ "help", no_argument, NULL, OPT_HELP },
 	{ "version", no_argument, NULL, OPT_VERSION },
 	{ NULL, 0, NULL, 0 }
@@ -228,7 +234,14 @@ static void find(const FastaIndex& faIndex, const FMIndex& fmIndex,
 
 	SAMRecord sam = toSAM(faIndex, fmIndex, rc ? rcm : m, rc,
 			rec.seq.size());
+	if (rec.id[0] == '@') {
+		cerr << PROGRAM ": error: "
+			"the query ID `" << rec.id << "' is invalid since it "
+			"begins with `@'\n";
+		exit(EXIT_FAILURE);
+	}
 	sam.qname = rec.id;
+
 #if SAM_SEQ_QUAL
 	sam.seq = rc ? rcqseq : rec.seq;
 	sam.qual = rec.qual.empty() ? "*" : rec.qual;
@@ -344,6 +357,9 @@ int main(int argc, char** argv)
 		commandLine = ss.str();
 	}
 
+	opt::chastityFilter = false;
+	opt::trimMasked = false;
+
 	bool die = false;
 	for (int c; (c = getopt_long(argc, argv,
 					shortopts, longopts, NULL)) != -1;) {
@@ -458,8 +474,6 @@ int main(int argc, char** argv)
 	} else if (opt::verbose > 0)
 		cerr << "Identifying duplicates.\n";
 
-	opt::chastityFilter = false;
-	opt::trimMasked = false;
 	FastaInterleave fa(argv + optind, argv + argc,
 			FastaReader::FOLD_CASE);
 	find(faIndex, fmIndex, fa);
diff --git a/Map/overlap.cc b/Map/overlap.cc
index b3f856f..5148356 100644
--- a/Map/overlap.cc
+++ b/Map/overlap.cc
@@ -19,6 +19,7 @@
 #include "Uncompress.h"
 #include "Graph/ContigGraph.h"
 #include "Graph/DirectedGraph.h"
+#include "Graph/GraphAlgorithms.h"
 #include "Graph/GraphIO.h"
 #include "Graph/GraphUtil.h"
 #include <algorithm>
@@ -43,7 +44,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FILE\n"
@@ -51,10 +52,14 @@ static const char USAGE_MESSAGE[] =
 "Output is written to standard output. The index files FILE.fai\n"
 "and FILE.fm will be used if present.\n"
 "\n"
-"  -m, --min=N             find matches at least N bp [30]\n"
+" Options:\n"
+"\n"
+"  -m, --min=N             find matches at least N bp [50]\n"
 "  -k, --max=N             find matches less than N bp [inf]\n"
 "  -j, --threads=N         use N parallel threads [1]\n"
 "  -s, --sample=N          sample the suffix array [1]\n"
+"      --tred              remove transitive edges [default]\n"
+"      --no-tred           do not remove transitive edges\n"
 "      --adj             output the results in adj format\n"
 "      --dot             output the results in dot format [default]\n"
 "      --sam             output the results in SAM format\n"
@@ -66,7 +71,7 @@ static const char USAGE_MESSAGE[] =
 
 namespace opt {
 	/** Find matches at least k bp. */
-	static unsigned minOverlap = 30;
+	static unsigned minOverlap = 50;
 
 	/** Find matches less than k bp. */
 	static unsigned maxOverlap = UINT_MAX;
@@ -74,6 +79,9 @@ namespace opt {
 	/** Sample the suffix array. */
 	static unsigned sampleSA;
 
+	/** Remove transitive edges. */
+	static int tred = true;
+
 	/** The number of parallel threads. */
 	static unsigned threads = 1;
 
@@ -97,6 +105,8 @@ static const struct option longopts[] = {
 	{ "min", required_argument, NULL, 'm' },
 	{ "sample", required_argument, NULL, 's' },
 	{ "threads", required_argument, NULL, 'j' },
+	{ "tred", no_argument, &opt::tred, true },
+	{ "no-tred", no_argument, &opt::tred, false },
 	{ "verbose", no_argument, NULL, 'v' },
 	{ "version", no_argument, NULL, OPT_VERSION },
 	{ NULL, 0, NULL, 0 }
@@ -120,8 +130,18 @@ static void addSuffixOverlaps(Graph &g,
 	Distance ep(-fmi.qspan());
 	assert(ep.distance < 0);
 	for (unsigned i = fmi.l; i < fmi.u; ++i) {
-		size_t tstart = fmIndex[i] + 1;
-		V v = find_vertex(faIndex[tstart].get<0>().id, false, g);
+		size_t toffset = fmIndex[i] + 1;
+		FastaIndex::SeqPos seqPos = faIndex[toffset];
+		const FAIRecord& tseq = seqPos.get<0>();
+		size_t tstart = seqPos.get<1>();
+		size_t tend = tstart + fmi.qspan();
+		assert(tend < tseq.size);
+		(void)tend;
+		if (tstart > 0) {
+			// This match is due to an ambiguity code in the target sequence.
+			continue;
+		}
+		V v = find_vertex(tseq.id, false, g);
 #pragma omp critical(g)
 		{
 			pair<E, bool> e = edge(u, v, g);
@@ -157,8 +177,17 @@ static void addPrefixOverlaps(Graph &g,
 	Distance ep(-fmi.qspan());
 	assert(ep.distance < 0);
 	for (unsigned i = fmi.l; i < fmi.u; ++i) {
-		size_t tstart = fmIndex[i];
-		V u = find_vertex(faIndex[tstart].get<0>().id, false, g);
+		size_t toffset = fmIndex[i];
+		FastaIndex::SeqPos seqPos = faIndex[toffset];
+		const FAIRecord& tseq = seqPos.get<0>();
+		size_t tstart = seqPos.get<1>();
+		size_t tend = tstart + fmi.qspan();
+		assert(tstart > 0);
+		if (tend < tseq.size) {
+			// This match is due to an ambiguity code in the target sequence.
+			continue;
+		}
+		V u = find_vertex(tseq.id, false, g);
 #pragma omp critical(g)
 		{
 			pair<E, bool> e = edge(u, v, g);
@@ -454,6 +483,16 @@ int main(int argc, char** argv)
 	if (opt::verbose > 0)
 		printGraphStats(cerr, g);
 
+	// Remove transitive edges.
+	if (opt::tred) {
+		unsigned numTransitive = remove_transitive_edges(g);
+		if (opt::verbose > 0) {
+			cerr << "Removed " << numTransitive
+				<< " transitive edges.\n";
+			printGraphStats(cerr, g);
+		}
+	}
+
 	write_graph(cout, g, PROGRAM, commandLine);
 	cout.flush();
 	assert_good(cout, "stdout");
diff --git a/MergePaths/Makefile.in b/MergePaths/Makefile.in
index 20dbaec..783e2f6 100644
--- a/MergePaths/Makefile.in
+++ b/MergePaths/Makefile.in
@@ -129,6 +129,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/MergePaths/MergeContigs.cpp b/MergePaths/MergeContigs.cpp
index e7ab728..5f1e3e0 100644
--- a/MergePaths/MergeContigs.cpp
+++ b/MergePaths/MergeContigs.cpp
@@ -38,15 +38,20 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FASTA [OVERLAP] PATH\n"
 "Merge paths of contigs to create larger contigs.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA    contigs in FASTA format\n"
 "  OVERLAP  contig overlap graph\n"
 "  PATH     sequences of contig IDs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=KMER_SIZE  k-mer size\n"
 "  -o, --out=FILE        output the merged contigs to FILE [stdout]\n"
 "  -g, --graph=FILE      write the contig overlap graph to FILE\n"
@@ -560,9 +565,8 @@ int main(int argc, char** argv)
 		minCovUsed = numeric_limits<float>::infinity();
 	for (unsigned i = 0; i < contigs.size(); i++) {
 		ContigProperties vp = g[ContigNode(i, false)];
-		if (vp.coverage == 0)
+		if (vp.coverage == 0 || vp.length < opt::k)
 			continue;
-		assert((int)vp.length - opt::k + 1 > 0);
 		float cov = (float)vp.coverage / (vp.length - opt::k + 1);
 		minCov = min(minCov, cov);
 		if (seen[i])
diff --git a/MergePaths/MergePaths.cpp b/MergePaths/MergePaths.cpp
index f73e5e8..09d12ab 100644
--- a/MergePaths/MergePaths.cpp
+++ b/MergePaths/MergePaths.cpp
@@ -42,14 +42,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... LEN PATH\n"
 "Merge sequences of contigs IDs.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  LEN   lengths of the contigs\n"
 "  PATH  sequences of contig IDs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=KMER_SIZE  k-mer size\n"
 "  -s, --seed-length=L   minimum length of a seed contig [0]\n"
 "  -o, --out=FILE        write result to FILE\n"
diff --git a/MergePaths/PathConsensus.cpp b/MergePaths/PathConsensus.cpp
index cbafb7f..dd2d9c2 100644
--- a/MergePaths/PathConsensus.cpp
+++ b/MergePaths/PathConsensus.cpp
@@ -35,17 +35,21 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman and Rong She.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FASTA ADJ PATH\n"
 "Align sequences of ambiguous paths and output a consensus\n"
 "sequence.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA  contigs in FASTA format\n"
 "  ADJ    contig adjacency graph\n"
 "  PATH   paths of these contigs\n"
 "\n"
 " Options:\n"
+"\n"
 "  -k, --kmer=N          k-mer size\n"
 "  -d, --dist-error=N    acceptable error of a distance estimate\n"
 "                        default: 6 bp\n"
diff --git a/Misc/Makefile.am b/Misc/Makefile.am
new file mode 100644
index 0000000..cb7230a
--- /dev/null
+++ b/Misc/Makefile.am
@@ -0,0 +1,12 @@
+if HAVE_GHC
+bin_PROGRAMS = abyss-samtobreak
+endif
+
+abyss_samtobreak_SOURCES = samtobreak.hs
+
+CLEANFILES=*.hi
+
+GHC_FLAGS=-O2
+
+abyss-samtobreak$(EXEEXT): $(abyss_samtobreak_SOURCES)
+	$(GHC) --make $(GHC_FLAGS) -hidir $(dir $@) -odir $(dir $@) -o $@ $^
diff --git a/bin/Makefile.in b/Misc/Makefile.in
similarity index 71%
copy from bin/Makefile.in
copy to Misc/Makefile.in
index 804aaf7..ed34c2c 100644
--- a/bin/Makefile.in
+++ b/Misc/Makefile.in
@@ -49,9 +49,9 @@ POST_INSTALL = :
 NORMAL_UNINSTALL = :
 PRE_UNINSTALL = :
 POST_UNINSTALL = :
-subdir = bin
-DIST_COMMON = $(dist_bin_SCRIPTS) $(dist_noinst_SCRIPTS) \
-	$(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ at HAVE_GHC_TRUE@bin_PROGRAMS = abyss-samtobreak$(EXEEXT)
+subdir = Misc
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -60,37 +60,18 @@ mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
-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__installdirs = "$(DESTDIR)$(bindir)"
-SCRIPTS = $(dist_bin_SCRIPTS) $(dist_noinst_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
+PROGRAMS = $(bin_PROGRAMS)
+am_abyss_samtobreak_OBJECTS =
+abyss_samtobreak_OBJECTS = $(am_abyss_samtobreak_OBJECTS)
+abyss_samtobreak_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(abyss_samtobreak_SOURCES)
+DIST_SOURCES = $(abyss_samtobreak_SOURCES)
 am__can_run_installinfo = \
   case $$AM_UPDATE_INFO_DIR in \
     n|no|NO) false;; \
@@ -121,6 +102,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
@@ -192,22 +174,9 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-dist_bin_SCRIPTS = \
-	abyss-bowtie \
-	abyss-bowtie2 \
-	abyss-bwa \
-	abyss-bwasw \
-	abyss-fatoagp \
-	abyss-kaligner \
-	abyss-pe \
-	abyss-samtoafg
-
-dist_noinst_SCRIPTS = \
-	abyss-adjtodot.pl \
-	abyss-cstont \
-	abyss-fac.pl \
-	abyss-joindist
-
+abyss_samtobreak_SOURCES = samtobreak.hs
+CLEANFILES = *.hi
+GHC_FLAGS = -O2
 all: all-am
 
 .SUFFIXES:
@@ -220,9 +189,9 @@ $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	      exit 1;; \
 	  esac; \
 	done; \
-	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Misc/Makefile'; \
 	$(am__cd) $(top_srcdir) && \
-	  $(AUTOMAKE) --foreign bin/Makefile
+	  $(AUTOMAKE) --foreign Misc/Makefile
 .PRECIOUS: Makefile
 Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 	@case '$?' in \
@@ -241,41 +210,52 @@ $(top_srcdir)/configure:  $(am__configure_deps)
 $(ACLOCAL_M4):  $(am__aclocal_m4_deps)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
-install-dist_binSCRIPTS: $(dist_bin_SCRIPTS)
+install-binPROGRAMS: $(bin_PROGRAMS)
 	@$(NORMAL_INSTALL)
-	@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	@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 \
-	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; 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' \
-	    -e 'h;s|.*|.|' \
-	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
-	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	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; \
-	      if (++n[d] == $(am__install_max)) { \
-		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
-	    else { print "f", d "/" $$4, $$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_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
-	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
-	     } \
+	    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-dist_binSCRIPTS:
+uninstall-binPROGRAMS:
 	@$(NORMAL_UNINSTALL)
-	@list='$(dist_bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
 	files=`for p in $$list; do echo "$$p"; done | \
-	       sed -e 's,.*/,,;$(transform)'`; \
-	dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
+	  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)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
 tags: TAGS
 TAGS:
 
@@ -317,7 +297,7 @@ distdir: $(DISTFILES)
 	done
 check-am: all-am
 check: check-am
-all-am: Makefile $(SCRIPTS)
+all-am: Makefile $(PROGRAMS)
 installdirs:
 	for dir in "$(DESTDIR)$(bindir)"; do \
 	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
@@ -344,6 +324,7 @@ install-strip:
 mostlyclean-generic:
 
 clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
 	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -354,11 +335,11 @@ maintainer-clean-generic:
 	@echo "it deletes files that may require special tools to rebuild."
 clean: clean-am
 
-clean-am: clean-generic mostlyclean-am
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
 
 distclean: distclean-am
 	-rm -f Makefile
-distclean-am: clean-am distclean-generic
+distclean-am: clean-am distclean-compile distclean-generic
 
 dvi: dvi-am
 
@@ -378,7 +359,7 @@ install-dvi: install-dvi-am
 
 install-dvi-am:
 
-install-exec-am: install-dist_binSCRIPTS
+install-exec-am: install-binPROGRAMS
 
 install-html: install-html-am
 
@@ -406,7 +387,7 @@ maintainer-clean-am: distclean-am maintainer-clean-generic
 
 mostlyclean: mostlyclean-am
 
-mostlyclean-am: mostlyclean-generic
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
 
 pdf: pdf-am
 
@@ -416,22 +397,25 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-dist_binSCRIPTS
+uninstall-am: uninstall-binPROGRAMS
 
 .MAKE: install-am install-strip
 
-.PHONY: all all-am check check-am clean clean-generic distclean \
-	distclean-generic distdir dvi dvi-am html html-am info info-am \
-	install install-am install-data install-data-am \
-	install-dist_binSCRIPTS 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 uninstall uninstall-am \
-	uninstall-dist_binSCRIPTS
-
+.PHONY: all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic distclean distclean-compile distclean-generic \
+	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 uninstall uninstall-am uninstall-binPROGRAMS
+
+
+abyss-samtobreak$(EXEEXT): $(abyss_samtobreak_SOURCES)
+	$(GHC) --make $(GHC_FLAGS) -hidir $(dir $@) -odir $(dir $@) -o $@ $^
 
 # 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.
diff --git a/Misc/samtobreak.hs b/Misc/samtobreak.hs
new file mode 100644
index 0000000..b53f66e
--- /dev/null
+++ b/Misc/samtobreak.hs
@@ -0,0 +1,327 @@
+{- Calculate contig and scaffold contiguity and correctness metrics.
+ - Written by Shaun Jackman.
+ -}
+
+import Control.Arrow ((***))
+import Control.Monad (when)
+import Data.Bits ((.&.))
+import Data.ByteString.Char8 (ByteString)
+import qualified Data.ByteString.Char8 as S
+import Data.Char (isDigit)
+import Data.Function (on)
+import Data.List (find, groupBy, intercalate, partition, sort, span)
+import System.Console.GetOpt
+import System.Environment (getArgs)
+import System.Exit (exitFailure, exitSuccess)
+import System.IO.MMap (mmapFileByteString)
+
+-- Return groups of equivalent elements. Unlike Data.List.groupBy,
+-- consecutive pairs of elements are compared, and the relation need
+-- not be transitive.
+groupBy' rel [] = []
+groupBy' rel (x:xs) = (x:ys) : groupBy' rel zs
+	where
+	(ys,zs) = groupByAux x xs
+	groupByAux x0 (x:xs) | rel x0 x = (x:ys, zs)
+		where (ys,zs) = groupByAux x xs
+	groupByAux y xs = ([], xs)
+
+-- Return pairs of elements from a list.
+pairs :: [a] -> [(a, a)]
+pairs [] = []
+pairs (x:y:ys) = (x, y) : pairs ys
+
+-- Parse an integer from a ByteString.
+readS :: ByteString -> Int
+readS s = x where Just (x, _) = S.readInt s
+
+-- Calculate the N50.
+n50 :: [Int] -> Int
+n50 ws = x
+	where
+	Just(x, _) = find ((>= g50) . snd) $ zip xs $ scanl1 (+) xs
+	g50 = sum xs `div` 2
+	xs = sort ws
+
+-- A SAM record.
+-- qname flag rname pos mapq cigar rnext pnext tlen seq qual
+data SAM = SAM {
+	qname :: ByteString,
+	flag :: Int,
+	rname :: ByteString,
+	pos :: Int,
+	mapq :: Int,
+	cigar :: ByteString,
+	--rnext :: ByteString,
+	--pnext :: Int,
+	--tlen :: Int,
+	--qseq :: ByteString,
+	--qual :: ByteString
+	seqLength :: Int
+}
+
+-- Return whether the unmapped flag is set.
+isUnmapped :: SAM -> Bool
+isUnmapped x = flag x .&. 4 /= 0
+
+-- Return whether the reverse complement flag is set.
+isRC :: SAM -> Bool
+isRC x = flag x .&. 16 /= 0
+
+-- Parse the CIGAR string.
+readCigar :: ByteString -> [(Int, Char)]
+readCigar s = map (readS *** S.head) . pairs
+	. S.groupBy ((==) `on` isDigit) $ s
+
+-- Return the left and right soft-clipping.
+getSoftClip :: SAM -> (Int, Int)
+getSoftClip sam = (
+		if snd x == 'S' then fst x else 0,
+		if snd y == 'S' then fst y else 0)
+	where
+	(x, y) = (head xs, last xs)
+	xs = readCigar $ cigar sam
+
+-- Return the sum of the specified CIGAR elements.
+cigarLength :: [Char] -> ByteString -> Int
+cigarLength ops s = sum [n | (n, op) <- readCigar s, op `elem` ops]
+
+-- Return the length of the query alignment.
+qLength :: SAM -> Int
+qLength = cigarLength "IM" . cigar
+
+-- Return the start position of the query alignment oriented to agree
+-- with the target.
+qStart' = fst . getSoftClip
+
+-- Return the end position of the query alignment oriented to agree
+-- with the target.
+qEnd' x = qStart' x + qLength x
+
+-- Return the start position of the query alignment.
+qStart :: SAM -> Int
+qStart x = (if isRC x then snd else fst) $ getSoftClip x
+
+-- Return the end position of the query alignment.
+qEnd :: SAM -> Int
+qEnd x = qStart x + qLength x
+
+-- Return the length of the target alignment.
+tLength :: SAM -> Int
+tLength = cigarLength "DMN" . cigar
+
+-- Return the start of the target alignment.
+tStart :: SAM -> Int
+tStart = pos
+
+-- Return the end position of the target alignment.
+tEnd :: SAM -> Int
+tEnd x = tStart x + tLength x
+
+-- Return the start position of the target alignment oriented to agree
+-- with the query. The coordinate system is [-length, 0).
+tStart' x = if isRC x then 0 - tEnd x else tStart x
+
+-- Return the end position of the target alignment oriented to agree
+-- with the query. The coordinate system is [-length, 0).
+tEnd' x = tStart' x + tLength x
+
+-- Parse a SAM record.
+readSAM :: ByteString -> SAM
+readSAM s = SAM qname (readS flag) rname (readS pos)
+		(readS mapq) cigar lengthQseq
+	where
+	lengthQseq = if S.head qseq == '*'
+		then cigarLength "IMS" cigar
+		else S.length qseq
+	(qname:flag:rname:pos:mapq:cigar:_:_:_:qseq:_) = S.words s
+
+-- Print a SAM record.
+showSAM :: SAM -> String
+showSAM (SAM qname flag rname pos mapq cigar _) = intercalate "\t"
+		[S.unpack qname, show flag, S.unpack rname, show pos,
+			show mapq, S.unpack cigar, "*", "0", "0", "*", "*"]
+
+-- Exclude alignments that overlap a long alignment by 50%.
+excludeOverlaps :: [SAM] -> [SAM]
+excludeOverlaps xs = reverse . foldl accum [] $ xs
+	where accum ys x = if any overlapx ys then ys else x:ys
+		where overlapx y = end - start > (qLength x) `div` 2
+			where
+			start = max (qStart x) (qStart y)
+			end = min (qEnd x) (qEnd y)
+
+{-
+-- Compare the target position.
+compareTStart :: SAM -> SAM -> Ordering
+compareTStart a b = compare (rname a, pos a) (rname b, pos b)
+
+-- Patch gaps in the alignments that are shorter than 500 bp.
+patchGaps :: [SAM] -> [SAM]
+patchGaps ws
+	= (x:) $ map snd . filter (not . isSmallGap) $ zip (x:xs) xs
+	where
+	(x:xs) = sortBy compareTStart ws
+	isSmallGap (q, p) = (rname p, isRC p) == (rname q, isRC q)
+			&& max gapt gapq < 500
+		where
+		gapt = abs (tStart p - tEnd q)
+		gapq = abs (qStart' p - qEnd' q)
+-}
+
+-- Return whether the pair of aligned contigs are colinear.
+isColinear :: SAM -> SAM -> Bool
+isColinear a b = (rname a, isRC a) == (rname b, isRC b)
+	&& tStart' a < tStart' b && tEnd' a < tEnd' b
+
+-- Return pairs of non-colinear alignments.
+filterNonColinear :: [SAM] -> [(SAM, SAM)]
+filterNonColinear xs = filter (not . uncurry isColinear)
+	$ zip xs (tail xs)
+
+-- The command line options.
+data Opt = OptLength Int | OptMapq Int | OptPrint | OptHelp
+	deriving Eq
+options :: [OptDescr Opt]
+options = [
+	Option ['l'] ["length"] (ReqArg (OptLength . read) "N")
+		"exclude contigs shorter than N bp [200]",
+	Option ['q'] ["mapq"] (ReqArg (OptMapq . read) "N")
+		"exclude alignments with mapq less than N [10]",
+	Option ['p'] ["print"] (NoArg OptPrint)
+		"print scaffold breakpoints in SAM format",
+	Option [] ["help"] (NoArg OptHelp)
+		"display this help and exit" ]
+data Options = Options {
+	optLength :: Int,
+	optMapq :: Int,
+	optPrint :: Bool
+}
+defaultOptions = Options {
+	optLength = 200,
+	optMapq = 10,
+	optPrint = False
+}
+
+-- Parse the command line options.
+parseOptions :: [Opt] -> Options
+parseOptions = foldl parseOption defaultOptions
+	where parseOption opt x = case x of
+		OptLength l -> opt { optLength = l }
+		OptMapq q -> opt { optMapq = q }
+		OptPrint -> opt { optPrint = True }
+
+-- Parse the command line arguments.
+parseArgs :: IO (Options, [String])
+parseArgs = do
+	args <- getArgs
+	case getOpt Permute options args of
+		(opts, files, []) -> if OptHelp `elem` opts then help else
+			return (parseOptions opts, files)
+		(_, _, errs) -> error (concat errs ++ tryHelp)
+	where
+	help = putStr (usageInfo usage options) >> exitSuccess
+	tryHelp = "Try 'abyss-samtobreak --help' for more information."
+	usage = "Usage: samtobreak [OPTION]...\n\
+\Calculate contig and scaffold contiguity and correctness metrics.\n"
+
+-- Calculate contig and scaffold contiguity and correctness metrics.
+printStats :: Options -> FilePath -> IO ()
+printStats (Options optLength optMapq optPrint) path = do
+	s <- mmapFileByteString path Nothing
+	when (S.null s) $ error $ "`" ++ path ++ "' is empty"
+
+	let
+		-- Parse the SAM file and discard short contigs.
+		isHeader x = S.head x == '@'
+		(headers, alignments) = span isHeader . S.lines $ s
+		isLong x = seqLength x >= optLength
+		(unmapped, mapped) = partition isUnmapped
+			. filter isLong . map readSAM $ alignments
+
+		-- Exclude overlapping alignments.
+		excluded = map excludeOverlaps
+			. groupBy ((==) `on` qname) $ mapped
+		concatExcluded = concat excluded
+		qLengths = map qLength concatExcluded
+
+		-- Kepp long alignments with high mapping quality.
+		isGood x = mapq x >= optMapq && qLength x >= 500
+		good = filter (not . null) . map (filter isGood) $ excluded
+
+		-- Group contigs into scaffolds by their name.
+		scaffoldName = S.takeWhile (/= '_') . qname
+		oneHit = concat . filter ((== 1) . length) $ good
+		scaffs = groupBy ((==) `on` scaffoldName) $ oneHit
+
+	when optPrint (do
+		-- Print scaffold breakpoints.
+		S.putStr $ S.unlines headers
+		putStr $ concat
+			$ map (\(a, b) -> unlines [showSAM a, showSAM b])
+			$ concatMap filterNonColinear scaffs
+		exitSuccess)
+
+	-- Calculate contig metrics.
+	putStr "Number of unmapped contigs: "
+	print $ length unmapped
+
+	putStr "Total length of unmapped contigs: "
+	print $ sum . map seqLength $ unmapped
+
+	putStr "Number of alignments dropped due to excessive overlaps: "
+	print $ length mapped - length concatExcluded
+
+	putStr "Mapped contig bases: "
+	print $ sum qLengths
+
+	putStr "Mapped N50: "
+	print $ n50 qLengths
+
+	putStr "Number of break points: "
+	print $ length concatExcluded - length excluded
+
+	putStr "Number of Q10 break points longer than 500 bp: "
+	print $ length (concat good) - length good
+
+{-
+	-- Patch small gaps.
+	let
+		patched = map patchGaps excluded
+		concatPatched = concat patched
+
+		patchedGood = map patchGaps good
+		concatPatchedGood = concat patchedGood
+
+	putStr "Number of break points after patching gaps shorter than 500 bp: "
+	print $ length concatPatched - length patched
+
+	putStr "Number of Q10 break points longer than 500 bp after gap patching: "
+	print $ length concatPatchedGood - length patchedGood
+-}
+
+	-- Calculate scaffold metrics.
+	let
+		scaffoldLength = sum . map qLength
+		scaffoldLengths = map scaffoldLength
+		colinearScaffs = concatMap (groupBy' isColinear) scaffs
+
+	putStr "Scaffold N50: "
+	print $ n50 . scaffoldLengths $ scaffs
+
+	putStr "Aligned scaffold N50: "
+	print $ n50 . scaffoldLengths $ colinearScaffs
+
+	putStr "Number of Q10 scaffold breakpoints longer than 500 bp: "
+	print $ length colinearScaffs - length scaffs
+
+-- Calculate contig and scaffold contiguity and correctness metrics.
+main :: IO ()
+main = do
+	(opt, files) <- parseArgs
+	case files of
+		[] -> printStats opt "/dev/stdin"
+		[path] -> printStats opt path
+		otherwise -> mapM_ (\path -> do
+			putStr $ "==> " ++ path ++ " <==\n"
+			printStats opt path) files
diff --git a/Overlap/Makefile.in b/Overlap/Makefile.in
index c24e091..0199f6b 100644
--- a/Overlap/Makefile.in
+++ b/Overlap/Makefile.in
@@ -111,6 +111,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Overlap/Overlap.cpp b/Overlap/Overlap.cpp
index 9695dc2..d4f1303 100644
--- a/Overlap/Overlap.cpp
+++ b/Overlap/Overlap.cpp
@@ -43,13 +43,15 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... CONTIGS ADJ DIST\n"
 "Find overlaps between blunt contigs that have negative distance\n"
 "estimates. Add edges to the overlap graph.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=KMER_SIZE  k-mer size\n"
 "  -m, --min=OVERLAP     require a minimum of OVERLAP bases\n"
 "                        default is 5 bases\n"
diff --git a/Parallel/Makefile.in b/Parallel/Makefile.in
index ecf5dd9..fc1c2f9 100644
--- a/Parallel/Makefile.in
+++ b/Parallel/Makefile.in
@@ -119,6 +119,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Parallel/NetworkSequenceCollection.cpp b/Parallel/NetworkSequenceCollection.cpp
index 9c24d42..e4a39c3 100644
--- a/Parallel/NetworkSequenceCollection.cpp
+++ b/Parallel/NetworkSequenceCollection.cpp
@@ -14,6 +14,11 @@
 
 using namespace std;
 
+// Don't load data into the control process when we have at least
+// DEDICATE_CONTROL_AT total processes. This is needed because the
+// control node uses a lot of memory at large NP.
+const int DEDICATE_CONTROL_AT = 1000;
+
 void NetworkSequenceCollection::loadSequences()
 {
 	Timer timer("LoadSequences");
@@ -431,7 +436,7 @@ void NetworkSequenceCollection::runControl()
 				pumpNetwork();
 				logger(0) << "Loaded " << m_data.size()
 					<< " k-mer.\n";
-				assert(!m_data.empty());
+				assert(!m_data.empty() || opt::numProc >= DEDICATE_CONTROL_AT);
 				m_data.shrink();
 				size_t numLoaded = m_comm.reduce(m_data.size());
 				cout << "Loaded " << numLoaded << " k-mer. "
@@ -1392,5 +1397,9 @@ bool NetworkSequenceCollection::isLocal(const Kmer& seq) const
 /** Return the process ID to which the specified kmer belongs. */
 int NetworkSequenceCollection::computeNodeID(const Kmer& seq) const
 {
-	return seq.getCode() % (unsigned)opt::numProc;
+	if (opt::numProc < DEDICATE_CONTROL_AT) {
+		return seq.getCode() % (unsigned)opt::numProc;
+	} else {
+		return seq.getCode() % (unsigned)(opt::numProc - 1) + 1;
+	}
 }
diff --git a/Parallel/parallelAbyss.cpp b/Parallel/parallelAbyss.cpp
index 45232bd..dbdaced 100644
--- a/Parallel/parallelAbyss.cpp
+++ b/Parallel/parallelAbyss.cpp
@@ -71,6 +71,10 @@ int main(int argc, char** argv)
 	MPI_Comm_rank(MPI_COMM_WORLD, &opt::rank);
 	MPI_Comm_size(MPI_COMM_WORLD, &opt::numProc);
 
+	// OMPI-1.6.1 and later reset the SIGCHLD handler so we need to
+	// reinitialize uncompress.
+	uncompress_init();
+
 	opt::parse(argc, argv);
 	if (opt::rank == 0)
 		cout << "Running on " << opt::numProc << " processors\n";
diff --git a/ParseAligns/Makefile.in b/ParseAligns/Makefile.in
index 565d6c8..f566614 100644
--- a/ParseAligns/Makefile.in
+++ b/ParseAligns/Makefile.in
@@ -112,6 +112,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/ParseAligns/ParseAligns.cpp b/ParseAligns/ParseAligns.cpp
index 327c65e..3d4c446 100644
--- a/ParseAligns/ParseAligns.cpp
+++ b/ParseAligns/ParseAligns.cpp
@@ -30,7 +30,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FILE]...\n"
@@ -38,6 +38,8 @@ static const char USAGE_MESSAGE[] =
 "Write pairs that map to different contigs to standard output.\n"
 "Alignments may be read from FILE(s) or standard input.\n"
 "\n"
+" Options:\n"
+"\n"
 "  -l, --min-align=N     minimum alignment length\n"
 "  -d, --dist=DISTANCE   write distance estimates to this file\n"
 "  -f, --frag=SAME       write fragment sizes to this file\n"
diff --git a/ParseAligns/abyss-fixmate.cc b/ParseAligns/abyss-fixmate.cc
index 1a169cf..c019065 100644
--- a/ParseAligns/abyss-fixmate.cc
+++ b/ParseAligns/abyss-fixmate.cc
@@ -25,7 +25,7 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... [FILE]...\n"
@@ -33,8 +33,11 @@ static const char USAGE_MESSAGE[] =
 "Write read pairs that map to different contigs to stdout.\n"
 "Alignments may be in FILE(s) or standard input.\n"
 "\n"
+" Options:\n"
+"\n"
 "      --no-qname        set the qname to * [default]\n"
 "      --qname           do not alter the qname\n"
+"  -l, --min-align=N     the minimal alignment size [1]\n"
 "  -s, --same=SAME       write properly-paired reads to this file\n"
 "  -h, --hist=FILE       write the fragment size histogram to FILE\n"
 "  -v, --verbose         display verbose output\n"
@@ -50,13 +53,14 @@ namespace opt {
 	static int verbose;
 }
 
-static const char shortopts[] = "h:s:v";
+static const char shortopts[] = "h:l:s:v";
 
 enum { OPT_HELP = 1, OPT_VERSION };
 
 static const struct option longopts[] = {
 	{ "qname",    no_argument,      &opt::qname, 1 },
 	{ "no-qname", no_argument,      &opt::qname, 0 },
+	{ "min-align", required_argument, NULL, 'l' },
 	{ "hist",    required_argument, NULL, 'h' },
 	{ "same",    required_argument, NULL, 's' },
 	{ "verbose", no_argument,       NULL, 'v' },
@@ -90,6 +94,7 @@ static void handlePair(SAMRecord& a0, SAMRecord& a1)
 	if (!opt::qname)
 		a0.qname = a1.qname = "*";
 
+	fixMate(a0, a1);
 	if (a0.isUnmapped() && a1.isUnmapped()) {
 		// Both reads are unaligned.
 		stats.bothUnaligned++;
@@ -99,25 +104,26 @@ static void handlePair(SAMRecord& a0, SAMRecord& a1)
 	} else if (a0.rname != a1.rname) {
 		// Different targets.
 		stats.numDifferent++;
-		fixMate(a0, a1);
 		// Set the mapping quality of both reads to their minimum.
 		a0.mapq = a1.mapq = min(a0.mapq, a1.mapq);
-		cout << a0 << '\n' << a1 << '\n';
+		if (!opt::histPath.empty())
+			cout << a0 << '\n' << a1 << '\n';
 	} else if (a0.isReverse() == a1.isReverse()) {
 		// Same target, FF orientation.
 		stats.numFF++;
 	} else {
 		// Same target, FR or RF orientation.
-		fixMate(a0, a1);
 		g_histogram.insert(a0.isReverse() ? a1.isize : a0.isize);
 		if (!opt::fragPath.empty()) {
 			g_fragFile << a0 << '\n' << a1 << '\n';
 			assert(g_fragFile.good());
-		} else if (opt::histPath.empty()) {
-			cout << a0 << '\n' << a1 << '\n';
-			assert(cout.good());
 		}
 	}
+
+	if (opt::histPath.empty()) {
+		cout << a0 << '\n' << a1 << '\n';
+		assert(cout.good());
+	}
 }
 
 #if SAM_SEQ_QUAL
@@ -182,6 +188,8 @@ static void readAlignments(istream& in, Alignments* pMap)
 			getline(in, line);
 			assert(in);
 			cout << line << '\n';
+			if (!opt::fragPath.empty())
+				g_fragFile << line << '\n';
 		} else if (in >> sam)
 			handleAlignment(sam, *pMap);
 	}
@@ -228,6 +236,9 @@ int main(int argc, char* const* argv)
 		istringstream arg(optarg != NULL ? optarg : "");
 		switch (c) {
 			case '?': die = true; break;
+			case 'l':
+				arg >> opt::minAlign;
+				break;
 			case 's': arg >> opt::fragPath; break;
 			case 'h': arg >> opt::histPath; break;
 			case 'v': opt::verbose++; break;
@@ -268,6 +279,20 @@ int main(int argc, char* const* argv)
 	if (opt::verbose > 0)
 		cerr << "Read " << stats.alignments << " alignments" << endl;
 
+	// Print the unpaired alignments.
+	if (opt::histPath.empty()) {
+		for (Alignments::iterator it = alignments.begin();
+				it != alignments.end(); it++) {
+#if SAM_SEQ_QUAL
+			SAMRecord& a0 = it->second;
+#else
+			SAMRecord a0(it->second, it->first);
+#endif
+			cout << a0 << '\n';
+			assert(cout.good());
+		}
+	}
+
 	unsigned numRF = g_histogram.count(INT_MIN, 0);
 	unsigned numFR = g_histogram.count(1, INT_MAX);
 	size_t sum = alignments.size()
diff --git a/PathOverlap/Makefile.in b/PathOverlap/Makefile.in
index 02818b6..a82b9c1 100644
--- a/PathOverlap/Makefile.in
+++ b/PathOverlap/Makefile.in
@@ -111,6 +111,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/PathOverlap/PathOverlap.cpp b/PathOverlap/PathOverlap.cpp
index dd607d3..25d5ab2 100644
--- a/PathOverlap/PathOverlap.cpp
+++ b/PathOverlap/PathOverlap.cpp
@@ -32,16 +32,21 @@ static const char *VERSION_MESSAGE =
 PROGRAM " (ABySS) " VERSION "\n"
 "Written by Shaun Jackman and Tony Raymond.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char *USAGE_MESSAGE =
 "Usage: " PROGRAM " [OPTION]... ADJ PATH\n"
 "Find paths that overlap. Either output the graph of overlapping\n"
 "paths, assemble overlapping paths into larger paths, or trim the\n"
 "overlapping paths.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  ADJ   contig adjacency graph\n"
 "  PATH  sequences of contig IDs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=N          k-mer size\n"
 "  -g, --graph=FILE      write the contig adjacency graph to FILE\n"
 "  -r, --repeats=FILE    write repeat contigs to FILE\n"
diff --git a/PopBubbles/Makefile.in b/PopBubbles/Makefile.in
index 394bcf6..668592d 100644
--- a/PopBubbles/Makefile.in
+++ b/PopBubbles/Makefile.in
@@ -115,6 +115,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/PopBubbles/PopBubbles.cpp b/PopBubbles/PopBubbles.cpp
index c60e2b4..8f3d8b4 100644
--- a/PopBubbles/PopBubbles.cpp
+++ b/PopBubbles/PopBubbles.cpp
@@ -53,14 +53,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FASTA ADJ\n"
 "Identify and pop simple bubbles.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA  contigs in FASTA format\n"
 "  ADJ    contig adjacency graph\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=N          k-mer size\n"
 "  -a, --branches=N      maximum number of branches, default: 2\n"
 "  -b, --bubble-length=N pop bubbles shorter than N bp\n"
diff --git a/README.html b/README.html
index f3ec08e..6edf1ed 100644
--- a/README.html
+++ b/README.html
@@ -3,11 +3,12 @@
 <head>
 	<meta charset="utf-8"/>
 	<title>ABySS README</title>
-	<meta name="author" content="Shaun Jackman"/>
+	<meta name="author" content="Shaun Jackman, Anthony Raymond"/>
 	<meta name="affiliation" content="Canada's Michael Smith Genome Science Centre"/>
 	<link type="text/css" rel="stylesheet" href="README.css"/>
 </head>
 <body>
+
 <h1 id="abyss">ABySS</h1>
 
 <p>ABySS is a <em>de novo</em> sequence assembler intended for short paired-end
@@ -55,8 +56,10 @@ reads and large genomes.</p>
 
 <h2 id="assembleasmallsyntheticdataset">Assemble a small synthetic data set</h2>
 
-<pre><code>abyss-pe k=25 name=test \
-se=https://raw.github.com/dzerbino/velvet/master/data/test_reads.fa
+<pre><code>wget http://www.bcgsc.ca/platform/bioinfo/software/abyss/releases/1.3.4/test-data.tar.gz
+tar xzvf test-data.tar.gz
+abyss-pe k=25 name=test \
+    in='test-data/reads1.fastq test-data/reads2.fastq'
 </code></pre>
 
 <h2 id="calculateassemblycontiguitystatistics">Calculate assembly contiguity statistics</h2>
@@ -77,6 +80,10 @@ se=https://raw.github.com/dzerbino/velvet/master/data/test_reads.fa
 <p>ABySS requires a C++ compiler that supports
 <a href="http://www.openmp.org">OpenMP</a> such as <a href="http://gcc.gnu.org">GCC</a>.</p>
 
+<p>ABySS will receive an error when compiling with Boost 1.51.0 or 1.52.0
+since they contain a bug. Download an earlier version such as
+<a href="http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2">Boost 1.50.0</a>.</p>
+
 <h1 id="compilingabyssfromsource">Compiling ABySS from source</h1>
 
 <p>To compile and install ABySS in <code>/usr/local</code>:</p>
@@ -333,6 +340,9 @@ manual page for more information on assembly parameters.</p>
 <li><code>abyss-todot</code>: convert graph formats and merge graphs</li>
 </ul>
 
+<p>For a flowchart showing the relationship between these programs,
+see doc/flowchart.pdf.</p>
+
 <h1 id="mailinglist">Mailing List</h1>
 
 <p>Subscribe to the
@@ -350,5 +360,8 @@ manual page for more information on assembly parameters.</p>
 <p>ABySS is written by Shaun Jackman, Tony Raymond and Jared Simpson.</p>
 
 <p>Copyright 2012 Canada’s Michael Smith Genome Science Centre</p>
+
+<p><a href="http://githalytics.com/sjackman/abyss"><img src="https://cruel-carlota.pagodabox.com/af4811df3b40b7d096f6085db2969f0e" alt="githalytics.com" title="githalytics.com" /></a></p>
+
 </body>
 </html>
diff --git a/README.md b/README.md
index 7e7aa85..04317d7 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 Title: ABySS README
-Author: Shaun Jackman
+Author: Shaun Jackman, Anthony Raymond
 Affiliation: Canada's Michael Smith Genome Science Centre
 CSS: README.css
 
@@ -47,8 +47,10 @@ Download and install the
 
 ## Assemble a small synthetic data set
 
+	wget http://www.bcgsc.ca/platform/bioinfo/software/abyss/releases/1.3.4/test-data.tar.gz
+	tar xzvf test-data.tar.gz
 	abyss-pe k=25 name=test \
-	se=https://raw.github.com/dzerbino/velvet/master/data/test_reads.fa
+		in='test-data/reads1.fastq test-data/reads2.fastq'
 
 ## Calculate assembly contiguity statistics
 
@@ -66,6 +68,10 @@ ABySS requires the following libraries:
 ABySS requires a C++ compiler that supports
 [OpenMP](http://www.openmp.org) such as [GCC](http://gcc.gnu.org).
 
+ABySS will receive an error when compiling with Boost 1.51.0 or 1.52.0
+since they contain a bug. Download an earlier version such as
+[Boost 1.50.0](http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2).
+
 Compiling ABySS from source
 ===========================
 
@@ -307,6 +313,9 @@ ABySS programs
  * `abyss-scaffold`: scaffold contigs using distance estimates
  * `abyss-todot`: convert graph formats and merge graphs
 
+For a flowchart showing the relationship between these programs,
+see doc/flowchart.pdf.
+
 Mailing List
 ============
 
@@ -328,3 +337,5 @@ This document is written by Shaun Jackman.
 ABySS is written by Shaun Jackman, Tony Raymond and Jared Simpson.
 
 Copyright 2012 Canada's Michael Smith Genome Science Centre
+
+[![githalytics.com](https://cruel-carlota.pagodabox.com/af4811df3b40b7d096f6085db2969f0e "githalytics.com")](http://githalytics.com/sjackman/abyss)
diff --git a/Scaffold/Makefile.in b/Scaffold/Makefile.in
index ea9e543..664ed86 100644
--- a/Scaffold/Makefile.in
+++ b/Scaffold/Makefile.in
@@ -122,6 +122,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/Scaffold/drawgraph.cc b/Scaffold/drawgraph.cc
index ccce65b..32a18e9 100644
--- a/Scaffold/drawgraph.cc
+++ b/Scaffold/drawgraph.cc
@@ -35,16 +35,21 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FASTA|OVERLAP DIST...\n"
 "Place each contig on a one-dimesional coordinate system using\n"
 "distance estimates and output a DOT graph with coordinates.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA    contigs in FASTA format\n"
 "  OVERLAP  the contig overlap graph\n"
 "  DIST     estimates of the distance between contigs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -x, --xscale=N        set the x scale to N nt/inch [100e3]\n"
 "  -v, --verbose         display verbose output\n"
 "      --help            display this help and exit\n"
diff --git a/Scaffold/junction.cc b/Scaffold/junction.cc
index 6ad417c..d26ef88 100644
--- a/Scaffold/junction.cc
+++ b/Scaffold/junction.cc
@@ -35,14 +35,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... OVERLAP [SCAFFOLD]...\n"
 "Extend junction contigs that are supported by the scaffold graph.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  OVERLAP   the overlap graph\n"
 "  SCAFFOLD  a scaffold graph\n"
 "\n"
+" Options:\n"
+"\n"
 "  -i, --ignore=FILE     ignore junctions seen in FILE\n"
 "  -v, --verbose         display verbose output\n"
 "      --help            display this help and exit\n"
diff --git a/Scaffold/scaffold.cc b/Scaffold/scaffold.cc
index 8bd5102..bd61e20 100644
--- a/Scaffold/scaffold.cc
+++ b/Scaffold/scaffold.cc
@@ -37,15 +37,20 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... FASTA|OVERLAP DIST...\n"
 "Scaffold contigs using the distance estimate graph.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  FASTA    contigs in FASTA format\n"
 "  OVERLAP  the contig overlap graph\n"
 "  DIST     estimates of the distance between contigs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -n, --npairs=N        minimum number of pairs [0]\n"
 "  -s, --seed-length=N   minimum contig length [200]\n"
 "          or -s N0-N1   Find the value of s in [N0,N1]\n"
@@ -107,6 +112,22 @@ static const struct option longopts[] = {
 typedef DirectedGraph<Length, DistanceEst> DG;
 typedef ContigGraph<DG> Graph;
 
+/** Return whether this edge is invalid.
+ * An edge is invalid when the overlap is larger than the length of
+ * either of its incident sequences.
+ */
+struct InvalidEdge {
+	InvalidEdge(Graph& g) : m_g(g) { }
+	bool operator()(graph_traits<Graph>::edge_descriptor e) const
+	{
+		int d = m_g[e].distance;
+		int ulength = m_g[source(e, m_g)].length;
+		int vlength = m_g[target(e, m_g)].length;
+		return d + ulength <= 0 || d + vlength <= 0;
+	}
+	const Graph& m_g;
+};
+
 /** Return whether the specified edges has sufficient support. */
 struct PoorSupport {
 	PoorSupport(Graph& g) : m_g(g) { }
@@ -705,6 +726,14 @@ int main(int argc, char** argv)
 		printGraphStats(cerr, g);
 	}
 
+	// Remove invalid edges.
+	unsigned numBefore = num_edges(g);
+	remove_edge_if(InvalidEdge(g), static_cast<DG&>(g));
+	unsigned numRemoved = numBefore - num_edges(g);
+	if (numRemoved > 0)
+		cerr << "waning: Removed "
+			<< numRemoved << " invalid edges.\n";
+
 	if (opt::minContigLengthEnd == 0) {
 		scaffold(g, opt::minContigLength, true);
 		return 0;
diff --git a/SimpleGraph/Makefile.in b/SimpleGraph/Makefile.in
index 943b645..0073220 100644
--- a/SimpleGraph/Makefile.in
+++ b/SimpleGraph/Makefile.in
@@ -112,6 +112,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/SimpleGraph/SimpleGraph.cpp b/SimpleGraph/SimpleGraph.cpp
index dfe82d9..e8a5118 100644
--- a/SimpleGraph/SimpleGraph.cpp
+++ b/SimpleGraph/SimpleGraph.cpp
@@ -30,14 +30,19 @@ static const char VERSION_MESSAGE[] =
 PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
 "Written by Jared Simpson and Shaun Jackman.\n"
 "\n"
-"Copyright 2012 Canada's Michael Smith Genome Science Centre\n";
+"Copyright 2013 Canada's Michael Smith Genome Science Centre\n";
 
 static const char USAGE_MESSAGE[] =
 "Usage: " PROGRAM " [OPTION]... ADJ DIST\n"
 "Find paths through contigs using distance estimates.\n"
+"\n"
+" Arguments:\n"
+"\n"
 "  ADJ   adjacency of the contigs\n"
 "  DIST  distance estimates between the contigs\n"
 "\n"
+" Options:\n"
+"\n"
 "  -k, --kmer=KMER_SIZE  k-mer size\n"
 "  -d, --dist-error=N    acceptable error of a distance estimate\n"
 "                        default is 6 bp\n"
diff --git a/bin/Makefile.in b/bin/Makefile.in
index 804aaf7..3e6e142 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -121,6 +121,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/bin/abyss-pe b/bin/abyss-pe
index c46b785..82f3f93 100755
--- a/bin/abyss-pe
+++ b/bin/abyss-pe
@@ -159,11 +159,10 @@ mapopt=$v -j$j -l$($*_l) $(ALIGNER_OPTIONS) $(MAP_OPTIONS)
 # fixmate parameters
 ifeq ($(align),abyss-kaligner)
 fixmate?=ParseAligns
-fmopt=$v -l$($*_l) $(FIXMATE_OPTIONS)
 else
 fixmate?=abyss-fixmate
-fmopt=$v $(FIXMATE_OPTIONS)
 endif
+fmopt=$v -l$($*_l) $(FIXMATE_OPTIONS)
 
 # DistanceEst parameters
 l?=$k
@@ -191,6 +190,10 @@ pcopt += -p$p
 S?=$s
 N?=$n
 
+# BWA-SW parameters
+bwaswopt=-t$j
+BWASW_OPTIONS='-b9 -q16 -r1 -w500'
+
 # Remove environment variables
 unexport in se $(lib) $(pe) $(mp)
 
@@ -231,7 +234,7 @@ Report bugs to <abyss-users at bcgsc.ca>.\n'
 
 version:
 	@printf '\
-abyss-pe (ABySS) 1.3.4\n\
+abyss-pe (ABySS) 1.3.5\n\
 Written by Shaun Jackman.\n\
 \n\
 Copyright 2012 Canada'\''s Michael Smith Genome Science Centre\n'
@@ -475,19 +478,23 @@ endif
 
 # Scaffold
 
-%-6.path1: $(name)-6.dot $(addsuffix -6.dist.dot, $(mp))
+%-6.path: $(name)-6.dot $(addsuffix -6.dist.dot, $(mp))
 	abyss-scaffold $v -k$k -s$S -n$N -g $@.dot $(SCAFFOLD_OPTIONS) $^ >$@
 
-%-6.path2: %-6.fa %-6.dot %-6.path1
-	PathConsensus $v -k$k -p1 -s /dev/null -o $@ $^
+%-7.path %-7.adj %-7.fa: %-6.fa %-6.dot %-6.path
+	PathConsensus $v -k$k $(pcopt) -s $*-7.fa -g $*-7.adj -o $*-7.path $^
 
-%-7.fa %-7.dot: %-6.fa %-6.dot %-6.path2
-	MergeContigs $v -k$k -o $*-7.fa -g $*-7.dot $^
+%-8.fa: %-6.fa %-7.fa %-7.adj %-7.path
+	cat $(wordlist 1, 2, $^) \
+		|MergeContigs $v -k$k -o $*-8.fa - $(wordlist 3, 4, $^)
+
+%-8.dot: %-7.adj %-7.path
+	PathOverlap --overlap $v --dot -k$k $^ >$@
 
-%-scaffolds.fa: %-7.fa
+%-scaffolds.fa: %-8.fa
 	ln -sf $< $@
 
-%-scaffolds.dot: %-7.dot
+%-scaffolds.dot: %-8.dot
 	ln -sf $< $@
 
 # Create the final BAM file
@@ -550,9 +557,9 @@ $(name)-stats:
 # Align the contigs to the reference
 
 %-$(ref).sam.gz: %.fa
-	bwa bwasw -t$j $(BWASW_OPTIONS) $($(ref)) $< |gzip >$@
+	bwa bwasw $(bwaswopt) $(BWASW_OPTIONS) $($(ref)) $< |gzip >$@
 
 # Find breakpoints in the alignments
 
 %.break: %.sam.gz
-	sam2break $(SAM2BREAK_OPTIONS) $< >$@
+	abyss-samtobreak $(SAMTOBREAK_OPTIONS) $< >$@
diff --git a/configure b/configure
index 7b12f18..0698b28 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ABySS 1.3.4.
+# Generated by GNU Autoconf 2.69 for ABySS 1.3.5.
 #
 # Report bugs to <abyss-users at bcgsc.ca>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ABySS'
 PACKAGE_TARNAME='abyss'
-PACKAGE_VERSION='1.3.4'
-PACKAGE_STRING='ABySS 1.3.4'
+PACKAGE_VERSION='1.3.5'
+PACKAGE_STRING='ABySS 1.3.5'
 PACKAGE_BUGREPORT='abyss-users at bcgsc.ca'
 PACKAGE_URL='http://www.bcgsc.ca/platform/bioinfo/software/abyss'
 
@@ -634,6 +634,9 @@ HAVE_LIBMPI_TRUE
 LIBOBJS
 EGREP
 GREP
+HAVE_GHC_FALSE
+HAVE_GHC_TRUE
+GHC
 RANLIB
 am__fastdepCXX_FALSE
 am__fastdepCXX_TRUE
@@ -1287,7 +1290,7 @@ 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 ABySS 1.3.4 to adapt to many kinds of systems.
+\`configure' configures ABySS 1.3.5 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1353,7 +1356,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ABySS 1.3.4:";;
+     short | recursive ) echo "Configuration of ABySS 1.3.5:";;
    esac
   cat <<\_ACEOF
 
@@ -1461,7 +1464,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ABySS configure 1.3.4
+ABySS configure 1.3.5
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2272,7 +2275,7 @@ 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 ABySS $as_me 1.3.4, which was
+It was created by ABySS $as_me 1.3.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3102,7 +3105,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='abyss'
- VERSION='1.3.4'
+ VERSION='1.3.5'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4784,6 +4787,106 @@ else
   RANLIB="$ac_cv_prog_RANLIB"
 fi
 
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ghc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ghc; 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_GHC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$GHC"; then
+  ac_cv_prog_GHC="$GHC" # 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_GHC="${ac_tool_prefix}ghc"
+    $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
+GHC=$ac_cv_prog_GHC
+if test -n "$GHC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GHC" >&5
+$as_echo "$GHC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_GHC"; then
+  ac_ct_GHC=$GHC
+  # Extract the first word of "ghc", so it can be a program name with args.
+set dummy ghc; 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_GHC+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_GHC"; then
+  ac_cv_prog_ac_ct_GHC="$ac_ct_GHC" # 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_GHC="ghc"
+    $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_GHC=$ac_cv_prog_ac_ct_GHC
+if test -n "$ac_ct_GHC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_GHC" >&5
+$as_echo "$ac_ct_GHC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_GHC" = x; then
+    GHC=""
+  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
+    GHC=$ac_ct_GHC
+  fi
+else
+  GHC="$ac_cv_prog_GHC"
+fi
+
+ if test "$GHC"; then
+  HAVE_GHC_TRUE=
+  HAVE_GHC_FALSE='#'
+else
+  HAVE_GHC_TRUE='#'
+  HAVE_GHC_FALSE=
+fi
+
 
 # Checks for header files.
 
@@ -6968,9 +7071,9 @@ if test $ac_cv_header_boost_property_map_property_map_hpp != yes; then
 	be downloaded from here: http://www.boost.org/users/download/
 	It is not necessary to compile Boost before installing it. The
 	following commands will download and install Boost for ABySS:
-	wget http://downloads.sourceforge.net/project/boost/boost/1.49.0/boost_1_49_0.tar.bz2
-	tar jxf boost_1_49_0.tar.bz2
-	ln -s boost_1_49_0/boost boost
+	wget http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2
+	tar jxf boost_1_50_0.tar.bz2
+	ln -s boost_1_50_0/boost boost
 	" "$LINENO" 5
 fi
 
@@ -7049,7 +7152,7 @@ fi
 AM_CXXFLAGS='-Wall -Wextra -Werror'
 
 
-ac_config_files="$ac_config_files Makefile ABYSS/Makefile Align/Makefile Assembly/Makefile Common/Makefile DataLayer/Makefile FMIndex/Makefile Graph/Makefile Parallel/Makefile bin/Makefile doc/Makefile dialign/Makefile kmerprint/Makefile AdjList/Makefile DAssembler/Makefile DistanceEst/Makefile Map/Makefile Overlap/Makefile PopBubbles/Makefile Scaffold/Makefile SimpleGraph/Makefile MergePaths/Makefile KAligner/Makefile ParseAligns/Makefile PathOverlap/Makefile Consensus/Makefile FilterGr [...]
+ac_config_files="$ac_config_files Makefile ABYSS/Makefile Align/Makefile Assembly/Makefile Common/Makefile DataLayer/Makefile FMIndex/Makefile Graph/Makefile Parallel/Makefile bin/Makefile doc/Makefile dialign/Makefile kmerprint/Makefile AdjList/Makefile DAssembler/Makefile DistanceEst/Makefile Layout/Makefile Map/Makefile Misc/Makefile Overlap/Makefile PopBubbles/Makefile Scaffold/Makefile SimpleGraph/Makefile MergePaths/Makefile KAligner/Makefile ParseAligns/Makefile PathOverlap/Makefi [...]
 
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
@@ -7188,6 +7291,10 @@ 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_GHC_TRUE}" && test -z "${HAVE_GHC_FALSE}"; then
+  as_fn_error $? "conditional \"HAVE_GHC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
 
 if test -z "${HAVE_LIBMPI_TRUE}" && test -z "${HAVE_LIBMPI_FALSE}"; then
   as_fn_error $? "conditional \"HAVE_LIBMPI\" was never defined.
@@ -7590,7 +7697,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ABySS $as_me 1.3.4, which was
+This file was extended by ABySS $as_me 1.3.5, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7657,7 +7764,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ABySS config.status 1.3.4
+ABySS config.status 1.3.5
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -7804,7 +7911,9 @@ do
     "AdjList/Makefile") CONFIG_FILES="$CONFIG_FILES AdjList/Makefile" ;;
     "DAssembler/Makefile") CONFIG_FILES="$CONFIG_FILES DAssembler/Makefile" ;;
     "DistanceEst/Makefile") CONFIG_FILES="$CONFIG_FILES DistanceEst/Makefile" ;;
+    "Layout/Makefile") CONFIG_FILES="$CONFIG_FILES Layout/Makefile" ;;
     "Map/Makefile") CONFIG_FILES="$CONFIG_FILES Map/Makefile" ;;
+    "Misc/Makefile") CONFIG_FILES="$CONFIG_FILES Misc/Makefile" ;;
     "Overlap/Makefile") CONFIG_FILES="$CONFIG_FILES Overlap/Makefile" ;;
     "PopBubbles/Makefile") CONFIG_FILES="$CONFIG_FILES PopBubbles/Makefile" ;;
     "Scaffold/Makefile") CONFIG_FILES="$CONFIG_FILES Scaffold/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index dfbd3aa..16b9d55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.59)
-AC_INIT(ABySS, 1.3.4, abyss-users at bcgsc.ca, abyss,
+AC_INIT(ABySS, 1.3.5, abyss-users at bcgsc.ca, abyss,
 		http://www.bcgsc.ca/platform/bioinfo/software/abyss)
 AM_INIT_AUTOMAKE(foreign)
 AC_CONFIG_SRCDIR([ABYSS/Abyss.cpp])
@@ -12,6 +12,8 @@ AC_PROG_CPP
 AC_PROG_CXX
 AC_PROG_INSTALL
 AC_PROG_RANLIB
+AC_CHECK_TOOL(GHC, ghc)
+AM_CONDITIONAL([HAVE_GHC], [test "$GHC"])
 
 # Checks for header files.
 AC_CHECK_HEADERS([dlfcn.h fcntl.h float.h limits.h \
@@ -149,9 +151,9 @@ if test $ac_cv_header_boost_property_map_property_map_hpp != yes; then
 	be downloaded from here: http://www.boost.org/users/download/
 	It is not necessary to compile Boost before installing it. The
 	following commands will download and install Boost for ABySS:
-	wget http://downloads.sourceforge.net/project/boost/boost/1.49.0/boost_1_49_0.tar.bz2
-	tar jxf boost_1_49_0.tar.bz2
-	ln -s boost_1_49_0/boost boost
+	wget http://downloads.sourceforge.net/project/boost/boost/1.50.0/boost_1_50_0.tar.bz2
+	tar jxf boost_1_50_0.tar.bz2
+	ln -s boost_1_50_0/boost boost
 	])
 fi
 
@@ -181,7 +183,9 @@ AC_CONFIG_FILES([
 	AdjList/Makefile
 	DAssembler/Makefile
 	DistanceEst/Makefile
+	Layout/Makefile
 	Map/Makefile
+	Misc/Makefile
 	Overlap/Makefile
 	PopBubbles/Makefile
 	Scaffold/Makefile
diff --git a/depcomp b/depcomp
index df8eea7..debb6ff 100755
--- a/depcomp
+++ b/depcomp
@@ -1,10 +1,9 @@
 #! /bin/sh
 # depcomp - compile a program generating dependencies as side-effects
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2012-03-27.16; # UTC
 
-# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
-# Software Foundation, Inc.
+# Copyright (C) 1999-2012 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
@@ -28,7 +27,7 @@ scriptversion=2009-04-28.21; # UTC
 
 case $1 in
   '')
-     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     echo "$0: No command.  Try '$0 --help' for more information." 1>&2
      exit 1;
      ;;
   -h | --h*)
@@ -40,11 +39,11 @@ as side-effects.
 
 Environment variables:
   depmode     Dependency tracking mode.
-  source      Source file read by `PROGRAMS ARGS'.
-  object      Object file output by `PROGRAMS ARGS'.
+  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.
+  tmpdepfile  Temporary file to use when outputting dependencies.
   libtool     Whether libtool is used (yes/no).
 
 Report bugs to <bug-automake at gnu.org>.
@@ -57,6 +56,12 @@ EOF
     ;;
 esac
 
+# A tabulation character.
+tab='	'
+# A newline character.
+nl='
+'
+
 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
@@ -90,10 +95,24 @@ 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"
+   cygpath_u='sed s,\\\\,/,g'
    depmode=msvisualcpp
 fi
 
+if test "$depmode" = msvc7msys; then
+   # This is just like msvc7 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=msvc7
+fi
+
+if test "$depmode" = xlc; then
+   # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency informations.
+   gccflag=-qmakedep=gcc,-MF
+   depmode=gcc
+fi
+
 case "$depmode" in
 gcc3)
 ## gcc 3 implements dependency tracking that does exactly what
@@ -148,20 +167,21 @@ gcc)
 ## 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.
+## 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
+  tr ' ' "$nl" < "$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.
+## well.  hp depmode also adds that space, but also prefixes the VPATH
+## to the object.  Take care to not repeat it in the output.
 ## 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"
+    sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \
+      | sed -e 's/$/ :/' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -193,18 +213,15 @@ sgi)
     # 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
+    # the IRIX cc adds comments like '#:fec' to the end of the
     # dependency line.
-    tr ' ' '
-' < "$tmpdepfile" \
+    tr ' ' "$nl" < "$tmpdepfile" \
     | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
-    tr '
-' ' ' >> "$depfile"
+    tr "$nl" ' ' >> "$depfile"
     echo >> "$depfile"
 
     # The second pass generates a dummy entry for each header file.
-    tr ' ' '
-' < "$tmpdepfile" \
+    tr ' ' "$nl" < "$tmpdepfile" \
    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
    >> "$depfile"
   else
@@ -216,10 +233,17 @@ sgi)
   rm -f "$tmpdepfile"
   ;;
 
+xlc)
+  # 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
+  ;;
+
 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
+  # 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|/[^/]*$|/|'`
@@ -249,12 +273,11 @@ aix)
     test -f "$tmpdepfile" && break
   done
   if test -f "$tmpdepfile"; then
-    # Each line is of the form `foo.o: dependent.h'.
+    # 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:'.
+    # '$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"
+    sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -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
@@ -265,23 +288,26 @@ aix)
   ;;
 
 icc)
-  # Intel's C compiler understands `-MD -MF file'.  However on
-  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # Intel's C compiler anf tcc (Tiny C Compiler) understand '-MD -MF file'.
+  # However on
+  #    $CC -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:
+  # 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 \ :
+  # and will wrap long lines using '\':
   #    foo.o: sub/foo.c ... \
   #     sub/foo.h ... \
   #     ...
-
+  # tcc 0.9.26 (FIXME still under development at the moment of writing)
+  # will emit a similar output, but also prepend the continuation lines
+  # with horizontal tabulation characters.
   "$@" -MD -MF "$tmpdepfile"
   stat=$?
   if test $stat -eq 0; then :
@@ -290,15 +316,21 @@ icc)
     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 \'.
+  # 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"
+  # '$object: dependent.h' and one to simply 'dependent.h:'.
+  sed -e "s/^[ $tab][ $tab]*/  /" -e "s,^[^:]*:,$object :," \
+    < "$tmpdepfile" > "$depfile"
+  sed '
+    s/[ '"$tab"'][ '"$tab"']*/ /g
+    s/^ *//
+    s/ *\\*$//
+    s/^[^:]*: *//
+    /^$/d
+    /:$/d
+    s/$/ :/
+  ' < "$tmpdepfile" >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
 
@@ -334,7 +366,7 @@ hp2)
   done
   if test -f "$tmpdepfile"; then
     sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
-    # Add `dependent.h:' lines.
+    # Add 'dependent.h:' lines.
     sed -ne '2,${
 	       s/^ *//
 	       s/ \\*$//
@@ -349,9 +381,9 @@ hp2)
 
 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'.
+   # 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.
+   # 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=
@@ -397,14 +429,59 @@ tru64)
    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"
+      sed -e 's,^.*\.[a-z]*:['"$tab"' ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
    else
       echo "#dummy" > "$depfile"
    fi
    rm -f "$tmpdepfile"
    ;;
 
+msvc7)
+  if test "$libtool" = yes; then
+    showIncludes=-Wc,-showIncludes
+  else
+    showIncludes=-showIncludes
+  fi
+  "$@" $showIncludes > "$tmpdepfile"
+  stat=$?
+  grep -v '^Note: including file: ' "$tmpdepfile"
+  if test "$stat" = 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  # The first sed program below extracts the file names and escapes
+  # backslashes for cygpath.  The second sed program outputs the file
+  # name when reading, but also accumulates all include files in the
+  # hold buffer in order to output them again at the end.  This only
+  # works with sed implementations that can handle large buffers.
+  sed < "$tmpdepfile" -n '
+/^Note: including file:  *\(.*\)/ {
+  s//\1/
+  s/\\/\\\\/g
+  p
+}' | $cygpath_u | sort -u | sed -n '
+s/ /\\ /g
+s/\(.*\)/'"$tab"'\1 \\/p
+s/.\(.*\) \\/\1:/
+H
+$ {
+  s/.*/'"$tab"'/
+  G
+  p
+}' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvc7msys)
+  # 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
+  ;;
+
 #nosideeffect)
   # This comment above is used by automake to tell side-effect
   # dependency tracking mechanisms from slower ones.
@@ -422,7 +499,7 @@ dashmstdout)
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -442,15 +519,14 @@ dashmstdout)
   done
 
   test -z "$dashmflag" && dashmflag=-M
-  # Require at least two characters before searching for `:'
+  # 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.
+  # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise.
   "$@" $dashmflag |
-    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+    sed 's:^['"$tab"' ]*[^:'"$tab"' ][^:][^:]*\:['"$tab"' ]*:'"$object"'\: :' > "$tmpdepfile"
   rm -f "$depfile"
   cat < "$tmpdepfile" > "$depfile"
-  tr ' ' '
-' < "$tmpdepfile" | \
+  tr ' ' "$nl" < "$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"
@@ -503,9 +579,10 @@ makedepend)
   touch "$tmpdepfile"
   ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
   rm -f "$depfile"
-  cat < "$tmpdepfile" > "$depfile"
-  sed '1,2d' "$tmpdepfile" | tr ' ' '
-' | \
+  # makedepend may prepend the VPATH from the source file name to the object.
+  # No need to regex-escape $object, excess matching of '.' is harmless.
+  sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' "$nl" | \
 ## 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"
@@ -525,7 +602,7 @@ cpp)
     shift
   fi
 
-  # Remove `-o $object'.
+  # Remove '-o $object'.
   IFS=" "
   for arg
   do
@@ -594,8 +671,8 @@ msvisualcpp)
   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::'"$tab"'\1 \\:p' >> "$depfile"
+  echo "$tab" >> "$depfile"
   sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
   rm -f "$tmpdepfile"
   ;;
diff --git a/dialign/Makefile.in b/dialign/Makefile.in
index 63c451c..e43e67c 100644
--- a/dialign/Makefile.in
+++ b/dialign/Makefile.in
@@ -117,6 +117,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/doc/ABYSS.1 b/doc/ABYSS.1
index d9c26eb..8136ad4 100644
--- a/doc/ABYSS.1
+++ b/doc/ABYSS.1
@@ -1,4 +1,4 @@
-.TH ABYSS "1" "2012-May" "ABYSS (ABySS) 1.3.4" "User Commands"
+.TH ABYSS "1" "2013-Mar" "ABYSS (ABySS) 1.3.5" "User Commands"
 .SH NAME
 ABYSS \- assemble short reads into contigs
 .SH SYNOPSIS
@@ -8,6 +8,14 @@ ABYSS \- assemble short reads into contigs
 Assemble all input files, FILE, which may be in FASTA, FASTQ, qseq,
 export, SRA, SAM or BAM format and may be compressed with gz, bz2 or
 xz and may be tarred.
+
+Users wishing to run a full assembly with ABySS are recommended to
+use abyss-pe as their entry point rather than the ABYSS program.
+abyss-pe is a Makefile that coordinates many of the ABySS tools
+(including ABYSS) in order to run the full ABySS assembly pipeline.
+abyss-pe is capable of doing many things that ABYSS is not,
+such as leveraging the distance information provided by paired end
+reads and mate pair reads.
 .TP
 \fB--chastity\fR
 discard unchaste reads [default]
@@ -83,4 +91,4 @@ Written by Jared Simpson and Shaun Jackman.
 .SH "REPORTING BUGS"
 Report bugs to <abyss-users at bcgsc.ca>.
 .SH COPYRIGHT
-Copyright 2012 Canada's Michael Smith Genome Science Centre
+Copyright 2013 Canada's Michael Smith Genome Science Centre
diff --git a/doc/Makefile.in b/doc/Makefile.in
index 1831227..586d129 100644
--- a/doc/Makefile.in
+++ b/doc/Makefile.in
@@ -124,6 +124,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/doc/abyss-pe.1 b/doc/abyss-pe.1
index 424ef36..42c76cc 100644
--- a/doc/abyss-pe.1
+++ b/doc/abyss-pe.1
@@ -1,9 +1,9 @@
-.TH abyss-pe "1" "2012-May" "abyss-pe (ABySS) 1.3.4" "User Commands"
+.TH abyss-pe "1" "2013-Mar" "abyss-pe (ABySS) 1.3.5" "User Commands"
 .SH NAME
 abyss-pe - assemble reads into contigs
 .SH SYNOPSIS
 .B abyss-pe
-[\fIOPTION\fR]...  [\fIPARAMETER\fR=\fIVALUE\fR]...
+[\fIOPTION\fR]...  [\fIPARAMETER\fR=\fIVALUE\fR]...  [\fIMAKE_TARGET\fR]...
 .SH DESCRIPTION
 Assemble the reads of the input files into contigs. The reads may be
 in FASTA, FASTQ, qseq, export, SRA, SAM or BAM format and may be
@@ -23,9 +23,11 @@ input files. Use this variable when assembling data from a single
 library.
 .TP
 .B lib
-list of paired-end libraries. Use this varible when assembling data
-from multiple fragment libraries. For each library in lib, a variable
-with the same name must specify the files containing those reads.
+a quoted list of whitespace-separated paired-end library names. Use
+this varible when assembling data from multiple paired-end libraries.
+For each library name in lib, the user must define a variable on
+the command line with the same name, which indicates the read files for
+that library. See \fBEXAMPLES\fR below for a concrete example of usage.
 .TP
 .B pe
 list of paired-end libraries that will be used only for merging
@@ -115,7 +117,7 @@ convert colour-space contigs to nucleotide contigs following assembly
 .TP
 \fB-n\fR, \fB--dry-run\fR
 Print the commands that would be executed, but do not execute them.
-.SS "Commands of abyss-pe"
+.SS "Make targets for abyss-pe"
 .TP
 .B default
 Equivalent to `scaffolds scaffolds-dot stats'.
@@ -221,4 +223,4 @@ Written by Shaun Jackman.
 .SH "REPORTING BUGS"
 Report bugs to <abyss-users at googlegroups.com>.
 .SH COPYRIGHT
-Copyright 2012 Canada's Michael Smith Genome Science Centre
+Copyright 2013 Canada's Michael Smith Genome Science Centre
diff --git a/doc/abyss-tofastq.1 b/doc/abyss-tofastq.1
index 97cbb27..6e8ecb2 100644
--- a/doc/abyss-tofastq.1
+++ b/doc/abyss-tofastq.1
@@ -1,4 +1,4 @@
-.TH abyss-tofastq "1" "2012-May" "ABySS 1.3.4" "User Commands"
+.TH abyss-tofastq "1" "2013-Mar" "ABySS 1.3.5" "User Commands"
 .SH NAME
 abyss-tofastq \- convert various file formats to FASTQ format
 .br
@@ -18,4 +18,4 @@ Written by Shaun Jackman.
 .SH "REPORTING BUGS"
 Report bugs to <abyss-users at bcgsc.ca>.
 .SH COPYRIGHT
-Copyright 2012 Canada's Michael Smith Genome Science Centre
+Copyright 2013 Canada's Michael Smith Genome Science Centre
diff --git a/doc/flowchart.pdf b/doc/flowchart.pdf
index 1dac27f..a59c16c 100644
Binary files a/doc/flowchart.pdf and b/doc/flowchart.pdf differ
diff --git a/install-sh b/install-sh
index 6781b98..377bb86 100755
--- a/install-sh
+++ b/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2011-11-20.07; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -35,7 +35,7 @@ scriptversion=2009-04-28.21; # UTC
 # 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
+# '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
@@ -156,6 +156,10 @@ while test $# -ne 0; do
     -s) stripcmd=$stripprog;;
 
     -t) dst_arg=$2
+	# Protect names problematic for 'test' and other utilities.
+	case $dst_arg in
+	  -* | [=\(\)!]) dst_arg=./$dst_arg;;
+	esac
 	shift;;
 
     -T) no_target_directory=true;;
@@ -186,6 +190,10 @@ if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
     fi
     shift # arg
     dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
   done
 fi
 
@@ -194,13 +202,17 @@ if test $# -eq 0; then
     echo "$0: no input file specified." >&2
     exit 1
   fi
-  # It's OK to call `install-sh -d' without argument.
+  # 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
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15
 
   # Set umask so as not to create temps with too-generous modes.
   # However, 'strip' requires both read and write access to temps.
@@ -228,9 +240,9 @@ fi
 
 for src
 do
-  # Protect names starting with `-'.
+  # Protect names problematic for 'test' and other utilities.
   case $src in
-    -*) src=./$src;;
+    -* | [=\(\)!]) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -252,12 +264,7 @@ do
       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.
@@ -347,7 +354,7 @@ do
 	      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.
+		   # other-writable 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
@@ -385,7 +392,7 @@ do
 
       case $dstdir in
 	/*) prefix='/';;
-	-*) prefix='./';;
+	[-=\(\)!]*) prefix='./';;
 	*)  prefix='';;
       esac
 
@@ -403,7 +410,7 @@ do
 
       for d
       do
-	test -z "$d" && continue
+	test X"$d" = X && continue
 
 	prefix=$prefix$d
 	if test -d "$prefix"; then
diff --git a/kmerprint/Makefile.in b/kmerprint/Makefile.in
index 931e79f..95a81fb 100644
--- a/kmerprint/Makefile.in
+++ b/kmerprint/Makefile.in
@@ -109,6 +109,7 @@ ECHO_N = @ECHO_N@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
+GHC = @GHC@
 GREP = @GREP@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
diff --git a/kmerprint/kmerprint.cc b/kmerprint/kmerprint.cc
index b0038de..243f0b1 100644
--- a/kmerprint/kmerprint.cc
+++ b/kmerprint/kmerprint.cc
@@ -3,6 +3,7 @@
  * Written by Shaun Jackman <sjackman at bcgsc.ca>.
  */
 
+#include "Sequence.h"
 #include "SequenceCollection.h"
 #include "Uncompress.h"
 #include <algorithm>
@@ -15,44 +16,71 @@ using namespace std;
 
 #define PROGRAM "kmerprint"
 
+static const char VERSION_MESSAGE[] =
+PROGRAM " (" PACKAGE_NAME ") " VERSION "\n"
+"Written by Shaun Jackman.\n"
+"\n"
+"Copyright 2013 Shaun Jackman\n";
+
+static const char USAGE_MESSAGE[] =
+"Usage: " PROGRAM " [OPTION]... GRAPH...\n"
+"Convert a binary de Bruijn graph to plain text.\n"
+"\n"
+" Arguments:\n"
+"\n"
+"  GRAPH  the binary de Bruijn graph\n"
+"\n"
+" Options:\n"
+"\n"
+"  -k, --kmer=N          length of a k-mer\n"
+"      --ray             output in Ray Cloud Browser format\n"
+"      --tsv             output in TSV format [default]\n"
+"      --help            display this help and exit\n"
+"      --version         output version information and exit\n"
+"\n"
+"Report bugs to <" PACKAGE_BUGREPORT ">.\n";
+
 namespace opt {
 	static unsigned k;
 	static bool strands;
-	static bool sequence;
-	static bool adj;
+
+	/** The output field separator character. */
+	static int ofsInt = '\t';
+	static char ofs;
 }
 
+static const char shortopts[] = "k:";
+
+enum { OPT_HELP = 1, OPT_VERSION };
+
 static const struct option longopts[] = {
-	{ "kmer",    required_argument, NULL, 'k' },
+	{ "kmer", required_argument, NULL, 'k' },
+	{ "ray", no_argument, &opt::ofsInt, ';' },
+	{ "tsv", no_argument, &opt::ofsInt, '\t' },
+	{ "help", no_argument, NULL, OPT_HELP },
+	{ "version", no_argument, NULL, OPT_VERSION },
+	{ NULL, 0, NULL, 0 }
 };
 
-static const char shortopts[] = "k:";
-
 static void print(const SequenceCollectionHash::value_type& seq)
 {
 	const KmerData& data = seq.second;
-	if (opt::sequence)
-		cout << seq.first.str() << '\t';
-	if (opt::adj)
-		cout << data.getExtension(SENSE) << '\t'
-			<< data.getExtension(ANTISENSE) << '\t';
-	cout << data.getMultiplicity() << '\n';
+	cout << seq.first.str()
+		<< opt::ofs << data.getMultiplicity()
+		<< opt::ofs << data.getExtension(SENSE)
+		<< opt::ofs << data.getExtension(ANTISENSE)
+		<< '\n';
 }
 
 static void print(const SequenceCollectionHash::value_type& seq,
 		extDirection sense)
 {
 	const KmerData& data = seq.second;
-	if (opt::sequence) {
-		if (sense)
-			cout << reverseComplement(seq.first).str();
-		else
-			cout << seq.first.str();
-		cout << '\t';
-	}
-	if (opt::adj)
-		cout << data.getExtension(sense) << '\t';
-	cout << data.getMultiplicity(sense) << '\n';
+	cout << (sense ? reverseComplement(seq.first).str()
+			: seq.first.str())
+		<< opt::ofs << data.getMultiplicity(sense)
+		<< opt::ofs << data.getExtension(sense)
+		<< '\n';
 }
 
 static void printFile(const char* path)
@@ -73,19 +101,44 @@ static void printFile(const char* path)
 
 int main(int argc, char* argv[])
 {
-	assert(argc > 1);
-
+	bool die = false;
 	for (int c; (c = getopt_long(argc, argv,
 					shortopts, longopts, NULL)) != -1;) {
 		istringstream arg(optarg != NULL ? optarg : "");
 		switch (c) {
-			case '?': exit(EXIT_FAILURE);
-			case 'k': arg >> opt::k; break;
+		  case '?':
+			  exit(EXIT_FAILURE);
+		  case 'k':
+			  arg >> opt::k;
+			  break;
+		  case OPT_HELP:
+			cout << USAGE_MESSAGE;
+			exit(EXIT_SUCCESS);
+		  case OPT_VERSION:
+			cout << VERSION_MESSAGE;
+			exit(EXIT_SUCCESS);
+		}
+		if (optarg != NULL && !arg.eof()) {
+			cerr << PROGRAM ": invalid option: `-"
+				<< (char)c << optarg << "'\n";
+			exit(EXIT_FAILURE);
 		}
 	}
+	opt::ofs = opt::ofsInt;
 
 	if (opt::k <= 0) {
 		cerr << PROGRAM ": " << "missing -k,--kmer option\n";
+		die = true;
+	}
+
+	if (argc - optind < 1) {
+		cerr << PROGRAM ": missing arguments\n";
+		die = true;
+	}
+
+	if (die) {
+		cerr << "Try `" << PROGRAM
+			<< " --help' for more information.\n";
 		exit(EXIT_FAILURE);
 	}
 
diff --git a/missing b/missing
index 28055d2..9a55648 100755
--- a/missing
+++ b/missing
@@ -1,10 +1,9 @@
 #! /bin/sh
 # Common stub for a few missing GNU programs while installing.
 
-scriptversion=2009-04-28.21; # UTC
+scriptversion=2012-01-06.18; # UTC
 
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
-# 2008, 2009 Free Software Foundation, Inc.
+# Copyright (C) 1996-2012 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
@@ -26,7 +25,7 @@ scriptversion=2009-04-28.21; # UTC
 # 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"
+  echo 1>&2 "Try '$0 --help' for more information"
   exit 1
 fi
 
@@ -34,7 +33,7 @@ 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
+# In the cases where this matters, 'missing' is being run in the
 # srcdir already.
 if test -f configure.ac; then
   configure_ac=configure.ac
@@ -65,7 +64,7 @@ case $1 in
     echo "\
 $0 [OPTION]... PROGRAM [ARGUMENT]...
 
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
 error status if there is no known handling for PROGRAM.
 
 Options:
@@ -74,21 +73,20 @@ Options:
   --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'
+  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
+  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
+  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]
+  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.
+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 $?
@@ -100,8 +98,8 @@ Send bug reports to <bug-automake at gnu.org>."
     ;;
 
   -*)
-    echo 1>&2 "$0: Unknown \`$1' option"
-    echo 1>&2 "Try \`$0 --help' for more information"
+    echo 1>&2 "$0: Unknown '$1' option"
+    echo 1>&2 "Try '$0 --help' for more information"
     exit 1
     ;;
 
@@ -122,22 +120,13 @@ case $1 in
     # 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
+       # running '$TOOL --version' or '$TOOL --help' to check whether
        # $TOOL exists and not knowing $TOOL uses missing.
        exit 1
     fi
@@ -149,27 +138,27 @@ esac
 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
+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
+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
+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"
@@ -186,9 +175,9 @@ WARNING: \`$1' is $msg.  You should only need it if
 
   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.
+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/' |
@@ -197,10 +186,10 @@ WARNING: \`$1' is $msg.  You should only need it if
 
   autom4te*)
     echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
+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
+         You can get '$1' as part of Autoconf from any GNU
          archive site."
 
     file=`echo "$*" | sed -n "$sed_output"`
@@ -220,13 +209,13 @@ WARNING: \`$1' is needed, but is $msg.
 
   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
+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."
+         Bison from any GNU archive site."
     rm -f y.tab.c y.tab.h
     if test $# -ne 1; then
-        eval LASTARG="\${$#}"
+        eval LASTARG=\${$#}
 	case $LASTARG in
 	*.y)
 	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
@@ -250,13 +239,13 @@ WARNING: \`$1' $msg.  You should only need it if
 
   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
+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."
+         Flex from any GNU archive site."
     rm -f lex.yy.c
     if test $# -ne 1; then
-        eval LASTARG="\${$#}"
+        eval LASTARG=\${$#}
 	case $LASTARG in
 	*.l)
 	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
@@ -273,10 +262,10 @@ WARNING: \`$1' is $msg.  You should only need it if
 
   help2man*)
     echo 1>&2 "\
-WARNING: \`$1' is $msg.  You should only need it if
+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."
+	 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"`
@@ -291,12 +280,12 @@ WARNING: \`$1' is $msg.  You should only need it if
 
   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
+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."
+         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"`
@@ -318,49 +307,14 @@ WARNING: \`$1' is $msg.  You should only need it if
     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.
+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,
+         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."
+         some other package would contain this missing '$1' program."
     exit 1
     ;;
 esac

-- 
Alioth's /git/debian-med/git-commit-notice on /srv/git.debian.org/git/debian-med/abyss.git



More information about the debian-med-commit mailing list