[med-svn] [tophat] 01/06: Imported Upstream version 2.1.1+dfsg

Alex Mestiashvili malex-guest at moszumanska.debian.org
Thu Mar 17 13:47:28 UTC 2016


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

malex-guest pushed a commit to branch master
in repository tophat.

commit 5e1ff735e522336796365b85772461a113a253cb
Author: Alexandre Mestiashvili <alex at biotec.tu-dresden.de>
Date:   Thu Mar 17 14:22:48 2016 +0100

    Imported Upstream version 2.1.1+dfsg
---
 AUTHORS                                   |   10 +
 COPYING                                   |  113 ---
 Makefile.am                               |    2 +-
 Makefile.in                               |    6 +-
 ax_boost_thread.m4                        |   17 +-
 configure                                 |   51 +-
 configure.ac                              |    8 +-
 src/GBase.cpp                             |   65 +-
 src/GBase.h                               |   15 +-
 src/GStr.cpp                              |   20 +-
 src/GVec.hh                               |   40 +-
 src/Makefile.am                           | 1115 +++++++++++++-----------
 src/Makefile.in                           | 1139 ++++++++++++------------
 src/bam2fastx.cpp                         |  160 ++--
 src/bam_merge.h                           |    3 +
 src/common.cpp                            |    4 +-
 src/common.h                              |    4 +-
 src/gff.cpp                               |  254 +++---
 src/gff.h                                 |   23 +-
 src/intervaltree/__init__.py              |   22 +
 src/intervaltree/interval.py              |  302 +++++++
 src/intervaltree/intervaltree.py          |  947 ++++++++++++++++++++
 src/intervaltree/node.py                  |  593 +++++++++++++
 src/long_spanning_reads.cpp               |    4 +-
 src/map2gtf.cpp                           |   13 -
 src/reads.h                               |   10 +-
 src/segment_juncs.cpp                     |  132 ++-
 src/sortedcontainers/__init__.py          |   55 ++
 src/sortedcontainers/sorteddict.py        |  737 ++++++++++++++++
 src/sortedcontainers/sortedlist.py        | 1233 ++++++++++++++++++++++++++
 src/sortedcontainers/sortedlistwithkey.py | 1331 +++++++++++++++++++++++++++++
 src/sortedcontainers/sortedset.py         |  294 +++++++
 src/tophat-fusion-post                    |    2 +-
 src/tophat.py                             |   16 +-
 src/tophat2.in                            |   15 -
 src/tophat2.sh                            |   10 +
 src/tophat_reports.cpp                    |   27 +-
 37 files changed, 7255 insertions(+), 1537 deletions(-)

diff --git a/AUTHORS b/AUTHORS
index 5b5292e..7307eef 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,8 +17,18 @@ The SeqAn-1.3 library is used in TopHat and some of its sources are included
   in TopHat source releases; its authors are Andreas Doring, David Weese, 
   Tobias Rausch, and Knut Reinert.
 
+The IntervalTree library is used by TopHat in its fusion-calling pipeline; 
+  its authors are Chaim-Leib Halbert and Konstantin Tretyakov. This package
+  is released under the Apache 2.0 license.
+
+The SortedContainers library is used by TopHat in its fusion-calling
+  pipeline; its author is Grant Jenks. This package is released under the
+  Apache 2.0 license.
+
 Websites:
  TopHat:                http://ccb.jhu.edu/software/tophat
  Bowtie:                http://bowtie-bio.sourceforge.net/bowtie2
  Samtools:              http://samtools.sourceforge.net
  SeqAn:                 http://www.seqan.de
+ IntervalTree:          https://github.com/chaimleib/intervaltree
+ SortedContainers:      http://www.grantjenks.com/docs/sortedcontainers/
diff --git a/COPYING b/COPYING
deleted file mode 100644
index 31a6350..0000000
--- a/COPYING
+++ /dev/null
@@ -1,113 +0,0 @@
-The Artistic License
-
-Preamble
-
-The intent of this document is to state the conditions under which a
-Package may be copied, such that the Copyright Holder maintains some
-semblance of artistic control over the development of the package,
-while giving the users of the package the right to use and distribute
-the Package in a more-or-less customary fashion, plus the right to
-make reasonable modifications.
-
-Definitions:
-    * "Package" refers to the collection of files distributed by the
-      Copyright Holder, and derivatives of that collection of files
-      created through textual modification.
-    * "Standard Version" refers to such a Package if it has not been
-      modified, or has been modified in accordance with the wishes of
-      the Copyright Holder.
-    * "Copyright Holder" is whoever is named in the copyright or
-      copyrights for the package.
-    * "You" is you, if you're thinking about copying or distributing
-      this Package.
-    * "Reasonable copying fee" is whatever you can justify on the
-      basis of media cost, duplication charges, time of people
-      involved, and so on. (You will not be required to justify it to
-      the Copyright Holder, but only to the computing community at
-      large as a market that must bear the fee.)
-    * "Freely Available" means that no fee is charged for the item
-      itself, though there may be fees involved in handling the
-      item. It also means that recipients of the item may redistribute
-      it under the same conditions they received it.
-
-1. You may make and give away verbatim copies of the source form of
-   the Standard Version of this Package without restriction, provided
-   that you duplicate all of the original copyright notices and
-   associated disclaimers.
-
-2. You may apply bug fixes, portability fixes and other modifications
-   derived from the Public Domain or from the Copyright Holder. A
-   Package modified in such a way shall still be considered the
-   Standard Version.
-
-3. You may otherwise modify your copy of this Package in any way,
-   provided that you insert a prominent notice in each changed file
-   stating how and when you changed that file, and provided that you
-   do at least ONE of the following:
-
-    a) place your modifications in the Public Domain or otherwise make
-    them Freely Available, such as by posting said modifications to
-    Usenet or an equivalent medium, or placing the modifications on a
-    major archive site such as ftp.uu.net, or by allowing the
-    Copyright Holder to include your modifications in the Standard
-    Version of the Package.
-
-    b) use the modified Package only within your corporation or
-    organization.
-
-    c) rename any non-standard executables so the names do not
-    conflict with standard executables, which must also be provided,
-    and provide a separate manual page for each non-standard
-    executable that clearly documents how it differs from the Standard
-    Version.
-
-    d) make other distribution arrangements with the Copyright Holder.
-
-4. You may distribute the programs of this Package in object code or
-   executable form, provided that you do at least ONE of the
-   following:
-
-    a) distribute a Standard Version of the executables and library
-    files, together with instructions (in the manual page or
-    equivalent) on where to get the Standard Version.
-
-    b) accompany the distribution with the machine-readable source of
-    the Package with your modifications.
-
-    c) accompany any non-standard executables with their corresponding
-    Standard Version executables, giving the non-standard executables
-    non-standard names, and clearly documenting the differences in
-    manual pages (or equivalent), together with instructions on where
-    to get the Standard Version.
-
-    d) make other distribution arrangements with the Copyright Holder.
-
-5. You may charge a reasonable copying fee for any distribution of
-   this Package. You may charge any fee you choose for support of this
-   Package. You may not charge a fee for this Package itself. However,
-   you may distribute this Package in aggregate with other (possibly
-   commercial) programs as part of a larger (possibly commercial)
-   software distribution provided that you do not advertise this
-   Package as a product of your own.
-
-6. The scripts and library files supplied as input to or produced as
-   output from the programs of this Package do not automatically fall
-   under the copyright of this Package, but belong to whomever
-   generated them, and may be sold commercially, and may be aggregated
-   with this Package.
-
-7. C or perl subroutines supplied by you and linked into this Package
-   shall not be considered part of this Package.
-
-8. The name of the Copyright Holder may not be used to endorse or
-   promote products derived from this software without specific prior
-   written permission.
-
-9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
-   WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
-   OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
-
-The End
-This license is approved by the Open Source Initiative
-(www.opensource.org) for certifying software as OSI Certified Open
-Source.
diff --git a/Makefile.am b/Makefile.am
index a319a05..cd9ae7e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2,6 +2,6 @@ ALWAYS_BUILT = src
 SUBDIRS = $(ALWAYS_BUILT)
 DIST_SUBDIRS = $(ALWAYS_BUILT) 
 
-EXTRA_DIST = LICENSE
+EXTRA_DIST = LICENSE README AUTHORS
 
 .PHONY: FORCE
diff --git a/Makefile.in b/Makefile.in
index 067e05d..0711a15 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -52,8 +52,8 @@ host_triplet = @host@
 subdir = .
 DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
-	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
-	THANKS ar-lib config.guess config.sub install-sh missing
+	$(top_srcdir)/configure AUTHORS ChangeLog INSTALL NEWS THANKS \
+	ar-lib config.guess config.sub depcomp install-sh missing
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/ax_boost_base.m4 \
 	$(top_srcdir)/ax_boost_thread.m4 $(top_srcdir)/configure.ac
@@ -248,7 +248,7 @@ top_srcdir = @top_srcdir@
 ALWAYS_BUILT = src
 SUBDIRS = $(ALWAYS_BUILT)
 DIST_SUBDIRS = $(ALWAYS_BUILT) 
-EXTRA_DIST = LICENSE
+EXTRA_DIST = LICENSE README AUTHORS
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
 
diff --git a/ax_boost_thread.m4 b/ax_boost_thread.m4
index 30cc340..d07fd9c 100644
--- a/ax_boost_thread.m4
+++ b/ax_boost_thread.m4
@@ -68,12 +68,12 @@ if test "$ax_cv_boost_thread" = yes; then
     AC_CHECK_LIB($ax_lib, main, [BOOST_THREAD_LIBS=-l$ax_lib; break])
   done
 
-  # in recent Boost versions, boost::thread depends on boost::system
+  # in some Boost versions, boost::thread depends on boost::system
   AC_CACHE_CHECK(whether Boost::Thread needs Boost::System library,
   ax_cv_boost_thread_system,
   [LIBS="$LIBS $BOOST_THREAD_LIBS"
   AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
-            [[boost::thread_group thrds; return 0;]])],
+                   [[boost::thread_group thrds; return 0;]])],
             [ax_cv_boost_thread_system=no],
             [LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
                 AC_LINK_IFELSE([
@@ -82,8 +82,17 @@ if test "$ax_cv_boost_thread" = yes; then
                     ],
                     [BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
                         ax_cv_boost_thread_system=yes],
-                    [AC_ERROR([Cannot use Boost::Thread])]
-                    )])
+		            [LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+		                AC_LINK_IFELSE([
+		                    AC_LANG_PROGRAM([[#include <boost/thread/thread.hpp>]],
+		                        [[boost::thread_group thrds; return 0;]])
+		                    ],
+		                    [BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+		                        ax_cv_boost_thread_system=yes],
+		                       [AC_ERROR([Cannot use Boost::Thread])]
+		                    )
+					 ])
+			 ])
   ])
   
   CXXFLAGS=$CXXFLAGS_SAVE
diff --git a/configure b/configure
index 8bdcd01..e1424ff 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 tophat 2.1.0.
+# Generated by GNU Autoconf 2.69 for tophat 2.1.1.
 #
 # Report bugs to <tophat.cufflinks at gmail.com>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='tophat'
 PACKAGE_TARNAME='tophat'
-PACKAGE_VERSION='2.1.0'
-PACKAGE_STRING='tophat 2.1.0'
+PACKAGE_VERSION='2.1.1'
+PACKAGE_STRING='tophat 2.1.1'
 PACKAGE_BUGREPORT='tophat.cufflinks at gmail.com'
 PACKAGE_URL=''
 
@@ -1304,7 +1304,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 tophat 2.1.0 to adapt to many kinds of systems.
+\`configure' configures tophat 2.1.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1374,7 +1374,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of tophat 2.1.0:";;
+     short | recursive ) echo "Configuration of tophat 2.1.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1484,7 +1484,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-tophat configure 2.1.0
+tophat configure 2.1.1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1945,7 +1945,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 tophat $as_me 2.1.0, which was
+It was created by tophat $as_me 2.1.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2294,7 +2294,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-$as_echo "#define SVN_REVISION \"exported\"" >>confdefs.h
+$as_echo "#define SVN_REVISION \"ecf7617\"" >>confdefs.h
 
 
 
@@ -2777,7 +2777,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='tophat'
- VERSION='2.1.0'
+ VERSION='2.1.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5602,7 +5602,7 @@ fi
 
   done
 
-  # in recent Boost versions, boost::thread depends on boost::system
+  # in some Boost versions, boost::thread depends on boost::system
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Boost::Thread needs Boost::System library" >&5
 $as_echo_n "checking whether Boost::Thread needs Boost::System library... " >&6; }
 if ${ax_cv_boost_thread_system+:} false; then :
@@ -5641,11 +5641,34 @@ if ac_fn_cxx_try_link "$LINENO"; then :
   BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread"
                         ax_cv_boost_thread_system=yes
 else
+  LIBS="$LIBS $BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+		                cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+		                    #include <boost/thread/thread.hpp>
+int
+main ()
+{
+boost::thread_group thrds; return 0;
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  BOOST_THREAD_LIBS="$BOOST_THREAD_LIBS -lboost_system$with_boost_thread -lrt"
+		                        ax_cv_boost_thread_system=yes
+else
   as_fn_error $? "Cannot use Boost::Thread" "$LINENO" 5
 
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
@@ -6900,7 +6923,7 @@ fi
 
 CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
 CXXFLAGS="$CFLAGS"
-CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.3"
+CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.4.2"
 LDFLAGS="$BAM_LDFLAGS $BOOST_LDFLAGS $user_LDFLAGS"
 
 if test "`cd $srcdir && pwd`" != "`pwd`"; then
@@ -6925,7 +6948,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='tophat'
- VERSION='2.1.0'
+ VERSION='2.1.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -7868,7 +7891,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 tophat $as_me 2.1.0, which was
+This file was extended by tophat $as_me 2.1.1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7934,7 +7957,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="\\
-tophat config.status 2.1.0
+tophat config.status 2.1.1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/configure.ac b/configure.ac
index 00a673c..dd5ac83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,6 +1,6 @@
-define([svnversion], esyscmd([sh -c "svnversion|tr -d '\n'"]))dnl
-AC_INIT([tophat],[2.1.0],[tophat.cufflinks at gmail.com])
-AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision])
+define([gitversion], esyscmd([sh -c 'git show -s --pretty=format:%h']))dnl
+AC_INIT([tophat],[2.1.1],[tophat.cufflinks at gmail.com])
+AC_DEFINE(SVN_REVISION, "gitversion", [SVN Revision])
 
 AC_CONFIG_SRCDIR([config.h.in])
 AC_CONFIG_HEADERS([config.h])
@@ -105,7 +105,7 @@ AS_IF([test "x$enable_debug" = xyes],
 	  
 CFLAGS="${generic_CFLAGS} ${ext_CFLAGS} ${user_CFLAGS} ${debug_CFLAGS}"
 CXXFLAGS="$CFLAGS"
-CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.3"
+CXXFLAGS="$CXXFLAGS $BAM_CPPFLAGS $BOOST_CPPFLAGS -I./SeqAn-1.4.2"
 LDFLAGS="$BAM_LDFLAGS $BOOST_LDFLAGS $user_LDFLAGS"
 
 AM_INIT_AUTOMAKE([-Wall foreign tar-pax foreign])
diff --git a/src/GBase.cpp b/src/GBase.cpp
index 4671e42..afb0791 100644
--- a/src/GBase.cpp
+++ b/src/GBase.cpp
@@ -1,6 +1,7 @@
 #include "GBase.h"
 #include <stdarg.h>
 #include <ctype.h>
+#include <errno.h>
 
 #ifndef S_ISDIR
 #define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
@@ -188,22 +189,38 @@ int Gstrcmp(const char* a, const char* b, int n) {
 
 }
 
-int G_mkdir(const char* path, int perms=0775) {
+int G_mkdir(const char* path, int perms = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
+   //int perms=(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
  #ifdef __WIN32__
      return _mkdir(path);
  #else
- //#if _POSIX_C_SOURCE
- //    return ::mkdir(path);
- //#else
-     return mkdir(path, perms); // not sure if this works on mac
- //#endif
+     return  mkdir(path, perms);
  #endif
 }
 
 
+void Gmktempdir(char* templ) {
+#ifdef __WIN32__
+  int blen=strlen(templ);
+  if (_mktemp_s(templ, blen)!=0)
+	  GError("Error creating temp dir %s!\n", templ);
+#else
+  char* cdir=mkdtemp(templ);
+  if (cdir==NULL)
+	  GError("Error creating temp dir %s!(%s)\n", templ, strerror(errno));
+#endif
+}
+
 int Gmkdir(const char *path, bool recursive, int perms) {
 	if (path==NULL || path[0]==0) return -1;
-	if (!recursive) return G_mkdir(path, perms);
+	mode_t process_mask = umask(0); //is this really needed?
+	if (!recursive) {
+	   int r=G_mkdir(path, perms);
+	   if (r!=0) 
+	      GMessage("Warning: G_mkdir(%s) failed: %s\n", path, strerror(errno));
+	   umask(process_mask);
+	   return r;
+	   }
 	int plen=strlen(path);
 	char* gpath=NULL;
 	//make sure gpath ends with /
@@ -221,17 +238,35 @@ int Gmkdir(const char *path, bool recursive, int perms) {
 	while (*ss!=0 && (psep=strchr(ss, '/'))!=NULL)  {
 		*psep=0; //now gpath is the path up to this /
 		ss=psep; ++ss; //ss repositioned just after the /
-		// create current level
-		if (fileExists(gpath)!=1 && G_mkdir(gpath, perms)!=0) {
+		// create current level if it doesn't exist
+		if (fileExists(gpath)) { //path exists
+		    *psep='/';
+		    continue; //assume it's a directory or a symlink to one
+		              //if not, it'll fail later
+		}
+		int mkdir_err=0;
+		if ((mkdir_err=G_mkdir(gpath, perms))!=0) {
+				GMessage("Warning: mkdir(%s) failed: %s\n", gpath, strerror(errno));
 			GFREE(gpath);
+			umask(process_mask);
 			return -1;
 		}
 		*psep='/';
 	}
 	GFREE(gpath);
+	umask(process_mask);
 	return 0;
 }
 
+FILE* Gfopen(const char *path, char *mode) {
+	FILE* f=NULL;
+	if (mode==NULL) f=fopen(path, "rb");
+	    	   else f=fopen(path, mode);
+	if (f==NULL)
+		GMessage("Error opening file '%s':  %s\n", path, strerror(errno));
+	return f;
+}
+
 bool GstrEq(const char* a, const char* b) {
 	 if (a==NULL || b==NULL) return false;
 	 register int i=0;
@@ -674,12 +709,12 @@ const char* getFileExt(const char* filepath) {
 int fileExists(const char* fname) {
   struct stat stFileInfo;
   int r=0;
-  // Attempt to get the file attributes
+  // Attempt to get the path attributes
   int fs = stat(fname,&stFileInfo);
   if (fs == 0) {
       r=3;
       // We were able to get the file attributes
-      // so the file obviously exists.
+      // so the path exists
       if (S_ISREG (stFileInfo.st_mode)) {
          r=2;
          }
@@ -690,14 +725,6 @@ int fileExists(const char* fname) {
   return r;
 }
 
-/*bool fileExists(const char* filepath) {
-  if (filepath==NULL) return false;
-  FILE* ft=fopen(filepath, "rb");
-  if (ft==NULL) return false;
-  fclose(ft);
-  return true;
-}
-*/
 int64 fileSize(const char* fpath) {
   struct stat results;
   if (stat(fpath, &results) == 0)
diff --git a/src/GBase.h b/src/GBase.h
index ec50000..8ff89f3 100644
--- a/src/GBase.h
+++ b/src/GBase.h
@@ -1,9 +1,9 @@
 #ifndef G_BASE_DEFINED
 #define G_BASE_DEFINED
-#ifndef _POSIX_SOURCE
+//#ifndef _POSIX_SOURCE
 //mostly for MinGW
-#define _POSIX_SOURCE
-#endif
+//#define _POSIX_SOURCE
+//#endif
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -171,8 +171,8 @@ inline int iround(double x) {
    return (int)floor(x + 0.5);
 }
 
-int Gmkdir(const char *path, bool recursive=true, int perms=0775);
-
+int Gmkdir(const char *path, bool recursive=true, int perms = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH));
+void Gmktempdir(char* templ);
 
 /****************************************************************************/
 
@@ -240,6 +240,9 @@ char* strupper(char * str);
 void* Gmemscan(void *mem, unsigned int len,
                   void *part, unsigned int partlen);
 
+
+FILE* Gfopen(const char *path, char *mode=NULL);
+
 // test if a char is in a string:
 bool chrInStr(char c, const char* str);
 
@@ -441,7 +444,7 @@ const char* getFileExt(const char* filepath);
 
 
 int fileExists(const char* fname);
-//returns 0 if file entry doesn't exist
+//returns 0 if path doesn't exist
 //        1 if it's a directory
 //        2 if it's a regular file
 //        3 otherwise (?)
diff --git a/src/GStr.cpp b/src/GStr.cpp
index 20137af..f4e6784 100644
--- a/src/GStr.cpp
+++ b/src/GStr.cpp
@@ -679,17 +679,23 @@ GStr GStr::substr(int idx, int len) const {
     // A negative idx specifies an idx from the right of the string.
     if (idx < 0)
         idx += length();
-
-    // A length of -1 specifies the rest of the string.
-    if (len < 0  || len>length()-idx)
+    else if (idx>=length()) {
+             len=0;
+             idx=length();
+             }
+    if (len) {
+      // A length of -1 specifies the rest of the string.
+      if (len < 0  || len>length()-idx)
         len = length() - idx;
-    
-    if (idx<0 || idx>=length() || len<0 )
+      if (idx<0 || idx>=length() || len<0 )
         invalid_args_error("substr()");
+    }
 
     GStr newstring;
-    newstring.replace_data(len);
-    ::memcpy(newstring.chrs(), &chars()[idx], len);
+    if (len) {
+      newstring.replace_data(len);
+      ::memcpy(newstring.chrs(), &chars()[idx], len);
+    }
     return newstring;
 }
 
diff --git a/src/GVec.hh b/src/GVec.hh
index 7b9800b..7023b75 100644
--- a/src/GVec.hh
+++ b/src/GVec.hh
@@ -566,38 +566,38 @@ template <class OBJ> GPVec<OBJ>::GPVec(GPVec& list) { //copy constructor
  fCount=list.fCount;
  fCapacity=list.fCapacity;
  fList=NULL;
- if (fCapacity>0) {
-      GMALLOC(fList, fCapacity*sizeof(OBJ*));
-      }
  fFreeProc=list.fFreeProc;
  fCount=list.fCount;
- memcpy(fList, list.fList, fCount*sizeof(OBJ*));
- //for (int i=0;i<list.Count();i++) Add(list[i]);
+ if (fCapacity>0) {
+    GMALLOC(fList, fCapacity*sizeof(OBJ*));
+    memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+ }
 }
 
 template <class OBJ> GPVec<OBJ>::GPVec(GPVec* plist) { //another copy constructor
- fCount=0;
- fCapacity=plist->fCapacity;
- fList=NULL;
- if (fCapacity>0) {
-     GMALLOC(fList, fCapacity*sizeof(OBJ*));
-     }
- fFreeProc=plist->fFreeProc;
- fCount=plist->fCount;
- memcpy(fList, plist->fList, fCount*sizeof(OBJ*));
- //for (int i=0;i<list->fCount;i++) Add(plist->Get(i));
+  fCount=0;
+  fCapacity=plist->fCapacity;
+  fList=NULL;
+  fFreeProc=plist->fFreeProc;
+  fCount=plist->fCount;
+  if (fCapacity>0) {
+    GMALLOC(fList, fCapacity*sizeof(OBJ*));
+    memcpy(fList, plist->fList, fCount*sizeof(OBJ*));
+  }
 }
 
 template <class OBJ> const GPVec<OBJ>& GPVec<OBJ>::operator=(GPVec& list) {
  if (&list!=this) {
      Clear();
      fFreeProc=list.fFreeProc;
-     //Attention: the object *POINTERS* are copied,
-     // but the actual object content is NOT duplicated
-     //for (int i=0;i<list.Count();i++) Add(list[i]);
+     //Attention: only the *POINTERS* are copied,
+     // the actual objects are NOT duplicated
      fCount=list.fCount;
-     GMALLOC(fList, fCapacity*sizeof(OBJ*));
-     memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+     fCapacity=list.fCapacity;
+     if (fCapacity>0) {
+        GMALLOC(fList, fCapacity*sizeof(OBJ*));
+        memcpy(fList, list.fList, fCount*sizeof(OBJ*));
+        }
      }
  return *this;
 }
diff --git a/src/Makefile.am b/src/Makefile.am
index 54db7c6..551383f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -6,7 +6,16 @@
 # - and tophat2.in added
 EXTRA_DIST = \
 tophat.py \
-tophat2.in \
+tophat2.sh \
+intervaltree/__init__.py \
+intervaltree/interval.py \
+intervaltree/intervaltree.py \
+intervaltree/node.py \
+sortedcontainers/__init__.py \
+sortedcontainers/sorteddict.py \
+sortedcontainers/sortedlist.py \
+sortedcontainers/sortedlistwithkey.py \
+sortedcontainers/sortedset.py \
 samtools-0.1.18/AUTHORS \
 samtools-0.1.18/COPYING \
 samtools-0.1.18/ChangeLog \
@@ -91,514 +100,588 @@ samtools-0.1.18/bcftools/prob1.c \
 samtools-0.1.18/bcftools/prob1.h \
 samtools-0.1.18/bcftools/vcf.c \
 samtools-0.1.18/bcftools/vcfutils.pl \
-SeqAn-1.3/COPYING \
-SeqAn-1.3/README \
-SeqAn-1.3/seqan/chaining/chain_generic.h \
-SeqAn-1.3/seqan/chaining/rt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/score_zero.h \
-SeqAn-1.3/seqan/chaining/geom_distribution.h \
-SeqAn-1.3/seqan/chaining/chain_base.h \
-SeqAn-1.3/seqan/chaining/chaining_generated_forwards.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/skip_element.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_element.h \
-SeqAn-1.3/seqan/chaining/rt_sl_impl.h \
-SeqAn-1.3/seqan/chaining/chain_wrapper_point.h \
-SeqAn-1.3/seqan/chaining/rmt_compl_algos.h \
-SeqAn-1.3/seqan/chaining/rmt_base.h \
-SeqAn-1.3/seqan/chaining/skip_list.h \
-SeqAn-1.3/seqan/chaining/skip_list_iterator.h \
-SeqAn-1.3/seqan/chaining/skip_base_element.h \
-SeqAn-1.3/seqan/chaining/fragment.h \
-SeqAn-1.3/seqan/chaining/skip_pool_alloc.h \
-SeqAn-1.3/seqan/chaining/skip_list_impl.h \
-SeqAn-1.3/seqan/chaining/rt_skip_element.h \
-SeqAn-1.3/seqan/chaining/tree_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rmt_common_algos.h \
-SeqAn-1.3/seqan/chaining/score_manhattan.h \
-SeqAn-1.3/seqan/chaining/score_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rt_impl.h \
-SeqAn-1.3/seqan/chaining/tree_chain.h \
-SeqAn-1.3/seqan/chaining/tree_chain_utils.h \
-SeqAn-1.3/seqan/chaining/skip_list_base.h \
-SeqAn-1.3/seqan/chaining/rt_sl_def_algos.h \
-SeqAn-1.3/seqan/chaining/range_tree.h \
-SeqAn-1.3/seqan/chaining/rmt_def_algos.h \
-SeqAn-1.3/seqan/chaining/chain_point.h \
-SeqAn-1.3/seqan/chaining/rt_base.h \
-SeqAn-1.3/seqan/chaining/chain_meta_fragment.h \
-SeqAn-1.3/seqan/chaining/score_chain.h \
-SeqAn-1.3/seqan/chaining/rt_common_algos.h \
-SeqAn-1.3/seqan/chaining/skip_list_dynamic.h \
-SeqAn-1.3/seqan/chaining/rt_sl_base.h \
-SeqAn-1.3/seqan/chaining/skip_list_type.h \
-SeqAn-1.3/seqan/chaining/range_max_tree.h \
-SeqAn-1.3/seqan/chaining/rt_sl_compl_algos.h \
-SeqAn-1.3/seqan/file/file_format_cgviz.h \
-SeqAn-1.3/seqan/file/stream.h \
-SeqAn-1.3/seqan/file/file_format_embl.h \
-SeqAn-1.3/seqan/file/file_format_fasta.h \
-SeqAn-1.3/seqan/file/string_mmap.h \
-SeqAn-1.3/seqan/file/file_format_raw.h \
-SeqAn-1.3/seqan/file/string_external.h \
-SeqAn-1.3/seqan/file/file_filereader.h \
-SeqAn-1.3/seqan/file/file_cstyle.h \
-SeqAn-1.3/seqan/file/file_page_raid0.h \
-SeqAn-1.3/seqan/file/cstream.h \
-SeqAn-1.3/seqan/file/file_format_guess.h \
-SeqAn-1.3/seqan/file/file_base.h \
-SeqAn-1.3/seqan/file/file_format_mmap.h \
-SeqAn-1.3/seqan/file/file_forwards.h \
-SeqAn-1.3/seqan/file/file_array.h \
-SeqAn-1.3/seqan/file/meta.h \
-SeqAn-1.3/seqan/file/stream_algorithms.h \
-SeqAn-1.3/seqan/file/file_format.h \
-SeqAn-1.3/seqan/file/file_filereaderiterator.h \
-SeqAn-1.3/seqan/file/file_format_genbank.h \
-SeqAn-1.3/seqan/file/file_generated_forwards.h \
-SeqAn-1.3/seqan/file/file_format_fasta_align.h \
-SeqAn-1.3/seqan/file/chunk_collector.h \
-SeqAn-1.3/seqan/file/file_page.h \
-SeqAn-1.3/seqan/seeds.h \
-SeqAn-1.3/seqan/find_motif.h \
-SeqAn-1.3/seqan/LICENSE \
-SeqAn-1.3/seqan/find2/find_approx_find_begin.h \
-SeqAn-1.3/seqan/find2/find_finder_default.h \
-SeqAn-1.3/seqan/find2/find_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_multiple_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_hamming_simple.h \
-SeqAn-1.3/seqan/find2/find_pattern_wild_shiftand.h \
-SeqAn-1.3/seqan/find2/find_approx_dpsearch.h \
-SeqAn-1.3/seqan/find2/find_exact_shiftand.h \
-SeqAn-1.3/seqan/find2/find2_generated_forwards.h \
-SeqAn-1.3/seqan/find2/find_base.h \
-SeqAn-1.3/seqan/platform.h \
-SeqAn-1.3/seqan/sequence_journaled.h \
-SeqAn-1.3/seqan/chaining.h \
-SeqAn-1.3/seqan/score/score_generated_forwards.h \
-SeqAn-1.3/seqan/score/score_matrix_data.h \
-SeqAn-1.3/seqan/score/score_matrix.h \
-SeqAn-1.3/seqan/score/score_simple.h \
-SeqAn-1.3/seqan/score/score_base.h \
-SeqAn-1.3/seqan/score/score_edit.h \
-SeqAn-1.3/seqan/graph_algorithms.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entry.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_sorted_array.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_generated_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
-SeqAn-1.3/seqan/align/gaps_iterator_base.h \
-SeqAn-1.3/seqan/align/gaps_array.h \
-SeqAn-1.3/seqan/align/matrix_base.h \
-SeqAn-1.3/seqan/align/gaps_base.h \
-SeqAn-1.3/seqan/align/align_iterator_base.h \
-SeqAn-1.3/seqan/align/align_algorithms.h \
-SeqAn-1.3/seqan/align/align_hirschberg.h \
-SeqAn-1.3/seqan/align/align_local_dynprog.h \
-SeqAn-1.3/seqan/align/align_cols_base.h \
-SeqAn-1.3/seqan/align/align_generated_forwards.h \
-SeqAn-1.3/seqan/align/align_base.h \
-SeqAn-1.3/seqan/align/gaps_sumlist.h \
-SeqAn-1.3/seqan/align/align_local_dynprog_banded.h \
-SeqAn-1.3/seqan/align/align_dynprog.h \
-SeqAn-1.3/seqan/align/align_myers.h \
-SeqAn-1.3/seqan/align/hirschberg_set.h \
-SeqAn-1.3/seqan/align/align_trace.h \
-SeqAn-1.3/seqan/pipe/pipe_sampler.h \
-SeqAn-1.3/seqan/pipe/pipe_filter.h \
-SeqAn-1.3/seqan/pipe/pool_sorter.h \
-SeqAn-1.3/seqan/pipe/pipe_namer.h \
-SeqAn-1.3/seqan/pipe/pipe_joiner.h \
-SeqAn-1.3/seqan/pipe/pipe_base.h \
-SeqAn-1.3/seqan/pipe/pipe_echoer.h \
-SeqAn-1.3/seqan/pipe/pipe_caster.h \
-SeqAn-1.3/seqan/pipe/pipe_generated_forwards.h \
-SeqAn-1.3/seqan/pipe/pipe_counter.h \
-SeqAn-1.3/seqan/pipe/pool_mapper.h \
-SeqAn-1.3/seqan/pipe/pipe_edit_environment.h \
-SeqAn-1.3/seqan/pipe/pool_base.h \
-SeqAn-1.3/seqan/pipe/pipe_shifter.h \
-SeqAn-1.3/seqan/pipe/pipe_source.h \
-SeqAn-1.3/seqan/pipe/pipe_tupler.h \
-SeqAn-1.3/seqan/pipe/pipe_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_vertex.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_oracle.h \
-SeqAn-1.3/seqan/graph_types/graph_idmanager.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_adjacency.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_automaton.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_trie.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_bfs.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_dfs.h \
-SeqAn-1.3/seqan/graph_types/graph_property.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_fragment.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_outedge.h \
-SeqAn-1.3/seqan/graph_types/graph_utility_parsing.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_undirected.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_hmm.h \
-SeqAn-1.3/seqan/graph_types/graph_base.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_edge.h \
-SeqAn-1.3/seqan/graph_types/graph_edgestump.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_tree.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_wordgraph.h \
-SeqAn-1.3/seqan/graph_types/graph_types_generated_forwards.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_directed.h \
-SeqAn-1.3/seqan/graph_types/graph_drawing.h \
-SeqAn-1.3/seqan/graph_types/graph_interface.h \
-SeqAn-1.3/seqan/file.h \
-SeqAn-1.3/seqan/system.h \
-SeqAn-1.3/seqan/refinement.h \
-SeqAn-1.3/seqan/pipe.h \
-SeqAn-1.3/seqan/system/system_thread.h \
-SeqAn-1.3/seqan/system/system_base.h \
-SeqAn-1.3/seqan/system/system_event.h \
-SeqAn-1.3/seqan/system/file_directory.h \
-SeqAn-1.3/seqan/system/system_mutex.h \
-SeqAn-1.3/seqan/system/file_manual_forwards.h \
-SeqAn-1.3/seqan/system/system_generated_forwards.h \
-SeqAn-1.3/seqan/system/file_sync.h \
-SeqAn-1.3/seqan/system/file_async.h \
-SeqAn-1.3/seqan/system/system_sema.h \
-SeqAn-1.3/seqan/system/system_manual_forwards.h \
-SeqAn-1.3/seqan/misc/edit_environment.h \
-SeqAn-1.3/seqan/misc/misc_parsing.h \
-SeqAn-1.3/seqan/misc/misc_generated_forwards.h \
-SeqAn-1.3/seqan/misc/misc_base.h \
-SeqAn-1.3/seqan/misc/priority_type_heap.h \
-SeqAn-1.3/seqan/misc/priority_type_base.h \
-SeqAn-1.3/seqan/misc/misc_dequeue.h \
-SeqAn-1.3/seqan/misc/misc_set.h \
-SeqAn-1.3/seqan/misc/misc_map.h \
-SeqAn-1.3/seqan/misc/misc_svg.h \
-SeqAn-1.3/seqan/misc/misc_interval_tree.h \
-SeqAn-1.3/seqan/misc/misc_long_word.h \
-SeqAn-1.3/seqan/misc/misc_cmdparser.h \
-SeqAn-1.3/seqan/misc/misc_random.h \
-SeqAn-1.3/seqan/platform/platform_mingw.h \
-SeqAn-1.3/seqan/platform/platform_gcc.h \
-SeqAn-1.3/seqan/platform/platform_windows.h \
-SeqAn-1.3/seqan/platform/platform_solaris.h \
-SeqAn-1.3/seqan/platform/platform_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman.h \
-SeqAn-1.3/seqan/graph_align/graph_align_base.h \
-SeqAn-1.3/seqan/graph_align/graph_align_hirschberg.h \
-SeqAn-1.3/seqan/graph_align/graph_align_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_interface.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_config.h \
-SeqAn-1.3/seqan/parallel/parallel_generated_forwards.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_misc.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_primitives.h \
-SeqAn-1.3/seqan/parallel/parallel_macros.h \
-SeqAn-1.3/seqan/store/store_io_gff.h \
-SeqAn-1.3/seqan/store/store_library.h \
-SeqAn-1.3/seqan/store/store_read.h \
-SeqAn-1.3/seqan/store/store_annotation.h \
-SeqAn-1.3/seqan/store/store_intervaltree.h \
-SeqAn-1.3/seqan/store/store_io_ucsc.h \
-SeqAn-1.3/seqan/store/store_all.h \
-SeqAn-1.3/seqan/store/store_matepair.h \
-SeqAn-1.3/seqan/store/store_align_intervals.h \
-SeqAn-1.3/seqan/store/store_io.h \
-SeqAn-1.3/seqan/store/store_io_sam.h \
-SeqAn-1.3/seqan/store/store_align.h \
-SeqAn-1.3/seqan/store/store_io_bam.h \
-SeqAn-1.3/seqan/store/store_contig.h \
-SeqAn-1.3/seqan/store/store_generated_forwards.h \
-SeqAn-1.3/seqan/store/store_base.h \
-SeqAn-1.3/seqan/align.h \
-SeqAn-1.3/seqan/modifier/modifier_string.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet_expansion.h \
-SeqAn-1.3/seqan/modifier/modifier_shortcuts.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet.h \
-SeqAn-1.3/seqan/modifier/modifier_iterator.h \
-SeqAn-1.3/seqan/modifier/modifier_reverse.h \
-SeqAn-1.3/seqan/modifier/modifier_generated_forwards.h \
-SeqAn-1.3/seqan/modifier/modifier_view.h \
-SeqAn-1.3/seqan/modifier/modifier_functors.h \
-SeqAn-1.3/seqan/seeds2.h \
-SeqAn-1.3/seqan/index/index_sa_btree.h \
-SeqAn-1.3/seqan/index/find_quasar.h \
-SeqAn-1.3/seqan/index/index_esa_algs.h \
-SeqAn-1.3/seqan/index/index_skew7.h \
-SeqAn-1.3/seqan/index/index_pizzachili.h \
-SeqAn-1.3/seqan/index/index_sa_lss.h \
-SeqAn-1.3/seqan/index/pump_extender7.h \
-SeqAn-1.3/seqan/index/index_shawarma.h \
-SeqAn-1.3/seqan/index/find_index_approx.h \
-SeqAn-1.3/seqan/index/index_lcp.h \
-SeqAn-1.3/seqan/index/find_swift.h \
-SeqAn-1.3/seqan/index/shape_threshold.h \
-SeqAn-1.3/seqan/index/pizzachili_api.h \
-SeqAn-1.3/seqan/index/index_sa_mm.h \
-SeqAn-1.3/seqan/index/index_esa_stree.h \
-SeqAn-1.3/seqan/index/index_qgram.h \
-SeqAn-1.3/seqan/index/pump_extender3.h \
-SeqAn-1.3/seqan/index/shape_onegapped.h \
-SeqAn-1.3/seqan/index/find_index_qgram.h \
-SeqAn-1.3/seqan/index/index_skew3.h \
-SeqAn-1.3/seqan/index/index_childtab.h \
-SeqAn-1.3/seqan/index/pipe_merger7.h \
-SeqAn-1.3/seqan/index/pipe_merger3.h \
-SeqAn-1.3/seqan/index/repeat_base.h \
-SeqAn-1.3/seqan/index/index_pizzachili_find.h \
-SeqAn-1.3/seqan/index/index_sa_qsort.h \
-SeqAn-1.3/seqan/index/index_shims.h \
-SeqAn-1.3/seqan/index/index_manual_forwards.h \
-SeqAn-1.3/seqan/index/shape_base.h \
-SeqAn-1.3/seqan/index/shape_predefined.h \
-SeqAn-1.3/seqan/index/index_pizzachili_string.h \
-SeqAn-1.3/seqan/index/index_generated_forwards.h \
-SeqAn-1.3/seqan/index/find_index_esa.h \
-SeqAn-1.3/seqan/index/pump_separator7.h \
-SeqAn-1.3/seqan/index/index_esa_base.h \
-SeqAn-1.3/seqan/index/radix.h \
-SeqAn-1.3/seqan/index/index_skew7_multi.h \
-SeqAn-1.3/seqan/index/index_esa_algs_multi.h \
-SeqAn-1.3/seqan/index/index_base.h \
-SeqAn-1.3/seqan/index/shape_gapped.h \
-SeqAn-1.3/seqan/index/index_lcp_tree.h \
-SeqAn-1.3/seqan/index/index_esa_drawing.h \
-SeqAn-1.3/seqan/index/find_index.h \
-SeqAn-1.3/seqan/index/pump_lcp_core.h \
-SeqAn-1.3/seqan/index/index_dfi.h \
-SeqAn-1.3/seqan/index/index_sa_bwtwalk.h \
-SeqAn-1.3/seqan/index/index_qgram_openaddressing.h \
-SeqAn-1.3/seqan/index/index_bwt.h \
-SeqAn-1.3/seqan/index/index_wotd.h \
-SeqAn-1.3/seqan/statistics/statistics_base.h \
-SeqAn-1.3/seqan/statistics/statistics_markov_model.h \
-SeqAn-1.3/seqan/statistics/statistics_generated_forwards.h \
-SeqAn-1.3/seqan/score.h \
-SeqAn-1.3/seqan/sequence.h \
-SeqAn-1.3/seqan/parallel.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithms_generated_forwards.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_hmm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_lis_his.h \
-SeqAn-1.3/seqan/blast.h \
-SeqAn-1.3/seqan/store.h \
-SeqAn-1.3/seqan/graph_align.h \
-SeqAn-1.3/seqan/random/random_lognormal.h \
-SeqAn-1.3/seqan/random/ext_MersenneTwister.h \
-SeqAn-1.3/seqan/random/random_generated_forwards.h \
-SeqAn-1.3/seqan/random/random_rng_functor.h \
-SeqAn-1.3/seqan/random/random_base.h \
-SeqAn-1.3/seqan/random/random_uniform.h \
-SeqAn-1.3/seqan/random/random_shuffle.h \
-SeqAn-1.3/seqan/random/random_normal.h \
-SeqAn-1.3/seqan/random/random_geometric.h \
-SeqAn-1.3/seqan/random/random_mt19937.h \
-SeqAn-1.3/seqan/basic.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_progressive.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_distance.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_io.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_kmer.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_refinement.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_msa.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
-SeqAn-1.3/seqan/graph_msa/graph_msa_generated_forwards.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_library.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_base.h \
-SeqAn-1.3/seqan/basic/basic_sse2.h \
-SeqAn-1.3/seqan/basic/basic_forwards.h \
-SeqAn-1.3/seqan/basic/basic_testing.h \
-SeqAn-1.3/seqan/basic/basic_counted_ptr.h \
-SeqAn-1.3/seqan/basic/basic_iterator_base.h \
-SeqAn-1.3/seqan/basic/basic_pointer.h \
-SeqAn-1.3/seqan/basic/basic_allocator_chunkpool.h \
-SeqAn-1.3/seqan/basic/basic_parallelism.h \
-SeqAn-1.3/seqan/basic/basic_allocator_singlepool.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adaptor.h \
-SeqAn-1.3/seqan/basic/basic_profile.h \
-SeqAn-1.3/seqan/basic/basic_tag.h \
-SeqAn-1.3/seqan/basic/basic_compare.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface.h \
-SeqAn-1.3/seqan/basic/basic_iterator_simple.h \
-SeqAn-1.3/seqan/basic/basic_definition.h \
-SeqAn-1.3/seqan/basic/basic_operator.h \
-SeqAn-1.3/seqan/basic/basic_holder_dynamic.h \
-SeqAn-1.3/seqan/basic/basic_allocator_multipool.h \
-SeqAn-1.3/seqan/basic/basic_proxy.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple_tabs.h \
-SeqAn-1.3/seqan/basic/basic_metaprogramming.h \
-SeqAn-1.3/seqan/basic/basic_host.h \
-SeqAn-1.3/seqan/basic/basic_allocator_to_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_interface.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface2.h \
-SeqAn-1.3/seqan/basic/basic_logvalue.h \
-SeqAn-1.3/seqan/basic/basic_volatile_ptr.h \
-SeqAn-1.3/seqan/basic/basic_debug.h \
-SeqAn-1.3/seqan/basic/basic_profchar.h \
-SeqAn-1.3/seqan/basic/basic_aggregates.h \
-SeqAn-1.3/seqan/basic/basic_transport.h \
-SeqAn-1.3/seqan/basic/basic_holder.h \
-SeqAn-1.3/seqan/basic/basic_converter.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple.h \
-SeqAn-1.3/seqan/basic/basic_type.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adapt_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_simple.h \
-SeqAn-1.3/seqan/basic/basic_iterator.h \
-SeqAn-1.3/seqan/basic/basic_generated_forwards.h \
-SeqAn-1.3/seqan/basic/basic_iterator_position.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_trait_basic.h \
-SeqAn-1.3/seqan/sequence/sequence_forwards.h \
-SeqAn-1.3/seqan/sequence/segment_infix.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_tight.h \
-SeqAn-1.3/seqan/sequence/segment_base.h \
-SeqAn-1.3/seqan/sequence/sequence_lexical.h \
-SeqAn-1.3/seqan/sequence/string_cstyle.h \
-SeqAn-1.3/seqan/sequence/sequence_concatenator.h \
-SeqAn-1.3/seqan/sequence/string_packed.h \
-SeqAn-1.3/seqan/sequence/sequence_stream.h \
-SeqAn-1.3/seqan/sequence/sequence_shortcuts.h \
-SeqAn-1.3/seqan/sequence/adapt_std_list.h \
-SeqAn-1.3/seqan/sequence/string_base.h \
-SeqAn-1.3/seqan/sequence/string_set_owner.h \
-SeqAn-1.3/seqan/sequence/adapt_std_string.h \
-SeqAn-1.3/seqan/sequence/sequence_generated_forwards.h \
-SeqAn-1.3/seqan/sequence/string_set_concat_direct.h \
-SeqAn-1.3/seqan/sequence/sequence_interface.h \
-SeqAn-1.3/seqan/sequence/adapt_array_pointer.h \
-SeqAn-1.3/seqan/sequence/segment_suffix.h \
-SeqAn-1.3/seqan/sequence/string_array.h \
-SeqAn-1.3/seqan/sequence/iter_concat_virtual.h \
-SeqAn-1.3/seqan/sequence/segment_prefix.h \
-SeqAn-1.3/seqan/sequence/string_block.h \
-SeqAn-1.3/seqan/sequence/string_set_base.h \
-SeqAn-1.3/seqan/sequence/adapt_std_vector.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_generous.h \
-SeqAn-1.3/seqan/sequence/string_alloc.h \
-SeqAn-1.3/seqan/modifier.h \
-SeqAn-1.3/seqan/random.h \
-SeqAn-1.3/seqan/statistics.h \
-SeqAn-1.3/seqan/consensus.h \
-SeqAn-1.3/seqan/find.h \
-SeqAn-1.3/seqan/find2.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_inexact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_fragment.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_annotation.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_align.h \
-SeqAn-1.3/seqan/refinement/refinement_generated_forwards.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_scoring.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact_iterative.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align_adapt.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_aligngraph.h \
-SeqAn-1.3/seqan/seeds/global_seed_chain.h \
-SeqAn-1.3/seqan/seeds/seedSet_score.h \
-SeqAn-1.3/seqan/seeds/seeds_generated_forwards.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align_affine.h \
-SeqAn-1.3/seqan/seeds/banded_align.h \
-SeqAn-1.3/seqan/seeds/memoryManager_int.h \
-SeqAn-1.3/seqan/seeds/seedHandlingTags.h \
-SeqAn-1.3/seqan/seeds/seedSet_iterator.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align.h \
-SeqAn-1.3/seqan/seeds/seed_multi.h \
-SeqAn-1.3/seqan/seeds/seedSet_base.h \
-SeqAn-1.3/seqan/seeds/propertyMap.h \
-SeqAn-1.3/seqan/seeds/memoryManager_base.h \
-SeqAn-1.3/seqan/seeds/seed_base.h \
-SeqAn-1.3/seqan/graph_msa.h \
-SeqAn-1.3/seqan/consensus/consensus_score.h \
-SeqAn-1.3/seqan/consensus/consensus_base.h \
-SeqAn-1.3/seqan/consensus/consensus_generated_forwards.h \
-SeqAn-1.3/seqan/consensus/consensus_realign.h \
-SeqAn-1.3/seqan/consensus/consensus_library.h \
-SeqAn-1.3/seqan/map/map_generated_forwards.h \
-SeqAn-1.3/seqan/map/map_base.h \
-SeqAn-1.3/seqan/map/map_chooser.h \
-SeqAn-1.3/seqan/map/map_vector.h \
-SeqAn-1.3/seqan/map/sumlist_mini.h \
-SeqAn-1.3/seqan/map/map_adapter_stl.h \
-SeqAn-1.3/seqan/map/sumlist.h \
-SeqAn-1.3/seqan/map/map_skiplist.h \
-SeqAn-1.3/seqan/map/sumlist_skip.h \
-SeqAn-1.3/seqan/blast/blast_stream_report.h \
-SeqAn-1.3/seqan/blast/blast_run.h \
-SeqAn-1.3/seqan/blast/blast_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hsp.h \
-SeqAn-1.3/seqan/blast/blast_base.h \
-SeqAn-1.3/seqan/blast/blast_hit.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit.h \
-SeqAn-1.3/seqan/blast/blast_iterator.h \
-SeqAn-1.3/seqan/blast/blast_parsing.h \
-SeqAn-1.3/seqan/blast/blast_report.h \
-SeqAn-1.3/seqan/blast/blast_generated_forwards.h \
-SeqAn-1.3/seqan/blast/blast_stream_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hit_iterator.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_base.h \
-SeqAn-1.3/seqan/seeds2/seeds_extension.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_unordered.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_base.h \
-SeqAn-1.3/seqan/seeds2/seeds2_generated_forwards.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_diagonal.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_simple.h \
-SeqAn-1.3/seqan/seeds2/seeds_base.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_combination.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_non_scored.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_linear.h \
-SeqAn-1.3/seqan/seeds2/align_chain_banded.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_linear.h \
-SeqAn-1.3/seqan/seeds2/basic_iter_indirect.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_gusfield.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_chained.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_scored.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_base.h \
-SeqAn-1.3/seqan/map.h \
-SeqAn-1.3/seqan/find/find_pattern_base.h \
-SeqAn-1.3/seqan/find/find_multiple_shiftand.h \
-SeqAn-1.3/seqan/find/find_generated_forwards.h \
-SeqAn-1.3/seqan/find/find_horspool.h \
-SeqAn-1.3/seqan/find/find_abndm.h \
-SeqAn-1.3/seqan/find/find_score.h \
-SeqAn-1.3/seqan/find/find_set_horspool.h \
-SeqAn-1.3/seqan/find/find_wild_shiftand.h \
-SeqAn-1.3/seqan/find/find_hamming_simple.h \
-SeqAn-1.3/seqan/find/find_shiftand.h \
-SeqAn-1.3/seqan/find/find_begin.h \
-SeqAn-1.3/seqan/find/find_shiftor.h \
-SeqAn-1.3/seqan/find/find_wumanber.h \
-SeqAn-1.3/seqan/find/find_multi.h \
-SeqAn-1.3/seqan/find/find_simple.h \
-SeqAn-1.3/seqan/find/find_bndm.h \
-SeqAn-1.3/seqan/find/find_pex.h \
-SeqAn-1.3/seqan/find/find_bom.h \
-SeqAn-1.3/seqan/find/find_ahocorasick.h \
-SeqAn-1.3/seqan/find/find_multiple_bfam.h \
-SeqAn-1.3/seqan/find/find_myers_ukkonen.h \
-SeqAn-1.3/seqan/find/find_base.h \
-SeqAn-1.3/seqan/index.h \
-SeqAn-1.3/seqan/graph_types.h \
-SeqAn-1.3/seqan/find_motif/profile.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pmsp.h \
-SeqAn-1.3/seqan/find_motif/sequence_model_types.h \
-SeqAn-1.3/seqan/find_motif/find_motif_base.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_p.h \
-SeqAn-1.3/seqan/find_motif/find_motif_epatternbranching.h \
-SeqAn-1.3/seqan/find_motif/find_motif_projection.h \
-SeqAn-1.3/seqan/find_motif/find_motif_generated_forwards.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_c.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_base.h \
-SeqAn-1.3/seqan/find_motif/em_algorithm.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pms1.h \
-SeqAn-1.3/seqan/find_motif/frequency_distribution.h \
-SeqAn-1.3/seqan.h
+SeqAn-1.4.2/LICENSE \
+SeqAn-1.4.2/README.rst \
+SeqAn-1.4.2/seqan/align/align_base.h \
+SeqAn-1.4.2/seqan/align/align_cols.h \
+SeqAn-1.4.2/seqan/align/align_config.h \
+SeqAn-1.4.2/seqan/align/align_iterator_base.h \
+SeqAn-1.4.2/seqan/align/alignment_algorithm_tags.h \
+SeqAn-1.4.2/seqan/align/alignment_operations.h \
+SeqAn-1.4.2/seqan/align/align_metafunctions.h \
+SeqAn-1.4.2/seqan/align/align_traceback.h \
+SeqAn-1.4.2/seqan/align/dp_algorithm_impl.h \
+SeqAn-1.4.2/seqan/align/dp_band.h \
+SeqAn-1.4.2/seqan/align/dp_cell_affine.h \
+SeqAn-1.4.2/seqan/align/dp_cell.h \
+SeqAn-1.4.2/seqan/align/dp_cell_linear.h \
+SeqAn-1.4.2/seqan/align/dp_formula_affine.h \
+SeqAn-1.4.2/seqan/align/dp_formula.h \
+SeqAn-1.4.2/seqan/align/dp_formula_linear.h \
+SeqAn-1.4.2/seqan/align/dp_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_trace_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_meta_info.h \
+SeqAn-1.4.2/seqan/align/dp_profile.h \
+SeqAn-1.4.2/seqan/align/dp_scout.h \
+SeqAn-1.4.2/seqan/align/dp_setup.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_adaptor.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_impl.h \
+SeqAn-1.4.2/seqan/align/dp_trace_segment.h \
+SeqAn-1.4.2/seqan/align/evaluate_alignment.h \
+SeqAn-1.4.2/seqan/align/gap_anchor.h \
+SeqAn-1.4.2/seqan/align/gapped_value_type.h \
+SeqAn-1.4.2/seqan/align/gaps_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_array.h \
+SeqAn-1.4.2/seqan/align/gaps_base.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_array.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_base.h \
+SeqAn-1.4.2/seqan/align/global_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/global_alignment_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_specialized.h \
+SeqAn-1.4.2/seqan/align/global_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align.h \
+SeqAn-1.4.2/seqan/align/INFO \
+SeqAn-1.4.2/seqan/align/local_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_banded_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/matrix_base.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_argument.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_ctd_support.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_exceptions.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_option.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_type_support.h \
+SeqAn-1.4.2/seqan/arg_parse/argument_parser.h \
+SeqAn-1.4.2/seqan/arg_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/INFO \
+SeqAn-1.4.2/seqan/arg_parse/tool_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/xml_support.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record_util.h \
+SeqAn-1.4.2/seqan/bam_io/bam_header_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_bai.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_base.h \
+SeqAn-1.4.2/seqan/bam_io/bam_io_context.h \
+SeqAn-1.4.2/seqan/bam_io/bam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/bam_sam_conversion.h \
+SeqAn-1.4.2/seqan/bam_io/bam_stream.h \
+SeqAn-1.4.2/seqan/bam_io/bam_tags_dict.h \
+SeqAn-1.4.2/seqan/bam_io/bam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/cigar.h \
+SeqAn-1.4.2/seqan/bam_io.h \
+SeqAn-1.4.2/seqan/bam_io/INFO \
+SeqAn-1.4.2/seqan/bam_io/read_bam.h \
+SeqAn-1.4.2/seqan/bam_io/read_sam.h \
+SeqAn-1.4.2/seqan/bam_io/sam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/sam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/write_bam.h \
+SeqAn-1.4.2/seqan/bam_io/write_sam.h \
+SeqAn-1.4.2/seqan/bam_io/xam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/xam_writer.h \
+SeqAn-1.4.2/seqan/basic/aggregate_concept.h \
+SeqAn-1.4.2/seqan/basic/allocator_chunkpool.h \
+SeqAn-1.4.2/seqan/basic/allocator_interface.h \
+SeqAn-1.4.2/seqan/basic/allocator_multipool.h \
+SeqAn-1.4.2/seqan/basic/allocator_simple.h \
+SeqAn-1.4.2/seqan/basic/allocator_singlepool.h \
+SeqAn-1.4.2/seqan/basic/allocator_to_std.h \
+SeqAn-1.4.2/seqan/basic/alphabet_adapt_builtins.h \
+SeqAn-1.4.2/seqan/basic/alphabet_bio.h \
+SeqAn-1.4.2/seqan/basic/alphabet_concept.h \
+SeqAn-1.4.2/seqan/basic/alphabet_math.h \
+SeqAn-1.4.2/seqan/basic/alphabet_profile.h \
+SeqAn-1.4.2/seqan/basic/alphabet_qualities.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_funcs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_tabs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_simple_type.h \
+SeqAn-1.4.2/seqan/basic/alphabet_storage.h \
+SeqAn-1.4.2/seqan/basic/array_construct_destruct.h \
+SeqAn-1.4.2/seqan/basic/basic_aggregate.h \
+SeqAn-1.4.2/seqan/basic/basic_allocator.h \
+SeqAn-1.4.2/seqan/basic/basic_alphabet.h \
+SeqAn-1.4.2/seqan/basic/basic_concept.h \
+SeqAn-1.4.2/seqan/basic/basic_container.h \
+SeqAn-1.4.2/seqan/basic/basic_debug.h \
+SeqAn-1.4.2/seqan/basic/basic_exception.h \
+SeqAn-1.4.2/seqan/basic/basic_fundamental.h \
+SeqAn-1.4.2/seqan/basic/basic_iterator.h \
+SeqAn-1.4.2/seqan/basic/basic_math.h \
+SeqAn-1.4.2/seqan/basic/basic_metaprogramming.h \
+SeqAn-1.4.2/seqan/basic/basic_parallelism.h \
+SeqAn-1.4.2/seqan/basic/basic_proxy.h \
+SeqAn-1.4.2/seqan/basic/basic_smart_pointer.h \
+SeqAn-1.4.2/seqan/basic/basic_tangle.h \
+SeqAn-1.4.2/seqan/basic/basic_type.h \
+SeqAn-1.4.2/seqan/basic/boost_preprocessor_subset.h \
+SeqAn-1.4.2/seqan/basic/builtin_functions.h \
+SeqAn-1.4.2/seqan/basic/concept_checking.h \
+SeqAn-1.4.2/seqan/basic/container_concept.h \
+SeqAn-1.4.2/seqan/basic/debug_helper.h \
+SeqAn-1.4.2/seqan/basic/debug_test_system.h \
+SeqAn-1.4.2/seqan/basic/fundamental_comparison.h \
+SeqAn-1.4.2/seqan/basic/fundamental_concepts.h \
+SeqAn-1.4.2/seqan/basic/fundamental_conversion.h \
+SeqAn-1.4.2/seqan/basic/fundamental_metafunctions.h \
+SeqAn-1.4.2/seqan/basic/fundamental_tags.h \
+SeqAn-1.4.2/seqan/basic/fundamental_transport.h \
+SeqAn-1.4.2/seqan/basic.h \
+SeqAn-1.4.2/seqan/basic/holder_base.h \
+SeqAn-1.4.2/seqan/basic/holder_simple.h \
+SeqAn-1.4.2/seqan/basic/holder_tristate.h \
+SeqAn-1.4.2/seqan/basic/hosted_type_interface.h \
+SeqAn-1.4.2/seqan/basic/INFO \
+SeqAn-1.4.2/seqan/basic/iterator_adaptor.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_pointer.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_std.h \
+SeqAn-1.4.2/seqan/basic/iterator_base.h \
+SeqAn-1.4.2/seqan/basic/iterator_concept.h \
+SeqAn-1.4.2/seqan/basic/iterator_interface.h \
+SeqAn-1.4.2/seqan/basic/iterator_position.h \
+SeqAn-1.4.2/seqan/basic/macro_deprecated.h \
+SeqAn-1.4.2/seqan/basic/math_functions.h \
+SeqAn-1.4.2/seqan/basic/math_log_space_value.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_control.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_enable_if.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_logic.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_math.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_type.h \
+SeqAn-1.4.2/seqan/basic/pair_base.h \
+SeqAn-1.4.2/seqan/basic/pair_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/pair_packed.h \
+SeqAn-1.4.2/seqan/basic/profiling.h \
+SeqAn-1.4.2/seqan/basic/proxy_base.h \
+SeqAn-1.4.2/seqan/basic/proxy_iterator.h \
+SeqAn-1.4.2/seqan/basic/test_system.h \
+SeqAn-1.4.2/seqan/basic/triple_base.h \
+SeqAn-1.4.2/seqan/basic/triple_packed.h \
+SeqAn-1.4.2/seqan/basic/tuple_base.h \
+SeqAn-1.4.2/seqan/basic/tuple_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/volatile_ptr.h \
+SeqAn-1.4.2/seqan/consensus/consensus_base.h \
+SeqAn-1.4.2/seqan/consensus/consensus_library.h \
+SeqAn-1.4.2/seqan/consensus/consensus_realign.h \
+SeqAn-1.4.2/seqan/consensus/consensus_score.h \
+SeqAn-1.4.2/seqan/consensus.h \
+SeqAn-1.4.2/seqan/consensus/INFO \
+SeqAn-1.4.2/seqan/file/chunk_collector.h \
+SeqAn-1.4.2/seqan/file/cstream.h \
+SeqAn-1.4.2/seqan/file/file_base.h \
+SeqAn-1.4.2/seqan/file/file_cstyle.h \
+SeqAn-1.4.2/seqan/file/file_filereader.h \
+SeqAn-1.4.2/seqan/file/file_filereaderiterator.h \
+SeqAn-1.4.2/seqan/file/file_format_cgviz.h \
+SeqAn-1.4.2/seqan/file/file_format_embl.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta_align.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta.h \
+SeqAn-1.4.2/seqan/file/file_format_genbank.h \
+SeqAn-1.4.2/seqan/file/file_format_guess.h \
+SeqAn-1.4.2/seqan/file/file_format.h \
+SeqAn-1.4.2/seqan/file/file_format_mmap.h \
+SeqAn-1.4.2/seqan/file/file_format_raw.h \
+SeqAn-1.4.2/seqan/file/file_forwards.h \
+SeqAn-1.4.2/seqan/file/file_interface.h \
+SeqAn-1.4.2/seqan/file/file_mapping.h \
+SeqAn-1.4.2/seqan/file/file_page.h \
+SeqAn-1.4.2/seqan/file.h \
+SeqAn-1.4.2/seqan/file/INFO \
+SeqAn-1.4.2/seqan/file/meta.h \
+SeqAn-1.4.2/seqan/file/stream_algorithms.h \
+SeqAn-1.4.2/seqan/file/stream.h \
+SeqAn-1.4.2/seqan/file/string_external.h \
+SeqAn-1.4.2/seqan/file/string_mmap.h \
+SeqAn-1.4.2/seqan/find/find_abndm.h \
+SeqAn-1.4.2/seqan/find/find_ahocorasick.h \
+SeqAn-1.4.2/seqan/find/find_base.h \
+SeqAn-1.4.2/seqan/find/find_begin.h \
+SeqAn-1.4.2/seqan/find/find_bndm.h \
+SeqAn-1.4.2/seqan/find/find_bom.h \
+SeqAn-1.4.2/seqan/find/find_hamming_simple.h \
+SeqAn-1.4.2/seqan/find/find_horspool.h \
+SeqAn-1.4.2/seqan/find/find_multi.h \
+SeqAn-1.4.2/seqan/find/find_multiple_bfam.h \
+SeqAn-1.4.2/seqan/find/find_multiple_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_myers_ukkonen.h \
+SeqAn-1.4.2/seqan/find/find_pattern_base.h \
+SeqAn-1.4.2/seqan/find/find_pex.h \
+SeqAn-1.4.2/seqan/find/find_score.h \
+SeqAn-1.4.2/seqan/find/find_set_horspool.h \
+SeqAn-1.4.2/seqan/find/find_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_shiftor.h \
+SeqAn-1.4.2/seqan/find/find_simple.h \
+SeqAn-1.4.2/seqan/find/find_wild_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_wumanber.h \
+SeqAn-1.4.2/seqan/find.h \
+SeqAn-1.4.2/seqan/find/INFO \
+SeqAn-1.4.2/seqan/gff_io/gff_io_base.h \
+SeqAn-1.4.2/seqan/gff_io/gff_io_context.h \
+SeqAn-1.4.2/seqan/gff_io/gff_stream.h \
+SeqAn-1.4.2/seqan/gff_io.h \
+SeqAn-1.4.2/seqan/gff_io/INFO \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_hmm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_lis_his.h \
+SeqAn-1.4.2/seqan/graph_algorithms.h \
+SeqAn-1.4.2/seqan/graph_algorithms/INFO \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_aligngraph.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_align.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_annotation.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact_iterative.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_fragment.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_inexact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_scoring.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align_adapt.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align.h \
+SeqAn-1.4.2/seqan/graph_align.h \
+SeqAn-1.4.2/seqan/graph_align/INFO \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_base.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_distance.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_io.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_kmer.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_library.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_progressive.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_refinement.h \
+SeqAn-1.4.2/seqan/graph_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/INFO \
+SeqAn-1.4.2/seqan/graph_types/graph_base.h \
+SeqAn-1.4.2/seqan/graph_types/graph_drawing.h \
+SeqAn-1.4.2/seqan/graph_types/graph_edgestump.h \
+SeqAn-1.4.2/seqan/graph_types/graph_idmanager.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_automaton.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_directed.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_fragment.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_hmm.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_oracle.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_tree.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_trie.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_undirected.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_wordgraph.h \
+SeqAn-1.4.2/seqan/graph_types/graph_interface.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_adjacency.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_bfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_dfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_edge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_outedge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_vertex.h \
+SeqAn-1.4.2/seqan/graph_types/graph_property.h \
+SeqAn-1.4.2/seqan/graph_types/graph_utility_parsing.h \
+SeqAn-1.4.2/seqan/graph_types.h \
+SeqAn-1.4.2/seqan/graph_types/INFO \
+SeqAn-1.4.2/seqan/index/find_index_approx.h \
+SeqAn-1.4.2/seqan/index/find_index_esa.h \
+SeqAn-1.4.2/seqan/index/find_index.h \
+SeqAn-1.4.2/seqan/index/find_index_qgram.h \
+SeqAn-1.4.2/seqan/index/find_pigeonhole.h \
+SeqAn-1.4.2/seqan/index/find_quasar.h \
+SeqAn-1.4.2/seqan/index/find_swift.h \
+SeqAn-1.4.2/seqan/index.h \
+SeqAn-1.4.2/seqan/index/index_base.h \
+SeqAn-1.4.2/seqan/index/index_bwt.h \
+SeqAn-1.4.2/seqan/index/index_childtab.h \
+SeqAn-1.4.2/seqan/index/index_dfi.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs_multi.h \
+SeqAn-1.4.2/seqan/index/index_esa_base.h \
+SeqAn-1.4.2/seqan/index/index_esa_drawing.h \
+SeqAn-1.4.2/seqan/index/index_esa_stree.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_doc.h \
+SeqAn-1.4.2/seqan/index/index_fm_dox.h \
+SeqAn-1.4.2/seqan/index/index_fm.h \
+SeqAn-1.4.2/seqan/index/index_fm_lf_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_prefix_sum_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_bms.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_wt.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_sentinel_rank_dictionary.h \
+SeqAn-1.4.2/seqan/index/index_fm_sparse_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_stree.h \
+SeqAn-1.4.2/seqan/index/index_forwards.h \
+SeqAn-1.4.2/seqan/index/index_lcp.h \
+SeqAn-1.4.2/seqan/index/index_lcp_tree.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_find.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_string.h \
+SeqAn-1.4.2/seqan/index/index_qgram.h \
+SeqAn-1.4.2/seqan/index/index_qgram_openaddressing.h \
+SeqAn-1.4.2/seqan/index/index_sa_btree.h \
+SeqAn-1.4.2/seqan/index/index_sa_bwtwalk.h \
+SeqAn-1.4.2/seqan/index/index_sa_lss.h \
+SeqAn-1.4.2/seqan/index/index_sa_mm.h \
+SeqAn-1.4.2/seqan/index/index_sa_qsort.h \
+SeqAn-1.4.2/seqan/index/index_shawarma.h \
+SeqAn-1.4.2/seqan/index/index_shims.h \
+SeqAn-1.4.2/seqan/index/index_skew3.h \
+SeqAn-1.4.2/seqan/index/index_skew7.h \
+SeqAn-1.4.2/seqan/index/index_skew7_multi.h \
+SeqAn-1.4.2/seqan/index/index_wotd.h \
+SeqAn-1.4.2/seqan/index/INFO \
+SeqAn-1.4.2/seqan/index/pipe_merger3.h \
+SeqAn-1.4.2/seqan/index/pipe_merger7.h \
+SeqAn-1.4.2/seqan/index/pizzachili_api.h \
+SeqAn-1.4.2/seqan/index/pump_extender3.h \
+SeqAn-1.4.2/seqan/index/pump_extender7.h \
+SeqAn-1.4.2/seqan/index/pump_lcp_core.h \
+SeqAn-1.4.2/seqan/index/pump_separator7.h \
+SeqAn-1.4.2/seqan/index/radix.h \
+SeqAn-1.4.2/seqan/index/repeat_base.h \
+SeqAn-1.4.2/seqan/index/shape_base.h \
+SeqAn-1.4.2/seqan/index/shape_gapped.h \
+SeqAn-1.4.2/seqan/index/shape_onegapped.h \
+SeqAn-1.4.2/seqan/index/shape_predefined.h \
+SeqAn-1.4.2/seqan/index/shape_threshold.h \
+SeqAn-1.4.2/seqan/LICENSE \
+SeqAn-1.4.2/seqan/map.h \
+SeqAn-1.4.2/seqan/map/INFO \
+SeqAn-1.4.2/seqan/map/map_adapter_stl.h \
+SeqAn-1.4.2/seqan/map/map_base.h \
+SeqAn-1.4.2/seqan/map/map_chooser.h \
+SeqAn-1.4.2/seqan/map/map_skiplist.h \
+SeqAn-1.4.2/seqan/map/map_vector.h \
+SeqAn-1.4.2/seqan/map/sumlist.h \
+SeqAn-1.4.2/seqan/map/sumlist_mini.h \
+SeqAn-1.4.2/seqan/map/sumlist_skip.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdoption.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_ctd_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_parse.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_type_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/INFO \
+SeqAn-1.4.2/seqan/misc/edit_environment.h \
+SeqAn-1.4.2/seqan/misc/INFO \
+SeqAn-1.4.2/seqan/misc/misc_accumulators.h \
+SeqAn-1.4.2/seqan/misc/misc_base.h \
+SeqAn-1.4.2/seqan/misc/misc_bit_twiddling.h \
+SeqAn-1.4.2/seqan/misc/misc_cmdparser.h \
+SeqAn-1.4.2/seqan/misc/misc_dequeue.h \
+SeqAn-1.4.2/seqan/misc/misc_interval_tree.h \
+SeqAn-1.4.2/seqan/misc/misc_map.h \
+SeqAn-1.4.2/seqan/misc/misc_memset.h \
+SeqAn-1.4.2/seqan/misc/misc_name_store_cache.h \
+SeqAn-1.4.2/seqan/misc/misc_parsing.h \
+SeqAn-1.4.2/seqan/misc/misc_set.h \
+SeqAn-1.4.2/seqan/misc/misc_sse2.h \
+SeqAn-1.4.2/seqan/misc/misc_svg.h \
+SeqAn-1.4.2/seqan/misc/misc_terminal.h \
+SeqAn-1.4.2/seqan/misc/misc_union_find.h \
+SeqAn-1.4.2/seqan/misc/priority_type_base.h \
+SeqAn-1.4.2/seqan/misc/priority_type_heap.h \
+SeqAn-1.4.2/seqan/modifier.h \
+SeqAn-1.4.2/seqan/modifier/INFO \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet_expansion.h \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet.h \
+SeqAn-1.4.2/seqan/modifier/modifier_functors.h \
+SeqAn-1.4.2/seqan/modifier/modifier_iterator.h \
+SeqAn-1.4.2/seqan/modifier/modifier_reverse.h \
+SeqAn-1.4.2/seqan/modifier/modifier_shortcuts.h \
+SeqAn-1.4.2/seqan/modifier/modifier_string.h \
+SeqAn-1.4.2/seqan/modifier/modifier_view.h \
+SeqAn-1.4.2/seqan/parallel.h \
+SeqAn-1.4.2/seqan/parallel/INFO \
+SeqAn-1.4.2/seqan/parallel/parallel_algorithms.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_misc.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_primitives.h \
+SeqAn-1.4.2/seqan/parallel/parallel_macros.h \
+SeqAn-1.4.2/seqan/parallel/parallel_splitting.h \
+SeqAn-1.4.2/seqan/parallel/parallel_tags.h \
+SeqAn-1.4.2/seqan/pipe.h \
+SeqAn-1.4.2/seqan/pipe/INFO \
+SeqAn-1.4.2/seqan/pipe/pipe_base.h \
+SeqAn-1.4.2/seqan/pipe/pipe_caster.h \
+SeqAn-1.4.2/seqan/pipe/pipe_counter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_echoer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_edit_environment.h \
+SeqAn-1.4.2/seqan/pipe/pipe_filter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_iterator.h \
+SeqAn-1.4.2/seqan/pipe/pipe_joiner.h \
+SeqAn-1.4.2/seqan/pipe/pipe_namer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_sampler.h \
+SeqAn-1.4.2/seqan/pipe/pipe_shifter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_source.h \
+SeqAn-1.4.2/seqan/pipe/pipe_tupler.h \
+SeqAn-1.4.2/seqan/pipe/pool_base.h \
+SeqAn-1.4.2/seqan/pipe/pool_mapper.h \
+SeqAn-1.4.2/seqan/pipe/pool_sorter.h \
+SeqAn-1.4.2/seqan/platform.h \
+SeqAn-1.4.2/seqan/platform/INFO \
+SeqAn-1.4.2/seqan/platform/platform_gcc.h \
+SeqAn-1.4.2/seqan/platform/platform_icc.h \
+SeqAn-1.4.2/seqan/platform/platform_mingw.h \
+SeqAn-1.4.2/seqan/platform/platform_nvcc.h \
+SeqAn-1.4.2/seqan/platform/platform_pgi.h \
+SeqAn-1.4.2/seqan/platform/platform_solaris.h \
+SeqAn-1.4.2/seqan/platform/platform_windows.h \
+SeqAn-1.4.2/seqan/platform/windows_stdint.h \
+SeqAn-1.4.2/seqan/random/ext_MersenneTwister.h \
+SeqAn-1.4.2/seqan/random.h \
+SeqAn-1.4.2/seqan/random/INFO \
+SeqAn-1.4.2/seqan/random/random_base.h \
+SeqAn-1.4.2/seqan/random/random_beta.h \
+SeqAn-1.4.2/seqan/random/random_beta_kfunc.h \
+SeqAn-1.4.2/seqan/random/random_geometric.h \
+SeqAn-1.4.2/seqan/random/random_lognormal.h \
+SeqAn-1.4.2/seqan/random/random_mt19937.h \
+SeqAn-1.4.2/seqan/random/random_normal.h \
+SeqAn-1.4.2/seqan/random/random_rng_functor.h \
+SeqAn-1.4.2/seqan/random/random_shuffle.h \
+SeqAn-1.4.2/seqan/random/random_uniform.h \
+SeqAn-1.4.2/seqan/score.h \
+SeqAn-1.4.2/seqan/score/INFO \
+SeqAn-1.4.2/seqan/score/score_base.h \
+SeqAn-1.4.2/seqan/score/score_edit.h \
+SeqAn-1.4.2/seqan/score/score_matrix_data.h \
+SeqAn-1.4.2/seqan/score/score_matrix.h \
+SeqAn-1.4.2/seqan/score/score_matrix_io.h \
+SeqAn-1.4.2/seqan/score/score_simple.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_impl.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_profile.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_scout.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_traceback.h \
+SeqAn-1.4.2/seqan/seeds/basic_iter_indirect.h \
+SeqAn-1.4.2/seqan/seeds.h \
+SeqAn-1.4.2/seqan/seeds/INFO \
+SeqAn-1.4.2/seqan/seeds/seeds_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_combination.h \
+SeqAn-1.4.2/seqan/seeds/seeds_extension.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_gusfield.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_chained.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_diagonal.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_non_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_unordered.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_simple.h \
+SeqAn-1.4.2/seqan/seq_io/fai_index.h \
+SeqAn-1.4.2/seqan/seq_io/genomic_region.h \
+SeqAn-1.4.2/seqan/seq_io/guess_stream_format.h \
+SeqAn-1.4.2/seqan/seq_io.h \
+SeqAn-1.4.2/seqan/seq_io/INFO \
+SeqAn-1.4.2/seqan/seq_io/read_embl.h \
+SeqAn-1.4.2/seqan/seq_io/read_fasta_fastq.h \
+SeqAn-1.4.2/seqan/seq_io/read_genbank.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream_impl.h \
+SeqAn-1.4.2/seqan/seq_io/simple_read_fasta.h \
+SeqAn-1.4.2/seqan/seq_io/write_fasta_fastq.h \
+SeqAn-1.4.2/seqan/sequence/adapt_array_pointer.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_list.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_string.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_vector.h \
+SeqAn-1.4.2/seqan/sequence.h \
+SeqAn-1.4.2/seqan/sequence/INFO \
+SeqAn-1.4.2/seqan/sequence/iter_concat_virtual.h \
+SeqAn-1.4.2/seqan/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/INFO \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_sorted_array.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entry.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled_iterator.h \
+SeqAn-1.4.2/seqan/sequence/segment_base.h \
+SeqAn-1.4.2/seqan/sequence/segment_infix.h \
+SeqAn-1.4.2/seqan/sequence/segment_prefix.h \
+SeqAn-1.4.2/seqan/sequence/segment_suffix.h \
+SeqAn-1.4.2/seqan/sequence/segment_utils.h \
+SeqAn-1.4.2/seqan/sequence/sequence_concatenator.h \
+SeqAn-1.4.2/seqan/sequence/sequence_forwards.h \
+SeqAn-1.4.2/seqan/sequence/sequence_interface.h \
+SeqAn-1.4.2/seqan/sequence/sequence_lexical.h \
+SeqAn-1.4.2/seqan/sequence/sequence_shortcuts.h \
+SeqAn-1.4.2/seqan/sequence/string_alloc.h \
+SeqAn-1.4.2/seqan/sequence/string_array.h \
+SeqAn-1.4.2/seqan/sequence/string_base.h \
+SeqAn-1.4.2/seqan/sequence/string_block.h \
+SeqAn-1.4.2/seqan/sequence/string_cstyle.h \
+SeqAn-1.4.2/seqan/sequence/string_packed.h \
+SeqAn-1.4.2/seqan/sequence/string_packed_old.h \
+SeqAn-1.4.2/seqan/sequence/string_set_base.h \
+SeqAn-1.4.2/seqan/sequence/string_set_concat_direct.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_generous.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_tight.h \
+SeqAn-1.4.2/seqan/sequence/string_set_owner.h \
+SeqAn-1.4.2/seqan/store.h \
+SeqAn-1.4.2/seqan/store/INFO \
+SeqAn-1.4.2/seqan/store/store_align.h \
+SeqAn-1.4.2/seqan/store/store_align_intervals.h \
+SeqAn-1.4.2/seqan/store/store_all.h \
+SeqAn-1.4.2/seqan/store/store_annotation.h \
+SeqAn-1.4.2/seqan/store/store_base.h \
+SeqAn-1.4.2/seqan/store/store_contig.h \
+SeqAn-1.4.2/seqan/store/store_intervaltree.h \
+SeqAn-1.4.2/seqan/store/store_io_gff.h \
+SeqAn-1.4.2/seqan/store/store_io.h \
+SeqAn-1.4.2/seqan/store/store_io_sam.h \
+SeqAn-1.4.2/seqan/store/store_io_ucsc.h \
+SeqAn-1.4.2/seqan/store/store_library.h \
+SeqAn-1.4.2/seqan/store/store_matepair.h \
+SeqAn-1.4.2/seqan/store/store_read.h \
+SeqAn-1.4.2/seqan/stream/adapt_cstdio.h \
+SeqAn-1.4.2/seqan/stream/adapt_fstream.h \
+SeqAn-1.4.2/seqan/stream/adapt_iostream.h \
+SeqAn-1.4.2/seqan/stream/adapt_mmap.h \
+SeqAn-1.4.2/seqan/stream/adapt_sstream.h \
+SeqAn-1.4.2/seqan/stream/concept_stream.h \
+SeqAn-1.4.2/seqan/stream/file_stream.h \
+SeqAn-1.4.2/seqan/stream.h \
+SeqAn-1.4.2/seqan/stream/INFO \
+SeqAn-1.4.2/seqan/stream/is.h \
+SeqAn-1.4.2/seqan/stream/lexical_cast.h \
+SeqAn-1.4.2/seqan/stream/read_auto_format.h \
+SeqAn-1.4.2/seqan/stream/read.h \
+SeqAn-1.4.2/seqan/stream/read_sam.h \
+SeqAn-1.4.2/seqan/stream/record_reader_base.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double_mmap.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single_mmap.h \
+SeqAn-1.4.2/seqan/stream/stream_base.h \
+SeqAn-1.4.2/seqan/stream/stream_bgzf.h \
+SeqAn-1.4.2/seqan/stream/stream_bz2_file.h \
+SeqAn-1.4.2/seqan/stream/stream_char_array.h \
+SeqAn-1.4.2/seqan/stream/stream_gz_file.h \
+SeqAn-1.4.2/seqan/stream/stream_put.h \
+SeqAn-1.4.2/seqan/stream/tokenize.h \
+SeqAn-1.4.2/seqan/stream/write.h \
+SeqAn-1.4.2/seqan/system/file_async.h \
+SeqAn-1.4.2/seqan/system/file_directory.h \
+SeqAn-1.4.2/seqan/system/file_forwards.h \
+SeqAn-1.4.2/seqan/system/file_sync.h \
+SeqAn-1.4.2/seqan/system.h \
+SeqAn-1.4.2/seqan/system/INFO \
+SeqAn-1.4.2/seqan/system/system_base.h \
+SeqAn-1.4.2/seqan/system/system_event.h \
+SeqAn-1.4.2/seqan/system/system_forwards.h \
+SeqAn-1.4.2/seqan/system/system_mutex.h \
+SeqAn-1.4.2/seqan/system/system_sema.h \
+SeqAn-1.4.2/seqan/system/system_thread.h \
+SeqAn-1.4.2/seqan/version.h
 
 SAMDIR = ./samtools-0.1.18
 SAMLIB = libbam.a
@@ -624,7 +707,6 @@ bin_PROGRAMS = \
 	tophat_reports \
 	sam_juncs
 
-#	$(SAMPROG) 
 bin_SCRIPTS = \
 	tophat2 \
 	tophat
@@ -636,10 +718,6 @@ dist_bin_SCRIPTS = \
 	sra_to_solid \
 	tophat-fusion-post
 
-
-#samtools_0_1_18_SOURCES = 
-#samtools_0_1_18_LDADD = 
-
 CLEANFILES = \
 	tophat2 \
 	tophat
@@ -647,11 +725,11 @@ CLEANFILES = \
 clean-local:
 	cd $(SAMDIR) && make clean
 
-tophat2: tophat2.in
-	sed -e 's|__PREFIX__|$(prefix)|' tophat2.in > tophat2
+tophat2: tophat2.sh
+	cp tophat2.sh tophat2 && chmod 755 tophat2
 
 tophat: tophat.py
-	sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat
+	sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat && chmod 755 tophat
 
 #-- tophat library for linking convienence
 noinst_LIBRARIES = $(SAMLIB) libgc.a libtophat.a
@@ -775,3 +853,6 @@ $(SAMPROG): $(SAMLIB)
 
 $(SAMLIB):
 	cd $(SAMDIR) && make $(SAMPROG) && cp $(SAMLIB) $(SAMPROG) ..
+
+install-data-hook:
+	cp -r intervaltree sortedcontainers $(DESTDIR)$(bindir)
diff --git a/src/Makefile.in b/src/Makefile.in
index fcf9d17..1c9b4d6 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -363,7 +363,16 @@ top_srcdir = @top_srcdir@
 # - and tophat2.in added
 EXTRA_DIST = \
 tophat.py \
-tophat2.in \
+tophat2.sh \
+intervaltree/__init__.py \
+intervaltree/interval.py \
+intervaltree/intervaltree.py \
+intervaltree/node.py \
+sortedcontainers/__init__.py \
+sortedcontainers/sorteddict.py \
+sortedcontainers/sortedlist.py \
+sortedcontainers/sortedlistwithkey.py \
+sortedcontainers/sortedset.py \
 samtools-0.1.18/AUTHORS \
 samtools-0.1.18/COPYING \
 samtools-0.1.18/ChangeLog \
@@ -448,520 +457,592 @@ samtools-0.1.18/bcftools/prob1.c \
 samtools-0.1.18/bcftools/prob1.h \
 samtools-0.1.18/bcftools/vcf.c \
 samtools-0.1.18/bcftools/vcfutils.pl \
-SeqAn-1.3/COPYING \
-SeqAn-1.3/README \
-SeqAn-1.3/seqan/chaining/chain_generic.h \
-SeqAn-1.3/seqan/chaining/rt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/score_zero.h \
-SeqAn-1.3/seqan/chaining/geom_distribution.h \
-SeqAn-1.3/seqan/chaining/chain_base.h \
-SeqAn-1.3/seqan/chaining/chaining_generated_forwards.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_base_element.h \
-SeqAn-1.3/seqan/chaining/skip_element.h \
-SeqAn-1.3/seqan/chaining/rmt_skip_element.h \
-SeqAn-1.3/seqan/chaining/rt_sl_impl.h \
-SeqAn-1.3/seqan/chaining/chain_wrapper_point.h \
-SeqAn-1.3/seqan/chaining/rmt_compl_algos.h \
-SeqAn-1.3/seqan/chaining/rmt_base.h \
-SeqAn-1.3/seqan/chaining/skip_list.h \
-SeqAn-1.3/seqan/chaining/skip_list_iterator.h \
-SeqAn-1.3/seqan/chaining/skip_base_element.h \
-SeqAn-1.3/seqan/chaining/fragment.h \
-SeqAn-1.3/seqan/chaining/skip_pool_alloc.h \
-SeqAn-1.3/seqan/chaining/skip_list_impl.h \
-SeqAn-1.3/seqan/chaining/rt_skip_element.h \
-SeqAn-1.3/seqan/chaining/tree_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rmt_common_algos.h \
-SeqAn-1.3/seqan/chaining/score_manhattan.h \
-SeqAn-1.3/seqan/chaining/score_chain_sop.h \
-SeqAn-1.3/seqan/chaining/rt_impl.h \
-SeqAn-1.3/seqan/chaining/tree_chain.h \
-SeqAn-1.3/seqan/chaining/tree_chain_utils.h \
-SeqAn-1.3/seqan/chaining/skip_list_base.h \
-SeqAn-1.3/seqan/chaining/rt_sl_def_algos.h \
-SeqAn-1.3/seqan/chaining/range_tree.h \
-SeqAn-1.3/seqan/chaining/rmt_def_algos.h \
-SeqAn-1.3/seqan/chaining/chain_point.h \
-SeqAn-1.3/seqan/chaining/rt_base.h \
-SeqAn-1.3/seqan/chaining/chain_meta_fragment.h \
-SeqAn-1.3/seqan/chaining/score_chain.h \
-SeqAn-1.3/seqan/chaining/rt_common_algos.h \
-SeqAn-1.3/seqan/chaining/skip_list_dynamic.h \
-SeqAn-1.3/seqan/chaining/rt_sl_base.h \
-SeqAn-1.3/seqan/chaining/skip_list_type.h \
-SeqAn-1.3/seqan/chaining/range_max_tree.h \
-SeqAn-1.3/seqan/chaining/rt_sl_compl_algos.h \
-SeqAn-1.3/seqan/file/file_format_cgviz.h \
-SeqAn-1.3/seqan/file/stream.h \
-SeqAn-1.3/seqan/file/file_format_embl.h \
-SeqAn-1.3/seqan/file/file_format_fasta.h \
-SeqAn-1.3/seqan/file/string_mmap.h \
-SeqAn-1.3/seqan/file/file_format_raw.h \
-SeqAn-1.3/seqan/file/string_external.h \
-SeqAn-1.3/seqan/file/file_filereader.h \
-SeqAn-1.3/seqan/file/file_cstyle.h \
-SeqAn-1.3/seqan/file/file_page_raid0.h \
-SeqAn-1.3/seqan/file/cstream.h \
-SeqAn-1.3/seqan/file/file_format_guess.h \
-SeqAn-1.3/seqan/file/file_base.h \
-SeqAn-1.3/seqan/file/file_format_mmap.h \
-SeqAn-1.3/seqan/file/file_forwards.h \
-SeqAn-1.3/seqan/file/file_array.h \
-SeqAn-1.3/seqan/file/meta.h \
-SeqAn-1.3/seqan/file/stream_algorithms.h \
-SeqAn-1.3/seqan/file/file_format.h \
-SeqAn-1.3/seqan/file/file_filereaderiterator.h \
-SeqAn-1.3/seqan/file/file_format_genbank.h \
-SeqAn-1.3/seqan/file/file_generated_forwards.h \
-SeqAn-1.3/seqan/file/file_format_fasta_align.h \
-SeqAn-1.3/seqan/file/chunk_collector.h \
-SeqAn-1.3/seqan/file/file_page.h \
-SeqAn-1.3/seqan/seeds.h \
-SeqAn-1.3/seqan/find_motif.h \
-SeqAn-1.3/seqan/LICENSE \
-SeqAn-1.3/seqan/find2/find_approx_find_begin.h \
-SeqAn-1.3/seqan/find2/find_finder_default.h \
-SeqAn-1.3/seqan/find2/find_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_multiple_exact_simple.h \
-SeqAn-1.3/seqan/find2/find_hamming_simple.h \
-SeqAn-1.3/seqan/find2/find_pattern_wild_shiftand.h \
-SeqAn-1.3/seqan/find2/find_approx_dpsearch.h \
-SeqAn-1.3/seqan/find2/find_exact_shiftand.h \
-SeqAn-1.3/seqan/find2/find2_generated_forwards.h \
-SeqAn-1.3/seqan/find2/find_base.h \
-SeqAn-1.3/seqan/platform.h \
-SeqAn-1.3/seqan/sequence_journaled.h \
-SeqAn-1.3/seqan/chaining.h \
-SeqAn-1.3/seqan/score/score_generated_forwards.h \
-SeqAn-1.3/seqan/score/score_matrix_data.h \
-SeqAn-1.3/seqan/score/score_matrix.h \
-SeqAn-1.3/seqan/score/score_simple.h \
-SeqAn-1.3/seqan/score/score_base.h \
-SeqAn-1.3/seqan/score/score_edit.h \
-SeqAn-1.3/seqan/graph_algorithms.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_iterator.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entry.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_sorted_array.h \
-SeqAn-1.3/seqan/sequence_journaled/sequence_journaled_generated_forwards.h \
-SeqAn-1.3/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
-SeqAn-1.3/seqan/align/gaps_iterator_base.h \
-SeqAn-1.3/seqan/align/gaps_array.h \
-SeqAn-1.3/seqan/align/matrix_base.h \
-SeqAn-1.3/seqan/align/gaps_base.h \
-SeqAn-1.3/seqan/align/align_iterator_base.h \
-SeqAn-1.3/seqan/align/align_algorithms.h \
-SeqAn-1.3/seqan/align/align_hirschberg.h \
-SeqAn-1.3/seqan/align/align_local_dynprog.h \
-SeqAn-1.3/seqan/align/align_cols_base.h \
-SeqAn-1.3/seqan/align/align_generated_forwards.h \
-SeqAn-1.3/seqan/align/align_base.h \
-SeqAn-1.3/seqan/align/gaps_sumlist.h \
-SeqAn-1.3/seqan/align/align_local_dynprog_banded.h \
-SeqAn-1.3/seqan/align/align_dynprog.h \
-SeqAn-1.3/seqan/align/align_myers.h \
-SeqAn-1.3/seqan/align/hirschberg_set.h \
-SeqAn-1.3/seqan/align/align_trace.h \
-SeqAn-1.3/seqan/pipe/pipe_sampler.h \
-SeqAn-1.3/seqan/pipe/pipe_filter.h \
-SeqAn-1.3/seqan/pipe/pool_sorter.h \
-SeqAn-1.3/seqan/pipe/pipe_namer.h \
-SeqAn-1.3/seqan/pipe/pipe_joiner.h \
-SeqAn-1.3/seqan/pipe/pipe_base.h \
-SeqAn-1.3/seqan/pipe/pipe_echoer.h \
-SeqAn-1.3/seqan/pipe/pipe_caster.h \
-SeqAn-1.3/seqan/pipe/pipe_generated_forwards.h \
-SeqAn-1.3/seqan/pipe/pipe_counter.h \
-SeqAn-1.3/seqan/pipe/pool_mapper.h \
-SeqAn-1.3/seqan/pipe/pipe_edit_environment.h \
-SeqAn-1.3/seqan/pipe/pool_base.h \
-SeqAn-1.3/seqan/pipe/pipe_shifter.h \
-SeqAn-1.3/seqan/pipe/pipe_source.h \
-SeqAn-1.3/seqan/pipe/pipe_tupler.h \
-SeqAn-1.3/seqan/pipe/pipe_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_vertex.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_oracle.h \
-SeqAn-1.3/seqan/graph_types/graph_idmanager.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_adjacency.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_automaton.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_trie.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_bfs.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_dfs.h \
-SeqAn-1.3/seqan/graph_types/graph_property.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_fragment.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_outedge.h \
-SeqAn-1.3/seqan/graph_types/graph_utility_parsing.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_undirected.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_hmm.h \
-SeqAn-1.3/seqan/graph_types/graph_base.h \
-SeqAn-1.3/seqan/graph_types/graph_iterator_edge.h \
-SeqAn-1.3/seqan/graph_types/graph_edgestump.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_tree.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_wordgraph.h \
-SeqAn-1.3/seqan/graph_types/graph_types_generated_forwards.h \
-SeqAn-1.3/seqan/graph_types/graph_impl_directed.h \
-SeqAn-1.3/seqan/graph_types/graph_drawing.h \
-SeqAn-1.3/seqan/graph_types/graph_interface.h \
-SeqAn-1.3/seqan/file.h \
-SeqAn-1.3/seqan/system.h \
-SeqAn-1.3/seqan/refinement.h \
-SeqAn-1.3/seqan/pipe.h \
-SeqAn-1.3/seqan/system/system_thread.h \
-SeqAn-1.3/seqan/system/system_base.h \
-SeqAn-1.3/seqan/system/system_event.h \
-SeqAn-1.3/seqan/system/file_directory.h \
-SeqAn-1.3/seqan/system/system_mutex.h \
-SeqAn-1.3/seqan/system/file_manual_forwards.h \
-SeqAn-1.3/seqan/system/system_generated_forwards.h \
-SeqAn-1.3/seqan/system/file_sync.h \
-SeqAn-1.3/seqan/system/file_async.h \
-SeqAn-1.3/seqan/system/system_sema.h \
-SeqAn-1.3/seqan/system/system_manual_forwards.h \
-SeqAn-1.3/seqan/misc/edit_environment.h \
-SeqAn-1.3/seqan/misc/misc_parsing.h \
-SeqAn-1.3/seqan/misc/misc_generated_forwards.h \
-SeqAn-1.3/seqan/misc/misc_base.h \
-SeqAn-1.3/seqan/misc/priority_type_heap.h \
-SeqAn-1.3/seqan/misc/priority_type_base.h \
-SeqAn-1.3/seqan/misc/misc_dequeue.h \
-SeqAn-1.3/seqan/misc/misc_set.h \
-SeqAn-1.3/seqan/misc/misc_map.h \
-SeqAn-1.3/seqan/misc/misc_svg.h \
-SeqAn-1.3/seqan/misc/misc_interval_tree.h \
-SeqAn-1.3/seqan/misc/misc_long_word.h \
-SeqAn-1.3/seqan/misc/misc_cmdparser.h \
-SeqAn-1.3/seqan/misc/misc_random.h \
-SeqAn-1.3/seqan/platform/platform_mingw.h \
-SeqAn-1.3/seqan/platform/platform_gcc.h \
-SeqAn-1.3/seqan/platform/platform_windows.h \
-SeqAn-1.3/seqan/platform/platform_solaris.h \
-SeqAn-1.3/seqan/platform/platform_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_generated_forwards.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman.h \
-SeqAn-1.3/seqan/graph_align/graph_align_base.h \
-SeqAn-1.3/seqan/graph_align/graph_align_hirschberg.h \
-SeqAn-1.3/seqan/graph_align/graph_align_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_interface.h \
-SeqAn-1.3/seqan/graph_align/graph_align_smith_waterman_clump.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_gotoh.h \
-SeqAn-1.3/seqan/graph_align/graph_align_banded_needleman_wunsch.h \
-SeqAn-1.3/seqan/graph_align/graph_align_config.h \
-SeqAn-1.3/seqan/parallel/parallel_generated_forwards.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_misc.h \
-SeqAn-1.3/seqan/parallel/parallel_atomic_primitives.h \
-SeqAn-1.3/seqan/parallel/parallel_macros.h \
-SeqAn-1.3/seqan/store/store_io_gff.h \
-SeqAn-1.3/seqan/store/store_library.h \
-SeqAn-1.3/seqan/store/store_read.h \
-SeqAn-1.3/seqan/store/store_annotation.h \
-SeqAn-1.3/seqan/store/store_intervaltree.h \
-SeqAn-1.3/seqan/store/store_io_ucsc.h \
-SeqAn-1.3/seqan/store/store_all.h \
-SeqAn-1.3/seqan/store/store_matepair.h \
-SeqAn-1.3/seqan/store/store_align_intervals.h \
-SeqAn-1.3/seqan/store/store_io.h \
-SeqAn-1.3/seqan/store/store_io_sam.h \
-SeqAn-1.3/seqan/store/store_align.h \
-SeqAn-1.3/seqan/store/store_io_bam.h \
-SeqAn-1.3/seqan/store/store_contig.h \
-SeqAn-1.3/seqan/store/store_generated_forwards.h \
-SeqAn-1.3/seqan/store/store_base.h \
-SeqAn-1.3/seqan/align.h \
-SeqAn-1.3/seqan/modifier/modifier_string.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet_expansion.h \
-SeqAn-1.3/seqan/modifier/modifier_shortcuts.h \
-SeqAn-1.3/seqan/modifier/modifier_alphabet.h \
-SeqAn-1.3/seqan/modifier/modifier_iterator.h \
-SeqAn-1.3/seqan/modifier/modifier_reverse.h \
-SeqAn-1.3/seqan/modifier/modifier_generated_forwards.h \
-SeqAn-1.3/seqan/modifier/modifier_view.h \
-SeqAn-1.3/seqan/modifier/modifier_functors.h \
-SeqAn-1.3/seqan/seeds2.h \
-SeqAn-1.3/seqan/index/index_sa_btree.h \
-SeqAn-1.3/seqan/index/find_quasar.h \
-SeqAn-1.3/seqan/index/index_esa_algs.h \
-SeqAn-1.3/seqan/index/index_skew7.h \
-SeqAn-1.3/seqan/index/index_pizzachili.h \
-SeqAn-1.3/seqan/index/index_sa_lss.h \
-SeqAn-1.3/seqan/index/pump_extender7.h \
-SeqAn-1.3/seqan/index/index_shawarma.h \
-SeqAn-1.3/seqan/index/find_index_approx.h \
-SeqAn-1.3/seqan/index/index_lcp.h \
-SeqAn-1.3/seqan/index/find_swift.h \
-SeqAn-1.3/seqan/index/shape_threshold.h \
-SeqAn-1.3/seqan/index/pizzachili_api.h \
-SeqAn-1.3/seqan/index/index_sa_mm.h \
-SeqAn-1.3/seqan/index/index_esa_stree.h \
-SeqAn-1.3/seqan/index/index_qgram.h \
-SeqAn-1.3/seqan/index/pump_extender3.h \
-SeqAn-1.3/seqan/index/shape_onegapped.h \
-SeqAn-1.3/seqan/index/find_index_qgram.h \
-SeqAn-1.3/seqan/index/index_skew3.h \
-SeqAn-1.3/seqan/index/index_childtab.h \
-SeqAn-1.3/seqan/index/pipe_merger7.h \
-SeqAn-1.3/seqan/index/pipe_merger3.h \
-SeqAn-1.3/seqan/index/repeat_base.h \
-SeqAn-1.3/seqan/index/index_pizzachili_find.h \
-SeqAn-1.3/seqan/index/index_sa_qsort.h \
-SeqAn-1.3/seqan/index/index_shims.h \
-SeqAn-1.3/seqan/index/index_manual_forwards.h \
-SeqAn-1.3/seqan/index/shape_base.h \
-SeqAn-1.3/seqan/index/shape_predefined.h \
-SeqAn-1.3/seqan/index/index_pizzachili_string.h \
-SeqAn-1.3/seqan/index/index_generated_forwards.h \
-SeqAn-1.3/seqan/index/find_index_esa.h \
-SeqAn-1.3/seqan/index/pump_separator7.h \
-SeqAn-1.3/seqan/index/index_esa_base.h \
-SeqAn-1.3/seqan/index/radix.h \
-SeqAn-1.3/seqan/index/index_skew7_multi.h \
-SeqAn-1.3/seqan/index/index_esa_algs_multi.h \
-SeqAn-1.3/seqan/index/index_base.h \
-SeqAn-1.3/seqan/index/shape_gapped.h \
-SeqAn-1.3/seqan/index/index_lcp_tree.h \
-SeqAn-1.3/seqan/index/index_esa_drawing.h \
-SeqAn-1.3/seqan/index/find_index.h \
-SeqAn-1.3/seqan/index/pump_lcp_core.h \
-SeqAn-1.3/seqan/index/index_dfi.h \
-SeqAn-1.3/seqan/index/index_sa_bwtwalk.h \
-SeqAn-1.3/seqan/index/index_qgram_openaddressing.h \
-SeqAn-1.3/seqan/index/index_bwt.h \
-SeqAn-1.3/seqan/index/index_wotd.h \
-SeqAn-1.3/seqan/statistics/statistics_base.h \
-SeqAn-1.3/seqan/statistics/statistics_markov_model.h \
-SeqAn-1.3/seqan/statistics/statistics_generated_forwards.h \
-SeqAn-1.3/seqan/score.h \
-SeqAn-1.3/seqan/sequence.h \
-SeqAn-1.3/seqan/parallel.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithms_generated_forwards.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_hmm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm.h \
-SeqAn-1.3/seqan/graph_algorithms/graph_algorithm_lis_his.h \
-SeqAn-1.3/seqan/blast.h \
-SeqAn-1.3/seqan/store.h \
-SeqAn-1.3/seqan/graph_align.h \
-SeqAn-1.3/seqan/random/random_lognormal.h \
-SeqAn-1.3/seqan/random/ext_MersenneTwister.h \
-SeqAn-1.3/seqan/random/random_generated_forwards.h \
-SeqAn-1.3/seqan/random/random_rng_functor.h \
-SeqAn-1.3/seqan/random/random_base.h \
-SeqAn-1.3/seqan/random/random_uniform.h \
-SeqAn-1.3/seqan/random/random_shuffle.h \
-SeqAn-1.3/seqan/random/random_normal.h \
-SeqAn-1.3/seqan/random/random_geometric.h \
-SeqAn-1.3/seqan/random/random_mt19937.h \
-SeqAn-1.3/seqan/basic.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_progressive.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_distance.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_io.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_kmer.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_refinement.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_msa.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
-SeqAn-1.3/seqan/graph_msa/graph_msa_generated_forwards.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_library.h \
-SeqAn-1.3/seqan/graph_msa/graph_align_tcoffee_base.h \
-SeqAn-1.3/seqan/basic/basic_sse2.h \
-SeqAn-1.3/seqan/basic/basic_forwards.h \
-SeqAn-1.3/seqan/basic/basic_testing.h \
-SeqAn-1.3/seqan/basic/basic_counted_ptr.h \
-SeqAn-1.3/seqan/basic/basic_iterator_base.h \
-SeqAn-1.3/seqan/basic/basic_pointer.h \
-SeqAn-1.3/seqan/basic/basic_allocator_chunkpool.h \
-SeqAn-1.3/seqan/basic/basic_parallelism.h \
-SeqAn-1.3/seqan/basic/basic_allocator_singlepool.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adaptor.h \
-SeqAn-1.3/seqan/basic/basic_profile.h \
-SeqAn-1.3/seqan/basic/basic_tag.h \
-SeqAn-1.3/seqan/basic/basic_compare.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface.h \
-SeqAn-1.3/seqan/basic/basic_iterator_simple.h \
-SeqAn-1.3/seqan/basic/basic_definition.h \
-SeqAn-1.3/seqan/basic/basic_operator.h \
-SeqAn-1.3/seqan/basic/basic_holder_dynamic.h \
-SeqAn-1.3/seqan/basic/basic_allocator_multipool.h \
-SeqAn-1.3/seqan/basic/basic_proxy.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple_tabs.h \
-SeqAn-1.3/seqan/basic/basic_metaprogramming.h \
-SeqAn-1.3/seqan/basic/basic_host.h \
-SeqAn-1.3/seqan/basic/basic_allocator_to_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_interface.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_interface2.h \
-SeqAn-1.3/seqan/basic/basic_logvalue.h \
-SeqAn-1.3/seqan/basic/basic_volatile_ptr.h \
-SeqAn-1.3/seqan/basic/basic_debug.h \
-SeqAn-1.3/seqan/basic/basic_profchar.h \
-SeqAn-1.3/seqan/basic/basic_aggregates.h \
-SeqAn-1.3/seqan/basic/basic_transport.h \
-SeqAn-1.3/seqan/basic/basic_holder.h \
-SeqAn-1.3/seqan/basic/basic_converter.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_simple.h \
-SeqAn-1.3/seqan/basic/basic_type.h \
-SeqAn-1.3/seqan/basic/basic_iterator_adapt_std.h \
-SeqAn-1.3/seqan/basic/basic_allocator_simple.h \
-SeqAn-1.3/seqan/basic/basic_iterator.h \
-SeqAn-1.3/seqan/basic/basic_generated_forwards.h \
-SeqAn-1.3/seqan/basic/basic_iterator_position.h \
-SeqAn-1.3/seqan/basic/basic_alphabet_trait_basic.h \
-SeqAn-1.3/seqan/sequence/sequence_forwards.h \
-SeqAn-1.3/seqan/sequence/segment_infix.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_tight.h \
-SeqAn-1.3/seqan/sequence/segment_base.h \
-SeqAn-1.3/seqan/sequence/sequence_lexical.h \
-SeqAn-1.3/seqan/sequence/string_cstyle.h \
-SeqAn-1.3/seqan/sequence/sequence_concatenator.h \
-SeqAn-1.3/seqan/sequence/string_packed.h \
-SeqAn-1.3/seqan/sequence/sequence_stream.h \
-SeqAn-1.3/seqan/sequence/sequence_shortcuts.h \
-SeqAn-1.3/seqan/sequence/adapt_std_list.h \
-SeqAn-1.3/seqan/sequence/string_base.h \
-SeqAn-1.3/seqan/sequence/string_set_owner.h \
-SeqAn-1.3/seqan/sequence/adapt_std_string.h \
-SeqAn-1.3/seqan/sequence/sequence_generated_forwards.h \
-SeqAn-1.3/seqan/sequence/string_set_concat_direct.h \
-SeqAn-1.3/seqan/sequence/sequence_interface.h \
-SeqAn-1.3/seqan/sequence/adapt_array_pointer.h \
-SeqAn-1.3/seqan/sequence/segment_suffix.h \
-SeqAn-1.3/seqan/sequence/string_array.h \
-SeqAn-1.3/seqan/sequence/iter_concat_virtual.h \
-SeqAn-1.3/seqan/sequence/segment_prefix.h \
-SeqAn-1.3/seqan/sequence/string_block.h \
-SeqAn-1.3/seqan/sequence/string_set_base.h \
-SeqAn-1.3/seqan/sequence/adapt_std_vector.h \
-SeqAn-1.3/seqan/sequence/string_set_dependent_generous.h \
-SeqAn-1.3/seqan/sequence/string_alloc.h \
-SeqAn-1.3/seqan/modifier.h \
-SeqAn-1.3/seqan/random.h \
-SeqAn-1.3/seqan/statistics.h \
-SeqAn-1.3/seqan/consensus.h \
-SeqAn-1.3/seqan/find.h \
-SeqAn-1.3/seqan/find2.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_inexact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_fragment.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_annotation.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_align.h \
-SeqAn-1.3/seqan/refinement/refinement_generated_forwards.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_scoring.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_exact_iterative.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align.h \
-SeqAn-1.3/seqan/refinement/graph_impl_align_adapt.h \
-SeqAn-1.3/seqan/refinement/graph_algorithm_refine_aligngraph.h \
-SeqAn-1.3/seqan/seeds/global_seed_chain.h \
-SeqAn-1.3/seqan/seeds/seedSet_score.h \
-SeqAn-1.3/seqan/seeds/seeds_generated_forwards.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align_affine.h \
-SeqAn-1.3/seqan/seeds/banded_align.h \
-SeqAn-1.3/seqan/seeds/memoryManager_int.h \
-SeqAn-1.3/seqan/seeds/seedHandlingTags.h \
-SeqAn-1.3/seqan/seeds/seedSet_iterator.h \
-SeqAn-1.3/seqan/seeds/banded_chain_align.h \
-SeqAn-1.3/seqan/seeds/seed_multi.h \
-SeqAn-1.3/seqan/seeds/seedSet_base.h \
-SeqAn-1.3/seqan/seeds/propertyMap.h \
-SeqAn-1.3/seqan/seeds/memoryManager_base.h \
-SeqAn-1.3/seqan/seeds/seed_base.h \
-SeqAn-1.3/seqan/graph_msa.h \
-SeqAn-1.3/seqan/consensus/consensus_score.h \
-SeqAn-1.3/seqan/consensus/consensus_base.h \
-SeqAn-1.3/seqan/consensus/consensus_generated_forwards.h \
-SeqAn-1.3/seqan/consensus/consensus_realign.h \
-SeqAn-1.3/seqan/consensus/consensus_library.h \
-SeqAn-1.3/seqan/map/map_generated_forwards.h \
-SeqAn-1.3/seqan/map/map_base.h \
-SeqAn-1.3/seqan/map/map_chooser.h \
-SeqAn-1.3/seqan/map/map_vector.h \
-SeqAn-1.3/seqan/map/sumlist_mini.h \
-SeqAn-1.3/seqan/map/map_adapter_stl.h \
-SeqAn-1.3/seqan/map/sumlist.h \
-SeqAn-1.3/seqan/map/map_skiplist.h \
-SeqAn-1.3/seqan/map/sumlist_skip.h \
-SeqAn-1.3/seqan/blast/blast_stream_report.h \
-SeqAn-1.3/seqan/blast/blast_run.h \
-SeqAn-1.3/seqan/blast/blast_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hsp.h \
-SeqAn-1.3/seqan/blast/blast_base.h \
-SeqAn-1.3/seqan/blast/blast_hit.h \
-SeqAn-1.3/seqan/blast/blast_stream_hit.h \
-SeqAn-1.3/seqan/blast/blast_iterator.h \
-SeqAn-1.3/seqan/blast/blast_parsing.h \
-SeqAn-1.3/seqan/blast/blast_report.h \
-SeqAn-1.3/seqan/blast/blast_generated_forwards.h \
-SeqAn-1.3/seqan/blast/blast_stream_hsp_iterator.h \
-SeqAn-1.3/seqan/blast/blast_hit_iterator.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_base.h \
-SeqAn-1.3/seqan/seeds2/seeds_extension.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_unordered.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_base.h \
-SeqAn-1.3/seqan/seeds2/seeds2_generated_forwards.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_diagonal.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_simple.h \
-SeqAn-1.3/seqan/seeds2/seeds_base.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_affine.h \
-SeqAn-1.3/seqan/seeds2/seeds_combination.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_non_scored.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_banded_linear.h \
-SeqAn-1.3/seqan/seeds2/align_chain_banded.h \
-SeqAn-1.3/seqan/seeds2/align_dynprog_linear.h \
-SeqAn-1.3/seqan/seeds2/basic_iter_indirect.h \
-SeqAn-1.3/seqan/seeds2/seeds_global_chaining_gusfield.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_chained.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_set_scored.h \
-SeqAn-1.3/seqan/seeds2/seeds_seed_base.h \
-SeqAn-1.3/seqan/map.h \
-SeqAn-1.3/seqan/find/find_pattern_base.h \
-SeqAn-1.3/seqan/find/find_multiple_shiftand.h \
-SeqAn-1.3/seqan/find/find_generated_forwards.h \
-SeqAn-1.3/seqan/find/find_horspool.h \
-SeqAn-1.3/seqan/find/find_abndm.h \
-SeqAn-1.3/seqan/find/find_score.h \
-SeqAn-1.3/seqan/find/find_set_horspool.h \
-SeqAn-1.3/seqan/find/find_wild_shiftand.h \
-SeqAn-1.3/seqan/find/find_hamming_simple.h \
-SeqAn-1.3/seqan/find/find_shiftand.h \
-SeqAn-1.3/seqan/find/find_begin.h \
-SeqAn-1.3/seqan/find/find_shiftor.h \
-SeqAn-1.3/seqan/find/find_wumanber.h \
-SeqAn-1.3/seqan/find/find_multi.h \
-SeqAn-1.3/seqan/find/find_simple.h \
-SeqAn-1.3/seqan/find/find_bndm.h \
-SeqAn-1.3/seqan/find/find_pex.h \
-SeqAn-1.3/seqan/find/find_bom.h \
-SeqAn-1.3/seqan/find/find_ahocorasick.h \
-SeqAn-1.3/seqan/find/find_multiple_bfam.h \
-SeqAn-1.3/seqan/find/find_myers_ukkonen.h \
-SeqAn-1.3/seqan/find/find_base.h \
-SeqAn-1.3/seqan/index.h \
-SeqAn-1.3/seqan/graph_types.h \
-SeqAn-1.3/seqan/find_motif/profile.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pmsp.h \
-SeqAn-1.3/seqan/find_motif/sequence_model_types.h \
-SeqAn-1.3/seqan/find_motif/find_motif_base.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_p.h \
-SeqAn-1.3/seqan/find_motif/find_motif_epatternbranching.h \
-SeqAn-1.3/seqan/find_motif/find_motif_projection.h \
-SeqAn-1.3/seqan/find_motif/find_motif_generated_forwards.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_mode_c.h \
-SeqAn-1.3/seqan/find_motif/pseudocount_base.h \
-SeqAn-1.3/seqan/find_motif/em_algorithm.h \
-SeqAn-1.3/seqan/find_motif/find_motif_pms1.h \
-SeqAn-1.3/seqan/find_motif/frequency_distribution.h \
-SeqAn-1.3/seqan.h
+SeqAn-1.4.2/LICENSE \
+SeqAn-1.4.2/README.rst \
+SeqAn-1.4.2/seqan/align/align_base.h \
+SeqAn-1.4.2/seqan/align/align_cols.h \
+SeqAn-1.4.2/seqan/align/align_config.h \
+SeqAn-1.4.2/seqan/align/align_iterator_base.h \
+SeqAn-1.4.2/seqan/align/alignment_algorithm_tags.h \
+SeqAn-1.4.2/seqan/align/alignment_operations.h \
+SeqAn-1.4.2/seqan/align/align_metafunctions.h \
+SeqAn-1.4.2/seqan/align/align_traceback.h \
+SeqAn-1.4.2/seqan/align/dp_algorithm_impl.h \
+SeqAn-1.4.2/seqan/align/dp_band.h \
+SeqAn-1.4.2/seqan/align/dp_cell_affine.h \
+SeqAn-1.4.2/seqan/align/dp_cell.h \
+SeqAn-1.4.2/seqan/align/dp_cell_linear.h \
+SeqAn-1.4.2/seqan/align/dp_formula_affine.h \
+SeqAn-1.4.2/seqan/align/dp_formula.h \
+SeqAn-1.4.2/seqan/align/dp_formula_linear.h \
+SeqAn-1.4.2/seqan/align/dp_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_score_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_navigator_trace_matrix.h \
+SeqAn-1.4.2/seqan/align/dp_matrix_sparse.h \
+SeqAn-1.4.2/seqan/align/dp_meta_info.h \
+SeqAn-1.4.2/seqan/align/dp_profile.h \
+SeqAn-1.4.2/seqan/align/dp_scout.h \
+SeqAn-1.4.2/seqan/align/dp_setup.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_adaptor.h \
+SeqAn-1.4.2/seqan/align/dp_traceback_impl.h \
+SeqAn-1.4.2/seqan/align/dp_trace_segment.h \
+SeqAn-1.4.2/seqan/align/evaluate_alignment.h \
+SeqAn-1.4.2/seqan/align/gap_anchor.h \
+SeqAn-1.4.2/seqan/align/gapped_value_type.h \
+SeqAn-1.4.2/seqan/align/gaps_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_array.h \
+SeqAn-1.4.2/seqan/align/gaps_base.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_anchor.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_array.h \
+SeqAn-1.4.2/seqan/align/gaps_iterator_base.h \
+SeqAn-1.4.2/seqan/align/global_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/global_alignment_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_hirschberg_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_myers_impl.h \
+SeqAn-1.4.2/seqan/align/global_alignment_specialized.h \
+SeqAn-1.4.2/seqan/align/global_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align.h \
+SeqAn-1.4.2/seqan/align/INFO \
+SeqAn-1.4.2/seqan/align/local_alignment_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_banded_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_banded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration.h \
+SeqAn-1.4.2/seqan/align/local_alignment_enumeration_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_unbanded.h \
+SeqAn-1.4.2/seqan/align/local_alignment_waterman_eggert_impl.h \
+SeqAn-1.4.2/seqan/align/matrix_base.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_argument.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_ctd_support.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_exceptions.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_option.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/arg_parse_type_support.h \
+SeqAn-1.4.2/seqan/arg_parse/argument_parser.h \
+SeqAn-1.4.2/seqan/arg_parse.h \
+SeqAn-1.4.2/seqan/arg_parse/INFO \
+SeqAn-1.4.2/seqan/arg_parse/tool_doc.h \
+SeqAn-1.4.2/seqan/arg_parse/xml_support.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_alignment_record_util.h \
+SeqAn-1.4.2/seqan/bam_io/bam_header_record.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_bai.h \
+SeqAn-1.4.2/seqan/bam_io/bam_index_base.h \
+SeqAn-1.4.2/seqan/bam_io/bam_io_context.h \
+SeqAn-1.4.2/seqan/bam_io/bam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/bam_sam_conversion.h \
+SeqAn-1.4.2/seqan/bam_io/bam_stream.h \
+SeqAn-1.4.2/seqan/bam_io/bam_tags_dict.h \
+SeqAn-1.4.2/seqan/bam_io/bam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/cigar.h \
+SeqAn-1.4.2/seqan/bam_io.h \
+SeqAn-1.4.2/seqan/bam_io/INFO \
+SeqAn-1.4.2/seqan/bam_io/read_bam.h \
+SeqAn-1.4.2/seqan/bam_io/read_sam.h \
+SeqAn-1.4.2/seqan/bam_io/sam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/sam_writer.h \
+SeqAn-1.4.2/seqan/bam_io/write_bam.h \
+SeqAn-1.4.2/seqan/bam_io/write_sam.h \
+SeqAn-1.4.2/seqan/bam_io/xam_reader.h \
+SeqAn-1.4.2/seqan/bam_io/xam_writer.h \
+SeqAn-1.4.2/seqan/basic/aggregate_concept.h \
+SeqAn-1.4.2/seqan/basic/allocator_chunkpool.h \
+SeqAn-1.4.2/seqan/basic/allocator_interface.h \
+SeqAn-1.4.2/seqan/basic/allocator_multipool.h \
+SeqAn-1.4.2/seqan/basic/allocator_simple.h \
+SeqAn-1.4.2/seqan/basic/allocator_singlepool.h \
+SeqAn-1.4.2/seqan/basic/allocator_to_std.h \
+SeqAn-1.4.2/seqan/basic/alphabet_adapt_builtins.h \
+SeqAn-1.4.2/seqan/basic/alphabet_bio.h \
+SeqAn-1.4.2/seqan/basic/alphabet_concept.h \
+SeqAn-1.4.2/seqan/basic/alphabet_math.h \
+SeqAn-1.4.2/seqan/basic/alphabet_profile.h \
+SeqAn-1.4.2/seqan/basic/alphabet_qualities.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_funcs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue.h \
+SeqAn-1.4.2/seqan/basic/alphabet_residue_tabs.h \
+SeqAn-1.4.2/seqan/basic/alphabet_simple_type.h \
+SeqAn-1.4.2/seqan/basic/alphabet_storage.h \
+SeqAn-1.4.2/seqan/basic/array_construct_destruct.h \
+SeqAn-1.4.2/seqan/basic/basic_aggregate.h \
+SeqAn-1.4.2/seqan/basic/basic_allocator.h \
+SeqAn-1.4.2/seqan/basic/basic_alphabet.h \
+SeqAn-1.4.2/seqan/basic/basic_concept.h \
+SeqAn-1.4.2/seqan/basic/basic_container.h \
+SeqAn-1.4.2/seqan/basic/basic_debug.h \
+SeqAn-1.4.2/seqan/basic/basic_exception.h \
+SeqAn-1.4.2/seqan/basic/basic_fundamental.h \
+SeqAn-1.4.2/seqan/basic/basic_iterator.h \
+SeqAn-1.4.2/seqan/basic/basic_math.h \
+SeqAn-1.4.2/seqan/basic/basic_metaprogramming.h \
+SeqAn-1.4.2/seqan/basic/basic_parallelism.h \
+SeqAn-1.4.2/seqan/basic/basic_proxy.h \
+SeqAn-1.4.2/seqan/basic/basic_smart_pointer.h \
+SeqAn-1.4.2/seqan/basic/basic_tangle.h \
+SeqAn-1.4.2/seqan/basic/basic_type.h \
+SeqAn-1.4.2/seqan/basic/boost_preprocessor_subset.h \
+SeqAn-1.4.2/seqan/basic/builtin_functions.h \
+SeqAn-1.4.2/seqan/basic/concept_checking.h \
+SeqAn-1.4.2/seqan/basic/container_concept.h \
+SeqAn-1.4.2/seqan/basic/debug_helper.h \
+SeqAn-1.4.2/seqan/basic/debug_test_system.h \
+SeqAn-1.4.2/seqan/basic/fundamental_comparison.h \
+SeqAn-1.4.2/seqan/basic/fundamental_concepts.h \
+SeqAn-1.4.2/seqan/basic/fundamental_conversion.h \
+SeqAn-1.4.2/seqan/basic/fundamental_metafunctions.h \
+SeqAn-1.4.2/seqan/basic/fundamental_tags.h \
+SeqAn-1.4.2/seqan/basic/fundamental_transport.h \
+SeqAn-1.4.2/seqan/basic.h \
+SeqAn-1.4.2/seqan/basic/holder_base.h \
+SeqAn-1.4.2/seqan/basic/holder_simple.h \
+SeqAn-1.4.2/seqan/basic/holder_tristate.h \
+SeqAn-1.4.2/seqan/basic/hosted_type_interface.h \
+SeqAn-1.4.2/seqan/basic/INFO \
+SeqAn-1.4.2/seqan/basic/iterator_adaptor.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_pointer.h \
+SeqAn-1.4.2/seqan/basic/iterator_adapt_std.h \
+SeqAn-1.4.2/seqan/basic/iterator_base.h \
+SeqAn-1.4.2/seqan/basic/iterator_concept.h \
+SeqAn-1.4.2/seqan/basic/iterator_interface.h \
+SeqAn-1.4.2/seqan/basic/iterator_position.h \
+SeqAn-1.4.2/seqan/basic/macro_deprecated.h \
+SeqAn-1.4.2/seqan/basic/math_functions.h \
+SeqAn-1.4.2/seqan/basic/math_log_space_value.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_control.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_enable_if.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_logic.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_math.h \
+SeqAn-1.4.2/seqan/basic/metaprogramming_type.h \
+SeqAn-1.4.2/seqan/basic/pair_base.h \
+SeqAn-1.4.2/seqan/basic/pair_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/pair_packed.h \
+SeqAn-1.4.2/seqan/basic/profiling.h \
+SeqAn-1.4.2/seqan/basic/proxy_base.h \
+SeqAn-1.4.2/seqan/basic/proxy_iterator.h \
+SeqAn-1.4.2/seqan/basic/test_system.h \
+SeqAn-1.4.2/seqan/basic/triple_base.h \
+SeqAn-1.4.2/seqan/basic/triple_packed.h \
+SeqAn-1.4.2/seqan/basic/tuple_base.h \
+SeqAn-1.4.2/seqan/basic/tuple_bit_compressed.h \
+SeqAn-1.4.2/seqan/basic/volatile_ptr.h \
+SeqAn-1.4.2/seqan/consensus/consensus_base.h \
+SeqAn-1.4.2/seqan/consensus/consensus_library.h \
+SeqAn-1.4.2/seqan/consensus/consensus_realign.h \
+SeqAn-1.4.2/seqan/consensus/consensus_score.h \
+SeqAn-1.4.2/seqan/consensus.h \
+SeqAn-1.4.2/seqan/consensus/INFO \
+SeqAn-1.4.2/seqan/file/chunk_collector.h \
+SeqAn-1.4.2/seqan/file/cstream.h \
+SeqAn-1.4.2/seqan/file/file_base.h \
+SeqAn-1.4.2/seqan/file/file_cstyle.h \
+SeqAn-1.4.2/seqan/file/file_filereader.h \
+SeqAn-1.4.2/seqan/file/file_filereaderiterator.h \
+SeqAn-1.4.2/seqan/file/file_format_cgviz.h \
+SeqAn-1.4.2/seqan/file/file_format_embl.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta_align.h \
+SeqAn-1.4.2/seqan/file/file_format_fasta.h \
+SeqAn-1.4.2/seqan/file/file_format_genbank.h \
+SeqAn-1.4.2/seqan/file/file_format_guess.h \
+SeqAn-1.4.2/seqan/file/file_format.h \
+SeqAn-1.4.2/seqan/file/file_format_mmap.h \
+SeqAn-1.4.2/seqan/file/file_format_raw.h \
+SeqAn-1.4.2/seqan/file/file_forwards.h \
+SeqAn-1.4.2/seqan/file/file_interface.h \
+SeqAn-1.4.2/seqan/file/file_mapping.h \
+SeqAn-1.4.2/seqan/file/file_page.h \
+SeqAn-1.4.2/seqan/file.h \
+SeqAn-1.4.2/seqan/file/INFO \
+SeqAn-1.4.2/seqan/file/meta.h \
+SeqAn-1.4.2/seqan/file/stream_algorithms.h \
+SeqAn-1.4.2/seqan/file/stream.h \
+SeqAn-1.4.2/seqan/file/string_external.h \
+SeqAn-1.4.2/seqan/file/string_mmap.h \
+SeqAn-1.4.2/seqan/find/find_abndm.h \
+SeqAn-1.4.2/seqan/find/find_ahocorasick.h \
+SeqAn-1.4.2/seqan/find/find_base.h \
+SeqAn-1.4.2/seqan/find/find_begin.h \
+SeqAn-1.4.2/seqan/find/find_bndm.h \
+SeqAn-1.4.2/seqan/find/find_bom.h \
+SeqAn-1.4.2/seqan/find/find_hamming_simple.h \
+SeqAn-1.4.2/seqan/find/find_horspool.h \
+SeqAn-1.4.2/seqan/find/find_multi.h \
+SeqAn-1.4.2/seqan/find/find_multiple_bfam.h \
+SeqAn-1.4.2/seqan/find/find_multiple_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_myers_ukkonen.h \
+SeqAn-1.4.2/seqan/find/find_pattern_base.h \
+SeqAn-1.4.2/seqan/find/find_pex.h \
+SeqAn-1.4.2/seqan/find/find_score.h \
+SeqAn-1.4.2/seqan/find/find_set_horspool.h \
+SeqAn-1.4.2/seqan/find/find_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_shiftor.h \
+SeqAn-1.4.2/seqan/find/find_simple.h \
+SeqAn-1.4.2/seqan/find/find_wild_shiftand.h \
+SeqAn-1.4.2/seqan/find/find_wumanber.h \
+SeqAn-1.4.2/seqan/find.h \
+SeqAn-1.4.2/seqan/find/INFO \
+SeqAn-1.4.2/seqan/gff_io/gff_io_base.h \
+SeqAn-1.4.2/seqan/gff_io/gff_io_context.h \
+SeqAn-1.4.2/seqan/gff_io/gff_stream.h \
+SeqAn-1.4.2/seqan/gff_io.h \
+SeqAn-1.4.2/seqan/gff_io/INFO \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_heap_tree.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_hmm.h \
+SeqAn-1.4.2/seqan/graph_algorithms/graph_algorithm_lis_his.h \
+SeqAn-1.4.2/seqan/graph_algorithms.h \
+SeqAn-1.4.2/seqan/graph_algorithms/INFO \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_aligngraph.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_align.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_annotation.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_exact_iterative.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_fragment.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_inexact.h \
+SeqAn-1.4.2/seqan/graph_align/graph_algorithm_refine_scoring.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align_adapt.h \
+SeqAn-1.4.2/seqan/graph_align/graph_impl_align.h \
+SeqAn-1.4.2/seqan/graph_align.h \
+SeqAn-1.4.2/seqan/graph_align/INFO \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_base.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_distance.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_guidetree.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_io.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_kmer.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_library.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_progressive.h \
+SeqAn-1.4.2/seqan/graph_msa/graph_align_tcoffee_refinement.h \
+SeqAn-1.4.2/seqan/graph_msa.h \
+SeqAn-1.4.2/seqan/graph_msa/INFO \
+SeqAn-1.4.2/seqan/graph_types/graph_base.h \
+SeqAn-1.4.2/seqan/graph_types/graph_drawing.h \
+SeqAn-1.4.2/seqan/graph_types/graph_edgestump.h \
+SeqAn-1.4.2/seqan/graph_types/graph_idmanager.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_automaton.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_directed.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_fragment.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_hmm.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_oracle.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_tree.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_trie.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_undirected.h \
+SeqAn-1.4.2/seqan/graph_types/graph_impl_wordgraph.h \
+SeqAn-1.4.2/seqan/graph_types/graph_interface.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_adjacency.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_bfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_dfs.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_edge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_outedge.h \
+SeqAn-1.4.2/seqan/graph_types/graph_iterator_vertex.h \
+SeqAn-1.4.2/seqan/graph_types/graph_property.h \
+SeqAn-1.4.2/seqan/graph_types/graph_utility_parsing.h \
+SeqAn-1.4.2/seqan/graph_types.h \
+SeqAn-1.4.2/seqan/graph_types/INFO \
+SeqAn-1.4.2/seqan/index/find_index_approx.h \
+SeqAn-1.4.2/seqan/index/find_index_esa.h \
+SeqAn-1.4.2/seqan/index/find_index.h \
+SeqAn-1.4.2/seqan/index/find_index_qgram.h \
+SeqAn-1.4.2/seqan/index/find_pigeonhole.h \
+SeqAn-1.4.2/seqan/index/find_quasar.h \
+SeqAn-1.4.2/seqan/index/find_swift.h \
+SeqAn-1.4.2/seqan/index.h \
+SeqAn-1.4.2/seqan/index/index_base.h \
+SeqAn-1.4.2/seqan/index/index_bwt.h \
+SeqAn-1.4.2/seqan/index/index_childtab.h \
+SeqAn-1.4.2/seqan/index/index_dfi.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs.h \
+SeqAn-1.4.2/seqan/index/index_esa_algs_multi.h \
+SeqAn-1.4.2/seqan/index/index_esa_base.h \
+SeqAn-1.4.2/seqan/index/index_esa_drawing.h \
+SeqAn-1.4.2/seqan/index/index_esa_stree.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa.h \
+SeqAn-1.4.2/seqan/index/index_fm_compressed_sa_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_doc.h \
+SeqAn-1.4.2/seqan/index/index_fm_dox.h \
+SeqAn-1.4.2/seqan/index/index_fm.h \
+SeqAn-1.4.2/seqan/index/index_fm_lf_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_prefix_sum_table.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_bms.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_dictionary_wt.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_rank_support_bit_string_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree.h \
+SeqAn-1.4.2/seqan/index/index_fm_right_array_binary_tree_iterator.h \
+SeqAn-1.4.2/seqan/index/index_fm_sentinel_rank_dictionary.h \
+SeqAn-1.4.2/seqan/index/index_fm_sparse_string.h \
+SeqAn-1.4.2/seqan/index/index_fm_stree.h \
+SeqAn-1.4.2/seqan/index/index_forwards.h \
+SeqAn-1.4.2/seqan/index/index_lcp.h \
+SeqAn-1.4.2/seqan/index/index_lcp_tree.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_find.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili.h \
+SeqAn-1.4.2/seqan/index/index_pizzachili_string.h \
+SeqAn-1.4.2/seqan/index/index_qgram.h \
+SeqAn-1.4.2/seqan/index/index_qgram_openaddressing.h \
+SeqAn-1.4.2/seqan/index/index_sa_btree.h \
+SeqAn-1.4.2/seqan/index/index_sa_bwtwalk.h \
+SeqAn-1.4.2/seqan/index/index_sa_lss.h \
+SeqAn-1.4.2/seqan/index/index_sa_mm.h \
+SeqAn-1.4.2/seqan/index/index_sa_qsort.h \
+SeqAn-1.4.2/seqan/index/index_shawarma.h \
+SeqAn-1.4.2/seqan/index/index_shims.h \
+SeqAn-1.4.2/seqan/index/index_skew3.h \
+SeqAn-1.4.2/seqan/index/index_skew7.h \
+SeqAn-1.4.2/seqan/index/index_skew7_multi.h \
+SeqAn-1.4.2/seqan/index/index_wotd.h \
+SeqAn-1.4.2/seqan/index/INFO \
+SeqAn-1.4.2/seqan/index/pipe_merger3.h \
+SeqAn-1.4.2/seqan/index/pipe_merger7.h \
+SeqAn-1.4.2/seqan/index/pizzachili_api.h \
+SeqAn-1.4.2/seqan/index/pump_extender3.h \
+SeqAn-1.4.2/seqan/index/pump_extender7.h \
+SeqAn-1.4.2/seqan/index/pump_lcp_core.h \
+SeqAn-1.4.2/seqan/index/pump_separator7.h \
+SeqAn-1.4.2/seqan/index/radix.h \
+SeqAn-1.4.2/seqan/index/repeat_base.h \
+SeqAn-1.4.2/seqan/index/shape_base.h \
+SeqAn-1.4.2/seqan/index/shape_gapped.h \
+SeqAn-1.4.2/seqan/index/shape_onegapped.h \
+SeqAn-1.4.2/seqan/index/shape_predefined.h \
+SeqAn-1.4.2/seqan/index/shape_threshold.h \
+SeqAn-1.4.2/seqan/LICENSE \
+SeqAn-1.4.2/seqan/map.h \
+SeqAn-1.4.2/seqan/map/INFO \
+SeqAn-1.4.2/seqan/map/map_adapter_stl.h \
+SeqAn-1.4.2/seqan/map/map_base.h \
+SeqAn-1.4.2/seqan/map/map_chooser.h \
+SeqAn-1.4.2/seqan/map/map_skiplist.h \
+SeqAn-1.4.2/seqan/map/map_vector.h \
+SeqAn-1.4.2/seqan/map/sumlist.h \
+SeqAn-1.4.2/seqan/map/sumlist_mini.h \
+SeqAn-1.4.2/seqan/map/sumlist_skip.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdoption.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_ctd_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_parse.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/cmdparser_type_support.h \
+SeqAn-1.4.2/seqan/misc/cmdparser/INFO \
+SeqAn-1.4.2/seqan/misc/edit_environment.h \
+SeqAn-1.4.2/seqan/misc/INFO \
+SeqAn-1.4.2/seqan/misc/misc_accumulators.h \
+SeqAn-1.4.2/seqan/misc/misc_base.h \
+SeqAn-1.4.2/seqan/misc/misc_bit_twiddling.h \
+SeqAn-1.4.2/seqan/misc/misc_cmdparser.h \
+SeqAn-1.4.2/seqan/misc/misc_dequeue.h \
+SeqAn-1.4.2/seqan/misc/misc_interval_tree.h \
+SeqAn-1.4.2/seqan/misc/misc_map.h \
+SeqAn-1.4.2/seqan/misc/misc_memset.h \
+SeqAn-1.4.2/seqan/misc/misc_name_store_cache.h \
+SeqAn-1.4.2/seqan/misc/misc_parsing.h \
+SeqAn-1.4.2/seqan/misc/misc_set.h \
+SeqAn-1.4.2/seqan/misc/misc_sse2.h \
+SeqAn-1.4.2/seqan/misc/misc_svg.h \
+SeqAn-1.4.2/seqan/misc/misc_terminal.h \
+SeqAn-1.4.2/seqan/misc/misc_union_find.h \
+SeqAn-1.4.2/seqan/misc/priority_type_base.h \
+SeqAn-1.4.2/seqan/misc/priority_type_heap.h \
+SeqAn-1.4.2/seqan/modifier.h \
+SeqAn-1.4.2/seqan/modifier/INFO \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet_expansion.h \
+SeqAn-1.4.2/seqan/modifier/modifier_alphabet.h \
+SeqAn-1.4.2/seqan/modifier/modifier_functors.h \
+SeqAn-1.4.2/seqan/modifier/modifier_iterator.h \
+SeqAn-1.4.2/seqan/modifier/modifier_reverse.h \
+SeqAn-1.4.2/seqan/modifier/modifier_shortcuts.h \
+SeqAn-1.4.2/seqan/modifier/modifier_string.h \
+SeqAn-1.4.2/seqan/modifier/modifier_view.h \
+SeqAn-1.4.2/seqan/parallel.h \
+SeqAn-1.4.2/seqan/parallel/INFO \
+SeqAn-1.4.2/seqan/parallel/parallel_algorithms.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_misc.h \
+SeqAn-1.4.2/seqan/parallel/parallel_atomic_primitives.h \
+SeqAn-1.4.2/seqan/parallel/parallel_macros.h \
+SeqAn-1.4.2/seqan/parallel/parallel_splitting.h \
+SeqAn-1.4.2/seqan/parallel/parallel_tags.h \
+SeqAn-1.4.2/seqan/pipe.h \
+SeqAn-1.4.2/seqan/pipe/INFO \
+SeqAn-1.4.2/seqan/pipe/pipe_base.h \
+SeqAn-1.4.2/seqan/pipe/pipe_caster.h \
+SeqAn-1.4.2/seqan/pipe/pipe_counter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_echoer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_edit_environment.h \
+SeqAn-1.4.2/seqan/pipe/pipe_filter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_iterator.h \
+SeqAn-1.4.2/seqan/pipe/pipe_joiner.h \
+SeqAn-1.4.2/seqan/pipe/pipe_namer.h \
+SeqAn-1.4.2/seqan/pipe/pipe_sampler.h \
+SeqAn-1.4.2/seqan/pipe/pipe_shifter.h \
+SeqAn-1.4.2/seqan/pipe/pipe_source.h \
+SeqAn-1.4.2/seqan/pipe/pipe_tupler.h \
+SeqAn-1.4.2/seqan/pipe/pool_base.h \
+SeqAn-1.4.2/seqan/pipe/pool_mapper.h \
+SeqAn-1.4.2/seqan/pipe/pool_sorter.h \
+SeqAn-1.4.2/seqan/platform.h \
+SeqAn-1.4.2/seqan/platform/INFO \
+SeqAn-1.4.2/seqan/platform/platform_gcc.h \
+SeqAn-1.4.2/seqan/platform/platform_icc.h \
+SeqAn-1.4.2/seqan/platform/platform_mingw.h \
+SeqAn-1.4.2/seqan/platform/platform_nvcc.h \
+SeqAn-1.4.2/seqan/platform/platform_pgi.h \
+SeqAn-1.4.2/seqan/platform/platform_solaris.h \
+SeqAn-1.4.2/seqan/platform/platform_windows.h \
+SeqAn-1.4.2/seqan/platform/windows_stdint.h \
+SeqAn-1.4.2/seqan/random/ext_MersenneTwister.h \
+SeqAn-1.4.2/seqan/random.h \
+SeqAn-1.4.2/seqan/random/INFO \
+SeqAn-1.4.2/seqan/random/random_base.h \
+SeqAn-1.4.2/seqan/random/random_beta.h \
+SeqAn-1.4.2/seqan/random/random_beta_kfunc.h \
+SeqAn-1.4.2/seqan/random/random_geometric.h \
+SeqAn-1.4.2/seqan/random/random_lognormal.h \
+SeqAn-1.4.2/seqan/random/random_mt19937.h \
+SeqAn-1.4.2/seqan/random/random_normal.h \
+SeqAn-1.4.2/seqan/random/random_rng_functor.h \
+SeqAn-1.4.2/seqan/random/random_shuffle.h \
+SeqAn-1.4.2/seqan/random/random_uniform.h \
+SeqAn-1.4.2/seqan/score.h \
+SeqAn-1.4.2/seqan/score/INFO \
+SeqAn-1.4.2/seqan/score/score_base.h \
+SeqAn-1.4.2/seqan/score/score_edit.h \
+SeqAn-1.4.2/seqan/score/score_matrix_data.h \
+SeqAn-1.4.2/seqan/score/score_matrix.h \
+SeqAn-1.4.2/seqan/score/score_matrix_io.h \
+SeqAn-1.4.2/seqan/score/score_simple.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_impl.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_profile.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_scout.h \
+SeqAn-1.4.2/seqan/seeds/banded_chain_alignment_traceback.h \
+SeqAn-1.4.2/seqan/seeds/basic_iter_indirect.h \
+SeqAn-1.4.2/seqan/seeds.h \
+SeqAn-1.4.2/seqan/seeds/INFO \
+SeqAn-1.4.2/seqan/seeds/seeds_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_combination.h \
+SeqAn-1.4.2/seqan/seeds/seeds_extension.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining_gusfield.h \
+SeqAn-1.4.2/seqan/seeds/seeds_global_chaining.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_chained.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_diagonal.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_base.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_non_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_scored.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_set_unordered.h \
+SeqAn-1.4.2/seqan/seeds/seeds_seed_simple.h \
+SeqAn-1.4.2/seqan/seq_io/fai_index.h \
+SeqAn-1.4.2/seqan/seq_io/genomic_region.h \
+SeqAn-1.4.2/seqan/seq_io/guess_stream_format.h \
+SeqAn-1.4.2/seqan/seq_io.h \
+SeqAn-1.4.2/seqan/seq_io/INFO \
+SeqAn-1.4.2/seqan/seq_io/read_embl.h \
+SeqAn-1.4.2/seqan/seq_io/read_fasta_fastq.h \
+SeqAn-1.4.2/seqan/seq_io/read_genbank.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream.h \
+SeqAn-1.4.2/seqan/seq_io/sequence_stream_impl.h \
+SeqAn-1.4.2/seqan/seq_io/simple_read_fasta.h \
+SeqAn-1.4.2/seqan/seq_io/write_fasta_fastq.h \
+SeqAn-1.4.2/seqan/sequence/adapt_array_pointer.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_list.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_string.h \
+SeqAn-1.4.2/seqan/sequence/adapt_std_vector.h \
+SeqAn-1.4.2/seqan/sequence.h \
+SeqAn-1.4.2/seqan/sequence/INFO \
+SeqAn-1.4.2/seqan/sequence/iter_concat_virtual.h \
+SeqAn-1.4.2/seqan/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/INFO \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_sorted_array.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_iterator.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entries_unbalanced_tree_node.h \
+SeqAn-1.4.2/seqan/sequence_journaled/journal_entry.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled.h \
+SeqAn-1.4.2/seqan/sequence_journaled/sequence_journaled_iterator.h \
+SeqAn-1.4.2/seqan/sequence/segment_base.h \
+SeqAn-1.4.2/seqan/sequence/segment_infix.h \
+SeqAn-1.4.2/seqan/sequence/segment_prefix.h \
+SeqAn-1.4.2/seqan/sequence/segment_suffix.h \
+SeqAn-1.4.2/seqan/sequence/segment_utils.h \
+SeqAn-1.4.2/seqan/sequence/sequence_concatenator.h \
+SeqAn-1.4.2/seqan/sequence/sequence_forwards.h \
+SeqAn-1.4.2/seqan/sequence/sequence_interface.h \
+SeqAn-1.4.2/seqan/sequence/sequence_lexical.h \
+SeqAn-1.4.2/seqan/sequence/sequence_shortcuts.h \
+SeqAn-1.4.2/seqan/sequence/string_alloc.h \
+SeqAn-1.4.2/seqan/sequence/string_array.h \
+SeqAn-1.4.2/seqan/sequence/string_base.h \
+SeqAn-1.4.2/seqan/sequence/string_block.h \
+SeqAn-1.4.2/seqan/sequence/string_cstyle.h \
+SeqAn-1.4.2/seqan/sequence/string_packed.h \
+SeqAn-1.4.2/seqan/sequence/string_packed_old.h \
+SeqAn-1.4.2/seqan/sequence/string_set_base.h \
+SeqAn-1.4.2/seqan/sequence/string_set_concat_direct.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_generous.h \
+SeqAn-1.4.2/seqan/sequence/string_set_dependent_tight.h \
+SeqAn-1.4.2/seqan/sequence/string_set_owner.h \
+SeqAn-1.4.2/seqan/store.h \
+SeqAn-1.4.2/seqan/store/INFO \
+SeqAn-1.4.2/seqan/store/store_align.h \
+SeqAn-1.4.2/seqan/store/store_align_intervals.h \
+SeqAn-1.4.2/seqan/store/store_all.h \
+SeqAn-1.4.2/seqan/store/store_annotation.h \
+SeqAn-1.4.2/seqan/store/store_base.h \
+SeqAn-1.4.2/seqan/store/store_contig.h \
+SeqAn-1.4.2/seqan/store/store_intervaltree.h \
+SeqAn-1.4.2/seqan/store/store_io_gff.h \
+SeqAn-1.4.2/seqan/store/store_io.h \
+SeqAn-1.4.2/seqan/store/store_io_sam.h \
+SeqAn-1.4.2/seqan/store/store_io_ucsc.h \
+SeqAn-1.4.2/seqan/store/store_library.h \
+SeqAn-1.4.2/seqan/store/store_matepair.h \
+SeqAn-1.4.2/seqan/store/store_read.h \
+SeqAn-1.4.2/seqan/stream/adapt_cstdio.h \
+SeqAn-1.4.2/seqan/stream/adapt_fstream.h \
+SeqAn-1.4.2/seqan/stream/adapt_iostream.h \
+SeqAn-1.4.2/seqan/stream/adapt_mmap.h \
+SeqAn-1.4.2/seqan/stream/adapt_sstream.h \
+SeqAn-1.4.2/seqan/stream/concept_stream.h \
+SeqAn-1.4.2/seqan/stream/file_stream.h \
+SeqAn-1.4.2/seqan/stream.h \
+SeqAn-1.4.2/seqan/stream/INFO \
+SeqAn-1.4.2/seqan/stream/is.h \
+SeqAn-1.4.2/seqan/stream/lexical_cast.h \
+SeqAn-1.4.2/seqan/stream/read_auto_format.h \
+SeqAn-1.4.2/seqan/stream/read.h \
+SeqAn-1.4.2/seqan/stream/read_sam.h \
+SeqAn-1.4.2/seqan/stream/record_reader_base.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double.h \
+SeqAn-1.4.2/seqan/stream/record_reader_double_mmap.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single.h \
+SeqAn-1.4.2/seqan/stream/record_reader_single_mmap.h \
+SeqAn-1.4.2/seqan/stream/stream_base.h \
+SeqAn-1.4.2/seqan/stream/stream_bgzf.h \
+SeqAn-1.4.2/seqan/stream/stream_bz2_file.h \
+SeqAn-1.4.2/seqan/stream/stream_char_array.h \
+SeqAn-1.4.2/seqan/stream/stream_gz_file.h \
+SeqAn-1.4.2/seqan/stream/stream_put.h \
+SeqAn-1.4.2/seqan/stream/tokenize.h \
+SeqAn-1.4.2/seqan/stream/write.h \
+SeqAn-1.4.2/seqan/system/file_async.h \
+SeqAn-1.4.2/seqan/system/file_directory.h \
+SeqAn-1.4.2/seqan/system/file_forwards.h \
+SeqAn-1.4.2/seqan/system/file_sync.h \
+SeqAn-1.4.2/seqan/system.h \
+SeqAn-1.4.2/seqan/system/INFO \
+SeqAn-1.4.2/seqan/system/system_base.h \
+SeqAn-1.4.2/seqan/system/system_event.h \
+SeqAn-1.4.2/seqan/system/system_forwards.h \
+SeqAn-1.4.2/seqan/system/system_mutex.h \
+SeqAn-1.4.2/seqan/system/system_sema.h \
+SeqAn-1.4.2/seqan/system/system_thread.h \
+SeqAn-1.4.2/seqan/version.h
 
 SAMDIR = ./samtools-0.1.18
 SAMLIB = libbam.a
 SAMPROG = samtools_0.1.18
-
-#	$(SAMPROG) 
 bin_SCRIPTS = \
 	tophat2 \
 	tophat
@@ -974,9 +1055,6 @@ dist_bin_SCRIPTS = \
 	sra_to_solid \
 	tophat-fusion-post
 
-
-#samtools_0_1_18_SOURCES = 
-#samtools_0_1_18_LDADD = 
 CLEANFILES = \
 	tophat2 \
 	tophat
@@ -1511,7 +1589,8 @@ info: info-am
 info-am:
 
 install-data-am:
-
+	@$(NORMAL_INSTALL)
+	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 install-dvi: install-dvi-am
 
 install-dvi-am:
@@ -1559,38 +1638,42 @@ ps-am:
 uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 	uninstall-dist_binSCRIPTS
 
-.MAKE: install-am install-strip
+.MAKE: install-am install-data-am install-strip
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
 	clean-generic clean-local clean-noinstLIBRARIES cscopelist \
 	ctags distclean distclean-compile distclean-generic \
 	distclean-tags distdir dvi dvi-am html html-am info info-am \
 	install install-am install-binPROGRAMS install-binSCRIPTS \
-	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-compile mostlyclean-generic pdf pdf-am \
-	ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-binSCRIPTS uninstall-dist_binSCRIPTS
+	install-data install-data-am install-data-hook \
+	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-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
+	uninstall-dist_binSCRIPTS
 
 
 clean-local:
 	cd $(SAMDIR) && make clean
 
-tophat2: tophat2.in
-	sed -e 's|__PREFIX__|$(prefix)|' tophat2.in > tophat2
+tophat2: tophat2.sh
+	cp tophat2.sh tophat2 && chmod 755 tophat2
 
 tophat: tophat.py
-	sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat
+	sed -e 's|__VERSION__|$(VERSION)|' tophat.py > tophat && chmod 755 tophat
 
 $(SAMPROG): $(SAMLIB)
 
 $(SAMLIB):
 	cd $(SAMDIR) && make $(SAMPROG) && cp $(SAMLIB) $(SAMPROG) ..
 
+install-data-hook:
+	cp -r intervaltree sortedcontainers $(DESTDIR)$(bindir)
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/src/bam2fastx.cpp b/src/bam2fastx.cpp
index e500fa8..b489939 100644
--- a/src/bam2fastx.cpp
+++ b/src/bam2fastx.cpp
@@ -1,3 +1,11 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#else
+#define PACKAGE_VERSION "local"
+#define SVN_REVISION "unknown"
+#endif
+
+
 #include <cstdlib>
 #include <cstdio>
 #include <cstring>
@@ -22,18 +30,45 @@ bool ignoreOQ=false; // ignore OQ tag
 
 string outfname;
 
-#define USAGE "Usage: bam2fastx [--fasta|-a|--fastq|-q] [--color] [-Q] [--sam|-s|-t]\n\
-   [-M|--mapped-only|-A|--all] [-o <outfile>] [-P|--paired] [-N] <in.bam>\n\
-   \nNote: By default, reads flagged as not passing quality controls are\n\
-   discarded; the -Q option can be used to ignore the QC flag.\n\
-   \nUse the -N option if the /1 and /2 suffixes should be appended to\n\
-   read names according to the SAM flags\n\
-   \nUse the -O option to ignore the OQ tag, if present, when writing quality values\n"
+#define USAGE "bam2fastx v%s (%s) usage:\n\
+ bam2fastx [--fasta|-a] [-C|--color] [-P|--paired] [-N]\n\
+ [-A|--all|-M|--mapped-only] [-Q] [--sam|-s|-t] [-o <outfname>] <in.bam>\n\
+ \nBy default, bam2fastx only converts the unmapped reads from the input file,\n\
+  discarding those unmapped reads flagged as QC failed.\n\
+  The input BAM/SAM file MUST be sorted by read name (-n option for samtools\n\
+  sort). If the input file name is \"-\", stdin will be used instead.\n\
+ \nOptions:\n\
+ -A,--all         convert all reads (mapped and unmapped)\n\
+                  (but discarding those flagged as QC failed, unless -Q)\n\
+ -P               paired reads are expected and converted into two output\n\
+                  files (see <outfname> comments below)\n\
+ -Q               convert unmapped reads even when flagged as QC failed\n\
+ -M,--maped-only  convert only mapped reads\n\
+ -N               for -P, append  /1 and /2 suffixes to read names\n\
+ -O               ignore the original quality values (OQ tag) and write the\n\
+                  current quality values (default is to use OQ data if found)\n\
+ -C,--color       reads are in ABI SOLiD color format\n\
+ -s,-t,--sam      input is a SAM text file (default: BAM input expected)\n\
+ -a,--fasta       output FASTA records, not FASTQ (discard quality values)\n\
+ -o <outfname>    output file name or template (see below)\n\
+\n\
+ <outfname> serves as a name template when -P option is provided, as suffixes\n\
+ .1 and .2 will be automatically inserted before the file extension in \n\
+ <outfname>, such that two file names will be created.\n\
+ If <outfname> ends in .gz or .bz2 then bam2fastx will write the\n\
+ output compressed by gzip or bzip2 respectively.\n\n\
+ Example of converting all paired reads from a BAM file to FASTQ format:\n\
+    bam2fastx -PANQ -o sample.fq.gz sample.sortedbyname.bam\n\
+ In this example the output will be written in two files: \n\
+   sample.1.fq.gz and sample.2.fq.gz\n\
+"
 
-const char *short_options = "o:ac:qstOQMAPN";
+const char *short_options = "o:ac:qvhstOQCMAPN";
 
 enum {
-   OPT_FASTA = 127,
+   OPT_HELP = 127,
+   OPT_VERSION,
+   OPT_FASTA,
    OPT_FASTQ,
    OPT_SAM,
    OPT_PAIRED,
@@ -41,7 +76,7 @@ enum {
    OPT_ALL,
    OPT_COLOR
    };
-   
+
 struct Read {
 	string name;
 	int mate;
@@ -56,6 +91,8 @@ struct Read {
 };
 
 struct option long_options[] = {
+  {"help", no_argument, 0, OPT_HELP},
+  {"version", no_argument, 0, OPT_VERSION},
   {"fasta", no_argument, 0, OPT_FASTA},
   {"fastq", no_argument, 0, OPT_FASTQ},
   {"sam", no_argument, 0, OPT_SAM},
@@ -73,54 +110,63 @@ int parse_options(int argc, char** argv)
   do {
      next_option = getopt_long(argc, argv, short_options, long_options, &option_index);
      switch (next_option) {
-       case -1:    
-         break;
-       case 'a':
-       case OPT_FASTA:
-         is_fastq = false;
-         break;
-       case 'q':
-       case OPT_FASTQ:
-         is_fastq = true;
-         break;
-       case 's':
-       case 't':
-       case OPT_SAM: //sam (text) input
-         sam_input = true;
-         break;
-       case 'M':
-       case OPT_MAPPED_ONLY:
-         mapped_only = true;
+      case -1:
          break;
-       case 'A':
-       case OPT_ALL:
-         all_reads = true;
-         break;
-     case OPT_COLOR:
-       color = true;
-       break;
-       case 'P':
-       case OPT_PAIRED:
-         pairs = true;
-         break;
-       case 'Q':
-    	 ignoreQC = true;
-    	 break;
-       case 'O':
-    	 ignoreOQ = true;
-    	 break;
-       case 'o':
-         outfname=optarg;
-         break;
-       case 'N':
-    	 add_matenum=true;
-    	 break;
-       default:
-         return 1;
-       }
+      case 'h':
+      case OPT_HELP:
+         fprintf(stdout, USAGE, PACKAGE_VERSION, SVN_REVISION);
+         exit(0);
+      case 'v':
+      case OPT_VERSION:
+         fprintf(stdout, "%s\n", PACKAGE_VERSION);
+         exit(0);
+      case 'a':
+      case OPT_FASTA:
+        is_fastq = false;
+        break;
+      case 'q':
+      case OPT_FASTQ:
+        is_fastq = true;
+        break;
+      case 's':
+      case 't':
+      case OPT_SAM: //sam (text) input
+        sam_input = true;
+        break;
+      case 'M':
+      case OPT_MAPPED_ONLY:
+        mapped_only = true;
+        break;
+      case 'A':
+      case OPT_ALL:
+        all_reads = true;
+        break;
+      case 'C':
+      case OPT_COLOR:
+        color = true;
+        break;
+     case 'P':
+        case OPT_PAIRED:
+        pairs = true;
+        break;
+      case 'Q':
+        ignoreQC = true;
+        break;
+      case 'O':
+        ignoreOQ = true;
+        break;
+      case 'o':
+        outfname=optarg;
+        break;
+      case 'N':
+        add_matenum=true;
+        break;
+      default:
+        return 1;
+      }
    } while(next_option != -1);
   if (all_reads && mapped_only) {
-    fprintf(stderr, "Error: incompatible options !\n");
+    fprintf(stderr, "Error: incompatible options, use either -A/--all or -M/--mapped-only!\n");
     exit(2);
     }
   return 0;
@@ -322,13 +368,13 @@ int main(int argc, char *argv[])
     char* fname=NULL;
     bool use_pclose=false;
     if (parse_options(argc, argv) || optind>=argc) {
-       fprintf(stderr, USAGE);
+       fprintf(stderr, USAGE, PACKAGE_VERSION, SVN_REVISION);
        return -1;
        }
     fname=argv[optind++];
 
     if (fname==NULL || fname[0]==0) {
-        fprintf(stderr, USAGE);
+        fprintf(stderr, USAGE, PACKAGE_VERSION, SVN_REVISION);
         return 1;
         }
     if (sam_input)
diff --git a/src/bam_merge.h b/src/bam_merge.h
index 6241e31..d7db357 100644
--- a/src/bam_merge.h
+++ b/src/bam_merge.h
@@ -43,6 +43,9 @@ struct equal_bam {
 
     if (first.b->core.n_cigar != second.b->core.n_cigar)
       return false;
+    
+    if ((first.b->core.flag & BAM_FREVERSE) != (second.b->core.flag & BAM_FREVERSE))
+      return false;
 
     for (int i = 0; i < first.b->core.n_cigar; ++i){
       if (bam1_cigar(first.b)[i] != bam1_cigar(second.b)[i])
diff --git a/src/common.cpp b/src/common.cpp
index 750e8cb..4a12292 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -969,7 +969,7 @@ uint8_t* dupalloc_bdata(bam1_t *b, int size) {
   return odata; //user must FREE this after
 }
 
-extern unsigned short bam_char2flag_table[];
+//extern unsigned short bam_char2flag_table[];
 
 GBamRecord::GBamRecord(const char* qname, int32_t gseq_tid,
 		       int pos, bool reverse, const char* qseq, const char* cigar, const char* quals) {
@@ -984,7 +984,7 @@ GBamRecord::GBamRecord(const char* qname, int32_t gseq_tid,
    b->core.tid=gseq_tid;
    b->core.mtid=-1;
    b->core.mpos=-1;
-   b->core.qual=255;
+   b->core.qual=0;
    int l_qseq=strlen(qseq);
    //this may not be accurate, setting CIGAR is the correct way
    //b->core.bin = bam_reg2bin(b->core.pos, b->core.pos+l_qseq-1);
diff --git a/src/common.h b/src/common.h
index 6f92ec0..6bea311 100644
--- a/src/common.h
+++ b/src/common.h
@@ -576,13 +576,13 @@ class GBamWriter {
       }
    void write(bam1_t* b, int64_t read_id=0) {
      int64_t pre_block_addr=0; //offsets after last write()
-     int     pre_block_offs=0; //but before this write()
+     //int     pre_block_offs=0; //but before this write()
      int64_t pre_pos=0;
      bool write_index=false;
      if (findex && read_id) {
        if (idxcount >= INDEX_REC_COUNT && read_id != idx_last_id) {
 	 pre_pos = this->tell();
-	 pre_block_offs = pre_pos & 0xFFFF;
+	 //pre_block_offs = pre_pos & 0xFFFF;
 	 pre_block_addr = (pre_pos >> 16) & 0xFFFFFFFFFFFFLL;
 	 write_index=true;
        }
diff --git a/src/gff.cpp b/src/gff.cpp
index d485aae..cc954cd 100644
--- a/src/gff.cpp
+++ b/src/gff.cpp
@@ -55,7 +55,8 @@ int gfo_cmpByLoc(const pointer p1, const pointer p2) {
                               return (int)(g1.end-g2.end);
                         else return strcmp(g1.getID(), g2.getID());
              }
-             else return (int)(g1.gseq_id-g2.gseq_id);
+             else //return (int)(g1.gseq_id-g2.gseq_id); // input order !
+            	 return strcmp(g1.getGSeqName(), g2.getGSeqName()); //lexicographic !
 }
 
 char* GffLine::extractAttr(const char* attr, bool caseStrict, bool enforce_GTF2) {
@@ -695,6 +696,7 @@ chr1	hg18_knownGene	exon	69805456	69806912	0.000000	+	.
   // -- make sure any other related boundaries are updated:
   start=exons.First()->start;
   end=exons.Last()->end;
+  /*
   if (uptr!=NULL) { //collect stats about the underlying genomic sequence
     GSeqStat* gsd=(GSeqStat*)uptr;
     if (start<gsd->mincoord) gsd->mincoord=start;
@@ -704,6 +706,7 @@ chr1	hg18_knownGene	exon	69805456	69806912	0.000000	+	.
         gsd->maxfeat=this;
         }
     }
+  */
 }
 
 void GffObj::removeExon(int idx) {
@@ -770,7 +773,9 @@ GffObj::GffObj(GffReader *gfrd, GffLine* gffline, bool keepAttr, bool noExonAttr
   if (gfrd==NULL)
     GError("Cannot use this GffObj constructor with a NULL GffReader!\n");
   gffnames_ref(names);
-  if (gfrd->names==NULL) gfrd->names=names;
+  if (gfrd->names==NULL) {
+	  gfrd->names=names;
+  }
   //qlen=0;qstart=0;qend=0;
   gscore=0;
   uscore=0;
@@ -849,17 +854,9 @@ GffObj::GffObj(GffReader *gfrd, GffLine* gffline, bool keepAttr, bool noExonAttr
 	 geneID=Gstrdup(gffline->parents[0]);
      }
 
-  //GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,names->gseqs.lastNameUsed()),true);
-  GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,gffline->gseqname), true);
-  uptr=gsd;
-  /*
-  if (start<gsd->mincoord) gsd->mincoord=start;
-  if (end>gsd->maxcoord) gsd->maxcoord=end;
-    if (this->len()>gsd->maxfeat_len) {
-        gsd->maxfeat_len=this->len();
-        gsd->maxfeat=this;
-        }
-  */
+  //GSeqStat* gsd=gfrd->gseqstats.AddIfNew(new GSeqStat(gseq_id,gffline->gseqname), true);
+  //GSeqStat* gsd=gfrd->gseqtable[gseq_id];
+  //uptr=gsd;
 }
 
 GffLine* GffReader::nextGffLine() {
@@ -917,7 +914,6 @@ GffObj* GffReader::gfoAdd(GffObj* gfo) {
  GPVec<GffObj>* glst=phash.Find(gfo->gffID);
  if (glst==NULL)
 	 glst=new GPVec<GffObj>(false);
- //GfoHolder gh(gfo); //,idx);
  int i=glst->Add(gfo);
  phash.Add(gfo->gffID, glst);
  return glst->Get(i);
@@ -998,25 +994,12 @@ GffObj* GffReader::newGffRec(GffLine* gffline, bool keepAttr, bool noExonAttr,
                           GffObj* parent, GffExon* pexon, GPVec<GffObj>* glst) {
   GffObj* newgfo=new GffObj(this, gffline, keepAttr, noExonAttr);
   GffObj* r=NULL;
-  //int gfoidx=gflst.Add(newgfo);
   gflst.Add(newgfo);
   r=(glst) ? gfoAdd(*glst, newgfo) : gfoAdd(newgfo);
   if (parent!=NULL) {
     updateParent(r, parent);
     if (pexon!=NULL) parent->removeExon(pexon);
     }
-  /*
-  if (gff_warns) {
-    int* pcount=tids.Find(newgfo->gffID);
-    if (pcount!=NULL) {
-       if (gff_warns) GMessage("Warning: duplicate GFF ID: %s\n", newgfo->gffID);
-       (*pcount)++;
-       }
-     else {
-       tids.Add(newgfo->gffID,new int(1));
-       }
-    }
-  */
   return r;
 }
 
@@ -1117,11 +1100,11 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 		GffObj* prevseen=NULL;
 		GPVec<GffObj>* prevgflst=NULL;
 		if (gffline->ID && gffline->exontype==0) {
-			//>> for a parent-like IDed feature (mRNA, gene, etc.)
-			//look for same ID on the same chromosome/strand/locus
+			//parent-like feature ID (mRNA, gene, etc.)
+			//check if this ID was previously seen on the same chromosome/strand within GFF_MAX_LOCUS distance
 			prevseen=gfoFind(gffline->ID, prevgflst, gffline->gseqname, gffline->strand, gffline->fstart);
-			if (prevseen!=NULL) {
-				//same ID/chromosome combo encountered before
+			if (prevseen) {
+				//same ID seen in the same locus/region
 				if (prevseen->createdByExon()) {
 					if (gff_show_warnings && (prevseen->start<gffline->fstart ||
 							prevseen->end>gffline->fend))
@@ -1130,14 +1113,14 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 					//this line has the main attributes for this ID
 					updateGffRec(prevseen, gffline, keepAttr);
 				}
-				else {
-					//- duplicate ID -- this must be a discontinuous feature according to GFF3 specs
-					//   e.g. a trans-spliced transcript
+				else
+				{ //duplicate ID -- but this could also be a discontinuous feature according to GFF3 specs
+				  //e.g. a trans-spliced transcript - but segments should not overlap
 					if (prevseen->overlap(gffline->fstart, gffline->fend)) {
-						//overlapping with same ID not allowed
-						GMessage("GFF Error: duplicate/invalid '%s' feature ID=%s\n", gffline->ftype, gffline->ID);
+						//overlapping feature with same ID is going too far
+						GMessage("GFF Error: overlapping duplicate %s feature (ID=%s)\n", gffline->ftype, gffline->ID);
 						//validation_errors = true;
-						if (gff_warns) {
+						if (gff_warns) { //validation intent: just skip the feature, allow the user to see other errors
 							delete gffline;
 							gffline=NULL;
 							continue;
@@ -1145,6 +1128,7 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 						else exit(1);
 					}
 					//create a new entry with the same ID
+					/*
 					int distance=INT_MAX;
 					if (prevseen->isTranscript() && prevseen->strand==gffline->strand) {
 						if (prevseen->start>=gffline->fstart)
@@ -1156,18 +1140,28 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 						//exception: make this an exon of previous ID
 						//addExonFeature(prevseen, gffline, pex, noExonAttr);
 						prevseen->addExon(this, gffline, false, true);
+						if (gff_warns) {
+							GMessage("GFF Warning: duplicate feature ID %s (%d-%d) added as exon of previous %d-%d!\n",
+									gffline->ID, gffline->fstart, gffline->fend, prevseen->start, prevseen->end);
+						}
 					}
-					else { //create a separate entry (true discontinuous feature)
+					else {
+					*/
+					//create a separate entry (true discontinuous feature)
 						prevseen=newGffRec(gffline, keepAttr, noExonAttr,
 								prevseen->parent, NULL, prevgflst);
-					}
-				} //duplicate ID on the same chromosome
-			} //prevseeen != NULL
-		} //parent-like ID feature
+						if (gff_warns) {
+							GMessage("GFF Warning: duplicate feature ID %s (%d-%d) (discontinuous feature?)\n",
+									gffline->ID, gffline->fstart, gffline->fend);
+						}
+					//}
+				} //duplicate ID in the same locus
+			} //ID seen previously in the same locus
+		} //parent-like ID feature (non-exon)
 		if (gffline->parents==NULL) {//start GFF3-like record with no parent (mRNA, gene)
 			if (!prevseen) newGffRec(gffline, keepAttr, noExonAttr, NULL, NULL, prevgflst);
 		}
-		else { //--- it's a child feature (exon/CDS but could still be a mRNA with gene(s) as parent)
+		else { //--- it's a child feature (exon/CDS or even a mRNA with a gene as parent)
 			//updates all the declared parents with this child
 			bool found_parent=false;
 			GffObj* newgfo=prevseen;
@@ -1215,7 +1209,7 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 						}
 					}
 					else { //potential exon subfeature?
-						//always discards dummy "intron" features
+						//always discard dummy "intron" features
 						if (!(gffline->exontype==exgffIntron && (parentgfo->isTranscript() || parentgfo->exons.Count()>0))) {
 							if (!addExonFeature(parentgfo, gffline, pex, noExonAttr))
 								validation_errors=true;
@@ -1257,10 +1251,6 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 	}//while gff lines
 	if (gflst.Count()>0) {
 		gflst.finalize(this, mergeCloseExons, keepAttr, noExonAttr); //force sorting by locus if so constructed
-		gseqStats.setCount(gseqstats.Last()->gseqid+1);
-		for (int gi=0;gi<gseqstats.Count();gi++) {
-			gseqStats.Put(gseqstats[gi]->gseqid, gseqstats[gi]); //copy the pointer only
-		}
 	}
 	// all gff records are now loaded in GList gflst
 	// so we can free the hash
@@ -1273,10 +1263,6 @@ void GffReader::readAll(bool keepAttr, bool mergeCloseExons, bool noExonAttr) {
 
 void GfList::finalize(GffReader* gfr, bool mergeCloseExons,
              bool keepAttrs, bool noExonAttr) { //if set, enforce sort by locus
-  if (mustSort) { //force (re-)sorting
-     this->setSorted(false);
-     this->setSorted((GCompareProc*)gfo_cmpByLoc);
-     }
   GList<GffObj> discarded(false,true,false);
   for (int i=0;i<Count();i++) {
     //finish the parsing for each GffObj
@@ -1296,94 +1282,106 @@ void GfList::finalize(GffReader* gfr, bool mergeCloseExons,
   if (discarded.Count()>0) {
           this->Pack();
           }
+  if (mustSort) { //force (re-)sorting
+     this->setSorted(false);
+     this->setSorted((GCompareProc*)gfo_cmpByLoc);
+     }
 }
 
 GffObj* GffObj::finalize(GffReader* gfr, bool mergeCloseExons, bool keepAttrs, bool noExonAttr) {
  //merge
  //always merge adjacent or overlapping segments
  //but if mergeCloseExons then merge even when distance is up to 5 bases
- udata=0;
- uptr=NULL;
  if (gfr->transcriptsOnly && !(isTranscript() || (isGene() && children.Count()==0))) {
-       isDiscarded(true);
-       }
+ 	isDiscarded(true);
+ }
  if (ftype_id==gff_fid_transcript && CDstart>0) {
-    ftype_id=gff_fid_mRNA;
-    //exon_ftype_id=gff_fid_exon;
-    }
+ 	ftype_id=gff_fid_mRNA;
+ 	//exon_ftype_id=gff_fid_exon;
+ }
  if (exons.Count()>0 && (isTranscript() || exon_ftype_id==gff_fid_exon)) {
-   if (mergeCloseExons) {
-     int mindist=mergeCloseExons ? 5:1;
-     for (int i=0;i<exons.Count()-1;i++) {
-       int ni=i+1;
-       uint mend=exons[i]->end;
-       while (ni<exons.Count()) {
-         int dist=(int)(exons[ni]->start-mend);
-         if (dist>mindist) break; //no merging with next segment
-         if (gfr!=NULL && gfr->gff_warns && dist!=0 && (exons[ni]->exontype!=exgffUTR && exons[i]->exontype!=exgffUTR)) {
-            GMessage("GFF warning: merging adjacent/overlapping segments of %s on %s (%d-%d, %d-%d)\n",
-                 gffID, getGSeqName(), exons[i]->start, exons[i]->end,exons[ni]->start, exons[ni]->end);
-            }
-         mend=exons[ni]->end;
-         covlen-=exons[i]->len();
-         exons[i]->end=mend;
-         covlen+=exons[i]->len();
-         covlen-=exons[ni]->len();
-         if (exons[ni]->attrs!=NULL && (exons[i]->attrs==NULL ||
-              exons[i]->attrs->Count()<exons[ni]->attrs->Count())) {
-                //use the other exon attributes, if more
-                delete(exons[i]->attrs);
-                exons[i]->attrs=exons[ni]->attrs;
-                exons[ni]->attrs=NULL;
-                }
-         exons.Delete(ni);
-         } //check for merge with next exon
-     } //for each exon
-   } //merge close exons
-   //shrink transcript to the exons' span
-   this->start=exons.First()->start;
-   this->end=exons.Last()->end;
-   //also update the stats for the reference sequence
-   if (uptr!=NULL) { //collect stats about the underlying genomic sequence
-       GSeqStat* gsd=(GSeqStat*)uptr;
-       if (start<gsd->mincoord) gsd->mincoord=start;
-       if (end>gsd->maxcoord) gsd->maxcoord=end;
-       if (this->len()>gsd->maxfeat_len) {
-          gsd->maxfeat_len=this->len();
-          gsd->maxfeat=this;
-          }
-       }
-   this->uptr=NULL;
-   this->udata=0;
+ 	if (mergeCloseExons) {
+ 		int mindist=mergeCloseExons ? 5:1;
+ 		for (int i=0;i<exons.Count()-1;i++) {
+ 			int ni=i+1;
+ 			uint mend=exons[i]->end;
+ 			while (ni<exons.Count()) {
+ 				int dist=(int)(exons[ni]->start-mend);
+ 				if (dist>mindist) break; //no merging with next segment
+ 				if (gfr!=NULL && gfr->gff_warns && dist!=0 && (exons[ni]->exontype!=exgffUTR && exons[i]->exontype!=exgffUTR)) {
+ 					GMessage("GFF warning: merging adjacent/overlapping segments of %s on %s (%d-%d, %d-%d)\n",
+ 							gffID, getGSeqName(), exons[i]->start, exons[i]->end,exons[ni]->start, exons[ni]->end);
+ 				}
+ 				mend=exons[ni]->end;
+ 				covlen-=exons[i]->len();
+ 				exons[i]->end=mend;
+ 				covlen+=exons[i]->len();
+ 				covlen-=exons[ni]->len();
+ 				if (exons[ni]->attrs!=NULL && (exons[i]->attrs==NULL ||
+ 						exons[i]->attrs->Count()<exons[ni]->attrs->Count())) {
+ 					//use the other exon attributes, if more
+ 					delete(exons[i]->attrs);
+ 					exons[i]->attrs=exons[ni]->attrs;
+ 					exons[ni]->attrs=NULL;
+ 				}
+ 				exons.Delete(ni);
+ 			} //check for merge with next exon
+ 		} //for each exon
+ 	} //merge close exons
+ 	//shrink transcript to the exons' span
+ 	this->start=exons.First()->start;
+ 	this->end=exons.Last()->end;
+ 	//also update the stats for the reference sequence
+ 	if (!this->isDiscarded()) { //collect stats about the underlying genomic sequence
+ 		if (gfr->gseqtable.Count()<=gseq_id) {
+ 			gfr->gseqtable.setCount(gseq_id+1);
+ 		}
+ 		GSeqStat* gsd=gfr->gseqtable[gseq_id];
+ 		if (gsd==NULL) {
+ 			gsd=new GSeqStat(gseq_id,names->gseqs.getName(gseq_id));
+ 			gfr->gseqtable.Put(gseq_id, gsd);
+ 			gfr->gseqStats.Add(gsd);
+ 		}
+ 		gsd->fcount++;
+ 		if (start<gsd->mincoord) gsd->mincoord=start;
+ 		if (end>gsd->maxcoord) gsd->maxcoord=end;
+ 		if (this->len()>gsd->maxfeat_len) {
+ 			gsd->maxfeat_len=this->len();
+ 			gsd->maxfeat=this;
+ 		}
+ 	}
+ 	uptr=NULL;
+ 	udata=0;
  }
+
  //attribute reduction for GTF records
  if (keepAttrs && !noExonAttr && !hasGffID()
-          && exons.Count()>0 && exons[0]->attrs!=NULL) {
-   bool attrs_discarded=false;
-   for (int a=0;a<exons[0]->attrs->Count();a++) {
-      int attr_name_id=exons[0]->attrs->Get(a)->attr_id;
-      char* attr_name=names->attrs.getName(attr_name_id);
-      char* attr_val =exons[0]->attrs->Get(a)->attr_val;
-      bool sameExonAttr=true;
-      for (int i=1;i<exons.Count();i++) {
-         char* ov=exons[i]->getAttr(attr_name_id);
-         if (ov==NULL || (strcmp(ov,attr_val)!=0)) { 
-             sameExonAttr=false; 
-             break;
-             }
-         }
-      if (sameExonAttr) {
-             //delete this attribute from exons level
-             attrs_discarded=true;
-             this->addAttr(attr_name, attr_val);
-             for (int i=1;i<exons.Count();i++) {
-                 removeExonAttr(*(exons[i]), attr_name_id);
-                 }
-             exons[0]->attrs->freeItem(a);
-             }
-      }
-   if (attrs_discarded) exons[0]->attrs->Pack();
-   }
+ 		&& exons.Count()>0 && exons[0]->attrs!=NULL) {
+ 	bool attrs_discarded=false;
+ 	for (int a=0;a<exons[0]->attrs->Count();a++) {
+ 		int attr_name_id=exons[0]->attrs->Get(a)->attr_id;
+ 		char* attr_name=names->attrs.getName(attr_name_id);
+ 		char* attr_val =exons[0]->attrs->Get(a)->attr_val;
+ 		bool sameExonAttr=true;
+ 		for (int i=1;i<exons.Count();i++) {
+ 			char* ov=exons[i]->getAttr(attr_name_id);
+ 			if (ov==NULL || (strcmp(ov,attr_val)!=0)) {
+ 				sameExonAttr=false;
+ 				break;
+ 			}
+ 		}
+ 		if (sameExonAttr) {
+ 			//delete this attribute from exons level
+ 			attrs_discarded=true;
+ 			this->addAttr(attr_name, attr_val);
+ 			for (int i=1;i<exons.Count();i++) {
+ 				removeExonAttr(*(exons[i]), attr_name_id);
+ 			}
+ 			exons[0]->attrs->freeItem(a);
+ 		}
+ 	}
+ 	if (attrs_discarded) exons[0]->attrs->Pack();
+ }
  return this;
 }
 
diff --git a/src/gff.h b/src/gff.h
index edf2b69..ba0b762 100644
--- a/src/gff.h
+++ b/src/gff.h
@@ -243,7 +243,7 @@ class GffNameInfo {
      }
 };
 
-class GffNameList:public GList<GffNameInfo> {
+class GffNameList:public GPVec<GffNameInfo> {
   friend class GffNameInfo;
   friend class GffNames;
 protected:
@@ -256,7 +256,8 @@ protected:
      byName.shkAdd(f->name,f);
      }
 public:
- GffNameList(int init_capacity=6):GList<GffNameInfo>(init_capacity, false,true,true), byName(false) {
+ //GffNameList(int init_capacity=6):GList<GffNameInfo>(init_capacity, false,true,true), byName(false) {
+  GffNameList(int init_capacity=6):GPVec<GffNameInfo>(init_capacity, true), byName(false) {
     idlast=-1;
     setCapacity(init_capacity);
     }
@@ -428,6 +429,7 @@ class GffCDSeg:public GSeg {
   char phase;
   int exonidx;
 };
+
 //one GFF mRNA object -- e.g. a mRNA with its exons and/or CDS segments
 class GffObj:public GSeg {
   //utility segment-merging function for addExon() 
@@ -451,6 +453,7 @@ class GffObj:public GSeg {
    friend class GffExon;
 public:
   static GffNames* names; // dictionary storage that holds the various attribute names etc.
+  //TODO: this makes the parser thread unsafe, use conditional compiling for names access!
   int track_id; // index of track name in names->tracks
   int gseq_id; // index of genomic sequence name in names->gseqs
   int ftype_id; // index of this record's feature name in names->feats, or the special gff_fid_mRNA value
@@ -1010,7 +1013,7 @@ class GffReader {
   bool transcriptsOnly; //keep only transcripts w/ their exon/CDS features
   GHash<int> discarded_ids; //for transcriptsOnly mode, keep track
                             // of discarded parent IDs
-  GHash< GPVec<GffObj> > phash; //transcript_id+contig (Parent~Contig) => [gflst index, GffObj]
+  GHash< GPVec<GffObj> > phash; //transcript_id => GPVec<GffObj>(false)
   //GHash<int> tids; //just for transcript_id uniqueness
   char* gfoBuildId(const char* id, const char* ctg);
   //void gfoRemove(const char* id, const char* ctg);
@@ -1024,12 +1027,12 @@ class GffReader {
   void subfPoolAdd(GHash<CNonExon>& pex, GffObj* newgfo);
   GffObj* promoteFeature(CNonExon* subp, char*& subp_name, GHash<CNonExon>& pex,
                                   bool keepAttr, bool noExonAttr);
-  GList<GSeqStat> gseqstats; //list of all genomic sequences seen by this reader, accumulates stats
 #ifdef CUFFLINKS
      boost::crc_32_type  _crc_result;
 #endif
  public:
-  GffNames* names; //just a pointer to the global static Gff names repository in GffObj
+  GPVec<GSeqStat> gseqtable; //table with all genomic sequences, but only current GXF gseq ID indices will have non-NULL
+  GffNames* names; //just a pointer to the global static Gff names repository
   GfList gflst; //accumulate GffObjs being read
   GffObj* newGffRec(GffLine* gffline, bool keepAttr, bool noExonAttr,
                                GffObj* parent=NULL, GffExon* pexon=NULL, GPVec<GffObj>* glst=NULL);
@@ -1038,9 +1041,9 @@ class GffReader {
                                          bool keepAttr);
   GffObj* updateParent(GffObj* newgfh, GffObj* parent);
   bool addExonFeature(GffObj* prevgfo, GffLine* gffline, GHash<CNonExon>& pex, bool noExonAttr);
-  GPVec<GSeqStat> gseqStats; //only populated after finalize()
+  GPVec<GSeqStat> gseqStats; //populated after finalize() with only the ref seqs in this file
   GffReader(FILE* f=NULL, bool t_only=false, bool sortbyloc=false):discarded_ids(true),
-                       phash(true), gseqstats(true,true,true), gflst(sortbyloc), gseqStats(1, false) {
+                       phash(true), gseqtable(1,true), gflst(sortbyloc), gseqStats(1, false) {
       gff_warns=gff_show_warnings;
       names=NULL;
       gffline=NULL;
@@ -1059,8 +1062,8 @@ class GffReader {
       transcriptsOnly=t_only;
       gflst.sortedByLoc(sortbyloc);
       }
-  GffReader(char* fn, bool t_only=false, bool sort=false):discarded_ids(true), phash(true),
-            gseqstats(true,true,true), gflst(sort), gseqStats(1,false) {
+  GffReader(const char* fn, bool t_only=false, bool sort=false):discarded_ids(true), phash(true),
+            gseqtable(1,true), gflst(sort), gseqStats(1,false) {
       gff_warns=gff_show_warnings;
       names=NULL;
       fname=Gstrdup(fn);
@@ -1076,11 +1079,11 @@ class GffReader {
       delete gffline;
       gffline=NULL;
       fpos=0;
+      if (fh) fclose(fh);
       gflst.freeUnused();
       gflst.Clear();
       discarded_ids.Clear();
       phash.Clear();
-      gseqstats.Clear();
       GFREE(fname);
       GFREE(linebuf);
       }
diff --git a/src/intervaltree/__init__.py b/src/intervaltree/__init__.py
new file mode 100755
index 0000000..4b8690f
--- /dev/null
+++ b/src/intervaltree/__init__.py
@@ -0,0 +1,22 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Root package.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from .interval import Interval
+from .intervaltree import IntervalTree
diff --git a/src/intervaltree/interval.py b/src/intervaltree/interval.py
new file mode 100755
index 0000000..4c19cba
--- /dev/null
+++ b/src/intervaltree/interval.py
@@ -0,0 +1,302 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Interval class
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from numbers import Number
+from collections import namedtuple
+
+
+# noinspection PyBroadException
+class Interval(namedtuple('IntervalBase', ['begin', 'end', 'data'])):
+    __slots__ = ()  # Saves memory, avoiding the need to create __dict__ for each interval
+
+    def __new__(cls, begin, end, data=None):
+        return super(Interval, cls).__new__(cls, begin, end, data)
+    
+    def overlaps(self, begin, end=None):
+        """
+        Whether the interval overlaps the given point, range or Interval.
+        :param begin: beginning point of the range, or the point, or an Interval
+        :param end: end point of the range. Optional if not testing ranges.
+        :return: True or False
+        :rtype: bool
+        """
+        if end is not None:
+            return (
+                (begin <= self.begin < end) or
+                (begin < self.end <= end) or
+                (self.begin <= begin < self.end) or
+                (self.begin < end <= self.end)
+            )
+        try:
+            return self.overlaps(begin.begin, begin.end)
+        except:
+            return self.contains_point(begin)
+
+    def contains_point(self, p):
+        """
+        Whether the Interval contains p.
+        :param p: a point
+        :return: True or False
+        :rtype: bool
+        """
+        return self.begin <= p < self.end
+    
+    def range_matches(self, other):
+        """
+        Whether the begins equal and the ends equal. Compare __eq__().
+        :param other: Interval
+        :return: True or False
+        :rtype: bool
+        """
+        return (
+            self.begin == other.begin and 
+            self.end == other.end
+        )
+    
+    def contains_interval(self, other):
+        """
+        Whether other is contained in this Interval.
+        :param other: Interval
+        :return: True or False
+        :rtype: bool
+        """
+        return (
+            self.begin <= other.begin and
+            self.end >= other.end
+        )
+    
+    def distance_to(self, other):
+        """
+        Returns the size of the gap between intervals, or 0 
+        if they touch or overlap.
+        :param other: Interval or point
+        :return: distance
+        :rtype: Number
+        """
+        if self.overlaps(other):
+            return 0
+        try:
+            if self.begin < other.begin:
+                return other.begin - self.end
+            else:
+                return self.begin - other.end
+        except:
+            if self.end < other:
+                return other - self.end
+            else:
+                return self.begin - other
+
+    def is_null(self):
+        """
+        Whether this equals the null interval.
+        :return: True if end <= begin else False
+        :rtype: bool
+        """
+        return self.begin >= self.end
+
+    def length(self):
+        """
+        The distance covered by this Interval.
+        :return: length
+        :type: Number
+        """
+        if self.is_null():
+            return 0
+        return self.end - self.begin
+
+    def __hash__(self):
+        """
+        Depends on begin and end only.
+        :return: hash
+        :rtype: Number
+        """
+        return hash((self.begin, self.end))
+
+    def __eq__(self, other):
+        """
+        Whether the begins equal, the ends equal, and the data fields
+        equal. Compare range_matches().
+        :param other: Interval
+        :return: True or False
+        :rtype: bool
+        """
+        return (
+            self.begin == other.begin and
+            self.end == other.end and
+            self.data == other.data
+        )
+
+    def __cmp__(self, other):
+        """
+        Tells whether other sorts before, after or equal to this
+        Interval.
+
+        Sorting is by begins, then by ends, then by data fields.
+
+        If data fields are not both sortable types, data fields are
+        compared alphabetically by type name.
+        :param other: Interval
+        :return: -1, 0, 1
+        :rtype: int
+        """
+        s = self[0:2]
+        try:
+            o = other[0:2]
+        except:
+            o = (other,)
+        if s != o:
+            return -1 if s < o else 1
+        try:
+            if self.data == other.data:
+                return 0
+            return -1 if self.data < other.data else 1
+        except TypeError:
+            s = type(self.data).__name__
+            o = type(other.data).__name__
+            if s == o:
+                return 0
+            return -1 if s < o else 1
+
+    def __lt__(self, other):
+        """
+        Less than operator. Parrots __cmp__()
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        return self.__cmp__(other) < 0
+
+    def __gt__(self, other):
+        """
+        Greater than operator. Parrots __cmp__()
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        return self.__cmp__(other) > 0
+
+    def _raise_if_null(self, other):
+        """
+        :raises ValueError: if either self or other is a null Interval
+        """
+        if self.is_null():
+            raise ValueError("Cannot compare null Intervals!")
+        if hasattr(other, 'is_null') and other.is_null():
+            raise ValueError("Cannot compare null Intervals!")
+
+    def lt(self, other):
+        """
+        Strictly less than. Returns True if no part of this Interval
+        extends higher than or into other.
+        :raises ValueError: if either self or other is a null Interval
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        self._raise_if_null(other)
+        return self.end <= getattr(other, 'begin', other)
+
+    def le(self, other):
+        """
+        Less than or overlaps. Returns True if no part of this Interval
+        extends higher than other.
+        :raises ValueError: if either self or other is a null Interval
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        self._raise_if_null(other)
+        return self.end <= getattr(other, 'end', other)
+
+    def gt(self, other):
+        """
+        Strictly greater than. Returns True if no part of this Interval
+        extends lower than or into other.
+        :raises ValueError: if either self or other is a null Interval
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        self._raise_if_null(other)
+        if hasattr(other, 'end'):
+            return self.begin >= other.end
+        else:
+            return self.begin > other
+
+    def ge(self, other):
+        """
+        Greater than or overlaps. Returns True if no part of this Interval
+        extends lower than other.
+        :raises ValueError: if either self or other is a null Interval
+        :param other: Interval or point
+        :return: True or False
+        :rtype: bool
+        """
+        self._raise_if_null(other)
+        return self.begin >= getattr(other, 'begin', other)
+
+    def _get_fields(self):
+        """
+        Used by str, unicode, repr and __reduce__.
+
+        Returns only the fields necessary to reconstruct the Interval.
+        :return: reconstruction info
+        :rtype: tuple
+        """
+        if self.data is not None:
+            return self.begin, self.end, self.data
+        else:
+            return self.begin, self.end
+    
+    def __repr__(self):
+        """
+        Executable string representation of this Interval.
+        :return: string representation
+        :rtype: str
+        """
+        if isinstance(self.begin, Number):
+            s_begin = str(self.begin)
+            s_end = str(self.end)
+        else:
+            s_begin = repr(self.begin)
+            s_end = repr(self.end)
+        if self.data is None:
+            return "Interval({0}, {1})".format(s_begin, s_end)
+        else:
+            return "Interval({0}, {1}, {2})".format(s_begin, s_end, repr(self.data))
+
+    __str__ = __repr__
+
+    def copy(self):
+        """
+        Shallow copy.
+        :return: copy of self
+        :rtype: Interval
+        """
+        return Interval(self.begin, self.end, self.data)
+    
+    def __reduce__(self):
+        """
+        For pickle-ing.
+        :return: pickle data
+        :rtype: tuple
+        """
+        return Interval, self._get_fields()
diff --git a/src/intervaltree/intervaltree.py b/src/intervaltree/intervaltree.py
new file mode 100755
index 0000000..0366f5f
--- /dev/null
+++ b/src/intervaltree/intervaltree.py
@@ -0,0 +1,947 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Core logic.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications Copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from .interval import Interval
+from .node import Node
+from numbers import Number
+import collections
+from sortedcontainers import SortedDict
+from warnings import warn
+
+try:
+    xrange  # Python 2?
+except NameError:
+    xrange = range
+
+
+# noinspection PyBroadException
+class IntervalTree(collections.MutableSet):
+    """
+    A binary lookup tree of intervals.
+    The intervals contained in the tree are represented using ``Interval(a, b, data)`` objects.
+    Each such object represents a half-open interval ``[a, b)`` with optional data.
+    
+    Examples:
+    ---------
+    
+    Initialize a blank tree::
+    
+        >>> tree = IntervalTree()
+        >>> tree
+        IntervalTree()
+    
+    Initialize a tree from an iterable set of Intervals in O(n * log n)::
+    
+        >>> tree = IntervalTree([Interval(-10, 10), Interval(-20.0, -10.0)])
+        >>> tree
+        IntervalTree([Interval(-20.0, -10.0), Interval(-10, 10)])
+        >>> len(tree)
+        2
+    
+    Note that this is a set, i.e. repeated intervals are ignored. However,
+    Intervals with different data fields are regarded as different::
+    
+        >>> tree = IntervalTree([Interval(-10, 10), Interval(-10, 10), Interval(-10, 10, "x")])
+        >>> tree
+        IntervalTree([Interval(-10, 10), Interval(-10, 10, 'x')])
+        >>> len(tree)
+        2
+    
+    Insertions::
+        >>> tree = IntervalTree()
+        >>> tree[0:1] = "data"
+        >>> tree.add(Interval(10, 20))
+        >>> tree.addi(19.9, 20)
+        >>> tree
+        IntervalTree([Interval(0, 1, 'data'), Interval(10, 20), Interval(19.9, 20)])
+        >>> tree.update([Interval(19.9, 20.1), Interval(20.1, 30)])
+        >>> len(tree)
+        5
+
+        Inserting the same Interval twice does nothing::
+            >>> tree = IntervalTree()
+            >>> tree[-10:20] = "arbitrary data"
+            >>> tree[-10:20] = None  # Note that this is also an insertion
+            >>> tree
+            IntervalTree([Interval(-10, 20), Interval(-10, 20, 'arbitrary data')])
+            >>> tree[-10:20] = None  # This won't change anything
+            >>> tree[-10:20] = "arbitrary data" # Neither will this
+            >>> len(tree)
+            2
+
+    Deletions::
+        >>> tree = IntervalTree(Interval(b, e) for b, e in [(-10, 10), (-20, -10), (10, 20)])
+        >>> tree
+        IntervalTree([Interval(-20, -10), Interval(-10, 10), Interval(10, 20)])
+        >>> tree.remove(Interval(-10, 10))
+        >>> tree
+        IntervalTree([Interval(-20, -10), Interval(10, 20)])
+        >>> tree.remove(Interval(-10, 10))
+        Traceback (most recent call last):
+        ...
+        ValueError
+        >>> tree.discard(Interval(-10, 10))  # Same as remove, but no exception on failure
+        >>> tree
+        IntervalTree([Interval(-20, -10), Interval(10, 20)])
+        
+    Delete intervals, overlapping a given point::
+    
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> tree.remove_overlap(1.1)
+        >>> tree
+        IntervalTree([Interval(-1.1, 1.1)])
+        
+    Delete intervals, overlapping an interval::
+    
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> tree.remove_overlap(0, 0.5)
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        >>> tree.remove_overlap(1.7, 1.8)
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        >>> tree.remove_overlap(1.6, 1.6)  # Null interval does nothing
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        >>> tree.remove_overlap(1.6, 1.5)  # Ditto
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        
+    Delete intervals, enveloped in the range::
+    
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> tree.remove_envelop(-1.0, 1.5)
+        >>> tree
+        IntervalTree([Interval(-1.1, 1.1), Interval(0.5, 1.7)])
+        >>> tree.remove_envelop(-1.1, 1.5)
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        >>> tree.remove_envelop(0.5, 1.5)
+        >>> tree
+        IntervalTree([Interval(0.5, 1.7)])
+        >>> tree.remove_envelop(0.5, 1.7)
+        >>> tree
+        IntervalTree()
+        
+    Point/interval overlap queries::
+    
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> assert tree[-1.1]         == set([Interval(-1.1, 1.1)])
+        >>> assert tree.search(1.1)   == set([Interval(-0.5, 1.5), Interval(0.5, 1.7)])   # Same as tree[1.1]
+        >>> assert tree[-0.5:0.5]     == set([Interval(-0.5, 1.5), Interval(-1.1, 1.1)])  # Interval overlap query
+        >>> assert tree.search(1.5, 1.5) == set()                                         # Same as tree[1.5:1.5]
+        >>> assert tree.search(1.5) == set([Interval(0.5, 1.7)])                          # Same as tree[1.5]
+
+        >>> assert tree.search(1.7, 1.8) == set()
+
+    Envelop queries::
+    
+        >>> assert tree.search(-0.5, 0.5, strict=True) == set()
+        >>> assert tree.search(-0.4, 1.7, strict=True) == set([Interval(0.5, 1.7)])
+        
+    Membership queries::
+
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> Interval(-0.5, 0.5) in tree
+        False
+        >>> Interval(-1.1, 1.1) in tree
+        True
+        >>> Interval(-1.1, 1.1, "x") in tree
+        False
+        >>> tree.overlaps(-1.1)
+        True
+        >>> tree.overlaps(1.7)
+        False
+        >>> tree.overlaps(1.7, 1.8)
+        False
+        >>> tree.overlaps(-1.2, -1.1)
+        False
+        >>> tree.overlaps(-1.2, -1.0)
+        True
+    
+    Sizing::
+
+        >>> tree = IntervalTree([Interval(-1.1, 1.1), Interval(-0.5, 1.5), Interval(0.5, 1.7)])
+        >>> len(tree)
+        3
+        >>> tree.is_empty()
+        False
+        >>> IntervalTree().is_empty()
+        True
+        >>> not tree
+        False
+        >>> not IntervalTree()
+        True
+        >>> print(tree.begin())    # using print() because of floats in Python 2.6
+        -1.1
+        >>> print(tree.end())      # ditto
+        1.7
+        
+    Iteration::
+
+        >>> tree = IntervalTree([Interval(-11, 11), Interval(-5, 15), Interval(5, 17)])
+        >>> [iv.begin for iv in sorted(tree)]
+        [-11, -5, 5]
+        >>> assert tree.items() == set([Interval(-5, 15), Interval(-11, 11), Interval(5, 17)])
+
+    Copy- and typecasting, pickling::
+    
+        >>> tree0 = IntervalTree([Interval(0, 1, "x"), Interval(1, 2, ["x"])])
+        >>> tree1 = IntervalTree(tree0)  # Shares Interval objects
+        >>> tree2 = tree0.copy()         # Shallow copy (same as above, as Intervals are singletons)
+        >>> import pickle
+        >>> tree3 = pickle.loads(pickle.dumps(tree0))  # Deep copy
+        >>> list(tree0[1])[0].data[0] = "y"  # affects shallow copies, but not deep copies
+        >>> tree0
+        IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+        >>> tree1
+        IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+        >>> tree2
+        IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['y'])])
+        >>> tree3
+        IntervalTree([Interval(0, 1, 'x'), Interval(1, 2, ['x'])])
+        
+    Equality testing::
+    
+        >>> IntervalTree([Interval(0, 1)]) == IntervalTree([Interval(0, 1)])
+        True
+        >>> IntervalTree([Interval(0, 1)]) == IntervalTree([Interval(0, 1, "x")])
+        False
+    """
+    @classmethod
+    def from_tuples(cls, tups):
+        """
+        Create a new IntervalTree from an iterable of 2- or 3-tuples,
+         where the tuple lists begin, end, and optionally data.
+        """
+        ivs = [Interval(*t) for t in tups]
+        return IntervalTree(ivs)
+
+    def __init__(self, intervals=None):
+        """
+        Set up a tree. If intervals is provided, add all the intervals 
+        to the tree.
+        
+        Completes in O(n*log n) time.
+        """
+        intervals = set(intervals) if intervals is not None else set()
+        for iv in intervals:
+            if iv.is_null():
+                raise ValueError(
+                    "IntervalTree: Null Interval objects not allowed in IntervalTree:"
+                    " {0}".format(iv)
+                )
+        self.all_intervals = intervals
+        self.top_node = Node.from_intervals(self.all_intervals)
+        self.boundary_table = SortedDict()
+        for iv in self.all_intervals:
+            self._add_boundaries(iv)
+
+    def copy(self):
+        """
+        Construct a new IntervalTree using shallow copies of the 
+        intervals in the source tree.
+        
+        Completes in O(n*log n) time.
+        :rtype: IntervalTree
+        """
+        return IntervalTree(iv.copy() for iv in self)
+    
+    def _add_boundaries(self, interval):
+        """
+        Records the boundaries of the interval in the boundary table.
+        """
+        begin = interval.begin
+        end = interval.end
+        if begin in self.boundary_table: 
+            self.boundary_table[begin] += 1
+        else:
+            self.boundary_table[begin] = 1
+        
+        if end in self.boundary_table:
+            self.boundary_table[end] += 1
+        else:
+            self.boundary_table[end] = 1
+    
+    def _remove_boundaries(self, interval):
+        """
+        Removes the boundaries of the interval from the boundary table.
+        """
+        begin = interval.begin
+        end = interval.end
+        if self.boundary_table[begin] == 1:
+            del self.boundary_table[begin]
+        else:
+            self.boundary_table[begin] -= 1
+        
+        if self.boundary_table[end] == 1:
+            del self.boundary_table[end]
+        else:
+            self.boundary_table[end] -= 1
+    
+    def add(self, interval):
+        """
+        Adds an interval to the tree, if not already present.
+        
+        Completes in O(log n) time.
+        """
+        if interval in self: 
+            return
+
+        if interval.is_null():
+            raise ValueError(
+                "IntervalTree: Null Interval objects not allowed in IntervalTree:"
+                " {0}".format(interval)
+            )
+
+        if not self.top_node:
+            self.top_node = Node.from_interval(interval)
+        else:
+            self.top_node = self.top_node.add(interval)
+        self.all_intervals.add(interval)
+        self._add_boundaries(interval)
+    append = add
+    
+    def addi(self, begin, end, data=None):
+        """
+        Shortcut for add(Interval(begin, end, data)).
+        
+        Completes in O(log n) time.
+        """
+        return self.add(Interval(begin, end, data))
+    appendi = addi
+    
+    def update(self, intervals):
+        """
+        Given an iterable of intervals, add them to the tree.
+        
+        Completes in O(m*log(n+m), where m = number of intervals to 
+        add.
+        """
+        for iv in intervals:
+            self.add(iv)
+
+    def extend(self, intervals):
+        """
+        Deprecated: Replaced by update().
+        """
+        warn("IntervalTree.extend() has been deprecated. Consider using update() instead", DeprecationWarning)
+        self.update(intervals)
+
+    def remove(self, interval):
+        """
+        Removes an interval from the tree, if present. If not, raises 
+        ValueError.
+        
+        Completes in O(log n) time.
+        """
+        #self.verify()
+        if interval not in self:
+            #print(self.all_intervals)
+            raise ValueError
+        self.top_node = self.top_node.remove(interval)
+        self.all_intervals.remove(interval)
+        self._remove_boundaries(interval)
+        #self.verify()
+    
+    def removei(self, begin, end, data=None):
+        """
+        Shortcut for remove(Interval(begin, end, data)).
+        
+        Completes in O(log n) time.
+        """
+        return self.remove(Interval(begin, end, data))
+    
+    def discard(self, interval):
+        """
+        Removes an interval from the tree, if present. If not, does 
+        nothing.
+        
+        Completes in O(log n) time.
+        """
+        if interval not in self:
+            return
+        self.all_intervals.discard(interval)
+        self.top_node = self.top_node.discard(interval)
+        self._remove_boundaries(interval)
+    
+    def discardi(self, begin, end, data=None):
+        """
+        Shortcut for discard(Interval(begin, end, data)).
+        
+        Completes in O(log n) time.
+        """
+        return self.discard(Interval(begin, end, data))
+
+    def difference(self, other):
+        """
+        Returns a new tree, comprising all intervals in self but not
+        in other.
+        """
+        ivs = set()
+        for iv in self:
+            if iv not in other:
+                ivs.add(iv)
+        return IntervalTree(ivs)
+
+    def difference_update(self, other):
+        """
+        Removes all intervals in other from self.
+        """
+        for iv in other:
+            self.discard(iv)
+
+    def union(self, other):
+        """
+        Returns a new tree, comprising all intervals from self
+        and other.
+        """
+        return IntervalTree(set(self).union(other))
+
+    def intersection(self, other):
+        """
+        Returns a new tree of all intervals common to both self and
+        other.
+        """
+        ivs = set()
+        shorter, longer = sorted([self, other], key=len)
+        for iv in shorter:
+            if iv in longer:
+                ivs.add(iv)
+        return IntervalTree(ivs)
+
+    def intersection_update(self, other):
+        """
+        Removes intervals from self unless they also exist in other.
+        """
+        for iv in self:
+            if iv not in other:
+                self.remove(iv)
+
+    def symmetric_difference(self, other):
+        """
+        Return a tree with elements only in self or other but not
+        both.
+        """
+        if not isinstance(other, set): other = set(other)
+        me = set(self)
+        ivs = me - other + (other - me)
+        return IntervalTree(ivs)
+
+    def symmetric_difference_update(self, other):
+        """
+        Throws out all intervals except those only in self or other,
+        not both.
+        """
+        other = set(other)
+        for iv in self:
+            if iv in other:
+                self.remove(iv)
+                other.remove(iv)
+        self.update(other)
+
+    def remove_overlap(self, begin, end=None):
+        """
+        Removes all intervals overlapping the given point or range.
+        
+        Completes in O((r+m)*log n) time, where:
+          * n = size of the tree
+          * m = number of matches
+          * r = size of the search range (this is 1 for a point)
+        """
+        hitlist = self.search(begin, end)
+        for iv in hitlist: 
+            self.remove(iv)
+
+    def remove_envelop(self, begin, end):
+        """
+        Removes all intervals completely enveloped in the given range.
+        
+        Completes in O((r+m)*log n) time, where:
+          * n = size of the tree
+          * m = number of matches
+          * r = size of the search range (this is 1 for a point)
+        """
+        hitlist = self.search(begin, end, strict=True)
+        for iv in hitlist:
+            self.remove(iv)
+
+    def chop(self, begin, end, datafunc=None):
+        """
+        Like remove_envelop(), but trims back Intervals hanging into
+        the chopped area so that nothing overlaps.
+        """
+        insertions = set()
+        begin_hits = [iv for iv in self[begin] if iv.begin < begin]
+        end_hits = [iv for iv in self[end] if iv.end > end]
+
+        if datafunc:
+            for iv in begin_hits:
+                insertions.add(Interval(iv.begin, begin, datafunc(iv, True)))
+            for iv in end_hits:
+                insertions.add(Interval(end, iv.end, datafunc(iv, False)))
+        else:
+            for iv in begin_hits:
+                insertions.add(Interval(iv.begin, begin, iv.data))
+            for iv in end_hits:
+                insertions.add(Interval(end, iv.end, iv.data))
+
+        self.remove_envelop(begin, end)
+        self.difference_update(begin_hits)
+        self.difference_update(end_hits)
+        self.update(insertions)
+
+    def slice(self, point, datafunc=None):
+        """
+        Split Intervals that overlap point into two new Intervals. if
+        specified, uses datafunc(interval, islower=True/False) to
+        set the data field of the new Intervals.
+        :param point: where to slice
+        :param datafunc(interval, isupper): callable returning a new
+        value for the interval's data field
+        """
+        hitlist = set(iv for iv in self[point] if iv.begin < point)
+        insertions = set()
+        if datafunc:
+            for iv in hitlist:
+                insertions.add(Interval(iv.begin, point, datafunc(iv, True)))
+                insertions.add(Interval(point, iv.end, datafunc(iv, False)))
+        else:
+            for iv in hitlist:
+                insertions.add(Interval(iv.begin, point, iv.data))
+                insertions.add(Interval(point, iv.end, iv.data))
+        self.difference_update(hitlist)
+        self.update(insertions)
+
+    def clear(self):
+        """
+        Empties the tree.
+
+        Completes in O(1) tine.
+        """
+        self.__init__()
+
+    def find_nested(self):
+        """
+        Returns a dictionary mapping parent intervals to sets of 
+        intervals overlapped by and contained in the parent.
+        
+        Completes in O(n^2) time.
+        :rtype: dict of [Interval, set of Interval]
+        """
+        result = {}
+        
+        def add_if_nested():
+            if parent.contains_interval(child):
+                if parent not in result:
+                    result[parent] = set()
+                result[parent].add(child)
+                
+        long_ivs = sorted(self.all_intervals, key=Interval.length, reverse=True)
+        for i, parent in enumerate(long_ivs):
+            for child in long_ivs[i + 1:]:
+                add_if_nested()
+        return result
+    
+    def overlaps(self, begin, end=None):
+        """
+        Returns whether some interval in the tree overlaps the given
+        point or range.
+        
+        Completes in O(r*log n) time, where r is the size of the
+        search range.
+        :rtype: bool
+        """
+        if end is not None:
+            return self.overlaps_range(begin, end)
+        elif isinstance(begin, Number):
+            return self.overlaps_point(begin)
+        else:
+            return self.overlaps_range(begin.begin, begin.end)
+    
+    def overlaps_point(self, p):
+        """
+        Returns whether some interval in the tree overlaps p.
+        
+        Completes in O(log n) time.
+        :rtype: bool
+        """
+        if self.is_empty():
+            return False
+        return bool(self.top_node.contains_point(p))
+    
+    def overlaps_range(self, begin, end):
+        """
+        Returns whether some interval in the tree overlaps the given
+        range.
+        
+        Completes in O(r*log n) time, where r is the range length and n
+        is the table size.
+        :rtype: bool
+        """
+        if self.is_empty():
+            return False
+        elif self.overlaps_point(begin):
+            return True
+        return any(
+            self.overlaps_point(bound) 
+            for bound in self.boundary_table 
+            if begin <= bound < end
+        )
+    
+    def split_overlaps(self):
+        """
+        Finds all intervals with overlapping ranges and splits them
+        along the range boundaries.
+        
+        Completes in worst-case O(n^2*log n) time (many interval 
+        boundaries are inside many intervals), best-case O(n*log n)
+        time (small number of overlaps << n per interval).
+        """
+        if not self:
+            return
+        if len(self.boundary_table) == 2:
+            return
+
+        bounds = sorted(self.boundary_table)  # get bound locations
+
+        new_ivs = set()
+        for lbound, ubound in zip(bounds[:-1], bounds[1:]):
+            for iv in self[lbound]:
+                new_ivs.add(Interval(lbound, ubound, iv.data))
+
+        self.__init__(new_ivs)
+
+    def items(self):
+        """
+        Constructs and returns a set of all intervals in the tree. 
+        
+        Completes in O(n) time.
+        :rtype: set of Interval
+        """
+        return set(self.all_intervals)
+    
+    def is_empty(self):
+        """
+        Returns whether the tree is empty.
+        
+        Completes in O(1) time.
+        :rtype: bool
+        """
+        return 0 == len(self)
+
+    def search(self, begin, end=None, strict=False):
+        """
+        Returns a set of all intervals overlapping the given range. Or,
+        if strict is True, returns the set of all intervals fully
+        contained in the range [begin, end].
+        
+        Completes in O(m + k*log n) time, where:
+          * n = size of the tree
+          * m = number of matches
+          * k = size of the search range (this is 1 for a point)
+        :rtype: set of Interval
+        """
+        root = self.top_node
+        if not root:
+            return set()
+        if end is None:
+            try:
+                iv = begin
+                return self.search(iv.begin, iv.end, strict=strict)
+            except:
+                return root.search_point(begin, set())
+        elif begin >= end:
+            return set()
+        else:
+            result = root.search_point(begin, set())
+
+            boundary_table = self.boundary_table
+            bound_begin = boundary_table.bisect_left(begin)
+            bound_end = boundary_table.bisect_left(end)  # exclude final end bound
+            result.update(root.search_overlap(
+                # slice notation is slightly slower
+                boundary_table.iloc[index] for index in xrange(bound_begin, bound_end)
+            ))
+
+            # TODO: improve strict search to use node info instead of less-efficient filtering
+            if strict:
+                result = set(
+                    iv for iv in result
+                    if iv.begin >= begin and iv.end <= end
+                )
+            return result
+    
+    def begin(self):
+        """
+        Returns the lower bound of the first interval in the tree.
+        
+        Completes in O(n) time.
+        :rtype: Number
+        """
+        if not self.boundary_table:
+            return 0
+        return min(self.boundary_table)
+    
+    def end(self):
+        """
+        Returns the upper bound of the last interval in the tree.
+        
+        Completes in O(n) time.
+        :rtype: Number
+        """
+        if not self.boundary_table:
+            return 0
+        return max(self.boundary_table)
+    
+    def print_structure(self, tostring=False):
+        """
+        ## FOR DEBUGGING ONLY ##
+        Pretty-prints the structure of the tree. 
+        If tostring is true, prints nothing and returns a string.
+        :rtype: None or str
+        """
+        if self.top_node:
+            return self.top_node.print_structure(tostring=tostring)
+        else:
+            result = "<empty IntervalTree>"
+            if not tostring:
+                print(result)
+            else:
+                return result
+        
+    def verify(self):
+        """
+        ## FOR DEBUGGING ONLY ##
+        Checks the table to ensure that the invariants are held.
+        """
+        if self.all_intervals:
+            ## top_node.all_children() == self.all_intervals
+            try:
+                assert self.top_node.all_children() == self.all_intervals
+            except AssertionError as e:
+                print(
+                    'Error: the tree and the membership set are out of sync!'
+                )
+                tivs = set(self.top_node.all_children())
+                print('top_node.all_children() - all_intervals:')
+                pprint(tivs - self.all_intervals)
+                print('all_intervals - top_node.all_children():')
+                pprint(self.all_intervals - tivs)
+                raise e
+
+            ## All members are Intervals
+            for iv in self:
+                assert isinstance(iv, Interval), (
+                    "Error: Only Interval objects allowed in IntervalTree:"
+                    " {0}".format(iv)
+                )
+
+            ## No null intervals
+            for iv in self:
+                assert not iv.is_null(), (
+                    "Error: Null Interval objects not allowed in IntervalTree:"
+                    " {0}".format(iv)
+                )
+
+            ## Reconstruct boundary_table
+            bound_check = {}
+            for iv in self:
+                if iv.begin in bound_check:
+                    bound_check[iv.begin] += 1
+                else:
+                    bound_check[iv.begin] = 1
+                if iv.end in bound_check:
+                    bound_check[iv.end] += 1
+                else:
+                    bound_check[iv.end] = 1
+
+            ## Reconstructed boundary table (bound_check) ==? boundary_table
+            assert set(self.boundary_table.keys()) == set(bound_check.keys()),\
+                'Error: boundary_table is out of sync with ' \
+                'the intervals in the tree!'
+
+            # For efficiency reasons this should be iteritems in Py2, but we
+            # don't care much for efficiency in debug methods anyway.
+            for key, val in self.boundary_table.items():
+                assert bound_check[key] == val, \
+                    'Error: boundary_table[{0}] should be {1},' \
+                    ' but is {2}!'.format(
+                        key, bound_check[key], val)
+
+            ## Internal tree structure
+            self.top_node.verify(set())
+        else:
+            ## Verify empty tree
+            assert not self.boundary_table, \
+                "Error: boundary table should be empty!"
+            assert self.top_node is None, \
+                "Error: top_node isn't None!"
+
+    def score(self, full_report=False):
+        """
+        Returns a number between 0 and 1, indicating how suboptimal the tree
+        is. The lower, the better. Roughly, this number represents the
+        fraction of flawed Intervals in the tree.
+        :rtype: float
+        """
+        if len(self) <= 2:
+            return 0.0
+
+        n = len(self)
+        m = self.top_node.count_nodes()
+
+        def s_center_score():
+            """
+            Returns a normalized score, indicating roughly how many times
+            intervals share s_center with other intervals. Output is full-scale
+            from 0 to 1.
+            :rtype: float
+            """
+            raw = n - m
+            maximum = n - 1
+            return raw / float(maximum)
+
+        report = {
+            "depth": self.top_node.depth_score(n, m),
+            "s_center": s_center_score(),
+        }
+        cumulative = max(report.values())
+        report["_cumulative"] = cumulative
+        if full_report:
+            return report
+        return cumulative
+
+    def __getitem__(self, index):
+        """
+        Returns a set of all intervals overlapping the given index or 
+        slice.
+        
+        Completes in O(k * log(n) + m) time, where:
+          * n = size of the tree
+          * m = number of matches
+          * k = size of the search range (this is 1 for a point)
+        :rtype: set of Interval
+        """
+        try:
+            start, stop = index.start, index.stop
+            if start is None:
+                start = self.begin()
+                if stop is None:
+                    return set(self)
+            if stop is None:
+                stop = self.end()
+            return self.search(start, stop)
+        except AttributeError:
+            return self.search(index)
+    
+    def __setitem__(self, index, value):
+        """
+        Adds a new interval to the tree. A shortcut for
+        add(Interval(index.start, index.stop, value)).
+        
+        If an identical Interval object with equal range and data 
+        already exists, does nothing.
+        
+        Completes in O(log n) time.
+        """
+        self.addi(index.start, index.stop, value)
+
+    def __delitem__(self, point):
+        """
+        Delete all items overlapping point.
+        """
+        self.remove_overlap(point)
+
+    def __contains__(self, item):
+        """
+        Returns whether item exists as an Interval in the tree.
+        This method only returns True for exact matches; for
+        overlaps, see the overlaps() method.
+        
+        Completes in O(1) time.
+        :rtype: bool
+        """
+        # Removed point-checking code; it might trick the user into
+        # thinking that this is O(1), which point-checking isn't.
+        #if isinstance(item, Interval):
+        return item in self.all_intervals
+        #else:
+        #    return self.contains_point(item)
+    
+    def containsi(self, begin, end, data=None):
+        """
+        Shortcut for (Interval(begin, end, data) in tree).
+        
+        Completes in O(1) time.
+        :rtype: bool
+        """
+        return Interval(begin, end, data) in self
+    
+    def __iter__(self):
+        """
+        Returns an iterator over all the intervals in the tree.
+        
+        Completes in O(1) time.
+        :rtype: collections.Iterable[Interval]
+        """
+        return self.all_intervals.__iter__()
+    iter = __iter__
+    
+    def __len__(self):
+        """
+        Returns how many intervals are in the tree.
+        
+        Completes in O(1) time.
+        :rtype: int
+        """
+        return len(self.all_intervals)
+    
+    def __eq__(self, other):
+        """
+        Whether two IntervalTrees are equal.
+        
+        Completes in O(n) time if sizes are equal; O(1) time otherwise.
+        :rtype: bool
+        """
+        return (
+            isinstance(other, IntervalTree) and 
+            self.all_intervals == other.all_intervals
+        )
+    
+    def __repr__(self):
+        """
+        :rtype: str
+        """
+        ivs = sorted(self)
+        if not ivs:
+            return "IntervalTree()"
+        else:
+            return "IntervalTree({0})".format(ivs)
+
+    __str__ = __repr__
+
+    def __reduce__(self):
+        """
+        For pickle-ing.
+        :rtype: tuple
+        """
+        return IntervalTree, (sorted(self.all_intervals),)
diff --git a/src/intervaltree/node.py b/src/intervaltree/node.py
new file mode 100755
index 0000000..e9d9170
--- /dev/null
+++ b/src/intervaltree/node.py
@@ -0,0 +1,593 @@
+"""
+intervaltree: A mutable, self-balancing interval tree for Python 2 and 3.
+Queries may be by point, by range overlap, or by range envelopment.
+
+Core logic: internal tree nodes.
+
+Copyright 2013-2015 Chaim-Leib Halbert
+Modifications Copyright 2014 Konstantin Tretyakov
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+from operator import attrgetter
+from math import floor, log
+
+
+def l2(num):
+    """
+    log base 2
+    :rtype real
+    """
+    return log(num, 2)
+
+
+class Node(object):
+    def __init__(self,
+                 x_center=None,
+                 s_center=set(),
+                 left_node=None,
+                 right_node=None):
+        self.x_center = x_center
+        self.s_center = set(s_center)
+        self.left_node = left_node
+        self.right_node = right_node
+        self.depth = 0    # will be set when rotated
+        self.balance = 0  # ditto
+        self.rotate()
+
+    @classmethod
+    def from_interval(cls, interval):
+        """
+        :rtype : Node
+        """
+        center = interval.begin
+        return Node(center, [interval])
+
+    @classmethod
+    def from_intervals(cls, intervals):
+        """
+        :rtype : Node
+        """
+        if not intervals:
+            return None
+        node = Node()
+        node = node.init_from_sorted(sorted(intervals))
+        return node
+
+    def init_from_sorted(self, intervals):
+        if not intervals:
+            return None
+        center_iv = intervals[len(intervals) // 2]
+        self.x_center = center_iv.begin
+        self.s_center = set()
+        s_left = []
+        s_right = []
+        for k in intervals:
+            if k.end <= self.x_center:
+                s_left.append(k)
+            elif k.begin > self.x_center:
+                s_right.append(k)
+            else:
+                self.s_center.add(k)
+        self.left_node = Node.from_intervals(s_left)
+        self.right_node = Node.from_intervals(s_right)
+        return self.rotate()
+
+    def center_hit(self, interval):
+        """Returns whether interval overlaps self.x_center."""
+        return interval.contains_point(self.x_center)
+
+    def hit_branch(self, interval):
+        """
+        Assuming not center_hit(interval), return which branch
+        (left=0, right=1) interval is in.
+        """
+        return interval.begin > self.x_center
+
+    def refresh_balance(self):
+        """
+        Recalculate self.balance and self.depth based on child node values.
+        """
+        left_depth = self.left_node.depth if self.left_node else 0
+        right_depth = self.right_node.depth if self.right_node else 0
+        self.depth = 1 + max(left_depth, right_depth)
+        self.balance = right_depth - left_depth
+
+    def compute_depth(self):
+        """
+        Recursively computes true depth of the subtree. Should only
+        be needed for debugging. Unless something is wrong, the
+        depth field should reflect the correct depth of the subtree.
+        """
+        left_depth = self.left_node.compute_depth() if self.left_node else 0
+        right_depth = self.right_node.compute_depth() if self.right_node else 0
+        return 1 + max(left_depth, right_depth)
+
+    def rotate(self):
+        """
+        Does rotating, if necessary, to balance this node, and
+        returns the new top node.
+        """
+        self.refresh_balance()
+        if abs(self.balance) < 2:
+            return self
+        # balance > 0  is the heavy side
+        my_heavy = self.balance > 0
+        child_heavy = self[my_heavy].balance > 0
+        if my_heavy == child_heavy or self[my_heavy].balance == 0:
+            ## Heavy sides same
+            #    self     save
+            #  save   -> 1   self
+            # 1
+            #
+            ## Heavy side balanced
+            #    self     save         save
+            #  save   -> 1   self  -> 1  self.rot()
+            #  1  2         2
+            return self.srotate()
+        else:
+            return self.drotate()
+
+    def srotate(self):
+        """Single rotation. Assumes that balance is +-2."""
+        #     self        save         save
+        #   save 3  ->   1   self  -> 1   self.rot()
+        #  1   2            2   3
+        #
+        #  self            save                save
+        # 3   save  ->  self  1    -> self.rot()   1
+        #    2   1     3   2
+
+        #assert(self.balance != 0)
+        heavy = self.balance > 0
+        light = not heavy
+        save = self[heavy]
+        #print("srotate: bal={},{}".format(self.balance, save.balance))
+        #self.print_structure()
+        self[heavy] = save[light]   # 2
+        #assert(save[light])
+        save[light] = self.rotate()  # Needed to ensure the 2 and 3 are balanced under new subnode
+
+        # Some intervals may overlap both self.x_center and save.x_center
+        # Promote those to the new tip of the tree
+        promotees = [iv for iv in save[light].s_center if save.center_hit(iv)]
+        if promotees:
+            for iv in promotees:
+                save[light] = save[light].remove(iv)  # may trigger pruning
+            # TODO: Use Node.add() here, to simplify future balancing improvements.
+            # For now, this is the same as augmenting save.s_center, but that may
+            # change.
+            save.s_center.update(promotees)
+        save.refresh_balance()
+        return save
+
+    def drotate(self):
+        # First rotation
+        my_heavy = self.balance > 0
+        self[my_heavy] = self[my_heavy].srotate()
+        self.refresh_balance()
+
+        # Second rotation
+        result = self.srotate()
+
+        return result
+
+    def add(self, interval):
+        """
+        Returns self after adding the interval and balancing.
+        """
+        if self.center_hit(interval):
+            self.s_center.add(interval)
+            return self
+        else:
+            direction = self.hit_branch(interval)
+            if not self[direction]:
+                self[direction] = Node.from_interval(interval)
+                self.refresh_balance()
+                return self
+            else:
+                self[direction] = self[direction].add(interval)
+                return self.rotate()
+
+    def remove(self, interval):
+        """
+        Returns self after removing the interval and balancing.
+
+        If interval is not present, raise ValueError.
+        """
+        # since this is a list, called methods can set this to [1],
+        # making it true
+        done = []
+        return self.remove_interval_helper(interval, done, should_raise_error=True)
+
+    def discard(self, interval):
+        """
+        Returns self after removing interval and balancing.
+
+        If interval is not present, do nothing.
+        """
+        done = []
+        return self.remove_interval_helper(interval, done, should_raise_error=False)
+
+    def remove_interval_helper(self, interval, done, should_raise_error):
+        """
+        Returns self after removing interval and balancing.
+        If interval doesn't exist, raise ValueError.
+
+        This method may set done to [1] to tell all callers that
+        rebalancing has completed.
+
+        See Eternally Confuzzled's jsw_remove_r function (lines 1-32)
+        in his AVL tree article for reference.
+        """
+        #trace = interval.begin == 347 and interval.end == 353
+        #if trace: print('\nRemoving from {} interval {}'.format(
+        #   self.x_center, interval))
+        if self.center_hit(interval):
+            #if trace: print('Hit at {}'.format(self.x_center))
+            if not should_raise_error and interval not in self.s_center:
+                done.append(1)
+                #if trace: print('Doing nothing.')
+                return self
+            try:
+                # raises error if interval not present - this is
+                # desired.
+                self.s_center.remove(interval)
+            except:
+                self.print_structure()
+                raise KeyError(interval)
+            if self.s_center:     # keep this node
+                done.append(1)    # no rebalancing necessary
+                #if trace: print('Removed, no rebalancing.')
+                return self
+
+            # If we reach here, no intervals are left in self.s_center.
+            # So, prune self.
+            return self.prune()
+        else:  # interval not in s_center
+            direction = self.hit_branch(interval)
+
+            if not self[direction]:
+                if should_raise_error:
+                    raise ValueError
+                done.append(1)
+                return self
+
+            #if trace:
+            #   print('Descending to {} branch'.format(
+            #       ['left', 'right'][direction]
+            #       ))
+            self[direction] = self[direction].remove_interval_helper(interval, done, should_raise_error)
+
+            # Clean up
+            if not done:
+                #if trace:
+                #    print('Rotating {}'.format(self.x_center))
+                #    self.print_structure()
+                return self.rotate()
+            return self
+
+    def search_overlap(self, point_list):
+        """
+        Returns all intervals that overlap the point_list.
+        """
+        result = set()
+        for j in point_list:
+            self.search_point(j, result)
+        return result
+
+    def search_point(self, point, result):
+        """
+        Returns all intervals that contain point.
+        """
+        for k in self.s_center:
+            if k.begin <= point < k.end:
+                result.add(k)
+        if point < self.x_center and self[0]:
+            return self[0].search_point(point, result)
+        elif point > self.x_center and self[1]:
+            return self[1].search_point(point, result)
+        return result
+
+    def prune(self):
+        """
+        On a subtree where the root node's s_center is empty,
+        return a new subtree with no empty s_centers.
+        """
+        if not self[0] or not self[1]:    # if I have an empty branch
+            direction = not self[0]       # graft the other branch here
+            #if trace:
+            #    print('Grafting {} branch'.format(
+            #       'right' if direction else 'left'))
+
+            result = self[direction]
+            #if result: result.verify()
+            return result
+        else:
+            # Replace the root node with the greatest predecessor.
+            heir, self[0] = self[0].pop_greatest_child()
+            #if trace:
+            #    print('Replacing {} with {}.'.format(
+            #        self.x_center, heir.x_center
+            #        ))
+            #    print('Removed greatest predecessor:')
+            #    self.print_structure()
+
+            #if self[0]: self[0].verify()
+            #if self[1]: self[1].verify()
+
+            # Set up the heir as the new root node
+            (heir[0], heir[1]) = (self[0], self[1])
+            #if trace: print('Setting up the heir:')
+            #if trace: heir.print_structure()
+
+            # popping the predecessor may have unbalanced this node;
+            # fix it
+            heir.refresh_balance()
+            heir = heir.rotate()
+            #heir.verify()
+            #if trace: print('Rotated the heir:')
+            #if trace: heir.print_structure()
+            return heir
+
+    def pop_greatest_child(self):
+        """
+        Used when pruning a node with both a left and a right branch.
+        Returns (greatest_child, node), where:
+          * greatest_child is a new node to replace the removed node.
+          * node is the subtree after:
+              - removing the greatest child
+              - balancing
+              - moving overlapping nodes into greatest_child
+
+        Assumes that self.s_center is not empty.
+
+        See Eternally Confuzzled's jsw_remove_r function (lines 34-54)
+        in his AVL tree article for reference.
+        """
+        #print('Popping from {}'.format(self.x_center))
+        if not self.right_node:         # This node is the greatest child.
+            # To reduce the chances of an overlap with a parent, return
+            # a child node containing the smallest possible number of
+            # intervals, as close as possible to the maximum bound.
+            ivs = sorted(self.s_center, key=attrgetter('end', 'begin'))
+            max_iv = ivs.pop()
+            new_x_center = self.x_center
+            while ivs:
+                next_max_iv = ivs.pop()
+                if next_max_iv.end == max_iv.end: continue
+                new_x_center = max(new_x_center, next_max_iv.end)
+            def get_new_s_center():
+                for iv in self.s_center:
+                    if iv.contains_point(new_x_center): yield iv
+
+            # Create a new node with the largest x_center possible.
+            child = Node.from_intervals(get_new_s_center())
+            #     [iv for iv in self.s_center if iv.contains_point(child_x_center)]
+            # )
+            child.x_center = new_x_center
+            self.s_center -= child.s_center
+
+            #print('Pop hit! Returning child   = {}'.format(
+            #    child.print_structure(tostring=True)
+            #    ))
+            #assert not child[0]
+            #assert not child[1]
+
+            if self.s_center:
+                #print('     and returning newnode = {}'.format( self ))
+                #self.verify()
+                return child, self
+            else:
+                #print('     and returning newnode = {}'.format( self[0] ))
+                #if self[0]: self[0].verify()
+                return child, self[0]  # Rotate left child up
+
+        else:
+            #print('Pop descent to {}'.format(self[1].x_center))
+            (greatest_child, self[1]) = self[1].pop_greatest_child()
+            self.refresh_balance()
+            new_self = self.rotate()
+
+            # Move any overlaps into greatest_child
+            for iv in set(new_self.s_center):
+                if iv.contains_point(greatest_child.x_center):
+                    new_self.s_center.remove(iv)
+                    greatest_child.add(iv)
+
+            #print('Pop Returning child   = {}'.format(
+            #    greatest_child.print_structure(tostring=True)
+            #    ))
+            if new_self.s_center:
+                #print('and returning newnode = {}'.format(
+                #    new_self.print_structure(tostring=True)
+                #    ))
+                #new_self.verify()
+                return greatest_child, new_self
+            else:
+                new_self = new_self.prune()
+                #print('and returning prune = {}'.format(
+                #    new_self.print_structure(tostring=True)
+                #    ))
+                #if new_self: new_self.verify()
+                return greatest_child, new_self
+
+    def contains_point(self, p):
+        """
+        Returns whether this node or a child overlaps p.
+        """
+        for iv in self.s_center:
+            if iv.contains_point(p):
+                return True
+        branch = self[p > self.x_center]
+        return branch and branch.contains_point(p)
+
+    def all_children(self):
+        return self.all_children_helper(set())
+
+    def all_children_helper(self, result):
+        result.update(self.s_center)
+        if self[0]:
+            self[0].all_children_helper(result)
+        if self[1]:
+            self[1].all_children_helper(result)
+        return result
+
+    def verify(self, parents=set()):
+        """
+        ## DEBUG ONLY ##
+        Recursively ensures that the invariants of an interval subtree
+        hold.
+        """
+        assert(isinstance(self.s_center, set))
+
+        bal = self.balance
+        assert abs(bal) < 2, \
+            "Error: Rotation should have happened, but didn't! \n{}".format(
+                self.print_structure(tostring=True)
+            )
+        self.refresh_balance()
+        assert bal == self.balance, \
+            "Error: self.balance not set correctly! \n{}".format(
+                self.print_structure(tostring=True)
+            )
+
+        assert self.s_center, \
+            "Error: s_center is empty! \n{}".format(
+                self.print_structure(tostring=True)
+            )
+        for iv in self.s_center:
+            assert hasattr(iv, 'begin')
+            assert hasattr(iv, 'end')
+            assert iv.begin < iv.end
+            assert iv.overlaps(self.x_center)
+            for parent in sorted(parents):
+                assert not iv.contains_point(parent), \
+                    "Error: Overlaps ancestor ({})! \n{}\n\n{}".format(
+                        parent, iv, self.print_structure(tostring=True)
+                    )
+        if self[0]:
+            assert self[0].x_center < self.x_center, \
+                "Error: Out-of-order left child! {}".format(self.x_center)
+            self[0].verify(parents.union([self.x_center]))
+        if self[1]:
+            assert self[1].x_center > self.x_center, \
+                "Error: Out-of-order right child! {}".format(self.x_center)
+            self[1].verify(parents.union([self.x_center]))
+
+    def __getitem__(self, index):
+        """
+        Returns the left child if input is equivalent to False, or
+        the right side otherwise.
+        """
+        if index:
+            return self.right_node
+        else:
+            return self.left_node
+
+    def __setitem__(self, key, value):
+        """Sets the left (0) or right (1) child."""
+        if key:
+            self.right_node = value
+        else:
+            self.left_node = value
+
+    def __str__(self):
+        """
+        Shows info about this node.
+
+        Since Nodes are internal data structures not revealed to the
+        user, I'm not bothering to make this copy-paste-executable as a
+        constructor.
+        """
+        return "Node<{0}, depth={1}, balance={2}>".format(
+            self.x_center,
+            self.depth,
+            self.balance
+        )
+        #fieldcount = 'c_count,has_l,has_r = <{}, {}, {}>'.format(
+        #    len(self.s_center),
+        #    bool(self.left_node),
+        #    bool(self.right_node)
+        #)
+        #fields = [self.x_center, self.balance, fieldcount]
+        #return "Node({}, b={}, {})".format(*fields)
+
+    def count_nodes(self):
+        """
+        Count the number of Nodes in this subtree.
+        :rtype: int
+        """
+        count = 1
+        if self.left_node:
+            count += self.left_node.count_nodes()
+        if self.right_node:
+            count += self.right_node.count_nodes()
+        return count
+
+    def depth_score(self, n, m):
+        """
+        Calculates flaws in balancing the tree.
+        :param n: size of tree
+        :param m: number of Nodes in tree
+        :rtype: real
+        """
+        if n == 0:
+            return 0.0
+
+        # dopt is the optimal maximum depth of the tree
+        dopt = 1 + int(floor(l2(m)))
+        f = 1 / float(1 + n - dopt)
+        return f * self.depth_score_helper(1, dopt)
+
+    def depth_score_helper(self, d, dopt):
+        """
+        Gets a weighted count of the number of Intervals deeper than dopt.
+        :param d: current depth, starting from 0
+        :param dopt: optimal maximum depth of a leaf Node
+        :rtype: real
+        """
+        # di is how may levels deeper than optimal d is
+        di = d - dopt
+        if di > 0:
+            count = di * len(self.s_center)
+        else:
+            count = 0
+        if self.right_node:
+            count += self.right_node.depth_score_helper(d + 1, dopt)
+        if self.left_node:
+            count += self.left_node.depth_score_helper(d + 1, dopt)
+        return count
+
+    def print_structure(self, indent=0, tostring=False):
+        """
+        For debugging.
+        """
+        nl = '\n'
+        sp = indent * '    '
+
+        rlist = [str(self) + nl]
+        if self.s_center:
+            for iv in sorted(self.s_center):
+                rlist.append(sp + ' ' + repr(iv) + nl)
+        if self.left_node:
+            rlist.append(sp + '<:  ')  # no CR
+            rlist.append(self.left_node.print_structure(indent + 1, True))
+        if self.right_node:
+            rlist.append(sp + '>:  ')  # no CR
+            rlist.append(self.right_node.print_structure(indent + 1, True))
+        result = ''.join(rlist)
+        if tostring:
+            return result
+        else:
+            print(result)
diff --git a/src/long_spanning_reads.cpp b/src/long_spanning_reads.cpp
index 598e4a9..6af43bc 100644
--- a/src/long_spanning_reads.cpp
+++ b/src/long_spanning_reads.cpp
@@ -13,6 +13,8 @@
 
 #include <cassert>
 #include <cstdio>
+#include <boost/thread.hpp>
+
 #include <vector>
 #include <string>
 #include <map>
@@ -31,8 +33,6 @@
 #include <seqan/modifier.h>
 #include <getopt.h>
 
-#include <boost/thread.hpp>
-
 #include "common.h"
 #include "utils.h"
 #include "bwt_map.h"
diff --git a/src/map2gtf.cpp b/src/map2gtf.cpp
index 8e23a51..cdf937b 100644
--- a/src/map2gtf.cpp
+++ b/src/map2gtf.cpp
@@ -69,10 +69,6 @@ GffTranscript::GffTranscript(const std::string& tline): exons(1),
 Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
     gtf_fname_(gtf_fname), in_fname_(in_fname), out_sam_header_(NULL), refSeqTable_(true)
 {
-	/*
-  gtf_fhandle_ = fopen(gtf_fname_.c_str(), "r");
-  if (gtf_fhandle_ == NULL)
-  */
 	tlststream.open(gtf_fname_.c_str(), std::ios::in);
 	if (!tlststream.good())
     {
@@ -95,8 +91,6 @@ Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
     }
   in_sam_header_ = in_fhandle_->header;
   std::cout << "Reading the transcript data: " << gtf_fname_ << std::endl;
-  //gtfReader_.init(gtf_fhandle_, true); //only recognizable transcripts will be loaded
-  //gtfReader_.readAll();
 
   std::string tline;
   while (std::getline(tlststream, tline)) {
@@ -114,13 +108,6 @@ Map2GTF::Map2GTF(const std::string& gtf_fname, const std::string& in_fname) :
 Map2GTF::~Map2GTF()
 {
   std::cout << "map2gtf has completed. Cleaning up." << std::endl;
-  /*
-  if (gtf_fhandle_ != NULL && fclose(gtf_fhandle_))
-    {
-      std::cerr << "Warning: Error closing annotation: " << gtf_fname_
-                << std::endl;
-    }
-  */
   if (in_fhandle_ != NULL)
     {
       samclose(in_fhandle_);
diff --git a/src/reads.h b/src/reads.h
index 8e14310..5360225 100644
--- a/src/reads.h
+++ b/src/reads.h
@@ -16,15 +16,9 @@
 #include <boost/shared_ptr.hpp>
 #include <seqan/sequence.h>
 #include "common.h"
-//#include "QReadData.h"
-
 
 using std::string;
 
-
-
-
-
 void reverse_complement(string& seq);
 string str_convert_color_to_bp(const string& color);
 seqan::String<char> convert_color_to_bp(char base, const seqan::String<char>& color);
@@ -251,9 +245,7 @@ struct GetReadProc {
 			if (rdata->matenum==1) bamrec.set_flag(BAM_FREAD1);
 			else bamrec.set_flag(BAM_FREAD2);
 		}
-		//if (found && um_code && !rdata->trashCode) {
-		//rdata->trashCode=um_code;
-		//}
+
 		if (rdata->trashCode) {
 			//multi-mapped reads did not really QC-fail
 			//should also not be written to unmapped.bam
diff --git a/src/segment_juncs.cpp b/src/segment_juncs.cpp
index 2405c05..eaf5db7 100644
--- a/src/segment_juncs.cpp
+++ b/src/segment_juncs.cpp
@@ -13,6 +13,7 @@
 
 #include <cassert>
 #include <cstdio>
+#include <boost/thread.hpp>
 #include <vector>
 #include <string>
 #include <map>
@@ -28,8 +29,6 @@
 #include <seqan/file.h>
 #include <getopt.h>
 
-#include <boost/thread.hpp>
-
 #include "common.h"
 #include "utils.h"
 #include "bwt_map.h"
@@ -67,8 +66,7 @@ void get_seqs(istream& ref_stream,
 	      bool keep_seqs = true)
 {    
   while(ref_stream.good() &&
-	!ref_stream.eof())
-    {
+	!ref_stream.eof()) {
       RefSequenceTable::Sequence* ref_str = new RefSequenceTable::Sequence();
       string name;
       readMeta(ref_stream, name, Fasta());
@@ -76,14 +74,17 @@ void get_seqs(istream& ref_stream,
       if (space_pos != string::npos)
 	{
 	  name.resize(space_pos);
-	}
+	} 
+    if (name.size()>0) {
       fprintf(stderr, "\tLoading %s...", name.c_str());
-      seqan::read(ref_stream, *ref_str, Fasta());
-      fprintf(stderr, "done\n");
-      rt.get_id(name, keep_seqs ? ref_str : NULL, 0);
-      if (!keep_seqs)
-	delete ref_str;
+      fflush(stderr);
     }
+    seqan::read(ref_stream, *ref_str, Fasta());
+    if (seqan::length(*ref_str)>0)
+      fprintf(stderr, " done (%ld bases).\n", seqan::length(*ref_str));
+    rt.get_id(name, keep_seqs ? ref_str : NULL, 0);
+    if (!keep_seqs) delete ref_str;
+    } //while FASTA records
 }
 
 RefSeg seg_from_bowtie_hit(const BowtieHit& T)
@@ -746,10 +747,10 @@ struct IntronMotifs
 	    Dna5String seg_str = seqan::infixWithLength(ref_str,
 							pos - half_splice_mer_len - 1,
 							half_splice_mer_len + 1);
-	    stringstream ss(stringstream::in | stringstream::out);
-	    string s;
-	    ss << seg_str;
-	    ss >> s;
+        stringstream ss;
+        ss << seg_str;
+        const std::string& s = ss.str();
+        //const char* cstr=s.c_str();
 	    
 	    string col_seg_str = convert_bp_to_color(s, true);
 	    uint64_t idx = colorstr_to_idx(col_seg_str);
@@ -760,21 +761,24 @@ struct IntronMotifs
 	    dinucs[i].second.last_in_string = s[half_splice_mer_len];
 	  }
 	else
-	  {
+	  { //regular sequence
 	    if (pos <= (size_t)half_splice_mer_len || pos >= length(ref_str))
 	      continue; 
-	    
 	    Dna5String seg_str = seqan::infixWithLength(ref_str,
 							pos - half_splice_mer_len,
 							half_splice_mer_len);
 	    
-	    stringstream ss(stringstream::in | stringstream::out);
-	    string s;
-	    ss << seg_str;
-	    ss >> s;
+        stringstream ss;
+        ss << seg_str;
+        const std::string& s = ss.str();
+        //const char* cstr=s.c_str();
+        //fprintf(stderr, "XXXXXXXX> infix at pos %ld (-%d) : \"%s\"\n", pos, half_splice_mer_len, cstr);
+
 	    uint64_t idx = dna5str_to_idx(s);
 	    dinucs[i].second.fwd_string = idx;
 	    dinucs[i].second.rev_string = rc_dna_str(idx);
+        //fprintf(stderr, "############ attach_upstream_mers pos=%ld, seg_str=\"%s\", fwd_string=%016lX, rev_string=%016lX\n",
+        //   pos, cstr, dinucs[i].second.fwd_string,  dinucs[i].second.rev_string);
 	  }
       }
   }
@@ -797,10 +801,10 @@ struct IntronMotifs
 	    Dna5String seg_str = seqan::infixWithLength(ref_str,
 							pos + 2 - 1,
 							half_splice_mer_len + 1);
-	    stringstream ss(stringstream::in | stringstream::out);
-	    string s;
-	    ss << seg_str;
-	    ss >> s;
+        stringstream ss;
+        ss << seg_str;
+        const std::string& s = ss.str();
+        //const char* cstr=s.c_str();
 	    
 	    string col_seg_str = convert_bp_to_color(s, true);
 	    uint64_t idx = colorstr_to_idx(col_seg_str);
@@ -816,10 +820,10 @@ struct IntronMotifs
 							pos + 2,
 							half_splice_mer_len);
 	    
-	    stringstream ss(stringstream::in | stringstream::out);
-	    string s;
-	    ss << seg_str;
-	    ss >> s;
+        stringstream ss;
+        ss << seg_str;
+        const std::string& s = ss.str();
+        //const char* cstr=s.c_str();
 	    uint64_t idx = dna5str_to_idx(s);
 	    
 	    dinucs[i].second.fwd_string = idx;
@@ -1519,11 +1523,13 @@ bool extendable_junction(uint64_t upstream_dna_str,
 			 size_t min_ext_len,
 			 bool reverse,
 			 char last_in_upstream = 'N',
-			 char first_in_downstream = 'N')
+			 char first_in_downstream = 'N', bool locdebug=false)
 {
   if (color)
     {
-      string two_bp; two_bp.push_back(last_in_upstream); two_bp.push_back(first_in_downstream);
+      string two_bp; 
+      two_bp.push_back(last_in_upstream); 
+      two_bp.push_back(first_in_downstream);
       string color = convert_bp_to_color(two_bp, true);
       char num = (color[0] - '0')  & 0x3;
 
@@ -1542,7 +1548,11 @@ bool extendable_junction(uint64_t upstream_dna_str,
   uint32_t key = junction_key(upstream_dna_str, 
 			      downstream_dna_str,
 			      splice_mer_len);
-
+ /*if (locdebug) {
+   fprintf(stderr, "===============x0x0x0x0x0x0x0x0x0x0x0x=== splice_mer_len=%d\n",splice_mer_len);
+   fprintf(stderr, "\t upstream_dna_str:%016lX, downstream_dna_str:%016lX\n", upstream_dna_str, downstream_dna_str);
+   fprintf(stderr, "\t            junction_key:%08X\n", key);
+ }*/
   upstream_dna_str >>= splice_mer_len;
   downstream_dna_str <<= splice_mer_len;
   
@@ -1581,7 +1591,9 @@ struct RecordExtendableJuncs
 	
 	size_t left_pos = left_sites[L].first;
 	size_t max_right_pos = left_pos + max_intron;
-	for (size_t R = curr_R; 
+    //fprintf(stderr, "XXXXXXXXXXX> curr_R=%ld, max_right_pos=%ld, right_sites.size()=%ld\n",
+    // curr_R, max_right_pos, right_sites.size());
+	for (size_t R = curr_R;
 	     R < right_sites.size() && right_sites[R].first < max_right_pos; ++R)
 	  {
 	    uint64_t upstream_dna_str = left_sites[L].second.fwd_string;
@@ -1590,20 +1602,22 @@ struct RecordExtendableJuncs
 	    char first_in_downstream = right_sites[R].second.first_in_string;
 	    uint64_t rc_upstream_dna_str = left_sites[L].second.rev_string;
 	    uint64_t rc_downstream_dna_str = right_sites[R].second.rev_string;
-
+        bool locdebug=(curr_R==28 && L==5 && R==28);
 	    if (extendable_junction(upstream_dna_str,
 				    downstream_dna_str, splice_mer_len, 7, false,
-				    last_in_upstream, first_in_downstream) ||
+				    last_in_upstream, first_in_downstream, locdebug) ||
 		extendable_junction(rc_downstream_dna_str,
 				    rc_upstream_dna_str, splice_mer_len, 7, true,
-				    last_in_upstream, first_in_downstream))
-	      {
+				    last_in_upstream, first_in_downstream, locdebug))
+		{
+        //DEBUG:
+        //fprintf(stderr, "xxxxxxxxxx> keeping junction (L,R)=(%ld, %ld), curr_R=%ld\n", L,R,curr_R);
 		juncs.insert(Junction(ref_id,
 				      left_sites[L].first - 1,
 				      right_sites[R].first + 2,
 				      antisense,
 				      R - curr_R));
-	      }
+		}
 	    if (juncs.size() > max_juncs)
 		juncs.erase(*(juncs.rbegin()));
 	      }			
@@ -2051,11 +2065,32 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
     
     MotifMap ims;
 	
-    seqan::DnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
-    seqan::DnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
+    //seqan::DnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
+    //seqan::DnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
     
-    if (talkative)
-        fprintf(stderr, "Collecting potential splice sites in islands\n");
+    seqan::DnaString rev_donor_dinuc(donor_dinuc);
+    seqan::DnaString rev_acceptor_dinuc(acceptor_dinuc);
+    seqan::reverseComplement(rev_donor_dinuc);
+    seqan::reverseComplement(rev_acceptor_dinuc);
+    
+    /* typedef seqan::ModifiedString<
+                    seqan::ModifiedString<seqan::DnaString const, seqan::ModView<seqan::FunctorComplement<seqan::Dna> > >,  
+                    seqan::ModReverse>   ConstDnaStringReverseComplement;
+    ConstDnaStringReverseComplement rev_donor_dinuc(donor_dinuc);
+    ConstDnaStringReverseComplement rev_acceptor_dinuc(acceptor_dinuc);
+    */
+
+    if (talkative) {
+        stringstream sdon,sacc;
+        sdon << donor_dinuc;
+        sacc << acceptor_dinuc;
+        const std::string& acctmp = sacc.str();
+        const char* accstr = acctmp.c_str();
+        const std::string& dontmp = sdon.str();
+        const char* donstr = dontmp.c_str();
+        fprintf(stderr, "Collecting potential splice sites in islands (%s-%s)\n",
+             donstr, accstr);
+        }
 
     // 
     bool all_both = true;
@@ -2306,7 +2341,8 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
 	
         //motifs.attach_mer_counts(*ref_str);
         motifs.attach_mers(*ref_str);
-        
+       //DEBUG: fprintf(stderr, "\tFWD (donors, acceptors) = (%d, %d)\n\tREV (donors, acceptors) = (%d, %d)\n",
+       //   motifs.fwd_donors.size(), motifs.fwd_acceptors.size(), motifs.rev_donors.size(), motifs.rev_acceptors.size());
         vector<pair<size_t, DnaSpliceStrings> >& fwd_donors = motifs.fwd_donors;
         vector<pair<size_t, DnaSpliceStrings> >& fwd_acceptors = motifs.fwd_acceptors;
         vector<pair<size_t, DnaSpliceStrings> >& rev_acceptors = motifs.rev_acceptors;
@@ -2324,7 +2360,8 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
                         max_intron, 
                         max_juncs,
                         half_splice_mer_len);
-        
+   //DEBUG:
+   //   fprintf(stderr, "\tFWD potential juncs: %d\n", juncs.size());
         recorder.record(ref_id, 
                         rev_acceptors, 
                         rev_donors, 
@@ -2334,6 +2371,7 @@ void juncs_from_ref_segs(RefSequenceTable& rt,
                         max_intron, 
                         max_juncs,
                         half_splice_mer_len);
+    //DEBUG:  fprintf(stderr, "\ttotal FWD+REV potential juncs: %d\n", juncs.size());
     }
     //fprintf(stderr, "Found %d total splices\n", num_juncs);
 }
@@ -3577,7 +3615,6 @@ void find_gaps(RefSequenceTable& rt,
 	    }
 	}
     } //for each hits_for_read
-
   juncs_from_ref_segs<RecordSegmentJuncs>(rt, 
 				      expected_don_acc_windows, 
 				      seg_juncs, 
@@ -4491,6 +4528,7 @@ void capture_island_ends(ReadTable& it,
 				  expected_look_left_windows.end());
   
   if (!butterfly_search) coverage_map.clear(); //free some memory
+  //fprintf(stderr, "--------->>>>>> RecordExtendableJuncs <<<<<<---------\n");
   juncs_from_ref_segs<RecordExtendableJuncs>(rt, 
 					     expected_don_acc_windows, 
 					     cov_juncs, 
@@ -4501,7 +4539,7 @@ void capture_island_ends(ReadTable& it,
 					     max_cov_juncs,
 					     true,
 					     half_splice_mer_len);
-  //fprintf(stderr, "Found %ld potential island-end pairing junctions\n", (long int)cov_juncs.size());
+  //fprintf(stderr, "############# found %ld potential island-end pairing junctions\n", (long int)cov_juncs.size());
 }
 
 void print_juncs(RefSequenceTable& rt, std::set<Junction, skip_count_lt>& juncs, const char* str)
@@ -4713,7 +4751,7 @@ void driver(istream& ref_stream,
   
   if (left_segmap_fnames.size() > 1)
     {
-      fprintf( stderr, "Loading left segment hits...\n");
+      fprintf( stderr, "Loading left segment hits... ");fflush(stderr);
       
       vector<uint64_t> read_ids;
       vector<vector<int64_t> > offsets;
@@ -4792,7 +4830,7 @@ void driver(istream& ref_stream,
   
   if (right_segmap_fnames.size() > 1)
     {
-      fprintf( stderr, "Loading right segment hits...\n");
+      fprintf( stderr, "Loading right segment hits...");fflush(stderr);
 
       vector<uint64_t> read_ids;
       vector<vector<int64_t> > offsets;
diff --git a/src/sortedcontainers/__init__.py b/src/sortedcontainers/__init__.py
new file mode 100755
index 0000000..98e04cd
--- /dev/null
+++ b/src/sortedcontainers/__init__.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+"""
+sortedcontainers Sorted Container Types Library
+===============================================
+
+SortedContainers is an Apache2 licensed containers library, written in
+pure-Python, and fast as C-extensions.
+
+Python's standard library is great until you need a sorted container type. Many
+will attest that you can get really far without one, but the moment you
+**really need** a sorted list, dict, or set, you're faced with a dozen
+different implementations, most using C-extensions without great documentation
+and benchmarking.
+
+Things shouldn't be this way. Not in Python.
+
+::
+
+    >>> from sortedcontainers import SortedList, SortedDict, SortedSet
+    >>> sl = SortedList(xrange(10000000))
+    >>> 1234567 in sl
+    True
+    >>> sl[7654321]
+    7654321
+    >>> sl.add(1234567)
+    >>> sl.count(1234567)
+    2
+    >>> sl *= 3
+    >>> len(sl)
+    30000003
+
+SortedContainers takes all of the work out of Python sorted types - making your
+deployment and use of Python easy. There's no need to install a C compiler or
+pre-build and distribute custom extensions. Performance is a feature and
+testing has 100% coverage with unit tests and hours of stress.
+
+:copyright: (c) 2014 by Grant Jenks.
+:license: Apache 2.0, see LICENSE for more details.
+
+"""
+
+__title__ = 'sortedcontainers'
+__version__ = '0.9.4'
+__build__ = 0x000904
+__author__ = 'Grant Jenks'
+__license__ = 'Apache 2.0'
+__copyright__ = 'Copyright 2014 Grant Jenks'
+
+from .sortedlist import SortedList
+from .sortedset import SortedSet
+from .sorteddict import SortedDict
+from .sortedlistwithkey import SortedListWithKey
+
+__all__ = ['SortedList', 'SortedSet', 'SortedDict', 'SortedListWithKey']
diff --git a/src/sortedcontainers/sorteddict.py b/src/sortedcontainers/sorteddict.py
new file mode 100755
index 0000000..0282ad5
--- /dev/null
+++ b/src/sortedcontainers/sorteddict.py
@@ -0,0 +1,737 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted dict implementation.
+
+from .sortedset import SortedSet
+from .sortedlist import SortedList, recursive_repr
+from .sortedlistwithkey import SortedListWithKey
+from collections import Set, Sequence
+from collections import KeysView as AbstractKeysView
+from collections import ValuesView as AbstractValuesView
+from collections import ItemsView as AbstractItemsView
+
+from functools import wraps
+from sys import hexversion
+
+_NotGiven = object()
+
+def not26(func):
+    """Function decorator for methods not implemented in Python 2.6."""
+
+    @wraps(func)
+    def errfunc(*args, **kwargs):
+        raise NotImplementedError
+
+    if hexversion < 0x02070000:
+        return errfunc
+    else:
+        return func
+
+class _IlocWrapper:
+    def __init__(self, _dict):
+        self._dict = _dict
+    def __len__(self):
+        return len(self._dict)
+    def __getitem__(self, index):
+        """
+        Very efficiently return the key at index *index* in iteration. Supports
+        negative indices and slice notation. Raises IndexError on invalid
+        *index*.
+        """
+        return self._dict._list[index]
+    def __delitem__(self, index):
+        """
+        Remove the ``sdict[sdict.iloc[index]]`` from *sdict*. Supports negative
+        indices and slice notation. Raises IndexError on invalid *index*.
+        """
+        _temp = self._dict
+        _list = _temp._list
+        _delitem = _temp._delitem
+
+        if isinstance(index, slice):
+            keys = _list[index]
+            del _list[index]
+            for key in keys:
+                _delitem(key)
+        else:
+            key = _list[index]
+            del _list[index]
+            _delitem(key)
+
+class SortedDict(dict):
+    """
+    A SortedDict provides the same methods as a dict.  Additionally, a
+    SortedDict efficiently maintains its keys in sorted order. Consequently, the
+    keys method will return the keys in sorted order, the popitem method will
+    remove the item with the highest key, etc.
+    """
+    def __init__(self, *args, **kwargs):
+        """
+        A SortedDict provides the same methods as a dict.  Additionally, a
+        SortedDict efficiently maintains its keys in sorted order. Consequently,
+        the keys method will return the keys in sorted order, the popitem method
+        will remove the item with the highest key, etc.
+
+        An optional *key* argument defines a callable that, like the `key`
+        argument to Python's `sorted` function, extracts a comparison key from
+        each dict key. If no function is specified, the default compares the
+        dict keys directly. The `key` argument must be provided as a positional
+        argument and must come before all other arguments.
+
+        An optional *load* argument defines the load factor of the internal list
+        used to maintain sort order. If present, this argument must come before
+        an iterable. The default load factor of '1000' works well for lists from
+        tens to tens of millions of elements.  Good practice is to use a value
+        that is the cube root of the list size.  With billions of elements, the
+        best load factor depends on your usage.  It's best to leave the load
+        factor at the default until you start benchmarking.
+
+        An optional *iterable* argument provides an initial series of items to
+        populate the SortedDict.  Each item in the series must itself contain
+        two items.  The first is used as a key in the new dictionary, and the
+        second as the key's value. If a given key is seen more than once, the
+        last value associated with it is retained in the new dictionary.
+
+        If keyword arguments are given, the keywords themselves with their
+        associated values are added as items to the dictionary. If a key is
+        specified both in the positional argument and as a keyword argument, the
+        value associated with the keyword is retained in the dictionary. For
+        example, these all return a dictionary equal to ``{"one": 2, "two":
+        3}``:
+
+        * ``SortedDict(one=2, two=3)``
+        * ``SortedDict({'one': 2, 'two': 3})``
+        * ``SortedDict(zip(('one', 'two'), (2, 3)))``
+        * ``SortedDict([['two', 3], ['one', 2]])``
+
+        The first example only works for keys that are valid Python
+        identifiers; the others work with any valid keys.
+        """
+        if len(args) > 0 and (args[0] is None or callable(args[0])):
+            self._key = args[0]
+            args = args[1:]
+        else:
+            self._key = None
+
+        if len(args) > 0 and type(args[0]) == int:
+            self._load = args[0]
+            args = args[1:]
+        else:
+            self._load = 1000
+
+        if self._key is None:
+            self._list = SortedList(load=self._load)
+        else:
+            self._list = SortedListWithKey(key=self._key, load=self._load)
+
+        # Cache function pointers to dict methods.
+
+        _dict = super(SortedDict, self)
+        self._dict = _dict
+        self._clear = _dict.clear
+        self._delitem = _dict.__delitem__
+        self._iter = _dict.__iter__
+        self._pop = _dict.pop
+        self._setdefault = _dict.setdefault
+        self._setitem = _dict.__setitem__
+        self._update = _dict.update
+
+        # Cache function pointers to SortedList methods.
+
+        self._list_add = self._list.add
+        self._list_bisect_left = self._list.bisect_left
+        self._list_bisect_right = self._list.bisect_right
+        self._list_clear = self._list.clear
+        self._list_index = self._list.index
+        self._list_pop = self._list.pop
+        self._list_remove = self._list.remove
+        self._list_update = self._list.update
+
+        self.iloc = _IlocWrapper(self)
+
+        self.update(*args, **kwargs)
+
+    def clear(self):
+        """Remove all elements from the dictionary."""
+        self._clear()
+        self._list_clear()
+
+    def __delitem__(self, key):
+        """
+        Remove ``d[key]`` from *d*.  Raises a KeyError if *key* is not in the
+        dictionary.
+        """
+        self._delitem(key)
+        self._list_remove(key)
+
+    def __iter__(self):
+        """Create an iterator over the sorted keys of the dictionary."""
+        return iter(self._list)
+
+    def __reversed__(self):
+        """
+        Create a reversed iterator over the sorted keys of the dictionary.
+        """
+        return reversed(self._list)
+
+    def __setitem__(self, key, value):
+        """Set `d[key]` to *value*."""
+        if key not in self:
+            self._list_add(key)
+        self._setitem(key, value)
+
+    def copy(self):
+        """Return a shallow copy of the sorted dictionary."""
+        return self.__class__(self._key, self._load, self.iteritems())
+
+    __copy__ = copy
+
+    @classmethod
+    def fromkeys(cls, seq, value=None):
+        """
+        Create a new dictionary with keys from *seq* and values set to *value*.
+        """
+        return cls((key, value) for key in seq)
+
+    if hexversion < 0x03000000:
+        def items(self):
+            """
+            Return a list of the dictionary's items (``(key, value)`` pairs).
+            """
+            return list(self.iteritems())
+    else:
+        def items(self):
+            """
+            Return a new ItemsView of the dictionary's items.  In addition to
+            the methods provided by the built-in `view` the ItemsView is
+            indexable (e.g. ``d.items()[5]``).
+            """
+            return ItemsView(self)
+
+    def iteritems(self):
+        """Return an iterable over the items (``(key, value)`` pairs)."""
+        return iter((key, self[key]) for key in self._list)
+
+    if hexversion < 0x03000000:
+        def keys(self):
+            """Return a SortedSet of the dictionary's keys."""
+            return SortedSet(self._list, key=self._key, load=self._load)
+    else:
+        def keys(self):
+            """
+            Return a new KeysView of the dictionary's keys.  In addition to the
+            methods provided by the built-in `view` the KeysView is indexable
+            (e.g. ``d.keys()[5]``).
+            """
+            return KeysView(self)
+
+    def iterkeys(self):
+        """Return an iterable over the keys of the dictionary."""
+        return iter(self._list)
+
+    if hexversion < 0x03000000:
+        def values(self):
+            """Return a list of the dictionary's values."""
+            return list(self.itervalues())
+    else:
+        def values(self):
+            """
+            Return a new :class:`ValuesView` of the dictionary's values.
+            In addition to the methods provided by the built-in `view` the
+            ValuesView is indexable (e.g., ``d.values()[5]``).
+            """
+            return ValuesView(self)
+
+    def itervalues(self):
+        """Return an iterable over the values of the dictionary."""
+        return iter(self[key] for key in self._list)
+
+    def pop(self, key, default=_NotGiven):
+        """
+        If *key* is in the dictionary, remove it and return its value,
+        else return *default*. If *default* is not given and *key* is not in
+        the dictionary, a KeyError is raised.
+        """
+        if key in self:
+            self._list_remove(key)
+            return self._pop(key)
+        else:
+            if default is _NotGiven:
+                raise KeyError(key)
+            else:
+                return default
+
+    def popitem(self):
+        """
+        Remove and return the ``(key, value)`` pair with the greatest *key*
+        from the dictionary.
+
+        If the dictionary is empty, calling `popitem` raises a
+        KeyError`.
+        """
+        if not len(self):
+            raise KeyError('popitem(): dictionary is empty')
+
+        key = self._list_pop()
+        value = self._pop(key)
+
+        return (key, value)
+
+    def setdefault(self, key, default=None):
+        """
+        If *key* is in the dictionary, return its value.  If not, insert *key*
+        with a value of *default* and return *default*.  *default* defaults to
+        ``None``.
+        """
+        if key in self:
+            return self[key]
+        else:
+            self._setitem(key, default)
+            self._list_add(key)
+            return default
+
+    def update(self, *args, **kwargs):
+        """
+        Update the dictionary with the key/value pairs from *other*, overwriting
+        existing keys.
+
+        *update* accepts either another dictionary object or an iterable of
+        key/value pairs (as a tuple or other iterable of length two).  If
+        keyword arguments are specified, the dictionary is then updated with
+        those key/value pairs: ``d.update(red=1, blue=2)``.
+        """
+        if not len(self):
+            self._update(*args, **kwargs)
+            self._list_update(self._iter())
+            return
+
+        if (len(kwargs) == 0 and len(args) == 1 and isinstance(args[0], dict)):
+            pairs = args[0]
+        else:
+            pairs = dict(*args, **kwargs)
+
+        if (10 * len(pairs)) > len(self):
+            self._update(pairs)
+            self._list_clear()
+            self._list_update(self._iter())
+        else:
+            for key in pairs:
+                self[key] = pairs[key]
+
+    def index(self, key, start=None, stop=None):
+        """
+        Return the smallest *k* such that `d.iloc[k] == key` and `i <= k < j`.
+        Raises `ValueError` if *key* is not present.  *stop* defaults to the end
+        of the set.  *start* defaults to the beginning.  Negative indexes are
+        supported, as for slice indices.
+        """
+        return self._list_index(key, start, stop)
+
+    def bisect_left(self, key):
+        """
+        Similar to the ``bisect`` module in the standard library, this returns
+        an appropriate index to insert *key* in SortedDict. If *key* is
+        already present in SortedDict, the insertion point will be before (to
+        the left of) any existing entries.
+        """
+        return self._list_bisect_left(key)
+
+    def bisect(self, key):
+        """Same as bisect_right."""
+        return self._list_bisect_right(key)
+
+    def bisect_right(self, key):
+        """
+        Same as `bisect_left`, but if *key* is already present in SortedDict,
+        the insertion point will be after (to the right of) any existing
+        entries.
+        """
+        return self._list_bisect_right(key)
+
+    @not26
+    def viewkeys(self):
+        """
+        In Python 2.7 and later, return a new `KeysView` of the dictionary's
+        keys.
+
+        In Python 2.6, raise a NotImplementedError.
+        """
+        return KeysView(self)
+
+    @not26
+    def viewvalues(self):
+        """
+        In Python 2.7 and later, return a new `ValuesView` of the dictionary's
+        values.
+
+        In Python 2.6, raise a NotImplementedError.
+        """
+        return ValuesView(self)
+
+    @not26
+    def viewitems(self):
+        """
+        In Python 2.7 and later, return a new `ItemsView` of the dictionary's
+        items.
+
+        In Python 2.6, raise a NotImplementedError.
+        """
+        return ItemsView(self)
+
+    def __reduce__(self):
+        return (self.__class__, (self._key, self._load, list(self.iteritems())))
+
+    @recursive_repr
+    def __repr__(self):
+        temp = '{0}({1}, {2}, {{{3}}})'
+        items = ', '.join('{0}: {1}'.format(repr(key), repr(self[key]))
+                          for key in self._list)
+        return temp.format(
+            self.__class__.__name__,
+            repr(self._key),
+            repr(self._load),
+            items
+        )
+
+    def _check(self):
+        self._list._check()
+        assert len(self) == len(self._list)
+        assert all(val in self for val in self._list)
+
+class KeysView(AbstractKeysView, Set, Sequence):
+    """
+    A KeysView object is a dynamic view of the dictionary's keys, which
+    means that when the dictionary's keys change, the view reflects
+    those changes.
+
+    The KeysView class implements the Set and Sequence Abstract Base Classes.
+    """
+    if hexversion < 0x03000000:
+        def __init__(self, sorted_dict):
+            """
+            Initialize a KeysView from a SortedDict container as *sorted_dict*.
+            """
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.viewkeys()
+    else:
+        def __init__(self, sorted_dict):
+            """
+            Initialize a KeysView from a SortedDict container as *sorted_dict*.
+            """
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.keys()
+    def __len__(self):
+        """Return the number of entries in the dictionary."""
+        return len(self._view)
+    def __contains__(self, key):
+        """
+        Return True if and only if *key* is one of the underlying dictionary's
+        keys.
+        """
+        return key in self._view
+    def __iter__(self):
+        """
+        Return an iterable over the keys in the dictionary. Keys are iterated
+        over in their sorted order.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a RuntimeError or fail to iterate over all entries.
+        """
+        return iter(self._list)
+    def __getitem__(self, index):
+        """Return the key at position *index*."""
+        return self._list[index]
+    def __reversed__(self):
+        """
+        Return a reversed iterable over the keys in the dictionary. Keys are
+        iterated over in their reverse sort order.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a RuntimeError or fail to iterate over all entries.
+        """
+        return reversed(self._list)
+    def index(self, value, start=None, stop=None):
+        """
+        Return the smallest *k* such that `keysview[k] == value` and `start <= k
+        < end`.  Raises `KeyError` if *value* is not present.  *stop* defaults
+        to the end of the set.  *start* defaults to the beginning.  Negative
+        indexes are supported, as for slice indices.
+        """
+        return self._list.index(value, start, stop)
+    def count(self, value):
+        """Return the number of occurrences of *value* in the set."""
+        return 1 if value in self._view else 0
+    def __eq__(self, that):
+        """Test set-like equality with *that*."""
+        return self._view == that
+    def __ne__(self, that):
+        """Test set-like inequality with *that*."""
+        return self._view != that
+    def __lt__(self, that):
+        """Test whether self is a proper subset of *that*."""
+        return self._view < that
+    def __gt__(self, that):
+        """Test whether self is a proper superset of *that*."""
+        return self._view > that
+    def __le__(self, that):
+        """Test whether self is contained within *that*."""
+        return self._view <= that
+    def __ge__(self, that):
+        """Test whether *that* is contained within self."""
+        return self._view >= that
+    def __and__(self, that):
+        """Return a SortedSet of the intersection of self and *that*."""
+        return SortedSet(self._view & that)
+    def __or__(self, that):
+        """Return a SortedSet of the union of self and *that*."""
+        return SortedSet(self._view | that)
+    def __sub__(self, that):
+        """Return a SortedSet of the difference of self and *that*."""
+        return SortedSet(self._view - that)
+    def __xor__(self, that):
+        """Return a SortedSet of the symmetric difference of self and *that*."""
+        return SortedSet(self._view ^ that)
+    if hexversion < 0x03000000:
+        def isdisjoint(self, that):
+            """Return True if and only if *that* is disjoint with self."""
+            return not any(key in self._list for key in that)
+    else:
+        def isdisjoint(self, that):
+            """Return True if and only if *that* is disjoint with self."""
+            return self._view.isdisjoint(that)
+    @recursive_repr
+    def __repr__(self):
+        return 'SortedDict_keys({0})'.format(repr(list(self)))
+
+class ValuesView(AbstractValuesView, Sequence):
+    """
+    A ValuesView object is a dynamic view of the dictionary's values, which
+    means that when the dictionary's values change, the view reflects those
+    changes.
+
+    The ValuesView class implements the Sequence Abstract Base Class.
+    """
+    if hexversion < 0x03000000:
+        def __init__(self, sorted_dict):
+            """
+            Initialize a ValuesView from a SortedDict container as
+            *sorted_dict*.
+            """
+            self._dict = sorted_dict
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.viewvalues()
+    else:
+        def __init__(self, sorted_dict):
+            """
+            Initialize a ValuesView from a SortedDict container as
+            *sorted_dict*.
+            """
+            self._dict = sorted_dict
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.values()
+    def __len__(self):
+        """Return the number of entries in the dictionary."""
+        return len(self._dict)
+    def __contains__(self, value):
+        """
+        Return True if and only if *value* is on the underlying dictionary's
+        values.
+        """
+        return value in self._view
+    def __iter__(self):
+        """
+        Return an iterator over the values in the dictionary.  Values are
+        iterated over in sorted order of the keys.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a `RuntimeError` or fail to iterate over all entries.
+        """
+        _dict = self._dict
+        return iter(_dict[key] for key in self._list)
+    def __getitem__(self, index):
+        """
+        Efficiently return value at *index* in iteration.
+
+        Supports slice notation and negative indexes.
+        """
+        _dict, _list = self._dict, self._list
+        if isinstance(index, slice):
+            return [_dict[key] for key in _list[index]]
+        else:
+            return _dict[_list[index]]
+    def __reversed__(self):
+        """
+        Return a reverse iterator over the values in the dictionary.  Values are
+        iterated over in reverse sort order of the keys.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a `RuntimeError` or fail to iterate over all entries.
+        """
+        _dict = self._dict
+        return iter(_dict[key] for key in reversed(self._list))
+    def index(self, value):
+        """
+        Return index of *value* in self.
+
+        Raises ValueError if *value* is not found.
+        """
+        for idx, val in enumerate(self):
+            if value == val:
+                return idx
+        else:
+            raise ValueError('{0} is not in dict'.format(repr(value)))
+    if hexversion < 0x03000000:
+        def count(self, value):
+            """Return the number of occurrences of *value* in self."""
+            return sum(1 for val in self._dict.itervalues() if val == value)
+    else:
+        def count(self, value):
+            """Return the number of occurrences of *value* in self."""
+            return sum(1 for val in _dict.values() if val == value)
+    def __lt__(self, that):
+        raise TypeError
+    def __gt__(self, that):
+        raise TypeError
+    def __le__(self, that):
+        raise TypeError
+    def __ge__(self, that):
+        raise TypeError
+    def __and__(self, that):
+        raise TypeError
+    def __or__(self, that):
+        raise TypeError
+    def __sub__(self, that):
+        raise TypeError
+    def __xor__(self, that):
+        raise TypeError
+    @recursive_repr
+    def __repr__(self):
+        return 'SortedDict_values({0})'.format(repr(list(self)))
+
+class ItemsView(AbstractItemsView, Set, Sequence):
+    """
+    An ItemsView object is a dynamic view of the dictionary's ``(key,
+    value)`` pairs, which means that when the dictionary changes, the
+    view reflects those changes.
+
+    The ItemsView class implements the Set and Sequence Abstract Base Classes.
+    However, the set-like operations (``&``, ``|``, ``-``, ``^``) will only
+    operate correctly if all of the dictionary's values are hashable.
+    """
+    if hexversion < 0x03000000:
+        def __init__(self, sorted_dict):
+            """
+            Initialize an ItemsView from a SortedDict container as
+            *sorted_dict*.
+            """
+            self._dict = sorted_dict
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.viewitems()
+    else:
+        def __init__(self, sorted_dict):
+            """
+            Initialize an ItemsView from a SortedDict container as
+            *sorted_dict*.
+            """
+            self._dict = sorted_dict
+            self._list = sorted_dict._list
+            self._view = sorted_dict._dict.items()
+    def __len__(self):
+        """Return the number of entries in the dictionary."""
+        return len(self._view)
+    def __contains__(self, key):
+        """
+        Return True if and only if *key* is one of the underlying dictionary's
+        items.
+        """
+        return key in self._view
+    def __iter__(self):
+        """
+        Return an iterable over the items in the dictionary. Items are iterated
+        over in their sorted order.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a RuntimeError or fail to iterate over all entries.
+        """
+        _dict = self._dict
+        return iter((key, _dict[key]) for key in self._list)
+    def __getitem__(self, index):
+        """Return the item as position *index*."""
+        _dict, _list = self._dict, self._list
+        if isinstance(index, slice):
+            return [(key, _dict[key]) for key in _list[index]]
+        else:
+            key = _list[index]
+            return (key, _dict[key])
+    def __reversed__(self):
+        """
+        Return a reversed iterable over the items in the dictionary. Items are
+        iterated over in their reverse sort order.
+
+        Iterating views while adding or deleting entries in the dictionary may
+        raise a RuntimeError or fail to iterate over all entries.
+        """
+        _dict = self._dict
+        return iter((key, _dict[key]) for key in reversed(self._list))
+    def index(self, key, start=None, stop=None):
+        """
+        Return the smallest *k* such that `itemssview[k] == key` and `start <= k
+        < end`.  Raises `KeyError` if *key* is not present.  *stop* defaults
+        to the end of the set.  *start* defaults to the beginning.  Negative
+        indexes are supported, as for slice indices.
+        """
+        temp, value = key
+        pos = self._list.index(temp, start, stop)
+        if value == self._dict[temp]:
+            return pos
+        else:
+            raise ValueError('{0} is not in dict'.format(repr(key)))
+    def count(self, item):
+        """Return the number of occurrences of *item* in the set."""
+        key, value = item
+        return 1 if key in self._dict and self._dict[key] == value else 0
+    def __eq__(self, that):
+        """Test set-like equality with *that*."""
+        return self._view == that
+    def __ne__(self, that):
+        """Test set-like inequality with *that*."""
+        return self._view != that
+    def __lt__(self, that):
+        """Test whether self is a proper subset of *that*."""
+        return self._view < that
+    def __gt__(self, that):
+        """Test whether self is a proper superset of *that*."""
+        return self._view > that
+    def __le__(self, that):
+        """Test whether self is contained within *that*."""
+        return self._view <= that
+    def __ge__(self, that):
+        """Test whether *that* is contained within self."""
+        return self._view >= that
+    def __and__(self, that):
+        """Return a SortedSet of the intersection of self and *that*."""
+        return SortedSet(self._view & that)
+    def __or__(self, that):
+        """Return a SortedSet of the union of self and *that*."""
+        return SortedSet(self._view | that)
+    def __sub__(self, that):
+        """Return a SortedSet of the difference of self and *that*."""
+        return SortedSet(self._view - that)
+    def __xor__(self, that):
+        """Return a SortedSet of the symmetric difference of self and *that*."""
+        return SortedSet(self._view ^ that)
+    if hexversion < 0x03000000:
+        def isdisjoint(self, that):
+            """Return True if and only if *that* is disjoint with self."""
+            _dict = self._dict
+            for key, value in that:
+                if key in _dict and _dict[key] == value:
+                    return False
+            return True
+    else:
+        def isdisjoint(self, that):
+            """Return True if and only if *that* is disjoint with self."""
+            return self._view.isdisjoint(that)
+    @recursive_repr
+    def __repr__(self):
+        return 'SortedDict_items({0})'.format(repr(list(self)))
diff --git a/src/sortedcontainers/sortedlist.py b/src/sortedcontainers/sortedlist.py
new file mode 100755
index 0000000..8549cb4
--- /dev/null
+++ b/src/sortedcontainers/sortedlist.py
@@ -0,0 +1,1233 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted list implementation.
+
+from __future__ import print_function
+from sys import hexversion
+
+from bisect import bisect_left, bisect_right, insort
+from itertools import chain, repeat, starmap
+from collections import MutableSequence
+from operator import iadd, add
+from functools import wraps
+from math import log
+
+if hexversion < 0x03000000:
+    from itertools import izip as zip
+    from itertools import imap as map
+    try:
+        from thread import get_ident
+    except ImportError:
+        from dummy_thread import get_ident
+else:
+    from functools import reduce
+    try:
+        from _thread import get_ident
+    except ImportError:
+        from _dummy_thread import get_ident
+
+def recursive_repr(func):
+    """Decorator to prevent infinite repr recursion."""
+    repr_running = set()
+
+    @wraps(func)
+    def wrapper(self):
+        key = id(self), get_ident()
+
+        if key in repr_running:
+            return '...'
+
+        repr_running.add(key)
+
+        try:
+            return func(self)
+        finally:
+            repr_running.discard(key)
+
+    return wrapper
+
+class SortedList(MutableSequence):
+    """
+    SortedList provides most of the same methods as a list but keeps the items
+    in sorted order.
+    """
+
+    def __init__(self, iterable=None, load=1000):
+        """
+        SortedList provides most of the same methods as a list but keeps the
+        items in sorted order.
+
+        An optional *iterable* provides an initial series of items to populate
+        the SortedList.
+
+        An optional *load* specifies the load-factor of the list. The default
+        load factor of '1000' works well for lists from tens to tens of millions
+        of elements.  Good practice is to use a value that is the cube root of
+        the list size.  With billions of elements, the best load factor depends
+        on your usage.  It's best to leave the load factor at the default until
+        you start benchmarking.
+        """
+        self._len, self._maxes, self._lists, self._index = 0, [], [], []
+        self._load, self._twice, self._half = load, load * 2, load >> 1
+        self._offset = 0
+
+        if iterable is not None:
+            self.update(iterable)
+
+    def clear(self):
+        """Remove all the elements from the list."""
+        self._len = 0
+        del self._maxes[:]
+        del self._lists[:]
+        del self._index[:]
+
+    def add(self, val):
+        """Add the element *val* to the list."""
+        _maxes, _lists = self._maxes, self._lists
+
+        if _maxes:
+            pos = bisect_right(_maxes, val)
+
+            if pos == len(_maxes):
+                pos -= 1
+                _maxes[pos] = val
+                _lists[pos].append(val)
+            else:
+                insort(_lists[pos], val)
+
+            self._expand(pos)
+        else:
+            _maxes.append(val)
+            _lists.append([val])
+
+        self._len += 1
+
+    def _expand(self, pos):
+        """Splits sublists that are more than double the load level.
+
+        Updates the index when the sublist length is less than double the load
+        level. This requires incrementing the nodes in a traversal from the leaf
+        node to the root. For an example traversal see self._loc.
+        """
+        _lists, _index = self._lists, self._index
+
+        if len(_lists[pos]) > self._twice:
+            _maxes, _load = self._maxes, self._load
+            half = _lists[pos][_load:]
+            del _lists[pos][_load:]
+            _maxes[pos] = _lists[pos][-1]
+            _maxes.insert(pos + 1, half[-1])
+            _lists.insert(pos + 1, half)
+            del _index[:]
+        else:
+            if len(_index) > 0:
+                child = self._offset + pos
+                while child > 0:
+                    _index[child] += 1
+                    child = (child - 1) >> 1
+                _index[0] += 1
+
+    def update(self, iterable):
+        """Update the list by adding all elements from *iterable*."""
+        _maxes, _lists = self._maxes, self._lists
+        values = sorted(iterable)
+
+        if _maxes:
+            if len(values) * 4 >= self._len:
+                values.extend(chain.from_iterable(_lists))
+                values.sort()
+                self.clear()
+            else:
+                _add = self.add
+                for val in values:
+                    _add(val)
+                return
+
+        _load, _index = self._load, self._index
+        _lists.extend(values[pos:(pos + _load)]
+                      for pos in range(0, len(values), _load))
+        _maxes.extend(sublist[-1] for sublist in _lists)
+        self._len = len(values)
+        del _index[:]
+
+    def __contains__(self, val):
+        """Return True if and only if *val* is an element in the list."""
+        _maxes = self._maxes
+
+        if not _maxes:
+            return False
+
+        pos = bisect_left(_maxes, val)
+
+        if pos == len(_maxes):
+            return False
+
+        _lists = self._lists
+        idx = bisect_left(_lists[pos], val)
+        return _lists[pos][idx] == val
+
+    def discard(self, val):
+        """
+        Remove the first occurrence of *val*.
+
+        If *val* is not a member, does nothing.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return
+
+        pos = bisect_left(_maxes, val)
+
+        if pos == len(_maxes):
+            return
+
+        _lists = self._lists
+        idx = bisect_left(_lists[pos], val)
+        if _lists[pos][idx] == val:
+            self._delete(pos, idx)
+
+    def remove(self, val):
+        """
+        Remove first occurrence of *val*.
+
+        Raises ValueError if *val* is not present.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            raise ValueError('{0} not in list'.format(repr(val)))
+
+        pos = bisect_left(_maxes, val)
+
+        if pos == len(_maxes):
+            raise ValueError('{0} not in list'.format(repr(val)))
+
+        _lists = self._lists
+        idx = bisect_left(_lists[pos], val)
+        if _lists[pos][idx] == val:
+            self._delete(pos, idx)
+        else:
+            raise ValueError('{0} not in list'.format(repr(val)))
+
+    def _delete(self, pos, idx):
+        """Delete the item at the given (pos, idx).
+
+        Combines lists that are less than half the load level.
+
+        Updates the index when the sublist length is more than half the load
+        level. This requires decrementing the nodes in a traversal from the leaf
+        node to the root. For an example traversal see self._loc.
+        """
+        _maxes, _lists, _index = self._maxes, self._lists, self._index
+
+        lists_pos = _lists[pos]
+
+        del lists_pos[idx]
+        self._len -= 1
+
+        len_lists_pos = len(lists_pos)
+
+        if len_lists_pos > self._half:
+
+            _maxes[pos] = lists_pos[-1]
+
+            if len(_index) > 0:
+                child = self._offset + pos
+                while child > 0:
+                    _index[child] -= 1
+                    child = (child - 1) >> 1
+                _index[0] -= 1
+
+        elif len(_lists) > 1:
+
+            if not pos:
+                pos += 1
+
+            prev = pos - 1
+            _lists[prev].extend(_lists[pos])
+            _maxes[prev] = _lists[prev][-1]
+
+            del _maxes[pos]
+            del _lists[pos]
+            del _index[:]
+
+            self._expand(prev)
+
+        elif len_lists_pos:
+
+            _maxes[pos] = lists_pos[-1]
+
+        else:
+
+            del _maxes[pos]
+            del _lists[pos]
+            del _index[:]
+
+    def _loc(self, pos, idx):
+        """Convert an index pair (alpha, beta) into a single index that corresponds to
+        the position of the value in the sorted list.
+
+        Most queries require the index be built. Details of the index are
+        described in self._build_index.
+
+        Indexing requires traversing the tree from a leaf node to the root. The
+        parent of each node is easily computable at (pos - 1) // 2.
+
+        Left-child nodes are always at odd indices and right-child nodes are
+        always at even indices.
+
+        When traversing up from a right-child node, increment the total by the
+        left-child node.
+
+        The final index is the sum from traversal and the index in the sublist.
+
+        For example, using the index from self._build_index:
+
+        _index = 14 5 9 3 2 4 5
+        _offset = 3
+
+        Tree:
+
+                 14
+              5      9
+            3   2  4   5
+
+        Converting index pair (2, 3) into a single index involves iterating like
+        so:
+
+        1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
+           the node as a left-child node. At such nodes, we simply traverse to
+           the parent.
+
+        2. At node 9, position 2, we recognize the node as a right-child node
+           and accumulate the left-child in our total. Total is now 5 and we
+           traverse to the parent at position 0.
+
+        3. Iteration ends at the root.
+
+        Computing the index is the sum of the total and beta: 5 + 3 = 8.
+        """
+        if not pos:
+            return idx
+
+        _index = self._index
+
+        if not len(_index):
+            self._build_index()
+
+        total = 0
+
+        # Increment pos to point in the index to len(self._lists[pos]).
+
+        pos += self._offset
+
+        # Iterate until reaching the root of the index tree at pos = 0.
+
+        while pos:
+
+            # Right-child nodes are at odd indices. At such indices
+            # account the total below the left child node.
+
+            if not (pos & 1):
+                total += _index[pos - 1]
+
+            # Advance pos to the parent node.
+
+            pos = (pos - 1) >> 1
+
+        return total + idx
+
+    def _pos(self, idx):
+        """Convert an index into a pair (alpha, beta) that can be used to access
+        the corresponding _lists[alpha][beta] position.
+
+        Most queries require the index be built. Details of the index are
+        described in self._build_index.
+
+        Indexing requires traversing the tree to a leaf node. Each node has
+        two children which are easily computable. Given an index, pos, the
+        left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
+
+        When the index is less than the left-child, traversal moves to the
+        left sub-tree. Otherwise, the index is decremented by the left-child
+        and traversal moves to the right sub-tree.
+
+        At a child node, the indexing pair is computed from the relative
+        position of the child node as compared with the offset and the remaining
+        index.
+
+        For example, using the index from self._build_index:
+
+        _index = 14 5 9 3 2 4 5
+        _offset = 3
+
+        Tree:
+
+                 14
+              5      9
+            3   2  4   5
+
+        Indexing position 8 involves iterating like so:
+
+        1. Starting at the root, position 0, 8 is compared with the left-child
+           node (5) which it is greater than. When greater the index is
+           decremented and the position is updated to the right child node.
+
+        2. At node 9 with index 3, we again compare the index to the left-child
+           node with value 4. Because the index is the less than the left-child
+           node, we simply traverse to the left.
+
+        3. At node 4 with index 3, we recognize that we are at a leaf node and
+           stop iterating.
+
+        4. To compute the sublist index, we subtract the offset from the index
+           of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
+           simply use the index remaining from iteration. In this case, 3.
+
+        The final index pair from our example is (2, 3) which corresponds to
+        index 8 in the sorted list.
+        """
+        _len, _lists = self._len, self._lists
+
+        if idx < 0:
+            last_len = len(_lists[-1])
+            if (-idx) <= last_len:
+                return len(_lists) - 1, last_len + idx
+            idx += _len
+            if idx < 0:
+                raise IndexError('list index out of range')
+        elif idx >= _len:
+            raise IndexError('list index out of range')
+
+        if idx < len(_lists[0]):
+            return 0, idx
+
+        _index = self._index
+
+        if not len(_index):
+            self._build_index()
+
+        pos = 0
+        len_index = len(_index)
+        child = (pos << 1) + 1
+
+        while child < len_index:
+            index_child = _index[child]
+
+            if idx < index_child:
+                pos = child
+            else:
+                idx -= index_child
+                pos = child + 1
+
+            child = (pos << 1) + 1
+
+        return (pos - self._offset, idx)
+
+    def _build_index(self):
+        """Build an index for indexing the sorted list.
+
+        Indexes are represented as binary trees in a dense array notation
+        similar to a binary heap.
+
+        For example, given a _lists representation storing integers:
+
+        [0]: 1 2 3
+        [1]: 4 5
+        [2]: 6 7 8 9
+        [3]: 10 11 12 13 14
+
+        The first transformation maps the sub-lists by their length. The
+        first row of the index is the length of the sub-lists.
+
+        [0]: 3 2 4 5
+
+        Each row after that is the sum of consecutive pairs of the previous row:
+
+        [1]: 5 9
+        [2]: 14
+
+        Finally, the index is built by concatenating these lists together:
+
+        _index = 14 5 9 3 2 4 5
+
+        An offset storing the start of the first row is also stored:
+
+        _offset = 3
+
+        When built, the index can be used for efficient indexing into the list.
+        See the comment and notes on self._pos for details.
+        """
+        row0 = list(map(len, self._lists))
+
+        if len(row0) == 1:
+            self._index[:] = row0
+            self._offset = 0
+            return
+
+        head = iter(row0)
+        tail = iter(head)
+        row1 = list(starmap(add, zip(head, tail)))
+
+        if len(row0) & 1:
+            row1.append(row0[-1])
+
+        if len(row1) == 1:
+            self._index[:] = row1 + row0
+            self._offset = 1
+            return
+
+        size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
+        row1.extend(repeat(0, size - len(row1)))
+        tree = [row0, row1]
+
+        while len(tree[-1]) > 1:
+            head = iter(tree[-1])
+            tail = iter(head)
+            row = list(starmap(add, zip(head, tail)))
+            tree.append(row)
+
+        reduce(iadd, reversed(tree), self._index)
+        self._offset = size * 2 - 1
+
+    def _slice(self, slc):
+        start, stop, step = slc.start, slc.stop, slc.step
+
+        if step == 0:
+            raise ValueError('slice step cannot be zero')
+
+        # Set defaults for missing values.
+
+        if step is None:
+            step = 1
+
+        if step > 0:
+            if start is None:
+                start = 0
+
+            if stop is None:
+                stop = len(self)
+            elif stop < 0:
+                stop += len(self)
+        else:
+            if start is None:
+                start = len(self) - 1
+
+            if stop is None:
+                stop = -1
+            elif stop < 0:
+                stop += len(self)
+
+        if start < 0:
+            start += len(self)
+
+        # Fix indices that are too big or too small.
+        # Slice notation is surprisingly permissive
+        # where normal indexing would raise IndexError.
+
+        if step > 0:
+            if start < 0:
+                start = 0
+            elif start > len(self):
+                start = len(self)
+
+            if stop < 0:
+                stop = 0
+            elif stop > len(self):
+                stop = len(self)
+        else:
+            if start < 0:
+                start = -1
+            elif start >= len(self):
+                start = len(self) - 1
+
+            if stop < 0:
+                stop = -1
+            elif stop > len(self):
+                stop = len(self)
+
+        return start, stop, step
+
+    def __delitem__(self, idx):
+        """Remove the element at *idx*. Supports slicing."""
+        if isinstance(idx, slice):
+            start, stop, step = self._slice(idx)
+
+            if ((step == 1) and (start < stop)
+                    and ((stop - start) * 8 >= self._len)):
+
+                values = self[:start]
+                if stop < self._len:
+                    values += self[stop:]
+                self.clear()
+                self.update(values)
+                return
+
+            indices = range(start, stop, step)
+
+            # Delete items from greatest index to least so
+            # that the indices remain valid throughout iteration.
+
+            if step > 0:
+                indices = reversed(indices)
+
+            _pos, _delete = self._pos, self._delete
+
+            for index in indices:
+                pos, idx = _pos(index)
+                _delete(pos, idx)
+        else:
+            pos, idx = self._pos(idx)
+            self._delete(pos, idx)
+
+    def __getitem__(self, idx):
+        """Return the element at *idx*. Supports slicing."""
+        _lists = self._lists
+
+        if isinstance(idx, slice):
+            start, stop, step = self._slice(idx)
+
+            if step == 1 and start < stop:
+                if start == 0 and stop == self._len:
+                    return self.as_list()
+
+                start_pos, start_idx = self._pos(start)
+
+                if stop == self._len:
+                    stop_pos = len(_lists) - 1
+                    stop_idx = len(_lists[stop_pos])
+                else:
+                    stop_pos, stop_idx = self._pos(stop)
+
+                if start_pos == stop_pos:
+                    return _lists[start_pos][start_idx:stop_idx]
+
+                prefix = _lists[start_pos][start_idx:]
+                middle = _lists[(start_pos + 1):stop_pos]
+                result = reduce(iadd, middle, prefix)
+                result += _lists[stop_pos][:stop_idx]
+
+                return result
+
+            if step == -1 and start > stop:
+                result = self[(stop + 1):(start + 1)]
+                result.reverse()
+                return result
+
+            # Return a list because a negative step could
+            # reverse the order of the items and this could
+            # be the desired behavior.
+
+            indices = range(start, stop, step)
+            return list(self[index] for index in indices)
+        else:
+            pos, idx = self._pos(idx)
+            return _lists[pos][idx]
+
+    def _check_order(self, idx, val):
+        _lists, _len = self._lists, self._len
+
+        pos, loc = self._pos(idx)
+
+        if idx < 0:
+            idx += _len
+
+        # Check that the inserted value is not less than the
+        # previous value.
+
+        if idx > 0:
+            idx_prev = loc - 1
+            pos_prev = pos
+
+            if idx_prev < 0:
+                pos_prev -= 1
+                idx_prev = len(_lists[pos_prev]) - 1
+
+            if _lists[pos_prev][idx_prev] > val:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+                raise ValueError(msg)
+
+        # Check that the inserted value is not greater than
+        # the previous value.
+
+        if idx < (_len - 1):
+            idx_next = loc + 1
+            pos_next = pos
+
+            if idx_next == len(_lists[pos_next]):
+                pos_next += 1
+                idx_next = 0
+
+            if _lists[pos_next][idx_next] < val:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+                raise ValueError(msg)
+
+    def __setitem__(self, index, value):
+        """
+        Replace the item at position *index* with *value*.
+
+        Supports slice notation. Raises a :exc:`ValueError` if the sort order
+        would be violated. When used with a slice and iterable, the
+        :exc:`ValueError` is raised before the list is mutated if the sort order
+        would be violated by the operation.
+        """
+        _maxes, _lists, _pos = self._maxes, self._lists, self._pos
+        _check_order = self._check_order
+
+        if isinstance(index, slice):
+            start, stop, step = self._slice(index)
+            indices = range(start, stop, step)
+
+            if step != 1:
+                if not hasattr(value, '__len__'):
+                    value = list(value)
+
+                indices = list(indices)
+
+                if len(value) != len(indices):
+                    raise ValueError(
+                        'attempt to assign sequence of size {0}'
+                        ' to extended slice of size {1}'
+                        .format(len(value), len(indices)))
+
+                # Keep a log of values that are set so that we can
+                # roll back changes if ordering is violated.
+
+                log = []
+                _append = log.append
+
+                for idx, val in zip(indices, value):
+                    pos, loc = _pos(idx)
+                    _append((idx, _lists[pos][loc], val))
+                    _lists[pos][loc] = val
+                    if len(_lists[pos]) == (loc + 1):
+                        _maxes[pos] = val
+
+                try:
+                    # Validate ordering of new values.
+
+                    for idx, oldval, newval in log:
+                        _check_order(idx, newval)
+
+                except ValueError:
+
+                    # Roll back changes from log.
+
+                    for idx, oldval, newval in log:
+                        pos, loc = _pos(idx)
+                        _lists[pos][loc] = oldval
+                        if len(_lists[pos]) == (loc + 1):
+                            _maxes[pos] = oldval
+
+                    raise
+            else:
+                # Test ordering using indexing. If the value given
+                # doesn't support getitem, convert it to a list.
+
+                if not hasattr(value, '__getitem__'):
+                    value = list(value)
+
+                # Check that the given values are ordered properly.
+
+                ordered = all(value[pos - 1] <= value[pos]
+                              for pos in range(1, len(value)))
+
+                if not ordered:
+                    raise ValueError('given sequence not in sort order')
+
+                # Check ordering in context of sorted list.
+
+                if not start or not len(value):
+                    # Nothing to check on the lhs.
+                    pass
+                else:
+                    if self[start - 1] > value[0]:
+                        msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
+                        raise ValueError(msg)
+
+                if stop == len(self) or not len(value):
+                    # Nothing to check on the rhs.
+                    pass
+                else:
+                    # "stop" is exclusive so we don't need
+                    # to add one for the index.
+                    if self[stop] < value[-1]:
+                        msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
+                        raise ValueError(msg)
+
+                # Delete the existing values.
+
+                del self[index]
+
+                # Insert the new values.
+
+                _insert = self.insert
+                for idx, val in enumerate(value):
+                    _insert(start + idx, val)
+        else:
+            pos, loc = _pos(index)
+            _check_order(index, value)
+            _lists[pos][loc] = value
+            if len(_lists[pos]) == (loc + 1):
+                _maxes[pos] = value
+
+    def __iter__(self):
+        """Create an iterator over the list."""
+        return chain.from_iterable(self._lists)
+
+    def __reversed__(self):
+        """Create an iterator to traverse the list in reverse."""
+        return chain.from_iterable(map(reversed, reversed(self._lists)))
+
+    def __len__(self):
+        """Return the number of elements in the list."""
+        return self._len
+
+    def bisect_left(self, val):
+        """
+        Similar to the *bisect* module in the standard library, this returns an
+        appropriate index to insert *val*. If *val* is already present, the
+        insertion point will be before (to the left of) any existing entries.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        pos = bisect_left(_maxes, val)
+
+        if pos == len(_maxes):
+            return self._len
+
+        idx = bisect_left(self._lists[pos], val)
+
+        return self._loc(pos, idx)
+
+    def bisect_right(self, val):
+        """
+        Same as *bisect_left*, but if *val* is already present, the insertion
+        point will be after (to the right of) any existing entries.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        pos = bisect_right(_maxes, val)
+
+        if pos == len(_maxes):
+            return self._len
+
+        idx = bisect_right(self._lists[pos], val)
+
+        return self._loc(pos, idx)
+
+    bisect = bisect_right
+
+    def count(self, val):
+        """Return the number of occurrences of *val* in the list."""
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        pos_left = bisect_left(_maxes, val)
+
+        if pos_left == len(_maxes):
+            return 0
+
+        _lists = self._lists
+        idx_left = bisect_left(_lists[pos_left], val)
+        pos_right = bisect_right(_maxes, val)
+
+        if pos_right == len(_maxes):
+            return self._len - self._loc(pos_left, idx_left)
+
+        idx_right = bisect_right(_lists[pos_right], val)
+
+        if pos_left == pos_right:
+            return idx_right - idx_left
+
+        right = self._loc(pos_right, idx_right)
+        left = self._loc(pos_left, idx_left)
+
+        return right - left
+
+    def copy(self):
+        """Return a shallow copy of the sorted list."""
+        return self.__class__(self, load=self._load)
+
+    __copy__ = copy
+
+    def append(self, val):
+        """
+        Append the element *val* to the list. Raises a ValueError if the *val*
+        would violate the sort order.
+        """
+        _maxes, _lists = self._maxes, self._lists
+
+        if not _maxes:
+            _maxes.append(val)
+            _lists.append([val])
+            self._len = 1
+            return
+
+        pos = len(_lists) - 1
+
+        if val < _lists[pos][-1]:
+            msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
+            raise ValueError(msg)
+
+        _maxes[pos] = val
+        _lists[pos].append(val)
+        self._len += 1
+        self._expand(pos)
+
+    def extend(self, values):
+        """
+        Extend the list by appending all elements from the *values*. Raises a
+        ValueError if the sort order would be violated.
+        """
+        _maxes, _lists, _load = self._maxes, self._lists, self._load
+
+        if not isinstance(values, list):
+            values = list(values)
+
+        if any(values[pos - 1] > values[pos]
+               for pos in range(1, len(values))):
+            raise ValueError('given sequence not in sort order')
+
+        offset = 0
+
+        if _maxes:
+            if values[0] < _lists[-1][-1]:
+                msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
+                raise ValueError(msg)
+
+            if len(_lists[-1]) < self._half:
+                _lists[-1].extend(values[:_load])
+                _maxes[-1] = _lists[-1][-1]
+                offset = _load
+
+        len_lists = len(_lists)
+
+        for idx in range(offset, len(values), _load):
+            _lists.append(values[idx:(idx + _load)])
+            _maxes.append(_lists[-1][-1])
+
+        _index = self._index
+
+        if len_lists == len(_lists):
+            len_index = len(_index)
+            if len_index > 0:
+                len_values = len(values)
+                child = len_index - 1
+                while child:
+                    _index[child] += len_values
+                    child = (child - 1) >> 1
+                _index[0] += len_values
+        else:
+            del _index[:]
+
+        self._len += len(values)
+
+    def insert(self, idx, val):
+        """
+        Insert the element *val* into the list at *idx*. Raises a ValueError if
+        the *val* at *idx* would violate the sort order.
+        """
+        _maxes, _lists, _len = self._maxes, self._lists, self._len
+
+        if idx < 0:
+            idx += _len
+        if idx < 0:
+            idx = 0
+        if idx > _len:
+            idx = _len
+
+        if not _maxes:
+            # The idx must be zero by the inequalities above.
+            _maxes.append(val)
+            _lists.append([val])
+            self._len = 1
+            return
+
+        if not idx:
+            if val > _lists[0][0]:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
+                raise ValueError(msg)
+            else:
+                _lists[0].insert(0, val)
+                self._expand(0)
+                self._len += 1
+                return
+
+        if idx == _len:
+            pos = len(_lists) - 1
+            if _lists[pos][-1] > val:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
+                raise ValueError(msg)
+            else:
+                _lists[pos].append(val)
+                _maxes[pos] = _lists[pos][-1]
+                self._expand(pos)
+                self._len += 1
+                return
+
+        pos, idx = self._pos(idx)
+        idx_before = idx - 1
+        if idx_before < 0:
+            pos_before = pos - 1
+            idx_before = len(_lists[pos_before]) - 1
+        else:
+            pos_before = pos
+
+        before = _lists[pos_before][idx_before]
+        if before <= val <= _lists[pos][idx]:
+            _lists[pos].insert(idx, val)
+            self._expand(pos)
+            self._len += 1
+        else:
+            msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+            raise ValueError(msg)
+
+    def pop(self, idx=-1):
+        """
+        Remove and return item at *idx* (default last).  Raises IndexError if
+        list is empty or index is out of range.  Negative indices are supported,
+        as for slice indices.
+        """
+        if (idx < 0 and -idx > self._len) or (idx >= self._len):
+            raise IndexError('pop index out of range')
+
+        pos, idx = self._pos(idx)
+        val = self._lists[pos][idx]
+        self._delete(pos, idx)
+
+        return val
+
+    def index(self, val, start=None, stop=None):
+        """
+        Return the smallest *k* such that L[k] == val and i <= k < j`.  Raises
+        ValueError if *val* is not present.  *stop* defaults to the end of the
+        list. *start* defaults to the beginning. Negative indices are supported,
+        as for slice indices.
+        """
+        _len, _maxes = self._len, self._maxes
+
+        if not _maxes:
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        if start is None:
+            start = 0
+        if start < 0:
+            start += _len
+        if start < 0:
+            start = 0
+
+        if stop is None:
+            stop = _len
+        if stop < 0:
+            stop += _len
+        if stop > _len:
+            stop = _len
+
+        if stop <= start:
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        stop -= 1
+        pos_left = bisect_left(_maxes, val)
+
+        if pos_left == len(_maxes):
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        _lists = self._lists
+        idx_left = bisect_left(_lists[pos_left], val)
+
+        if _lists[pos_left][idx_left] != val:
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        left = self._loc(pos_left, idx_left)
+
+        if start <= left:
+            if left <= stop:
+                return left
+        else:
+            right = self.bisect_right(val) - 1
+
+            if start <= right:
+                return start
+
+        raise ValueError('{0} is not in list'.format(repr(val)))
+
+    def as_list(self):
+        """Very efficiently convert the SortedList to a list."""
+        return reduce(iadd, self._lists, [])
+
+    def __add__(self, that):
+        """
+        Return a new sorted list containing all the elements in *self* and
+        *that*. Elements in *that* do not need to be properly ordered with
+        respect to *self*.
+        """
+        values = self.as_list()
+        values.extend(that)
+        return self.__class__(values, load=self._load)
+
+    def __iadd__(self, that):
+        """
+        Update *self* to include all values in *that*. Elements in *that* do not
+        need to be properly ordered with respect to *self*.
+        """
+        self.update(that)
+        return self
+
+    def __mul__(self, that):
+        """
+        Return a new sorted list containing *that* shallow copies of each item
+        in SortedList.
+        """
+        values = self.as_list() * that
+        return self.__class__(values, load=self._load)
+
+    def __imul__(self, that):
+        """
+        Increase the length of the list by appending *that* shallow copies of
+        each item.
+        """
+        values = self.as_list() * that
+        self.clear()
+        self.update(values)
+        return self
+
+    def __eq__(self, that):
+        """Compare two Sequences for equality."""
+        return ((self._len == len(that))
+                and all(lhs == rhs for lhs, rhs in zip(self, that)))
+
+    def __ne__(self, that):
+        """Compare two Sequences for inequality."""
+        return ((self._len != len(that))
+                or any(lhs != rhs for lhs, rhs in zip(self, that)))
+
+    def __lt__(self, that):
+        """Compare two Sequences for less than."""
+        return ((self._len <= len(that))
+                and all(lhs < rhs for lhs, rhs in zip(self, that)))
+
+    def __le__(self, that):
+        """Compare two Sequences for less than equal."""
+        return ((self._len <= len(that))
+                and all(lhs <= rhs for lhs, rhs in zip(self, that)))
+
+    def __gt__(self, that):
+        """Compare two Sequences for greater than."""
+        return ((self._len >= len(that))
+                and all(lhs > rhs for lhs, rhs in zip(self, that)))
+
+    def __ge__(self, that):
+        """Compare two Sequences for greater than equal."""
+        return ((self._len >= len(that))
+                and all(lhs >= rhs for lhs, rhs in zip(self, that)))
+
+    @recursive_repr
+    def __repr__(self):
+        """Return string representation of SortedList."""
+        temp = '{0}({1}, load={2})'
+        return temp.format(
+            self.__class__.__name__,
+            repr(list(self)),
+            repr(self._load)
+        )
+
+    def _check(self):
+        try:
+            # Check load parameters.
+
+            assert self._load >= 4
+            assert self._half == (self._load >> 1)
+            assert self._twice == (self._load * 2)
+
+            # Check empty sorted list case.
+
+            if self._maxes == []:
+                assert self._lists == []
+                return
+
+            assert len(self._maxes) > 0 and len(self._lists) > 0
+
+            # Check all sublists are sorted.
+
+            assert all(sublist[pos - 1] <= sublist[pos]
+                       for sublist in self._lists
+                       for pos in range(1, len(sublist)))
+
+            # Check beginning/end of sublists are sorted.
+
+            for pos in range(1, len(self._lists)):
+                assert self._lists[pos - 1][-1] <= self._lists[pos][0]
+
+            # Check length of _maxes and _lists match.
+
+            assert len(self._maxes) == len(self._lists)
+
+            # Check _maxes is a map of _lists.
+
+            assert all(self._maxes[pos] == self._lists[pos][-1]
+                       for pos in range(len(self._maxes)))
+
+            # Check load level is less than _twice.
+
+            assert all(len(sublist) <= self._twice for sublist in self._lists)
+
+            # Check load level is greater than _half for all
+            # but the last sublist.
+
+            assert all(len(self._lists[pos]) >= self._half
+                       for pos in range(0, len(self._lists) - 1))
+
+            # Check length.
+
+            assert self._len == sum(len(sublist) for sublist in self._lists)
+
+            # Check index.
+
+            if len(self._index):
+                assert len(self._index) == self._offset + len(self._lists)
+                assert self._len == self._index[0]
+
+                def test_offset_pos(pos):
+                    from_index = self._index[self._offset + pos]
+                    return from_index == len(self._lists[pos])
+
+                assert all(test_offset_pos(pos)
+                           for pos in range(len(self._lists)))
+
+                for pos in range(self._offset):
+                    child = (pos << 1) + 1
+                    if self._index[pos] == 0:
+                        assert child >= len(self._index)
+                    elif child + 1 == len(self._index):
+                        assert self._index[pos] == self._index[child]
+                    else:
+                        child_sum = self._index[child] + self._index[child + 1]
+                        assert self._index[pos] == child_sum
+
+        except:
+            import sys
+            import traceback
+
+            traceback.print_exc(file=sys.stdout)
+
+            print('len', self._len)
+            print('load', self._load, self._half, self._twice)
+            print('offset', self._offset)
+            print('len_index', len(self._index))
+            print('index', self._index)
+            print('len_maxes', len(self._maxes))
+            print('maxes', self._maxes)
+            print('len_lists', len(self._lists))
+            print('lists', self._lists)
+
+            raise
diff --git a/src/sortedcontainers/sortedlistwithkey.py b/src/sortedcontainers/sortedlistwithkey.py
new file mode 100755
index 0000000..688cf1f
--- /dev/null
+++ b/src/sortedcontainers/sortedlistwithkey.py
@@ -0,0 +1,1331 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted list implementation.
+
+from __future__ import print_function
+from sys import hexversion
+
+from .sortedlist import recursive_repr
+from bisect import bisect_left, bisect_right, insort
+from itertools import chain, repeat, starmap
+from collections import MutableSequence
+from operator import iadd, add
+from functools import wraps
+from math import log
+
+if hexversion < 0x03000000:
+    from itertools import izip as zip
+    from itertools import imap as map
+else:
+    from functools import reduce
+
+def identity(value):
+    return value
+
+class SortedListWithKey(MutableSequence):
+    """
+    SortedList provides most of the same methods as a list but keeps the items
+    in sorted order.
+    """
+
+    def __init__(self, iterable=None, key=identity, load=1000):
+        """
+        SortedList provides most of the same methods as a list but keeps the
+        items in sorted order.
+
+        An optional *iterable* provides an initial series of items to populate
+        the SortedList.
+
+        An optional *load* specifies the load-factor of the list. The default
+        load factor of '1000' works well for lists from tens to tens of millions
+        of elements.  Good practice is to use a value that is the cube root of
+        the list size.  With billions of elements, the best load factor depends
+        on your usage.  It's best to leave the load factor at the default until
+        you start benchmarking.
+        """
+        self._len, self._maxes, self._lists, self._keys, self._index = 0, [], [], [], []
+        self._key, self._load, self._twice, self._half = key, load, load * 2, load >> 1
+        self._offset = 0
+
+        if iterable is not None:
+            self.update(iterable)
+
+    def clear(self):
+        """Remove all the elements from the list."""
+        self._len = 0
+        del self._maxes[:]
+        del self._lists[:]
+        del self._keys[:]
+        del self._index[:]
+
+    def add(self, val):
+        """Add the element *val* to the list."""
+        _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+
+        key = self._key(val)
+
+        if _maxes:
+            pos = bisect_right(_maxes, key)
+
+            if pos == len(_maxes):
+                pos -= 1
+                _maxes[pos] = key
+                _keys[pos].append(key)
+                _lists[pos].append(val)
+            else:
+                idx = bisect_right(_keys[pos], key)
+                _keys[pos].insert(idx, key)
+                _lists[pos].insert(idx, val)
+
+            self._expand(pos)
+        else:
+            _maxes.append(key)
+            _keys.append([key])
+            _lists.append([val])
+
+        self._len += 1
+
+    def _expand(self, pos):
+        """
+        Splits sublists that are more than double the load level.
+
+        Updates the index when the sublist length is less than double the load
+        level. This requires incrementing the nodes in a traversal from the leaf
+        node to the root. For an example traversal see self._loc.
+        """
+        _lists, _keys, _index = self._lists, self._keys, self._index
+
+        if len(_keys[pos]) > self._twice:
+            _maxes, _load = self._maxes, self._load
+
+            half = _keys[pos][_load:]
+            half_list = _lists[pos][_load:]
+            del _keys[pos][_load:]
+            del _lists[pos][_load:]
+            _maxes[pos] = _keys[pos][-1]
+
+            _maxes.insert(pos + 1, half[-1])
+            _keys.insert(pos + 1, half)
+            _lists.insert(pos + 1, half_list)
+
+            del _index[:]
+        else:
+            if len(_index) > 0:
+                child = self._offset + pos
+                while child > 0:
+                    _index[child] += 1
+                    child = (child - 1) >> 1
+                _index[0] += 1
+
+    def update(self, iterable):
+        """Update the list by adding all elements from *iterable*."""
+        _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+        values = sorted(iterable, key=self._key)
+
+        if _maxes:
+            if len(values) * 4 >= self._len:
+                values.extend(chain.from_iterable(_lists))
+                values.sort(key=self._key)
+                self.clear()
+            else:
+                _add = self.add
+                for val in values:
+                    _add(val)
+                return
+
+        _load, _index = self._load, self._index
+        _lists.extend(values[pos:(pos + _load)]
+                      for pos in range(0, len(values), _load))
+        _keys.extend(list(map(self._key, _list)) for _list in _lists)
+        _maxes.extend(sublist[-1] for sublist in _keys)
+        self._len = len(values)
+        del _index[:]
+
+    def __contains__(self, val):
+        """Return True if and only if *val* is an element in the list."""
+        _maxes = self._maxes
+
+        if not _maxes:
+            return False
+
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            return False
+
+        _keys = self._keys
+        _lists = self._lists
+
+        idx = bisect_left(_keys[pos], key)
+
+        len_keys = len(_keys)
+        len_sublist = len(_keys[pos])
+
+        while True:
+            if _keys[pos][idx] != key:
+                return False
+            if _lists[pos][idx] == val:
+                return True
+            idx += 1
+            if idx == len_sublist:
+                pos += 1
+                if pos == len_keys:
+                    return False
+                len_sublist = len(_keys[pos])
+                idx = 0
+
+    def discard(self, val):
+        """
+        Remove the first occurrence of *val*.
+
+        If *val* is not a member, does nothing.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return
+
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            return
+
+        _keys = self._keys
+        _lists = self._lists
+        idx = bisect_left(_keys[pos], key)
+
+        len_keys = len(_keys)
+        len_sublist = len(_keys[pos])
+
+        while True:
+            if _keys[pos][idx] != key:
+                return
+            if _lists[pos][idx] == val:
+                self._delete(pos, idx)
+                return
+            idx += 1
+            if idx == len_sublist:
+                pos += 1
+                if pos == len_keys:
+                    return
+                len_sublist = len(_keys[pos])
+                idx = 0
+
+    def remove(self, val):
+        """
+        Remove first occurrence of *val*.
+
+        Raises ValueError if *val* is not present.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            raise ValueError('{0} not in list'.format(repr(val)))
+
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            raise ValueError('{0} not in list'.format(repr(val)))
+
+        _keys = self._keys
+        _lists = self._lists
+        idx = bisect_left(_keys[pos], key)
+
+        len_keys = len(_keys)
+        len_sublist = len(_keys[pos])
+
+        while True:
+            if _keys[pos][idx] != key:
+                raise ValueError('{0} not in list'.format(repr(val)))
+            if _lists[pos][idx] == val:
+                self._delete(pos, idx)
+                return
+            idx += 1
+            if idx == len_sublist:
+                pos += 1
+                if pos == len_keys:
+                    raise ValueError('{0} not in list'.format(repr(val)))
+                len_sublist = len(_keys[pos])
+                idx = 0
+
+    def _delete(self, pos, idx):
+        """
+        Delete the item at the given (pos, idx).
+
+        Combines lists that are less than half the load level.
+
+        Updates the index when the sublist length is more than half the load
+        level. This requires decrementing the nodes in a traversal from the leaf
+        node to the root. For an example traversal see self._loc.
+        """
+        _maxes, _lists, _keys, _index = self._maxes, self._lists, self._keys, self._index
+
+        keys_pos = _keys[pos]
+        lists_pos = _lists[pos]
+
+        del keys_pos[idx]
+        del lists_pos[idx]
+        self._len -= 1
+
+        len_keys_pos = len(keys_pos)
+
+        if len_keys_pos > self._half:
+
+            _maxes[pos] = keys_pos[-1]
+
+            if len(_index) > 0:
+                child = self._offset + pos
+                while child > 0:
+                    _index[child] -= 1
+                    child = (child - 1) >> 1
+                _index[0] -= 1
+
+        elif len(_keys) > 1:
+
+            if not pos:
+                pos += 1
+
+            prev = pos - 1
+            _keys[prev].extend(_keys[pos])
+            _lists[prev].extend(_lists[pos])
+            _maxes[prev] = _keys[prev][-1]
+
+            del _keys[pos]
+            del _lists[pos]
+            del _maxes[pos]
+            del _index[:]
+
+            self._expand(prev)
+
+        elif len_keys_pos:
+
+            _maxes[pos] = keys_pos[-1]
+
+        else:
+
+            del _keys[pos]
+            del _lists[pos]
+            del _maxes[pos]
+            del _index[:]
+
+    def _loc(self, pos, idx):
+        """Convert an index pair (alpha, beta) into a single index that corresponds to
+        the position of the value in the sorted list.
+
+        Most queries require the index be built. Details of the index are
+        described in self._build_index.
+
+        Indexing requires traversing the tree from a leaf node to the root. The
+        parent of each node is easily computable at (pos - 1) // 2.
+
+        Left-child nodes are always at odd indices and right-child nodes are
+        always at even indices.
+
+        When traversing up from a right-child node, increment the total by the
+        left-child node.
+
+        The final index is the sum from traversal and the index in the sublist.
+
+        For example, using the index from self._build_index:
+
+        _index = 14 5 9 3 2 4 5
+        _offset = 3
+
+        Tree:
+
+                 14
+              5      9
+            3   2  4   5
+
+        Converting index pair (2, 3) into a single index involves iterating like
+        so:
+
+        1. Starting at the leaf node: offset + alpha = 3 + 2 = 5. We identify
+           the node as a left-child node. At such nodes, we simply traverse to
+           the parent.
+
+        2. At node 9, position 2, we recognize the node as a right-child node
+           and accumulate the left-child in our total. Total is now 5 and we
+           traverse to the parent at position 0.
+
+        3. Iteration ends at the root.
+
+        Computing the index is the sum of the total and beta: 5 + 3 = 8.
+        """
+        if not pos:
+            return idx
+
+        _index = self._index
+
+        if not len(_index):
+            self._build_index()
+
+        total = 0
+
+        # Increment pos to point in the index to len(self._lists[pos]).
+
+        pos += self._offset
+
+        # Iterate until reaching the root of the index tree at pos = 0.
+
+        while pos:
+
+            # Right-child nodes are at odd indices. At such indices
+            # account the total below the left child node.
+
+            if not (pos & 1):
+                total += _index[pos - 1]
+
+            # Advance pos to the parent node.
+
+            pos = (pos - 1) >> 1
+
+        return total + idx
+
+    def _pos(self, idx):
+        """Convert an index into a pair (alpha, beta) that can be used to access
+        the corresponding _lists[alpha][beta] position.
+
+        Most queries require the index be built. Details of the index are
+        described in self._build_index.
+
+        Indexing requires traversing the tree to a leaf node. Each node has
+        two children which are easily computable. Given an index, pos, the
+        left-child is at pos * 2 + 1 and the right-child is at pos * 2 + 2.
+
+        When the index is less than the left-child, traversal moves to the
+        left sub-tree. Otherwise, the index is decremented by the left-child
+        and traversal moves to the right sub-tree.
+
+        At a child node, the indexing pair is computed from the relative
+        position of the child node as compared with the offset and the remaining
+        index.
+
+        For example, using the index from self._build_index:
+
+        _index = 14 5 9 3 2 4 5
+        _offset = 3
+
+        Tree:
+
+                 14
+              5      9
+            3   2  4   5
+
+        Indexing position 8 involves iterating like so:
+
+        1. Starting at the root, position 0, 8 is compared with the left-child
+           node (5) which it is greater than. When greater the index is
+           decremented and the position is updated to the right child node.
+
+        2. At node 9 with index 3, we again compare the index to the left-child
+           node with value 4. Because the index is the less than the left-child
+           node, we simply traverse to the left.
+
+        3. At node 4 with index 3, we recognize that we are at a leaf node and
+           stop iterating.
+
+        4. To compute the sublist index, we subtract the offset from the index
+           of the leaf node: 5 - 3 = 2. To compute the index in the sublist, we
+           simply use the index remaining from iteration. In this case, 3.
+
+        The final index pair from our example is (2, 3) which corresponds to
+        index 8 in the sorted list.
+        """
+        _len, _lists = self._len, self._lists
+
+        if idx < 0:
+            last_len = len(_lists[-1])
+            if (-idx) <= last_len:
+                return len(_lists) - 1, last_len + idx
+            idx += _len
+            if idx < 0:
+                raise IndexError('list index out of range')
+        elif idx >= _len:
+            raise IndexError('list index out of range')
+
+        if idx < len(_lists[0]):
+            return 0, idx
+
+        _index = self._index
+
+        if not len(_index):
+            self._build_index()
+
+        pos = 0
+        len_index = len(_index)
+        child = (pos << 1) + 1
+
+        while child < len_index:
+            index_child = _index[child]
+
+            if idx < index_child:
+                pos = child
+            else:
+                idx -= index_child
+                pos = child + 1
+
+            child = (pos << 1) + 1
+
+        return (pos - self._offset, idx)
+
+    def _build_index(self):
+        """Build an index for indexing the sorted list.
+
+        Indexes are represented as binary trees in a dense array notation
+        similar to a binary heap.
+
+        For example, given a _lists representation storing integers:
+
+        [0]: 1 2 3
+        [1]: 4 5
+        [2]: 6 7 8 9
+        [3]: 10 11 12 13 14
+
+        The first transformation maps the sub-lists by their length. The
+        first row of the index is the length of the sub-lists.
+
+        [0]: 3 2 4 5
+
+        Each row after that is the sum of consecutive pairs of the previous row:
+
+        [1]: 5 9
+        [2]: 14
+
+        Finally, the index is built by concatenating these lists together:
+
+        _index = 14 5 9 3 2 4 5
+
+        An offset storing the start of the first row is also stored:
+
+        _offset = 3
+
+        When built, the index can be used for efficient indexing into the list.
+        See the comment and notes on self._pos for details.
+        """
+        row0 = list(map(len, self._lists))
+
+        if len(row0) == 1:
+            self._index[:] = row0
+            self._offset = 0
+            return
+
+        head = iter(row0)
+        tail = iter(head)
+        row1 = list(starmap(add, zip(head, tail)))
+
+        if len(row0) & 1:
+            row1.append(row0[-1])
+
+        if len(row1) == 1:
+            self._index[:] = row1 + row0
+            self._offset = 1
+            return
+
+        size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
+        row1.extend(repeat(0, size - len(row1)))
+        tree = [row0, row1]
+
+        while len(tree[-1]) > 1:
+            head = iter(tree[-1])
+            tail = iter(head)
+            row = list(starmap(add, zip(head, tail)))
+            tree.append(row)
+
+        reduce(iadd, reversed(tree), self._index)
+        self._offset = size * 2 - 1
+
+    def _slice(self, slc):
+        start, stop, step = slc.start, slc.stop, slc.step
+
+        if step == 0:
+            raise ValueError('slice step cannot be zero')
+
+        # Set defaults for missing values.
+
+        if step is None:
+            step = 1
+
+        if step > 0:
+            if start is None:
+                start = 0
+
+            if stop is None:
+                stop = len(self)
+            elif stop < 0:
+                stop += len(self)
+        else:
+            if start is None:
+                start = len(self) - 1
+
+            if stop is None:
+                stop = -1
+            elif stop < 0:
+                stop += len(self)
+
+        if start < 0:
+            start += len(self)
+
+        # Fix indices that are too big or too small.
+        # Slice notation is surprisingly permissive
+        # where normal indexing would raise IndexError.
+
+        if step > 0:
+            if start < 0:
+                start = 0
+            elif start > len(self):
+                start = len(self)
+
+            if stop < 0:
+                stop = 0
+            elif stop > len(self):
+                stop = len(self)
+        else:
+            if start < 0:
+                start = -1
+            elif start >= len(self):
+                start = len(self) - 1
+
+            if stop < 0:
+                stop = -1
+            elif stop > len(self):
+                stop = len(self)
+
+        return start, stop, step
+
+    def __delitem__(self, idx):
+        """Remove the element at *idx*. Supports slicing."""
+        if isinstance(idx, slice):
+            start, stop, step = self._slice(idx)
+
+            if ((step == 1) and (start < stop)
+                    and ((stop - start) * 8 >= self._len)):
+
+                values = self[:start]
+                if stop < self._len:
+                    values += self[stop:]
+                self.clear()
+                self.update(values)
+                return
+
+            indices = range(start, stop, step)
+
+            # Delete items from greatest index to least so
+            # that the indices remain valid throughout iteration.
+
+            if step > 0:
+                indices = reversed(indices)
+
+            _pos, _delete = self._pos, self._delete
+
+            for index in indices:
+                pos, idx = _pos(index)
+                _delete(pos, idx)
+        else:
+            pos, idx = self._pos(idx)
+            self._delete(pos, idx)
+
+    def __getitem__(self, idx):
+        """Return the element at *idx*. Supports slicing."""
+        _lists = self._lists
+
+        if isinstance(idx, slice):
+            start, stop, step = self._slice(idx)
+
+            if step == 1 and start < stop:
+                if start == 0 and stop == self._len:
+                    return self.as_list()
+
+                start_pos, start_idx = self._pos(start)
+
+                if stop == self._len:
+                    stop_pos = len(_lists) - 1
+                    stop_idx = len(_lists[stop_pos])
+                else:
+                    stop_pos, stop_idx = self._pos(stop)
+
+                if start_pos == stop_pos:
+                    return _lists[start_pos][start_idx:stop_idx]
+
+                prefix = _lists[start_pos][start_idx:]
+                middle = _lists[(start_pos + 1):stop_pos]
+                result = reduce(iadd, middle, prefix)
+                result += _lists[stop_pos][:stop_idx]
+
+                return result
+
+            if step == -1 and start > stop:
+                result = self[(stop + 1):(start + 1)]
+                result.reverse()
+                return result
+
+            # Return a list because a negative step could
+            # reverse the order of the items and this could
+            # be the desired behavior.
+
+            indices = range(start, stop, step)
+            return list(self[index] for index in indices)
+        else:
+            pos, idx = self._pos(idx)
+            return _lists[pos][idx]
+
+    def _check_order(self, idx, key, val):
+        _keys, _len = self._keys, self._len
+
+        pos, loc = self._pos(idx)
+
+        if idx < 0:
+            idx += _len
+
+        # Check that the inserted value is not less than the
+        # previous value.
+
+        if idx > 0:
+            idx_prev = loc - 1
+            pos_prev = pos
+
+            if idx_prev < 0:
+                pos_prev -= 1
+                idx_prev = len(_keys[pos_prev]) - 1
+
+            if _keys[pos_prev][idx_prev] > key:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+                raise ValueError(msg)
+
+        # Check that the inserted value is not greater than
+        # the previous value.
+
+        if idx < (_len - 1):
+            idx_next = loc + 1
+            pos_next = pos
+
+            if idx_next == len(_keys[pos_next]):
+                pos_next += 1
+                idx_next = 0
+
+            if _keys[pos_next][idx_next] < key:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+                raise ValueError(msg)
+
+    def __setitem__(self, index, value):
+        """
+        Replace the item at position *index* with *value*.
+
+        Supports slice notation. Raises a :exc:`ValueError` if the sort order
+        would be violated. When used with a slice and iterable, the
+        :exc:`ValueError` is raised before the list is mutated if the sort order
+        would be violated by the operation.
+        """
+        _maxes, _lists, _keys, _pos = self._maxes, self._lists, self._keys, self._pos
+        _check_order = self._check_order
+
+        if isinstance(index, slice):
+            start, stop, step = self._slice(index)
+            indices = range(start, stop, step)
+
+            if step != 1:
+                if not hasattr(value, '__len__'):
+                    value = list(value)
+
+                indices = list(indices)
+
+                if len(value) != len(indices):
+                    raise ValueError(
+                        'attempt to assign sequence of size {0}'
+                        ' to extended slice of size {1}'
+                        .format(len(value), len(indices)))
+
+                # Keep a log of values that are set so that we can
+                # roll back changes if ordering is violated.
+
+                log = []
+                _append = log.append
+
+                for idx, val in zip(indices, value):
+                    pos, loc = _pos(idx)
+                    key = self._key(val)
+                    _append((idx, _keys[pos][loc], key, _lists[pos][loc], val))
+                    _keys[pos][loc] = key
+                    _lists[pos][loc] = val
+                    if len(_keys[pos]) == (loc + 1):
+                        _maxes[pos] = key
+
+                try:
+                    # Validate ordering of new values.
+
+                    for idx, oldkey, newkey, oldval, newval in log:
+                        _check_order(idx, newkey, newval)
+
+                except ValueError:
+
+                    # Roll back changes from log.
+
+                    for idx, oldkey, newkey, oldval, newval in log:
+                        pos, loc = _pos(idx)
+                        _keys[pos][loc] = oldkey
+                        _lists[pos][loc] = oldval
+                        if len(_keys[pos]) == (loc + 1):
+                            _maxes[pos] = oldkey
+
+                    raise
+            else:
+                # Test ordering using indexing. If the value given
+                # doesn't support getitem, convert it to a list.
+
+                if not hasattr(value, '__getitem__'):
+                    value = list(value)
+
+                # Check that the given values are ordered properly.
+
+                keys = list(map(self._key, value))
+                ordered = all(keys[pos - 1] <= keys[pos]
+                              for pos in range(1, len(keys)))
+
+                if not ordered:
+                    raise ValueError('given sequence not in sort order')
+
+                # Check ordering in context of sorted list.
+
+                if not start or not len(value):
+                    # Nothing to check on the lhs.
+                    pass
+                else:
+                    pos, loc = _pos(start - 1)
+                    if _keys[pos][loc] > keys[0]:
+                        msg = '{0} not in sort order at index {1}'.format(repr(value[0]), start)
+                        raise ValueError(msg)
+
+                if stop == len(self) or not len(value):
+                    # Nothing to check on the rhs.
+                    pass
+                else:
+                    # "stop" is exclusive so we don't need
+                    # to add one for the index.
+                    pos, loc = _pos(stop)
+                    if _keys[pos][loc] < keys[-1]:
+                        msg = '{0} not in sort order at index {1}'.format(repr(value[-1]), stop)
+                        raise ValueError(msg)
+
+                # Delete the existing values.
+
+                del self[index]
+
+                # Insert the new values.
+
+                _insert = self.insert
+                for idx, val in enumerate(value):
+                    _insert(start + idx, val)
+        else:
+            pos, loc = _pos(index)
+            key = self._key(value)
+            _check_order(index, key, value)
+            _keys[pos][loc] = key
+            _lists[pos][loc] = value
+            if len(_lists[pos]) == (loc + 1):
+                _maxes[pos] = key
+
+    def __iter__(self):
+        """Create an iterator over the list."""
+        return chain.from_iterable(self._lists)
+
+    def __reversed__(self):
+        """Create an iterator to traverse the list in reverse."""
+        return chain.from_iterable(map(reversed, reversed(self._lists)))
+
+    def __len__(self):
+        """Return the number of elements in the list."""
+        return self._len
+
+    def bisect_left(self, val):
+        """
+        Similar to the *bisect* module in the standard library, this returns an
+        appropriate index to insert *val*. If *val* is already present, the
+        insertion point will be before (to the left of) any existing entries.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            return self._len
+
+        idx = bisect_left(self._keys[pos], key)
+
+        return self._loc(pos, idx)
+
+    def bisect_right(self, val):
+        """
+        Same as *bisect_left*, but if *val* is already present, the insertion
+        point will be after (to the right of) any existing entries.
+        """
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        key = self._key(val)
+        pos = bisect_right(_maxes, key)
+
+        if pos == len(_maxes):
+            return self._len
+
+        idx = bisect_right(self._keys[pos], key)
+
+        return self._loc(pos, idx)
+
+    bisect = bisect_right
+
+    def count(self, val):
+        """Return the number of occurrences of *val* in the list."""
+        _maxes = self._maxes
+
+        if not _maxes:
+            return 0
+
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            return 0
+
+        _keys = self._keys
+        _lists = self._lists
+
+        idx = bisect_left(_keys[pos], key)
+
+        total = 0
+        len_keys = len(_keys)
+        len_sublist = len(_keys[pos])
+
+        while True:
+            if _keys[pos][idx] != key:
+                return total
+            if _lists[pos][idx] == val:
+                total += 1
+            idx += 1
+            if idx == len_sublist:
+                pos += 1
+                if pos == len_keys:
+                    return total
+                len_sublist = len(_keys[pos])
+                idx = 0
+
+    def copy(self):
+        """Return a shallow copy of the sorted list."""
+        return self.__class__(self, key=self._key, load=self._load)
+
+    __copy__ = copy
+
+    def append(self, val):
+        """
+        Append the element *val* to the list. Raises a ValueError if the *val*
+        would violate the sort order.
+        """
+        _maxes, _lists, _keys = self._maxes, self._lists, self._keys
+
+        key = self._key(val)
+
+        if not _maxes:
+            _maxes.append(key)
+            _keys.append([key])
+            _lists.append([val])
+            self._len = 1
+            return
+
+        pos = len(_keys) - 1
+
+        if key < _keys[pos][-1]:
+            msg = '{0} not in sort order at index {1}'.format(repr(val), self._len)
+            raise ValueError(msg)
+
+        _maxes[pos] = key
+        _keys[pos].append(key)
+        _lists[pos].append(val)
+        self._len += 1
+        self._expand(pos)
+
+    def extend(self, values):
+        """
+        Extend the list by appending all elements from the *values*. Raises a
+        ValueError if the sort order would be violated.
+        """
+        _maxes, _keys, _lists, _load = self._maxes, self._keys, self._lists, self._load
+
+        if not isinstance(values, list):
+            values = list(values)
+
+        keys = list(map(self._key, values))
+
+        if any(keys[pos - 1] > keys[pos]
+               for pos in range(1, len(keys))):
+            raise ValueError('given sequence not in sort order')
+
+        offset = 0
+
+        if _maxes:
+            if keys[0] < _keys[-1][-1]:
+                msg = '{0} not in sort order at index {1}'.format(repr(values[0]), self._len)
+                raise ValueError(msg)
+
+            if len(_keys[-1]) < self._half:
+                _lists[-1].extend(values[:_load])
+                _keys[-1].extend(keys[:_load])
+                _maxes[-1] = _keys[-1][-1]
+                offset = _load
+
+        len_keys = len(_keys)
+
+        for idx in range(offset, len(keys), _load):
+            _lists.append(values[idx:(idx + _load)])
+            _keys.append(keys[idx:(idx + _load)])
+            _maxes.append(_keys[-1][-1])
+
+        _index = self._index
+
+        if len_keys == len(_keys):
+            len_index = len(_index)
+            if len_index > 0:
+                len_values = len(values)
+                child = len_index - 1
+                while child:
+                    _index[child] += len_values
+                    child = (child - 1) >> 1
+                _index[0] += len_values
+        else:
+            del _index[:]
+
+        self._len += len(values)
+
+    def insert(self, idx, val):
+        """
+        Insert the element *val* into the list at *idx*. Raises a ValueError if
+        the *val* at *idx* would violate the sort order.
+        """
+        _maxes, _lists, _keys, _len = self._maxes, self._lists, self._keys, self._len
+
+        if idx < 0:
+            idx += _len
+        if idx < 0:
+            idx = 0
+        if idx > _len:
+            idx = _len
+
+        key = self._key(val)
+
+        if not _maxes:
+            # The idx must be zero by the inequalities above.
+            _maxes.append(key)
+            _lists.append([val])
+            _keys.append([key])
+            self._len = 1
+            return
+
+        if not idx:
+            if key > _keys[0][0]:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), 0)
+                raise ValueError(msg)
+            else:
+                _keys[0].insert(0, key)
+                _lists[0].insert(0, val)
+                self._expand(0)
+                self._len += 1
+                return
+
+        if idx == _len:
+            pos = len(_keys) - 1
+            if _keys[pos][-1] > key:
+                msg = '{0} not in sort order at index {1}'.format(repr(val), _len)
+                raise ValueError(msg)
+            else:
+                _keys[pos].append(key)
+                _lists[pos].append(val)
+                _maxes[pos] = _keys[pos][-1]
+                self._expand(pos)
+                self._len += 1
+                return
+
+        pos, idx = self._pos(idx)
+        idx_before = idx - 1
+        if idx_before < 0:
+            pos_before = pos - 1
+            idx_before = len(_keys[pos_before]) - 1
+        else:
+            pos_before = pos
+
+        before = _keys[pos_before][idx_before]
+        if before <= key <= _keys[pos][idx]:
+            _lists[pos].insert(idx, val)
+            _keys[pos].insert(idx, key)
+            self._expand(pos)
+            self._len += 1
+        else:
+            msg = '{0} not in sort order at index {1}'.format(repr(val), idx)
+            raise ValueError(msg)
+
+    def pop(self, idx=-1):
+        """
+        Remove and return item at *idx* (default last).  Raises IndexError if
+        list is empty or index is out of range.  Negative indices are supported,
+        as for slice indices.
+        """
+        if (idx < 0 and -idx > self._len) or (idx >= self._len):
+            raise IndexError('pop index out of range')
+
+        pos, idx = self._pos(idx)
+        val = self._lists[pos][idx]
+        self._delete(pos, idx)
+
+        return val
+
+    def index(self, val, start=None, stop=None):
+        """
+        Return the smallest *k* such that L[k] == val and i <= k < j`.  Raises
+        ValueError if *val* is not present.  *stop* defaults to the end of the
+        list. *start* defaults to the beginning. Negative indices are supported,
+        as for slice indices.
+        """
+        _len, _maxes = self._len, self._maxes
+
+        if not _maxes:
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        if start is None:
+            start = 0
+        if start < 0:
+            start += _len
+        if start < 0:
+            start = 0
+
+        if stop is None:
+            stop = _len
+        if stop < 0:
+            stop += _len
+        if stop > _len:
+            stop = _len
+
+        if stop <= start:
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        stop -= 1
+        key = self._key(val)
+        pos = bisect_left(_maxes, key)
+
+        if pos == len(_maxes):
+            raise ValueError('{0} is not in list'.format(repr(val)))
+
+        _keys = self._keys
+        _lists = self._lists
+
+        idx = bisect_left(_keys[pos], key)
+
+        len_keys = len(_keys)
+        len_sublist = len(_keys[pos])
+
+        while True:
+            if _keys[pos][idx] != key:
+                raise ValueError('{0} is not in list'.format(repr(val)))
+            if _lists[pos][idx] == val:
+                loc = self._loc(pos, idx)
+                if start <= loc <= stop:
+                    return loc
+                elif loc > stop:
+                    break
+            idx += 1
+            if idx == len_sublist:
+                pos += 1
+                if pos == len_keys:
+                    raise ValueError('{0} is not in list'.format(repr(val)))
+                len_sublist = len(_keys[pos])
+                idx = 0
+
+        raise ValueError('{0} is not in list'.format(repr(val)))
+
+    def as_list(self):
+        """Very efficiently convert the SortedList to a list."""
+        return reduce(iadd, self._lists, [])
+
+    def __add__(self, that):
+        """
+        Return a new sorted list containing all the elements in *self* and
+        *that*. Elements in *that* do not need to be properly ordered with
+        respect to *self*.
+        """
+        values = self.as_list()
+        values.extend(that)
+        return self.__class__(values, key=self._key, load=self._load)
+
+    def __iadd__(self, that):
+        """
+        Update *self* to include all values in *that*. Elements in *that* do not
+        need to be properly ordered with respect to *self*.
+        """
+        self.update(that)
+        return self
+
+    def __mul__(self, that):
+        """
+        Return a new sorted list containing *that* shallow copies of each item
+        in SortedList.
+        """
+        values = self.as_list() * that
+        return self.__class__(values, key=self._key, load=self._load)
+
+    def __imul__(self, that):
+        """
+        Increase the length of the list by appending *that* shallow copies of
+        each item.
+        """
+        values = self.as_list() * that
+        self.clear()
+        self.update(values)
+        return self
+
+    def __eq__(self, that):
+        """Compare two Sequences for equality."""
+        return ((self._len == len(that))
+                and all(lhs == rhs for lhs, rhs in zip(self, that)))
+
+    def __ne__(self, that):
+        """Compare two Sequences for inequality."""
+        return ((self._len != len(that))
+                or any(lhs != rhs for lhs, rhs in zip(self, that)))
+
+    def __lt__(self, that):
+        """Compare two Sequences for less than."""
+        return ((self._len <= len(that))
+                and all(lhs < rhs for lhs, rhs in zip(self, that)))
+
+    def __le__(self, that):
+        """Compare two Sequences for less than equal."""
+        return ((self._len <= len(that))
+                and all(lhs <= rhs for lhs, rhs in zip(self, that)))
+
+    def __gt__(self, that):
+        """Compare two Sequences for greater than."""
+        return ((self._len >= len(that))
+                and all(lhs > rhs for lhs, rhs in zip(self, that)))
+
+    def __ge__(self, that):
+        """Compare two Sequences for greater than equal."""
+        return ((self._len >= len(that))
+                and all(lhs >= rhs for lhs, rhs in zip(self, that)))
+
+    @recursive_repr
+    def __repr__(self):
+        """Return string representation of SortedListWithKey."""
+        temp = '{0}({1}, key={2}, load={3})'
+        return temp.format(
+            self.__class__.__name__,
+            repr(list(self)),
+            repr(self._key),
+            repr(self._load)
+        )
+
+    def _check(self):
+        try:
+            # Check load parameters.
+
+            assert self._load >= 4
+            assert self._half == (self._load >> 1)
+            assert self._twice == (self._load * 2)
+
+            # Check empty sorted list case.
+
+            if self._maxes == []:
+                assert self._keys == []
+                assert self._lists == []
+                return
+
+            assert len(self._maxes) > 0 and len(self._keys) > 0 and len(self._lists) > 0
+
+            # Check all sublists are sorted.
+
+            assert all(sublist[pos - 1] <= sublist[pos]
+                       for sublist in self._keys
+                       for pos in range(1, len(sublist)))
+
+            # Check beginning/end of sublists are sorted.
+
+            for pos in range(1, len(self._keys)):
+                assert self._keys[pos - 1][-1] <= self._keys[pos][0]
+
+            # Check length of _maxes and _lists match.
+
+            assert len(self._maxes) == len(self._lists) == len(self._keys)
+
+            # Check _keys matches _key mapped to _lists.
+
+            assert all(len(val_list) == len(key_list)
+                       for val_list, key_list in zip(self._lists, self._keys))
+            assert all(self._key(val) == key for val, key in
+                       zip((_val for _val_list in self._lists for _val in _val_list),
+                           (_key for _key_list in self._keys for _key in _key_list)))
+
+            # Check _maxes is a map of _keys.
+
+            assert all(self._maxes[pos] == self._keys[pos][-1]
+                       for pos in range(len(self._maxes)))
+
+            # Check load level is less than _twice.
+
+            assert all(len(sublist) <= self._twice for sublist in self._lists)
+
+            # Check load level is greater than _half for all
+            # but the last sublist.
+
+            assert all(len(self._lists[pos]) >= self._half
+                       for pos in range(0, len(self._lists) - 1))
+
+            # Check length.
+
+            assert self._len == sum(len(sublist) for sublist in self._lists)
+
+            # Check index.
+
+            if len(self._index):
+                assert len(self._index) == self._offset + len(self._lists)
+                assert self._len == self._index[0]
+
+                def test_offset_pos(pos):
+                    from_index = self._index[self._offset + pos]
+                    return from_index == len(self._lists[pos])
+
+                assert all(test_offset_pos(pos)
+                           for pos in range(len(self._lists)))
+
+                for pos in range(self._offset):
+                    child = (pos << 1) + 1
+                    if self._index[pos] == 0:
+                        assert child >= len(self._index)
+                    elif child + 1 == len(self._index):
+                        assert self._index[pos] == self._index[child]
+                    else:
+                        child_sum = self._index[child] + self._index[child + 1]
+                        assert self._index[pos] == child_sum
+
+        except:
+            import sys
+            import traceback
+
+            traceback.print_exc(file=sys.stdout)
+
+            print('len', self._len)
+            print('load', self._load, self._half, self._twice)
+            print('offset', self._offset)
+            print('len_index', len(self._index))
+            print('index', self._index)
+            print('len_maxes', len(self._maxes))
+            print('maxes', self._maxes)
+            print('len_keys', len(self._keys))
+            print('keys', self._keys)
+            print('len_lists', len(self._lists))
+            print('lists', self._lists)
+
+            raise
diff --git a/src/sortedcontainers/sortedset.py b/src/sortedcontainers/sortedset.py
new file mode 100755
index 0000000..d9ab42c
--- /dev/null
+++ b/src/sortedcontainers/sortedset.py
@@ -0,0 +1,294 @@
+# -*- coding: utf-8 -*-
+#
+# Sorted set implementation.
+
+from .sortedlist import SortedList, recursive_repr
+from .sortedlistwithkey import SortedListWithKey
+from collections import Set, MutableSet, Sequence
+from itertools import chain
+import operator as op
+
+class SortedSet(MutableSet, Sequence):
+    """
+    A `SortedSet` provides the same methods as a `set`.  Additionally, a
+    `SortedSet` maintains its items in sorted order, allowing the `SortedSet` to
+    be indexed.
+
+    Unlike a `set`, a `SortedSet` requires items be hashable and comparable.
+    """
+    def __init__(self, iterable=None, key=None, load=1000, _set=None):
+        """
+        A `SortedSet` provides the same methods as a `set`.  Additionally, a
+        `SortedSet` maintains its items in sorted order, allowing the
+        `SortedSet` to be indexed.
+
+        An optional *iterable* provides an initial series of items to populate
+        the `SortedSet`.
+
+        An optional *key* argument defines a callable that, like the `key`
+        argument to Python's `sorted` function, extracts a comparison key from
+        each set item. If no function is specified, the default compares the
+        set items directly.
+
+        An optional *load* specifies the load-factor of the set. The default
+        load factor of '1000' works well for sets from tens to tens of millions
+        of elements.  Good practice is to use a value that is the cube root of
+        the set size.  With billions of elements, the best load factor depends
+        on your usage.  It's best to leave the load factor at the default until
+        you start benchmarking.
+        """
+        self._key = key
+        self._load = load
+
+        self._set = set() if _set is None else _set
+
+        _set = self._set
+        self.isdisjoint = _set.isdisjoint
+        self.issubset = _set.issubset
+        self.issuperset = _set.issuperset
+
+        if key is None:
+            self._list = SortedList(self._set, load=load)
+        else:
+            self._list = SortedListWithKey(self._set, key=key, load=load)
+
+        _list = self._list
+        self.bisect_left = _list.bisect_left
+        self.bisect = _list.bisect
+        self.bisect_right = _list.bisect_right
+        self.index = _list.index
+
+        if iterable is not None:
+            self.update(iterable)
+
+    def __contains__(self, value):
+        """Return True if and only if *value* is an element in the set."""
+        return (value in self._set)
+
+    def __getitem__(self, index):
+        """
+        Return the element at position *index*.
+
+        Supports slice notation and negative indexes.
+        """
+        return self._list[index]
+
+    def __delitem__(self, index):
+        """
+        Remove the element at position *index*.
+
+        Supports slice notation and negative indexes.
+        """
+        _list = self._list
+        if isinstance(index, slice):
+            values = _list[index]
+            self._set.difference_update(values)
+        else:
+            value = _list[index]
+            self._set.remove(value)
+        del _list[index]
+
+    def _make_cmp(set_op, doc):
+        def comparer(self, that):
+            if isinstance(that, SortedSet):
+                return set_op(self._set, that._set)
+            elif isinstance(that, Set):
+                return set_op(self._set, that)
+            else:
+                raise TypeError('can only compare to a Set')
+
+        comparer.__name__ = '__{0}__'.format(set_op.__name__)
+        comparer.__doc__ = 'Return True if and only if ' + doc
+
+        return comparer
+
+    __eq__ = _make_cmp(op.eq, 'self and *that* are equal sets.')
+    __ne__ = _make_cmp(op.ne, 'self and *that* are inequal sets.')
+    __lt__ = _make_cmp(op.lt, 'self is a proper subset of *that*.')
+    __gt__ = _make_cmp(op.gt, 'self is a proper superset of *that*.')
+    __le__ = _make_cmp(op.le, 'self is a subset of *that*.')
+    __ge__ = _make_cmp(op.ge, 'self is a superset of *that*.')
+
+    def __len__(self):
+        """Return the number of elements in the set."""
+        return len(self._set)
+
+    def __iter__(self):
+        """
+        Return an iterator over the SortedSet. Elements are iterated over
+        in their sorted order.
+        """
+        return iter(self._list)
+
+    def __reversed__(self):
+        """
+        Return an iterator over the SortedSet. Elements are iterated over
+        in their reversed sorted order.
+        """
+        return reversed(self._list)
+
+    def add(self, value):
+        """Add the element *value* to the set."""
+        if value not in self._set:
+            self._set.add(value)
+            self._list.add(value)
+
+    def clear(self):
+        """Remove all elements from the set."""
+        self._set.clear()
+        self._list.clear()
+
+    def copy(self):
+        """Create a shallow copy of the sorted set."""
+        return self.__class__(key=self._key, load=self._load, _set=set(self._set))
+
+    __copy__ = copy
+
+    def count(self, value):
+        """Return the number of occurrences of *value* in the set."""
+        return 1 if value in self._set else 0
+
+    def discard(self, value):
+        """
+        Remove the first occurrence of *value*.  If *value* is not a member,
+        does nothing.
+        """
+        if value in self._set:
+            self._set.remove(value)
+            self._list.discard(value)
+
+    def pop(self, index=-1):
+        """
+        Remove and return item at *index* (default last).  Raises IndexError if
+        set is empty or index is out of range.  Negative indexes are supported,
+        as for slice indices.
+        """
+        value = self._list.pop(index)
+        self._set.remove(value)
+        return value
+
+    def remove(self, value):
+        """
+        Remove first occurrence of *value*.  Raises ValueError if
+        *value* is not present.
+        """
+        self._set.remove(value)
+        self._list.remove(value)
+
+    def difference(self, *iterables):
+        """
+        Return a new set with elements in the set that are not in the
+        *iterables*.
+        """
+        diff = self._set.difference(*iterables)
+        new_set = self.__class__(key=self._key, load=self._load, _set=diff)
+        return new_set
+
+    __sub__ = difference
+    __rsub__ = __sub__
+
+    def difference_update(self, *iterables):
+        """
+        Update the set, removing elements found in keeping only elements
+        found in any of the *iterables*.
+        """
+        values = set(chain(*iterables))
+        if (4 * len(values)) > len(self):
+            self._set.difference_update(values)
+            self._list.clear()
+            self._list.update(self._set)
+        else:
+            _discard = self.discard
+            for value in values:
+                _discard(value)
+        return self
+
+    __isub__ = difference_update
+
+    def intersection(self, *iterables):
+        """
+        Return a new set with elements common to the set and all *iterables*.
+        """
+        comb = self._set.intersection(*iterables)
+        new_set = self.__class__(key=self._key, load=self._load, _set=comb)
+        return new_set
+
+    __and__ = intersection
+    __rand__ = __and__
+
+    def intersection_update(self, *iterables):
+        """
+        Update the set, keeping only elements found in it and all *iterables*.
+        """
+        self._set.intersection_update(*iterables)
+        self._list.clear()
+        self._list.update(self._set)
+        return self
+
+    __iand__ = intersection_update
+
+    def symmetric_difference(self, that):
+        """
+        Return a new set with elements in either *self* or *that* but not both.
+        """
+        diff = self._set.symmetric_difference(that)
+        new_set = self.__class__(key=self._key, load=self._load, _set=diff)
+        return new_set
+
+    __xor__ = symmetric_difference
+    __rxor__ = __xor__
+
+    def symmetric_difference_update(self, that):
+        """
+        Update the set, keeping only elements found in either *self* or *that*,
+        but not in both.
+        """
+        self._set.symmetric_difference_update(that)
+        self._list.clear()
+        self._list.update(self._set)
+        return self
+
+    __ixor__ = symmetric_difference_update
+
+    def union(self, *iterables):
+        """
+        Return a new SortedSet with elements from the set and all *iterables*.
+        """
+        return self.__class__(chain(iter(self), *iterables), key=self._key, load=self._load)
+
+    __or__ = union
+    __ror__ = __or__
+
+    def update(self, *iterables):
+        """Update the set, adding elements from all *iterables*."""
+        values = set(chain(*iterables))
+        if (4 * len(values)) > len(self):
+            self._set.update(values)
+            self._list.clear()
+            self._list.update(self._set)
+        else:
+            _add = self.add
+            for value in values:
+                _add(value)
+        return self
+
+    __ior__ = union
+
+    def __reduce__(self):
+        return (self.__class__, ((), self._key, self._load, self._set))
+
+    @recursive_repr
+    def __repr__(self):
+        temp = '{0}({1}, key={2}, load={3})'
+        return temp.format(
+            self.__class__.__name__,
+            repr(list(self)),
+            repr(self._key),
+            repr(self._load)
+        )
+
+    def _check(self):
+        self._list._check()
+        assert len(self._set) == len(self._list)
+        _set = self._set
+        assert all(val in _set for val in self._list)
diff --git a/src/tophat-fusion-post b/src/tophat-fusion-post
index 64fb53d..f055ee9 100755
--- a/src/tophat-fusion-post
+++ b/src/tophat-fusion-post
@@ -2865,7 +2865,7 @@ def prog_path(program):
 
 
 def get_version():
-   return "2.1.0"
+   return "2.1.1"
 
 
 def main(argv=None):
diff --git a/src/tophat.py b/src/tophat.py
index 66eb89e..1eed276 100755
--- a/src/tophat.py
+++ b/src/tophat.py
@@ -1288,9 +1288,21 @@ def check_bowtie_index(idx_prefix, is_bowtie2, add="(genome)"):
        os.path.exists(idx_rev_2):
         if os.path.exists(idx_prefix + ".1.ebwt") and os.path.exists(idx_prefix + ".1.bt2"):
             print >> sys.stderr, bwtbotherr
-
         return
     else:
+        if is_bowtie2:
+            idxext="bt2l"
+            bowtie_ver="2 "
+            idx_fwd_1 = idx_prefix + ".1."+idxext
+            idx_fwd_2 = idx_prefix + ".2."+idxext
+            idx_rev_1 = idx_prefix + ".rev.1."+idxext
+            idx_rev_2 = idx_prefix + ".rev.2."+idxext
+            if os.path.exists(idx_fwd_1) and \
+               os.path.exists(idx_fwd_2) and \
+               os.path.exists(idx_rev_1) and \
+               os.path.exists(idx_rev_2):
+                return
+            
         bwtidxerr="Error: Could not find Bowtie "+bowtie_ver+"index files (" + idx_prefix + ".*."+idxext+")"
 
         if is_bowtie2:
@@ -4087,7 +4099,7 @@ def main(argv=None):
 
     except Usage, err:
         th_logp(sys.argv[0].split("/")[-1] + ": " + str(err.msg))
-        th_logp("    for detailed help see http://tophat.cbcb.umd.edu/manual.html")
+        th_logp("    for detailed help see http://ccb.jhu.edu/software/tophat/manual.shtml")
         return 2
 
 
diff --git a/src/tophat2.in b/src/tophat2.in
deleted file mode 100644
index d4f66c3..0000000
--- a/src/tophat2.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-prefix="__PREFIX__"
-pbin=""
-if [[ -z $prefix ]]; then
-   fl=$(readlink $0)
-   if [[ -z $fl ]]; then
-     pbin=$(dirname $0)
-   else
-     pbin=$(dirname $fl)
-   fi
-else
- pbin=$prefix/bin
-fi
-export PATH=$pbin:$PATH
-$pbin/tophat "$@"
diff --git a/src/tophat2.sh b/src/tophat2.sh
new file mode 100644
index 0000000..4ab88ee
--- /dev/null
+++ b/src/tophat2.sh
@@ -0,0 +1,10 @@
+#!/usr/bin/env bash
+pbin=""
+fl=$(readlink $0)
+if [[ -z "$fl" ]]; then
+   pbin=$(dirname $0)
+ else
+   pbin=$(dirname $fl)
+fi
+export PATH=$pbin:$PATH
+$pbin/tophat "$@"
diff --git a/src/tophat_reports.cpp b/src/tophat_reports.cpp
index 99dddd0..50d2165 100644
--- a/src/tophat_reports.cpp
+++ b/src/tophat_reports.cpp
@@ -16,6 +16,9 @@
 
 #include <cassert>
 #include <cstdio>
+#include <boost/thread.hpp>
+#include <boost/random/mersenne_twister.hpp>
+
 #include <cstring>
 #include <vector>
 #include <string>
@@ -30,8 +33,6 @@
 #include <seqan/file.h>
 #include <getopt.h>
 #include <inttypes.h>
-#include <boost/thread.hpp>
-#include <boost/random/mersenne_twister.hpp>
 
 #include "common.h"
 #include "utils.h"
@@ -709,7 +710,7 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
   
   string qname(read_alt_name);
   size_t slash_pos=qname.rfind('/');
-  if (slash_pos!=string::npos)
+  if (slash_pos!=string::npos && qname.length()-slash_pos<4)
     qname.resize(slash_pos);
   //read_alt_name as QNAME
   int flag=atoi(sam_toks[1].c_str()); //FLAG
@@ -798,19 +799,19 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
   tokenize(bwt_buf, "\t", sam_toks);
   string qname(read_alt_name);
   size_t slash_pos=qname.rfind('/');
-  if (slash_pos!=string::npos)
+  if (slash_pos!=string::npos && qname.length()-slash_pos<4)
     qname.resize(slash_pos);
   //read_alt_name as QNAME
   int flag = atoi(sam_toks[1].c_str());
   // 0x0010 (strand of query) is assumed to be set correctly
   // to begin with
-  flag |= 0x0001; //it must be paired
+  flag |= BAM_FPAIRED; //it must be paired
   if (insert_side == FRAG_LEFT)
-    flag |= 0x0040;
+    flag |= BAM_FREAD1;
   else if (insert_side == FRAG_RIGHT)
-    flag |= 0x0080;
+    flag |= BAM_FREAD2;
   if (!primary)
-    flag |= 0x100;
+    flag |= BAM_FSECONDARY;
 
   string ref_name = sam_toks[2], ref_name2 = "";
   char cigar1[1024] = {0}, cigar2[1024] = {0};
@@ -878,9 +879,9 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
     }
     mate_pos = partner->left() + 1;
     if (grade.happy())
-      flag |= 0x0002;
+      flag |= BAM_FPROPER_PAIR;
     if (partner->antisense_align())
-      flag |=  0x0020;
+      flag |=  BAM_FMREVERSE;
 
     if (fusion_alignment)
       {
@@ -914,7 +915,7 @@ bool rewrite_sam_record(GBamWriter& bam_writer,
   }
   else {
     mate_pos = 0;
-    flag |= 0x0008;
+    flag |= BAM_FMUNMAP;
   }
 
   string rg_aux = "";
@@ -2289,12 +2290,12 @@ struct ReportWorker {
 		char map_flags=read_best_alignments(curr_hit_group, best_hits, *gtf_junctions, *junctions,
 				*insertions, *deletions, *fusions, *coverage, final_report, &rng);
 
-		char map_code=0;
+		//char map_code=0;
 		if (map_flags & 4) {
 			(*aligned_counter_multi)++;
 		}
 		if (map_flags & 16) {
-			map_code='M';
+			//map_code='M';
 			(*aligned_counter_xmulti)++;
 		}
 		if (map_flags & 1) (*aligned_counter)++; //acceptable mappings found

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



More information about the debian-med-commit mailing list