[med-svn] [libbiod] 02/03: Inject commits from BioD git - may be creating a new source tarball would be more transparent but for the moment I'm to lazy to write get-orig-source script

Andreas Tille tille at debian.org
Wed Mar 1 12:27:24 UTC 2017


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

tille pushed a commit to branch master
in repository libbiod.

commit cf777ae2df3f3431b720a72cdc2c44a6bc8b6c5e
Author: Andreas Tille <tille at debian.org>
Date:   Wed Mar 1 13:16:09 2017 +0100

    Inject commits from BioD git - may be creating a new source tarball would be more transparent but for the moment I'm to lazy to write get-orig-source script
---
 .../patches/0002-improved-big-endian-support.patch | 554 ++++++++++++++
 ...003-include-the-AH-header-tag-to-SQ-lines.patch |  31 +
 debian/patches/0004-use-consistent-naming-21.patch |  33 +
 .../0005-fixes-lomereiter-sambamba-244.patch       |  59 ++
 debian/patches/0006-switch-to-undead.stream.patch  | 265 +++++++
 debian/patches/0007-std.c-core.stdc.patch          | 175 +++++
 .../0008-fix-deprecations-and-some-warnings.patch  | 187 +++++
 debian/patches/0009-fix-toHash-signature.patch     | 128 ++++
 ...r-.travis.yml-uses-dub-test-and-tests-ldc.patch |  24 +
 ...ix-toJSON-usage-for-new-and-old-compilers.patch |  28 +
 ...CoordinatesAndStrand-to-fix-sorting-test-.patch | 840 +++++++++++++++++++++
 .../patches/0015-Add-Meson-build-definition.patch  | 140 ++++
 debian/patches/series                              |  14 +-
 13 files changed, 2477 insertions(+), 1 deletion(-)

diff --git a/debian/patches/0002-improved-big-endian-support.patch b/debian/patches/0002-improved-big-endian-support.patch
new file mode 100644
index 0000000..9aba730
--- /dev/null
+++ b/debian/patches/0002-improved-big-endian-support.patch
@@ -0,0 +1,554 @@
+From 0b44f2a93ea1843f383c35126b677a2aaebab1f2 Mon Sep 17 00:00:00 2001
+From: Artem Tarasov <artem.tarasov at embl.de>
+Date: Sat, 16 Jul 2016 06:57:56 +0200
+Subject: [PATCH 02/14] improved big endian support
+
+---
+ bio/bam/read.d              |  5 ++--
+ bio/bam/readrange.d         | 34 +++++++++++---------------
+ bio/bam/writer.d            | 21 ++++++----------
+ bio/core/bgzf/compress.d    | 36 ++++++++++-----------------
+ bio/core/bgzf/constants.d   | 34 +++++++++++++-------------
+ bio/core/bgzf/inputstream.d | 59 ++++++++++++++++++++++-----------------------
+ 6 files changed, 84 insertions(+), 105 deletions(-)
+
+diff --git a/bio/bam/read.d b/bio/bam/read.d
+index 3d15881..6e81263 100644
+--- a/bio/bam/read.d
++++ b/bio/bam/read.d
+@@ -71,6 +71,7 @@ import std.exception;
+ import std.system;
+ import std.traits;
+ import std.array;
++import std.bitmanip;
+ import std.c.stdlib;
+ 
+ /**
+@@ -704,7 +705,7 @@ struct BamRead {
+     /*
+       Constructs the struct from memory chunk
+       */
+-    this(ubyte[] chunk) {
++    this(ubyte[] chunk, bool fix_byte_order=true) {
+ 
+         // Switching endianness lazily is not a good idea:
+         //
+@@ -720,7 +721,7 @@ struct BamRead {
+         _chunk = chunk;
+         this._is_slice = true;
+ 
+-        if (std.system.endian != Endian.littleEndian) {
++        if (fix_byte_order && std.system.endian != Endian.littleEndian) {
+             switchChunkEndianness();
+ 
+             // Dealing with tags is the responsibility of TagStorage.
+diff --git a/bio/bam/readrange.d b/bio/bam/readrange.d
+index 1a2ec87..6767a74 100644
+--- a/bio/bam/readrange.d
++++ b/bio/bam/readrange.d
+@@ -1,6 +1,6 @@
+ /*
+     This file is part of BioD.
+-    Copyright (C) 2012-2014    Artem Tarasov <lomereiter at gmail.com>
++    Copyright (C) 2012-2016    Artem Tarasov <lomereiter at gmail.com>
+ 
+     Permission is hereby granted, free of charge, to any person obtaining a
+     copy of this software and associated documentation files (the "Software"),
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -28,11 +28,11 @@ import bio.bam.abstractreader;
+ import bio.bam.reader;
+ import bio.core.bgzf.inputstream;
+ import bio.core.bgzf.virtualoffset;
+-import bio.core.utils.switchendianness;
+ 
+ import std.stream;
+ import std.algorithm;
+ import std.system;
++import std.bitmanip;
+ 
+ /// Read + its start/end virtual offsets
+ struct BamReadBlock {
+@@ -54,7 +54,7 @@ mixin template withOffsets() {
+                  plus the current read itself.
+      */
+     BamReadBlock front() @property {
+-        return BamReadBlock(_start_voffset, 
++        return BamReadBlock(_start_voffset,
+                             _stream.virtualTell(),
+                             _current_record);
+     }
+@@ -79,8 +79,8 @@ mixin template withoutOffsets() {
+ }
+ 
+ /// $(D front) return type is determined by $(I IteratePolicy)
+-struct BamReadRange(alias IteratePolicy) 
+-{ 
++struct BamReadRange(alias IteratePolicy)
++{
+     /// Create new range from BgzfInputStream.
+     this(BgzfInputStream stream, BamReader reader=null) {
+         _stream = stream;
+@@ -95,7 +95,7 @@ struct BamReadRange(alias IteratePolicy)
+     }
+ 
+     mixin IteratePolicy;
+-   
++
+     ///
+     void popFront() {
+         readNext();
+@@ -126,21 +126,18 @@ private:
+             _empty = true;
+             return;
+         }
+-     
++
+         // In order to get the right virtual offset, we need to do it here.
+         version(extraVerbose) {
+             // import std.stdio; stderr.writeln("record v.o. = ", _stream.virtualTell());
+         }
+         beforeNextBamReadLoad();
+ 
+-        // (FIXME: that won't work on Big Endian systems!)
+-        
+         // Here's where _empty is really set!
+-        int block_size = void;
+-        ubyte* ptr = cast(ubyte*)(&block_size);
++        ubyte[int.sizeof] tmp = void;
+         auto _read = 0;
+         while (_read < int.sizeof) {
+-            auto _actually_read = _endian_stream.readBlock(ptr, int.sizeof - _read);
++            auto _actually_read = _endian_stream.readBlock(tmp.ptr + _read, int.sizeof - _read);
+             if (_actually_read == 0) {
+                 version(development) {
+                     import std.stdio;
+@@ -150,18 +147,15 @@ private:
+                 return;
+             }
+             _read += _actually_read;
+-            ptr += _actually_read;
+-        } 
++        }
++
++        int block_size = littleEndianToNative!int(tmp);
+ 
+         version(extraVerbose) {
+             import std.stdio;
+             stderr.writeln("[uncompressed] record size: ", block_size);
+         }
+ 
+-        if (std.system.endian != Endian.littleEndian) {
+-            switchEndianness(&block_size, int.sizeof);
+-        }
+-
+         ubyte[] data = void;
+         if (_reader !is null && _reader._seqprocmode) {
+             if (block_size > _buffer.length)
+diff --git a/bio/bam/writer.d b/bio/bam/writer.d
+index 187b40a..4d5b4f1 100644
+--- a/bio/bam/writer.d
++++ b/bio/bam/writer.d
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -32,7 +32,6 @@ import bio.bam.readrange;
+ import bio.core.bgzf.outputstream;
+ import bio.core.bgzf.virtualoffset;
+ import bio.core.utils.stream;
+-import bio.core.utils.switchendianness;
+ 
+ import std.parallelism;
+ import std.exception;
+@@ -41,6 +40,7 @@ import std.traits;
+ import std.system;
+ import std.algorithm;
+ import std.array;
++import std.bitmanip;
+ 
+ /** Class for outputting BAM.
+     $(BR)
+@@ -73,12 +73,12 @@ final class BamWriter {
+     ///     compression_level  = compression level, must be in range -1..9
+     ///     task_pool          = task pool to use for parallel compression
+     ///     buffer_size        = size of BgzfOutputStream buffer
+-    this(std.stream.Stream stream, 
++    this(std.stream.Stream stream,
+          int compression_level=-1,
+          std.parallelism.TaskPool task_pool=std.parallelism.taskPool,
+-         size_t buffer_size=0) 
++         size_t buffer_size=0)
+     {
+-        _stream = new BgzfOutputStream(stream, compression_level, 
++        _stream = new BgzfOutputStream(stream, compression_level,
+                                        task_pool, buffer_size);
+         _stream.setWriteHandler((ubyte[] uncompressed, ubyte[] compressed) {
+             _bytes_written += compressed.length;
+@@ -120,13 +120,8 @@ final class BamWriter {
+ 
+     package void writeInteger(T)(T integer) if (isIntegral!T)
+     {
+-        T num = integer;
+-        static if (T.sizeof != 1) {
+-            if (std.system.endian != Endian.littleEndian) {
+-                switchEndianness(&num, T.sizeof);
+-            }
+-        }
+-        _stream.writeExact(&num, T.sizeof);
++        ubyte[T.sizeof] buf = nativeToLittleEndian(integer);
++        _stream.writeExact(buf.ptr, buf.length);
+     }
+ 
+     private {
+diff --git a/bio/core/bgzf/compress.d b/bio/core/bgzf/compress.d
+index 5bf01ad..63b959a 100644
+--- a/bio/core/bgzf/compress.d
++++ b/bio/core/bgzf/compress.d
+@@ -1,6 +1,6 @@
+ /*
+     This file is part of BioD.
+-    Copyright (C) 2012-2014    Artem Tarasov <lomereiter at gmail.com>
++    Copyright (C) 2012-2016    Artem Tarasov <lomereiter at gmail.com>
+ 
+     Permission is hereby granted, free of charge, to any person obtaining a
+     copy of this software and associated documentation files (the "Software"),
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -28,20 +28,20 @@ import bio.core.utils.zlib;
+ 
+ import std.array;
+ import std.system;
+-import core.bitop;
++import std.bitmanip: nativeToLittleEndian;
+ 
+ /// Returns BGZF block containing compressed $(D chunk).
+ /// If $(D buffer) is provided, it will be used for storing the block.
+ ///
+-/// Params: 
++/// Params:
+ ///         chunk =  chunk of memory to be compressed
+ ///         level =  compression level, see zlib documentation
+ ///         buffer = optional buffer which will be used for storing
+ ///                  decompressed data
+ ///
+ /// For uncompressed BAM output, use level = 0.
+-ubyte[] bgzfCompress(ubyte[] chunk, int level=-1, ubyte[] buffer=null) 
+-in 
++ubyte[] bgzfCompress(ubyte[] chunk, int level=-1, ubyte[] buffer=null)
++in
+ {
+     assert(-1 <= level && level <= 9);
+ }
+@@ -70,9 +70,9 @@ body
+     zs.avail_out = cast(int)(buffer.length - BLOCK_HEADER_LENGTH - BLOCK_FOOTER_LENGTH);
+ 
+     auto err = bio.core.utils.zlib.deflateInit2(&zs, /* compression level */ level,
+-                                            /* deflated compression method */ Z_DEFLATED, 
+-                                            /* winbits (no header) */ -15, 
+-                                            /* memory usage level (default) */ 8, 
++                                            /* deflated compression method */ Z_DEFLATED,
++                                            /* winbits (no header) */ -15,
++                                            /* memory usage level (default) */ 8,
+                                             /* default compression strategy */ Z_DEFAULT_STRATEGY);
+     if (err != Z_OK) {
+         throw new ZlibException("deflateInit2", err);
+@@ -94,20 +94,10 @@ body
+     // Write (block length - 1) in BC subfield.
+     // Why -1? To fit the value into 2 bytes (it's assumed to be in range 1-65536).
+     ushort len = cast(ushort)(buffer.length - 1);
+-    buffer[BLOCK_HEADER_LENGTH - 2] = len & 0xFF;         // little endian
+-    buffer[BLOCK_HEADER_LENGTH - 1] = len >> 8;
++    buffer[BLOCK_HEADER_LENGTH - 2 .. $][0 .. 2] = nativeToLittleEndian(len);
+ 
+     // Write the footer
+-    *(cast(uint*)(buffer.ptr + buffer.length - 8)) = crc32(0, chunk);
+-    *(cast(uint*)(buffer.ptr + buffer.length - 4)) = cast(uint)chunk.length;
+-
+-    uint* ptr;
+-    if (std.system.endian != Endian.littleEndian) {
+-        ptr = cast(uint*)(buffer.ptr + buffer.length - 8);
+-        *ptr = bswap(*ptr);
+-        ptr = cast(uint*)(buffer.ptr + buffer.length - 4);
+-        *ptr = bswap(*ptr);
+-    }
+-
++    buffer[$ - 8 .. $ - 4] = nativeToLittleEndian(crc32(0, chunk));
++    buffer[$- 4 .. $] = nativeToLittleEndian(cast(uint)chunk.length);
+     return buffer;
+ }
+diff --git a/bio/core/bgzf/constants.d b/bio/core/bgzf/constants.d
+index 1985309..9136bc9 100644
+--- a/bio/core/bgzf/constants.d
++++ b/bio/core/bgzf/constants.d
+@@ -1,6 +1,6 @@
+ /*
+     This file is part of BioD.
+-    Copyright (C) 2012    Artem Tarasov <lomereiter at gmail.com>
++    Copyright (C) 2012-2016    Artem Tarasov <lomereiter at gmail.com>
+ 
+     Permission is hereby granted, free of charge, to any person obtaining a
+     copy of this software and associated documentation files (the "Software"),
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -23,9 +23,9 @@
+ */
+ module bio.core.bgzf.constants;
+ 
+-immutable BGZF_MAGIC = 0x04_08_8B_1F; // little endian
++immutable ubyte[4] BGZF_MAGIC = [0x1F, 0x8B, 0x8, 0x4];
+ 
+-immutable ubyte[16] BLOCK_HEADER_START = 
++immutable ubyte[16] BLOCK_HEADER_START =
+     [ 31, 139,   8,   4,  // BGZF magic
+        0,   0,   0,   0,  // GZIP modification time
+        0,                 // GZIP extra flags
+@@ -35,17 +35,17 @@ immutable ubyte[16] BLOCK_HEADER_START =
+        2,   0];           // Subfield length (holds 1 ushort)
+ 
+ // empty block
+-immutable ubyte[28] BGZF_EOF = 
+-    [31, 139, 8, 4, 
+-        0, 0, 0, 0, 
+-                 0, 
+-               255, 
+-              6, 0, 
+-            66, 67, 
+-              2, 0, 
+-             27, 0, 
+-              3, 0, 
+-        0, 0, 0, 0, 
++immutable ubyte[28] BGZF_EOF =
++    [31, 139, 8, 4,
++        0, 0, 0, 0,
++                 0,
++               255,
++              6, 0,
++            66, 67,
++              2, 0,
++             27, 0,
++              3, 0,
++        0, 0, 0, 0,
+         0, 0, 0, 0];
+ 
+ 
+@@ -58,4 +58,4 @@ immutable BLOCK_HEADER_LENGTH = BLOCK_HEADER_START.length + ushort.sizeof;
+ immutable BLOCK_FOOTER_LENGTH = uint.sizeof + uint.sizeof;
+ 
+ immutable BGZF_MAX_BLOCK_SIZE = 65536;
+-immutable BGZF_BLOCK_SIZE = 0xFF00; 
++immutable BGZF_BLOCK_SIZE = 0xFF00;
+diff --git a/bio/core/bgzf/inputstream.d b/bio/core/bgzf/inputstream.d
+index fa9548b..169e189 100644
+--- a/bio/core/bgzf/inputstream.d
++++ b/bio/core/bgzf/inputstream.d
+@@ -1,6 +1,6 @@
+ /*
+     This file is part of BioD.
+-    Copyright (C) 2013    Artem Tarasov <lomereiter at gmail.com>
++    Copyright (C) 2013-2016    Artem Tarasov <lomereiter at gmail.com>
+ 
+     Permission is hereby granted, free of charge, to any person obtaining a
+     copy of this software and associated documentation files (the "Software"),
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -48,7 +48,7 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+ {
+     if (stream.eof())
+         return false;
+-    
++
+     ulong start_offset;
+     void throwBgzfException(string msg) {
+         throw new BgzfException("Error reading BGZF block starting from offset " ~
+@@ -57,24 +57,23 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+ 
+     if (is_seekable)
+         start_offset = stream.position;
+-    
++
+     try {
+-        uint bgzf_magic = void;
+-           
+-        // TODO: fix byte order if needed
++        ubyte[4] bgzf_magic = void;
++
+         size_t bytes_read;
+-        while (bytes_read < uint.sizeof) {
+-            auto buf = (cast(ubyte*)&bgzf_magic)[bytes_read .. uint.sizeof];
+-            auto read_ = stream.read(buf);
++        while (bytes_read < 4) {
++            auto buf = bgzf_magic.ptr + bytes_read;
++            auto read_ = stream.read(buf[0 .. 4 - bytes_read]);
+             if (read_ == 0)
+                 return false;
+             bytes_read += read_;
+         }
+ 
+-        if (bgzf_magic != BGZF_MAGIC) { 
++        if (bgzf_magic != BGZF_MAGIC) {
+             throwBgzfException("wrong BGZF magic");
+         }
+-        
++
+         ushort gzip_extra_length = void;
+ 
+         if (is_seekable) {
+@@ -89,7 +88,7 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+         }
+ 
+         stream.read(gzip_extra_length);
+-          
++
+         ushort bsize = void; // total Block SIZE minus 1
+         bool found_block_size = false;
+ 
+@@ -99,16 +98,16 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+             ubyte si1 = void;    // Subfield Identifier1
+             ubyte si2 = void;    // Subfield Identifier2
+             ushort slen = void;  // Subfield LENgth
+-                
+-            stream.read(si1);    
+-            stream.read(si2);    
+-            stream.read(slen);   
+ 
+-            if (si1 == BAM_SI1 && si2 == BAM_SI2) { 
++            stream.read(si1);
++            stream.read(si2);
++            stream.read(slen);
++
++            if (si1 == BAM_SI1 && si2 == BAM_SI2) {
+                 // found 'BC' as subfield identifier
+-                    
++
+                 if (slen != 2) {
+-                    throwBgzfException("wrong BC subfield length: " ~ 
++                    throwBgzfException("wrong BC subfield length: " ~
+                                        to!string(slen) ~ "; expected 2");
+                 }
+ 
+@@ -117,7 +116,7 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+                 }
+ 
+                 // read block size
+-                stream.read(bsize); 
++                stream.read(bsize);
+                 found_block_size = true;
+ 
+                 // skip the rest
+@@ -139,11 +138,11 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+             if (number_of_bytes_read !is null)
+                 *number_of_bytes_read += nbytes;
+             len += nbytes;
+-        } 
++        }
+ 
+         if (len != gzip_extra_length) {
+-            throwBgzfException("total length of subfields in bytes (" ~ 
+-                               to!string(len) ~ 
++            throwBgzfException("total length of subfields in bytes (" ~
++                               to!string(len) ~
+                                ") is not equal to gzip_extra_length (" ~
+                                to!string(gzip_extra_length) ~ ")");
+         }
+@@ -151,7 +150,7 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+         if (!found_block_size) {
+             throwBgzfException("block size was not found in any subfield");
+         }
+-           
++
+         // read compressed data
+         auto cdata_size = bsize - gzip_extra_length - 19;
+         if (cdata_size > BGZF_MAX_BLOCK_SIZE) {
+@@ -178,7 +177,7 @@ bool fillBgzfBufferFromStream(Stream stream, bool is_seekable,
+ 
+         if (number_of_bytes_read !is null)
+             *number_of_bytes_read += 12 + cdata_size + block.crc32.sizeof + block.input_size.sizeof;
+-           
++
+         // version(extraVerbose) {stderr.writeln("[compressed] read block input size: ", block.input_size);}
+         block._buffer = buffer[0 .. max(block.input_size, cdata_size)];
+         block.start_offset = start_offset;
+@@ -213,7 +212,7 @@ class StreamSupplier : BgzfBlockSupplier {
+         size_t _size;
+         ushort _skip_start;
+     }
+-    
++
+     ///
+     this(Stream stream, ushort skip_start=0) {
+         _stream = stream;
+@@ -267,7 +266,7 @@ class StreamChunksSupplier : BgzfBlockSupplier {
+             }
+         }
+     }
+-    
++
+     this(Stream stream, bio.core.bgzf.chunk.Chunk[] chunks) {
+         _stream = stream;
+         assert(_stream.seekable);
+@@ -485,7 +484,7 @@ class BgzfInputStream : Stream {
+             setEOF();
+             return 0;
+         }
+-        
++
+         auto buffer = cast(ubyte*)buf;
+ 
+         auto len = min(size, _read_buffer.length);
+-- 
+2.11.0
+
diff --git a/debian/patches/0003-include-the-AH-header-tag-to-SQ-lines.patch b/debian/patches/0003-include-the-AH-header-tag-to-SQ-lines.patch
new file mode 100644
index 0000000..0c63d54
--- /dev/null
+++ b/debian/patches/0003-include-the-AH-header-tag-to-SQ-lines.patch
@@ -0,0 +1,31 @@
+From 589d65025a68a42ec03bbf6d64c57a7da7754201 Mon Sep 17 00:00:00 2001
+From: indraniel <indraniel at gmail.com>
+Date: Thu, 4 Aug 2016 15:43:37 -0500
+Subject: [PATCH 03/14] + include the AH header tag to @SQ lines
+
+  - the "AH" header tag corresponds to Alternate Haplotypes in ALT
+    mapping mode
+  - based on samtools/hts-specs issue 147: https://github.com/samtools/hts-specs/pull/147
+  - this tag is already being produced by `bwa` 0.7.15
+      * see tag 0.7.15 (r1140) https://github.com/lh3/bwa/releases/tag/v0.7.15
+---
+ bio/sam/header.d | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/bio/sam/header.d b/bio/sam/header.d
+index b6ec094..aceac15 100644
+--- a/bio/sam/header.d
++++ b/bio/sam/header.d
+@@ -223,7 +223,8 @@ mixin HeaderLineStruct!("SqLine", "@SQ", "name",
+           Field!("assembly", "AS"),
+           Field!("md5", "M5"),
+           Field!("species", "SP"),
+-          Field!("uri", "UR"));
++          Field!("uri", "UR"),
++          Field!("AlternateHaplotype", "AH"));
+ 
+ mixin HeaderLineStruct!("RgLine", "@RG", "identifier",
+           Field!("identifier", "ID"),
+-- 
+2.11.0
+
diff --git a/debian/patches/0004-use-consistent-naming-21.patch b/debian/patches/0004-use-consistent-naming-21.patch
new file mode 100644
index 0000000..3a727ba
--- /dev/null
+++ b/debian/patches/0004-use-consistent-naming-21.patch
@@ -0,0 +1,33 @@
+From 47d081e06cb2df81269ec31d45cc50f12ec3c8b1 Mon Sep 17 00:00:00 2001
+From: Artem Tarasov <artem.tarasov at embl.de>
+Date: Fri, 5 Aug 2016 06:43:33 +0200
+Subject: [PATCH 04/14] use consistent naming (#21)
+
+---
+ bio/sam/header.d | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/bio/sam/header.d b/bio/sam/header.d
+index aceac15..6f315e5 100644
+--- a/bio/sam/header.d
++++ b/bio/sam/header.d
+@@ -1,6 +1,6 @@
+ /*
+     This file is part of BioD.
+-    Copyright (C) 2012-2015    Artem Tarasov <lomereiter at gmail.com>
++    Copyright (C) 2012-2016    Artem Tarasov <lomereiter at gmail.com>
+ 
+     Permission is hereby granted, free of charge, to any person obtaining a
+     copy of this software and associated documentation files (the "Software"),
+@@ -224,7 +224,7 @@ mixin HeaderLineStruct!("SqLine", "@SQ", "name",
+           Field!("md5", "M5"),
+           Field!("species", "SP"),
+           Field!("uri", "UR"),
+-          Field!("AlternateHaplotype", "AH"));
++          Field!("alternate_haplotype", "AH"));
+ 
+ mixin HeaderLineStruct!("RgLine", "@RG", "identifier",
+           Field!("identifier", "ID"),
+-- 
+2.11.0
+
diff --git a/debian/patches/0005-fixes-lomereiter-sambamba-244.patch b/debian/patches/0005-fixes-lomereiter-sambamba-244.patch
new file mode 100644
index 0000000..f350cbe
--- /dev/null
+++ b/debian/patches/0005-fixes-lomereiter-sambamba-244.patch
@@ -0,0 +1,59 @@
+From 1248586b54af4bd4dfb28ebfebfc6bf012e7a587 Mon Sep 17 00:00:00 2001
+From: Artem Tarasov <artem.tarasov at embl.de>
+Date: Sat, 10 Sep 2016 08:58:07 +0200
+Subject: [PATCH 05/14] fixes lomereiter/sambamba#244
+
+---
+ bio/bam/pileup.d | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+diff --git a/bio/bam/pileup.d b/bio/bam/pileup.d
+index 576a16b..a4c6a12 100644
+--- a/bio/bam/pileup.d
++++ b/bio/bam/pileup.d
+@@ -864,6 +864,11 @@ struct PileupChunkRange(C) {
+     private bool _use_md_tag;
+     private ulong _start_from;
+     private ulong _end_at;
++    private int _chunk_right_end;
++
++    private int computeRightEnd(ref ElementType!C chunk) {
++        return chunk.map!(r => r.position + r.basesCovered()).reduce!max;
++    }
+ 
+     this(C chunks, bool use_md_tag, ulong start_from, ulong end_at) {
+         _chunks = chunks;
+@@ -885,10 +890,9 @@ struct PileupChunkRange(C) {
+                     break;
+                 }
+ 
+-                auto last_read = _current_chunk[$-1];
+-                if (last_read.position + last_read.basesCovered() > start_from) {
++                _chunk_right_end = computeRightEnd(_current_chunk);
++                if (_chunk_right_end > start_from)
+                     break;
+-                }
+             }
+         }
+     }
+@@ -900,7 +904,7 @@ struct PileupChunkRange(C) {
+     auto front() @property {
+         auto end_pos = _current_chunk[$-1].position;
+         if (_chunks.empty || _chunks.front[0].ref_id != _current_chunk[$-1].ref_id)
+-            end_pos += _current_chunk[$-1].basesCovered();
++            end_pos = _chunk_right_end;
+ 
+         return makePileup(chain(_prev_chunk, _current_chunk),
+                           _use_md_tag,
+@@ -921,6 +925,8 @@ struct PileupChunkRange(C) {
+             if (_current_chunk[0].ref_id >= 0) break;
+         }
+ 
++        _chunk_right_end = computeRightEnd(_current_chunk);
++
+         // if we changed reference, nullify prev_chunk
+         if (_prev_chunk.length > 0 &&
+             _prev_chunk[$ - 1].ref_id == _current_chunk[0].ref_id)
+-- 
+2.11.0
+
diff --git a/debian/patches/0006-switch-to-undead.stream.patch b/debian/patches/0006-switch-to-undead.stream.patch
new file mode 100644
index 0000000..66f73aa
--- /dev/null
+++ b/debian/patches/0006-switch-to-undead.stream.patch
@@ -0,0 +1,265 @@
+From c37b0e7e03de77d231d596a16293907fa4f7ca92 Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 12:41:21 +0000
+Subject: [PATCH 06/14] switch to undead.stream;
+
+---
+ bio/bam/bai/indexing.d             | 2 +-
+ bio/bam/baifile.d                  | 2 +-
+ bio/bam/reader.d                   | 2 +-
+ bio/bam/readrange.d                | 2 +-
+ bio/bam/reference.d                | 2 +-
+ bio/bam/referenceinfo.d            | 2 +-
+ bio/bam/writer.d                   | 4 ++--
+ bio/core/bgzf/inputstream.d        | 2 +-
+ bio/core/bgzf/outputstream.d       | 2 +-
+ bio/core/utils/stream.d            | 4 ++--
+ bio/core/utils/switchendianness.d  | 2 +-
+ bio/sff/reader.d                   | 2 +-
+ bio/sff/readrange.d                | 2 +-
+ bio/sff/writer.d                   | 2 +-
+ dub.json                           | 5 ++++-
+ examples/create_bam_from_scratch.d | 2 +-
+ test/unittests.d                   | 2 +-
+ 17 files changed, 22 insertions(+), 19 deletions(-)
+
+diff --git a/bio/bam/bai/indexing.d b/bio/bam/bai/indexing.d
+index 270f5e6..43e89d3 100644
+--- a/bio/bam/bai/indexing.d
++++ b/bio/bam/bai/indexing.d
+@@ -30,7 +30,7 @@ import bio.bam.constants;
+ import bio.bam.bai.bin;
+ import bio.core.bgzf.chunk;
+ 
+-import std.stream;
++import undead.stream;
+ import std.array;
+ import std.algorithm;
+ import std.system;
+diff --git a/bio/bam/baifile.d b/bio/bam/baifile.d
+index 57359a9..276e685 100644
+--- a/bio/bam/baifile.d
++++ b/bio/bam/baifile.d
+@@ -28,7 +28,7 @@ public import bio.bam.bai.bin;
+ import bio.core.bgzf.virtualoffset;
+ import bio.bam.constants;
+ 
+-import std.stream;
++import undead.stream;
+ import std.system;
+ import std.exception;
+ import std.algorithm;
+diff --git a/bio/bam/reader.d b/bio/bam/reader.d
+index fae864f..728ccb5 100644
+--- a/bio/bam/reader.d
++++ b/bio/bam/reader.d
+@@ -94,7 +94,7 @@ class BamReader : IBamSamReader {
+       }
+       -------------------------------------------
+      */
+-    this(std.stream.Stream stream, 
++    this(undead.stream.Stream stream,
+          std.parallelism.TaskPool task_pool = std.parallelism.taskPool) {
+         _source_stream = new EndianStream(stream, Endian.littleEndian);
+         _task_pool = task_pool;
+diff --git a/bio/bam/readrange.d b/bio/bam/readrange.d
+index 6767a74..fc17aff 100644
+--- a/bio/bam/readrange.d
++++ b/bio/bam/readrange.d
+@@ -29,7 +29,7 @@ import bio.bam.reader;
+ import bio.core.bgzf.inputstream;
+ import bio.core.bgzf.virtualoffset;
+ 
+-import std.stream;
++import undead.stream;
+ import std.algorithm;
+ import std.system;
+ import std.bitmanip;
+diff --git a/bio/bam/reference.d b/bio/bam/reference.d
+index 997e6b4..6406b32 100644
+--- a/bio/bam/reference.d
++++ b/bio/bam/reference.d
+@@ -47,7 +47,7 @@ import bio.bam.region;
+ import bio.bam.randomaccessmanager;
+ import bio.core.bgzf.virtualoffset;
+ 
+-import std.stream;
++import undead.stream;
+ import std.exception;
+ import std.array;
+ 
+diff --git a/bio/bam/referenceinfo.d b/bio/bam/referenceinfo.d
+index 3824fe8..91b8d96 100644
+--- a/bio/bam/referenceinfo.d
++++ b/bio/bam/referenceinfo.d
+@@ -23,7 +23,7 @@
+ */
+ module bio.bam.referenceinfo;
+ 
+-import std.stream;
++import undead.stream;
+ import std.exception;
+ import std.array;
+ 
+diff --git a/bio/bam/writer.d b/bio/bam/writer.d
+index 4d5b4f1..5e92930 100644
+--- a/bio/bam/writer.d
++++ b/bio/bam/writer.d
+@@ -35,7 +35,7 @@ import bio.core.utils.stream;
+ 
+ import std.parallelism;
+ import std.exception;
+-import std.stream;
++import undead.stream;
+ import std.traits;
+ import std.system;
+ import std.algorithm;
+@@ -73,7 +73,7 @@ final class BamWriter {
+     ///     compression_level  = compression level, must be in range -1..9
+     ///     task_pool          = task pool to use for parallel compression
+     ///     buffer_size        = size of BgzfOutputStream buffer
+-    this(std.stream.Stream stream,
++    this(undead.stream.Stream stream,
+          int compression_level=-1,
+          std.parallelism.TaskPool task_pool=std.parallelism.taskPool,
+          size_t buffer_size=0)
+diff --git a/bio/core/bgzf/inputstream.d b/bio/core/bgzf/inputstream.d
+index 169e189..2bfc658 100644
+--- a/bio/core/bgzf/inputstream.d
++++ b/bio/core/bgzf/inputstream.d
+@@ -30,7 +30,7 @@ import bio.core.bgzf.chunk;
+ import bio.bam.constants;
+ import bio.core.utils.roundbuf;
+ 
+-import std.stream;
++import undead.stream;
+ import std.exception;
+ import std.conv;
+ import std.parallelism;
+diff --git a/bio/core/bgzf/outputstream.d b/bio/core/bgzf/outputstream.d
+index b9f3d07..89cbecb 100644
+--- a/bio/core/bgzf/outputstream.d
++++ b/bio/core/bgzf/outputstream.d
+@@ -28,7 +28,7 @@ import bio.core.bgzf.compress;
+ 
+ import bio.core.utils.roundbuf;
+ 
+-import std.stream;
++import undead.stream;
+ import std.exception;
+ import std.parallelism;
+ import std.array;
+diff --git a/bio/core/utils/stream.d b/bio/core/utils/stream.d
+index 6c5146d..ee57fe7 100644
+--- a/bio/core/utils/stream.d
++++ b/bio/core/utils/stream.d
+@@ -1,6 +1,6 @@
+ module bio.core.utils.stream;
+ 
+-public import std.stream;
++public import undead.stream;
+ import core.stdc.stdio;
+ import core.stdc.errno;
+ import core.stdc.string;
+@@ -48,7 +48,7 @@ FileMode toFileMode(string mode) {
+     return result;
+ }
+ 
+-final class File: std.stream.File {
++final class File: undead.stream.File {
+     this(string filename, string mode="rb") {
+         version (Posix) {
+             // Issue 8528 workaround
+diff --git a/bio/core/utils/switchendianness.d b/bio/core/utils/switchendianness.d
+index 7b141cf..6772e70 100644
+--- a/bio/core/utils/switchendianness.d
++++ b/bio/core/utils/switchendianness.d
+@@ -1,5 +1,5 @@
+ /**
+-  (Almost) a copy-paste from std/stream.d
++  (Almost) a copy-paste from undead.stream.d
+ */
+ module bio.core.utils.switchendianness;
+ 
+diff --git a/bio/sff/reader.d b/bio/sff/reader.d
+index d0c21a2..257a859 100644
+--- a/bio/sff/reader.d
++++ b/bio/sff/reader.d
+@@ -29,7 +29,7 @@ import bio.sff.readrange;
+ import bio.sff.constants;
+ 
+ import bio.core.utils.stream;
+-import std.stream;
++import undead.stream;
+ import std.system;
+ import std.range;
+ import std.exception;
+diff --git a/bio/sff/readrange.d b/bio/sff/readrange.d
+index eda29d3..5f70f08 100644
+--- a/bio/sff/readrange.d
++++ b/bio/sff/readrange.d
+@@ -5,7 +5,7 @@ import bio.sff.index;
+ import bio.core.utils.switchendianness;
+ 
+ import std.algorithm;
+-import std.stream;
++import undead.stream;
+ import std.system;
+ import std.array;
+ 
+diff --git a/bio/sff/writer.d b/bio/sff/writer.d
+index 7937d79..1ebd0ca 100644
+--- a/bio/sff/writer.d
++++ b/bio/sff/writer.d
+@@ -4,7 +4,7 @@ import bio.sff.constants;
+ import bio.sff.utils.roundup;
+ 
+ import bio.core.utils.stream;
+-import std.stream;
++import undead.stream;
+ import std.system;
+ 
+ /// Class for outputting SFF files
+diff --git a/dub.json b/dub.json
+index ec26904..6135f32 100644
+--- a/dub.json
++++ b/dub.json
+@@ -8,5 +8,8 @@
+ 	"copyright": "Copyright © 2016, BioD developers",
+ 	"license": "MIT",
+ 	"sourcePaths": ["bio"],
+-	"importPaths": ["bio"]
++	"importPaths": ["bio"],
++    "dependencies": {
++        "undead": "~>1.0.6"
++    }
+ }
+diff --git a/examples/create_bam_from_scratch.d b/examples/create_bam_from_scratch.d
+index ad6053a..b011d93 100644
+--- a/examples/create_bam_from_scratch.d
++++ b/examples/create_bam_from_scratch.d
+@@ -3,7 +3,7 @@
+ // this example shows how to create BAM files from scratch
+ import bio.bam.read, bio.bam.referenceinfo, bio.sam.header;
+ import bio.bam.reader, bio.bam.writer;
+-import std.stream, std.stdio;
++import undead.stream, std.stdio;
+ 
+ void main() {
+     auto header = new SamHeader(); // First, create SAM header 
+diff --git a/test/unittests.d b/test/unittests.d
+index 4435008..cefa6a9 100644
+--- a/test/unittests.d
++++ b/test/unittests.d
+@@ -49,7 +49,7 @@ import bio.core.utils.roundbuf;
+ import std.path;
+ import std.range;
+ import std.stdio;
+-import std.stream;
++import undead.stream;
+ import std.algorithm;
+ import std.array;
+ import std.conv;
+-- 
+2.11.0
+
diff --git a/debian/patches/0007-std.c-core.stdc.patch b/debian/patches/0007-std.c-core.stdc.patch
new file mode 100644
index 0000000..9a12a66
--- /dev/null
+++ b/debian/patches/0007-std.c-core.stdc.patch
@@ -0,0 +1,175 @@
+From 4901cda76512a1c819bc2f9ec2af7048ae9db80d Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 13:30:13 +0000
+Subject: [PATCH 07/14] std.c -> core.stdc
+
+---
+ bio/bam/bai/indexing.d       | 2 +-
+ bio/bam/read.d               | 2 +-
+ bio/bam/thirdparty/msgpack.d | 4 ++--
+ bio/bam/utils/array.d        | 2 +-
+ bio/core/bgzf/outputstream.d | 6 +++---
+ bio/core/utils/bylinefast.d  | 2 +-
+ bio/core/utils/format.d      | 6 +++---
+ bio/core/utils/stream.d      | 2 +-
+ bio/sam/reader.d             | 2 +-
+ 9 files changed, 14 insertions(+), 14 deletions(-)
+
+diff --git a/bio/bam/bai/indexing.d b/bio/bam/bai/indexing.d
+index 43e89d3..fec5662 100644
+--- a/bio/bam/bai/indexing.d
++++ b/bio/bam/bai/indexing.d
+@@ -35,7 +35,7 @@ import std.array;
+ import std.algorithm;
+ import std.system;
+ import std.exception;
+-import std.c.string;
++import core.stdc.string;
+ 
+ // Suppose we have an alignment which covers bases on a reference,
+ // starting from one position and ending at another position.
+diff --git a/bio/bam/read.d b/bio/bam/read.d
+index 6e81263..3f51dc8 100644
+--- a/bio/bam/read.d
++++ b/bio/bam/read.d
+@@ -72,7 +72,7 @@ import std.system;
+ import std.traits;
+ import std.array;
+ import std.bitmanip;
+-import std.c.stdlib;
++import core.stdc.stdlib;
+ 
+ /**
+   Represents single CIGAR operation
+diff --git a/bio/bam/thirdparty/msgpack.d b/bio/bam/thirdparty/msgpack.d
+index bf5ca5b..1032b33 100644
+--- a/bio/bam/thirdparty/msgpack.d
++++ b/bio/bam/thirdparty/msgpack.d
+@@ -59,7 +59,7 @@ else
+ // for Converting Endian using ntohs and ntohl;
+ version(Windows)
+ {
+-    import std.c.windows.winsock;
++    import core.stdc.windows.winsock;
+ }
+ else
+ {
+@@ -82,7 +82,7 @@ static if (real.sizeof == double.sizeof) {
+     import std.numeric;
+ }
+ 
+-version(unittest) import std.file, std.c.string;
++version(unittest) import std.file, core.stdc.string;
+ 
+ 
+ @trusted:
+diff --git a/bio/bam/utils/array.d b/bio/bam/utils/array.d
+index 4e5f8a1..42000df 100644
+--- a/bio/bam/utils/array.d
++++ b/bio/bam/utils/array.d
+@@ -23,7 +23,7 @@
+ */
+ module bio.bam.utils.array;
+ 
+-import std.c.string;
++import core.stdc.string;
+ import std.traits;
+ 
+ /// Modifies array in-place so that $(D slice) is replaced by
+diff --git a/bio/core/bgzf/outputstream.d b/bio/core/bgzf/outputstream.d
+index 89cbecb..ae335be 100644
+--- a/bio/core/bgzf/outputstream.d
++++ b/bio/core/bgzf/outputstream.d
+@@ -34,7 +34,7 @@ import std.parallelism;
+ import std.array;
+ import std.algorithm : max;
+ import std.typecons;
+-import std.c.stdlib;
++import core.stdc.stdlib;
+ 
+ alias void delegate(ubyte[], ubyte[]) BlockWriteHandler;
+ 
+@@ -88,7 +88,7 @@ class BgzfOutputStream : Stream {
+ 
+         // 1 extra block to which we can write while n_tasks are executed
+         auto comp_buf_size = (2 * n_tasks + 2) * max_block_size;
+-        auto p = cast(ubyte*)std.c.stdlib.malloc(comp_buf_size);
++        auto p = cast(ubyte*)core.stdc.stdlib.malloc(comp_buf_size);
+         _compression_buffer = p[0 .. comp_buf_size];
+         _buffer = _compression_buffer[0 .. block_size];
+         _tmp = _compression_buffer[max_block_size .. max_block_size * 2];
+@@ -210,7 +210,7 @@ class BgzfOutputStream : Stream {
+         _stream.close();
+ 
+         writeable = false;
+-        std.c.stdlib.free(_compression_buffer.ptr);
++        core.stdc.stdlib.free(_compression_buffer.ptr);
+     }
+ 
+     /// Adds EOF block. This function is called in close() method.
+diff --git a/bio/core/utils/bylinefast.d b/bio/core/utils/bylinefast.d
+index 50fb756..6a71520 100644
+--- a/bio/core/utils/bylinefast.d
++++ b/bio/core/utils/bylinefast.d
+@@ -6,7 +6,7 @@ module bio.core.utils.bylinefast;
+ 
+ import std.stdio;
+ import std.string: indexOf;
+-import std.c.string: memmove;
++import core.stdc.string: memmove;
+ 
+ /**
+    Reads by line in an efficient way (10 times faster than File.byLine from std.stdio).
+diff --git a/bio/core/utils/format.d b/bio/core/utils/format.d
+index ae8b4e6..a3ac3f1 100644
+--- a/bio/core/utils/format.d
++++ b/bio/core/utils/format.d
+@@ -34,8 +34,8 @@
+  */
+ module bio.core.utils.format;
+ 
+-import std.c.stdio;
+-import std.c.stdlib;
++import core.stdc.stdio;
++import core.stdc.stdlib;
+ import std.string;
+ import std.traits;
+ import std.array;
+@@ -161,7 +161,7 @@ private {
+         if (isSomeString!T)
+     {
+         auto str = cast(const(char)[])s;
+-        std.c.string.memcpy(sink, str.ptr, str.length);
++        core.stdc.string.memcpy(sink, str.ptr, str.length);
+         sink += str.length;
+     }
+ 
+diff --git a/bio/core/utils/stream.d b/bio/core/utils/stream.d
+index ee57fe7..b3f7d34 100644
+--- a/bio/core/utils/stream.d
++++ b/bio/core/utils/stream.d
+@@ -15,7 +15,7 @@ version(Posix){
+ version(Windows) {
+     private import std.file;
+     private import std.utf;
+-    private import std.c.windows.windows;
++    private import core.stdc.windows.windows;
+     extern (Windows) {
+         DWORD GetFileType(HANDLE hFile);
+     }
+diff --git a/bio/sam/reader.d b/bio/sam/reader.d
+index e7724ed..4302e9b 100644
+--- a/bio/sam/reader.d
++++ b/bio/sam/reader.d
+@@ -49,7 +49,7 @@ import std.typecons;
+ import std.parallelism;
+ import std.process;
+ import std.exception;
+-import std.c.string;
++import core.stdc.string;
+ 
+ BamRead _parseSamRecord(Tuple!(char[], SamReader, OutBuffer) t) {
+     auto r = parseAlignmentLine(cast(string)t[0], t[1]._header, t[2]);
+-- 
+2.11.0
+
diff --git a/debian/patches/0008-fix-deprecations-and-some-warnings.patch b/debian/patches/0008-fix-deprecations-and-some-warnings.patch
new file mode 100644
index 0000000..3014060
--- /dev/null
+++ b/debian/patches/0008-fix-deprecations-and-some-warnings.patch
@@ -0,0 +1,187 @@
+From 4394f15bfdda766dce69fd3f5711d05bae71a1bb Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 14:25:58 +0000
+Subject: [PATCH 08/14] fix deprecations and some warnings
+
+---
+ bio/bam/randomaccessmanager.d | 1 +
+ bio/bam/read.d                | 1 +
+ bio/bam/reader.d              | 2 +-
+ bio/bam/snpcallers/maq.d      | 2 +-
+ bio/bam/tagvalue.d            | 2 +-
+ bio/bam/thirdparty/msgpack.d  | 8 ++++----
+ bio/core/utils/format.d       | 1 +
+ bio/core/utils/outbuffer.d    | 2 +-
+ bio/core/utils/stream.d       | 1 -
+ bio/sam/header.d              | 2 +-
+ dub.json                      | 3 ++-
+ 11 files changed, 14 insertions(+), 11 deletions(-)
+
+diff --git a/bio/bam/randomaccessmanager.d b/bio/bam/randomaccessmanager.d
+index e5beb4b..fcd5d62 100644
+--- a/bio/bam/randomaccessmanager.d
++++ b/bio/bam/randomaccessmanager.d
+@@ -50,6 +50,7 @@ import std.traits;
+ import std.exception;
+ import std.container;
+ import std.parallelism;
++static import std.file;
+ 
+ debug {
+     import std.stdio;
+diff --git a/bio/bam/read.d b/bio/bam/read.d
+index 3f51dc8..b2f8cd1 100644
+--- a/bio/bam/read.d
++++ b/bio/bam/read.d
+@@ -1579,6 +1579,7 @@ unittest {
+ 
+     {
+     import std.typecons;
++    static import bio.bam.thirdparty.msgpack;
+     auto packer = bio.bam.thirdparty.msgpack.packer(Appender!(ubyte[])());
+     read.toMsgpack(packer);
+     auto data = packer.stream.data;
+diff --git a/bio/bam/reader.d b/bio/bam/reader.d
+index 728ccb5..f1fb8d4 100644
+--- a/bio/bam/reader.d
++++ b/bio/bam/reader.d
+@@ -95,7 +95,7 @@ class BamReader : IBamSamReader {
+       -------------------------------------------
+      */
+     this(undead.stream.Stream stream,
+-         std.parallelism.TaskPool task_pool = std.parallelism.taskPool) {
++         TaskPool task_pool = taskPool) {
+         _source_stream = new EndianStream(stream, Endian.littleEndian);
+         _task_pool = task_pool;
+ 
+diff --git a/bio/bam/snpcallers/maq.d b/bio/bam/snpcallers/maq.d
+index 2cb8a4b..3eee066 100644
+--- a/bio/bam/snpcallers/maq.d
++++ b/bio/bam/snpcallers/maq.d
+@@ -5,7 +5,7 @@ module bio.bam.snpcallers.maq;
+  */
+ 
+ import core.stdc.math;
+-import std.math : LN2, LN10, isnan;
++import std.math : LN2, LN10, isNaN;
+ import std.traits;
+ import std.range;
+ import std.algorithm;
+diff --git a/bio/bam/tagvalue.d b/bio/bam/tagvalue.d
+index dbd9aad..55adb1d 100644
+--- a/bio/bam/tagvalue.d
++++ b/bio/bam/tagvalue.d
+@@ -296,7 +296,7 @@ string injectOpCast() {
+     }
+ 
+     cs ~= `(is(T == string)) {` ~
+-          `  if (is_string) {`
++          `  if (is_string) {` ~
+           `    return bam_typeid == 'Z' ? u.Z : u.H;`~
+           `  } else if (is_integer || is_float || is_character) {`~
+           `    `~injectSwitchPrimitive("string")~
+diff --git a/bio/bam/thirdparty/msgpack.d b/bio/bam/thirdparty/msgpack.d
+index 1032b33..8aea071 100644
+--- a/bio/bam/thirdparty/msgpack.d
++++ b/bio/bam/thirdparty/msgpack.d
+@@ -344,7 +344,7 @@ struct PackerImpl(Stream) if (isOutputRange!(Stream, ubyte) && isOutputRange!(St
+      * Params:
+      *  withFieldName = serialize class / struct with field name
+      */
+-    this(bool withFieldName = false)
++    this(bool withFieldName)
+     {
+         withFieldName_ = withFieldName;
+     }
+@@ -3145,7 +3145,7 @@ struct Value
+      *  type  = the type of value.
+      */
+     @safe
+-    this(Type type = Type.nil)
++    this(Type type)
+     {
+         this.type = type;
+     }
+@@ -3617,7 +3617,7 @@ struct Value
+                         ret ^= value.toHash();
+                     }
+                     return ret;
+-                } catch assert(0);
++                } catch (Exception) assert(0);
+         }
+     }
+ }
+@@ -4656,7 +4656,7 @@ mixin template MessagePackable(Members...)
+             if (withFieldName) {
+                 packer.beginMap(this.tupleof.length);
+                 foreach (i, member; this.tupleof) {
+-                    pack(getFieldName!(typeof(this), i));
++                    packer.pack(getFieldName!(typeof(this), i));
+                     packer.pack(member);
+                 }
+             } else {
+diff --git a/bio/core/utils/format.d b/bio/core/utils/format.d
+index a3ac3f1..74bcfaf 100644
+--- a/bio/core/utils/format.d
++++ b/bio/core/utils/format.d
+@@ -36,6 +36,7 @@ module bio.core.utils.format;
+ 
+ import core.stdc.stdio;
+ import core.stdc.stdlib;
++static import core.stdc.string;
+ import std.string;
+ import std.traits;
+ import std.array;
+diff --git a/bio/core/utils/outbuffer.d b/bio/core/utils/outbuffer.d
+index 56c0879..983bb58 100644
+--- a/bio/core/utils/outbuffer.d
++++ b/bio/core/utils/outbuffer.d
+@@ -93,7 +93,7 @@ class OutBuffer {
+     /// Responsibility that there's enough capacity is on the user
+     void putUnsafe(T)(T bytes) if (is(T == ubyte[])) {
+         _heap_ptr[_heap_used .. _heap_used + bytes.length] = bytes[];
+-        _heap_used += bytes.length;;
++        _heap_used += bytes.length;
+     }
+ 
+     /// ditto
+diff --git a/bio/core/utils/stream.d b/bio/core/utils/stream.d
+index b3f7d34..aafcd43 100644
+--- a/bio/core/utils/stream.d
++++ b/bio/core/utils/stream.d
+@@ -135,7 +135,6 @@ final class File: undead.stream.File {
+                         if (ret <= 0) {
+                             size = 0;
+                             throw new ReadException("read timeout");
+-                            break;
+                         }
+                     } else {
+                         throw new ReadException(to!string(strerror(errno)));
+diff --git a/bio/sam/header.d b/bio/sam/header.d
+index 6f315e5..3d4697e 100644
+--- a/bio/sam/header.d
++++ b/bio/sam/header.d
+@@ -707,7 +707,7 @@ class SamHeader {
+ 
+         JSONValue json;
+         json.object = result;
+-        sink.write(toJSON(&json));
++        sink.write(toJSON(json));
+     }
+ 
+     /// Packs message in the following format:
+diff --git a/dub.json b/dub.json
+index 6135f32..693e9c7 100644
+--- a/dub.json
++++ b/dub.json
+@@ -11,5 +11,6 @@
+ 	"importPaths": ["bio"],
+     "dependencies": {
+         "undead": "~>1.0.6"
+-    }
++    },
++    "buildRequirements": ["allowWarnings"]
+ }
+-- 
+2.11.0
+
diff --git a/debian/patches/0009-fix-toHash-signature.patch b/debian/patches/0009-fix-toHash-signature.patch
new file mode 100644
index 0000000..b00be3e
--- /dev/null
+++ b/debian/patches/0009-fix-toHash-signature.patch
@@ -0,0 +1,128 @@
+From 05f86b887728a30128c68cb14012f84093132eac Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 14:28:52 +0000
+Subject: [PATCH 09/14] fix toHash signature
+
+---
+ bio/sam/header.d | 30 +++++++++++++++---------------
+ 1 file changed, 15 insertions(+), 15 deletions(-)
+
+diff --git a/bio/sam/header.d b/bio/sam/header.d
+index 3d4697e..df88d64 100644
+--- a/bio/sam/header.d
++++ b/bio/sam/header.d
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -117,7 +117,7 @@ private {
+     mixin template toSamMethod(string line_prefix, Field...) {
+         void toSam(Sink)(auto ref Sink sink) const if (isSomeSink!Sink) {
+             sink.write(line_prefix);
+-            mixin(serializeFields!Field());    
++            mixin(serializeFields!Field());
+         }
+     }
+ 
+@@ -132,9 +132,9 @@ private {
+ 
+     mixin template toHashMethod(string struct_name, string id_field, Field...) {
+         static if (id_field != null) {
+-            hash_t toHash() const {
++            hash_t toHash() const nothrow @safe{
+                 hash_t result = 1;
+-                mixin(generateHashExpression!Field());    
++                mixin(generateHashExpression!Field());
+                 return result;
+             }
+ 
+@@ -195,12 +195,12 @@ private {
+         }
+     }
+ 
+-    mixin template HeaderLineStruct(string struct_name, 
++    mixin template HeaderLineStruct(string struct_name,
+                                     string line_prefix,
+                                     string id_field,
+-                                    Field...) 
++                                    Field...)
+     {
+-         mixin(`struct `~struct_name~`{ 
++         mixin(`struct `~struct_name~`{
+                     mixin structFields!Field;
+                     mixin parseStaticMethod!(struct_name, Field);
+                     mixin toSamMethod!(line_prefix, Field);
+@@ -359,7 +359,7 @@ class HeaderLineDictionary(T) {
+             _index_to_id.length = _index_to_id.length - 1;
+ 
+             _dict.remove(id);
+-            _id_to_index.remove(id); 
++            _id_to_index.remove(id);
+ 
+             return true;
+         }
+@@ -484,7 +484,7 @@ class SamHeader {
+                     try {
+                         sorting_order = to!SortingOrder(header_line.sorting_order);
+                     } catch (ConvException e) {
+-                        sorting_order = SortingOrder.unknown; 
++                        sorting_order = SortingOrder.unknown;
+                         // FIXME: should we do that silently?
+                     }
+                 } else {
+@@ -536,14 +536,14 @@ class SamHeader {
+ 
+         core.memory.GC.enable();
+     }
+-       
++
+     /// Format version
+     string format_version;
+ 
+     /// Sorting order
+     SortingOrder sorting_order = SortingOrder.unknown;
+ 
+-    /// Dictionary of @SQ lines. 
++    /// Dictionary of @SQ lines.
+     /// Removal is not allowed, you can only replace the whole dictionary.
+     SqLineDictionary sequences() @property {
+         if (_sequences is null)
+@@ -624,7 +624,7 @@ class SamHeader {
+             sink.write(to!string(sorting_order));
+         }
+         sink.write('\n');
+-       
++
+         for (size_t i = 0; i < sequences.length; i++) {
+             auto sq_line = getSequence(i);
+             sq_line.toSam(sink);
+@@ -713,7 +713,7 @@ class SamHeader {
+     /// Packs message in the following format:
+     /// $(BR)
+     /// MsgPack array with elements
+-    ///   $(OL 
++    ///   $(OL
+     ///     $(LI format version - string)
+     ///     $(LI sorting order - string)
+     ///     $(LI @SQ lines - array of dictionaries)
+@@ -789,7 +789,7 @@ unittest {
+     dict["zzz"] = zzz;
+     header.sequences = dict;
+ 
+-    assert(header.text == 
++    assert(header.text ==
+       "@HD\tVN:1.4\tSO:coordinate\n at SQ\tSN:yay\tLN:111\n at SQ\tSN:zzz\tLN:222\tUR:ftp://nyan.cat\n");
+     assert(header.sequences == dict);
+ 
+-- 
+2.11.0
+
diff --git a/debian/patches/0011-better-.travis.yml-uses-dub-test-and-tests-ldc.patch b/debian/patches/0011-better-.travis.yml-uses-dub-test-and-tests-ldc.patch
new file mode 100644
index 0000000..00e764a
--- /dev/null
+++ b/debian/patches/0011-better-.travis.yml-uses-dub-test-and-tests-ldc.patch
@@ -0,0 +1,24 @@
+From 27cbaadf3707728f18621970ba60fe9a4d5755aa Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 14:35:27 +0000
+Subject: [PATCH 11/14] better .travis.yml, uses dub test and tests ldc
+
+---
+ .travis.yml | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/.travis.yml b/.travis.yml
+index d7b3485..5a09379 100644
+--- a/.travis.yml
++++ b/.travis.yml
+@@ -1,3 +1,5 @@
+ language: d
+-script:
+-- rdmd -unittest -d test/unittests.d
++
++d:
++  - dmd
++  - ldc
+-- 
+2.11.0
+
diff --git a/debian/patches/0013-fix-toJSON-usage-for-new-and-old-compilers.patch b/debian/patches/0013-fix-toJSON-usage-for-new-and-old-compilers.patch
new file mode 100644
index 0000000..56142e9
--- /dev/null
+++ b/debian/patches/0013-fix-toJSON-usage-for-new-and-old-compilers.patch
@@ -0,0 +1,28 @@
+From 468c01931dcdade9478c6849e85a105c8930c604 Mon Sep 17 00:00:00 2001
+From: John Colvin <john.loughran.colvin at gmail.com>
+Date: Fri, 16 Dec 2016 14:40:47 +0000
+Subject: [PATCH 13/14] fix toJSON usage for new and old compilers
+
+---
+ bio/sam/header.d | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/bio/sam/header.d b/bio/sam/header.d
+index df88d64..57054bf 100644
+--- a/bio/sam/header.d
++++ b/bio/sam/header.d
+@@ -707,7 +707,10 @@ class SamHeader {
+ 
+         JSONValue json;
+         json.object = result;
+-        sink.write(toJSON(json));
++        static if (__VERSION__ < 2072)
++            sink.write(toJSON(&json));
++        else
++            sink.write(toJSON(json));
+     }
+ 
+     /// Packs message in the following format:
+-- 
+2.11.0
+
diff --git a/debian/patches/0014-Add-compareCoordinatesAndStrand-to-fix-sorting-test-.patch b/debian/patches/0014-Add-compareCoordinatesAndStrand-to-fix-sorting-test-.patch
new file mode 100644
index 0000000..1cc5f7a
--- /dev/null
+++ b/debian/patches/0014-Add-compareCoordinatesAndStrand-to-fix-sorting-test-.patch
@@ -0,0 +1,840 @@
+From b7f1db860d212ee5fb6f9adfb36c6e783aaeb6f5 Mon Sep 17 00:00:00 2001
+From: Pjotr Prins <pjotr.public01 at thebird.nl>
+Date: Thu, 23 Feb 2017 10:24:23 +0000
+Subject: [PATCH 14/14] Add compareCoordinatesAndStrand to fix sorting test in
+ depth which came out when compiling with debug settings.
+
+sambamba depth now tests for a sorted BAM file irrespective of read
+direction/strand.
+
+Also removed trailing spaces in these files.
+---
+ bio/bam/multireader.d |  26 ++---
+ bio/bam/read.d        | 274 ++++++++++++++++++++++++++------------------------
+ 2 files changed, 156 insertions(+), 144 deletions(-)
+
+diff --git a/bio/bam/multireader.d b/bio/bam/multireader.d
+index 2a9705f..c0650b0 100644
+--- a/bio/bam/multireader.d
++++ b/bio/bam/multireader.d
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -66,7 +66,7 @@ bool compare(T)(auto ref T r1, auto ref T r2) {
+         sorting_order = r1[1].merged_header.sorting_order;
+ 
+     if (sorting_order == SortingOrder.coordinate)
+-        return compareCoordinates(r1[0], r2[0]);
++        return compareCoordinatesAndStrand(r1[0], r2[0]);
+     else if (sorting_order == SortingOrder.queryname)
+         return compareReadNames(r1[0], r2[0]);
+     else
+@@ -86,10 +86,10 @@ auto readRange(BamReader reader, SamHeaderMerger merger, FileId index) {
+     return zip(reader.reads.multiBamReads(index), repeat(merger), repeat(index));
+ }
+ 
+-// (BamReader, SamHeaderMerger, FileId, int, uint, uint) -> 
++// (BamReader, SamHeaderMerger, FileId, int, uint, uint) ->
+ //                                    [(MultiBamRead, SamHeaderMerger, FileId)]
+ auto readRange(BamReader reader, SamHeaderMerger merger, FileId index,
+-               int ref_id, uint start, uint end) 
++               int ref_id, uint start, uint end)
+ {
+     int old_ref_id = ref_id;
+     if (merger !is null)
+@@ -139,12 +139,12 @@ auto readRangesWithProgress
+                   .map!(t => readRangeWithProgress(t[0], t[1], t[2], f, u(t[2])))();
+ }
+ 
+-// ([BamReader], SamHeaderMerger, int, uint, uint) -> 
++// ([BamReader], SamHeaderMerger, int, uint, uint) ->
+ //                                    [[(MultiBamRead, SamHeaderMerger, FileId)]]
+-auto readRanges(BamReader[] readers, SamHeaderMerger merger, 
+-                int ref_id, uint start, uint end) 
++auto readRanges(BamReader[] readers, SamHeaderMerger merger,
++                int ref_id, uint start, uint end)
+ {
+-    return readers.zip(repeat(merger), iota(readers.length), 
++    return readers.zip(repeat(merger), iota(readers.length),
+                        repeat(ref_id), repeat(start), repeat(end))
+                   .map!(t => readRange(t[0], t[1], t[2], t[3], t[4], t[5]))();
+ }
+@@ -160,8 +160,8 @@ auto readRanges(BamReader[] readers, SamHeaderMerger merger, BamRegion[] regions
+ 
+ // tweaks RG and PG tags, and reference sequence ID
+ // [[(BamRead, SamHeaderMerger, size_t)]] -> [[MultiBamRead]]
+-auto adjustTags(R)(R reads_with_aux_info, TaskPool pool, size_t bufsize) 
+-    if (isInputRange!R) 
++auto adjustTags(R)(R reads_with_aux_info, TaskPool pool, size_t bufsize)
++    if (isInputRange!R)
+ {
+   alias R2 = typeof(pool.map!adjustTagsInRange(reads_with_aux_info.front, 1));
+   R2[] result;
+@@ -189,7 +189,7 @@ auto adjustTagsInRange(R)(R read_with_aux_info) if (!isInputRange!R) {
+             auto new_ref_id = to!int(ref_id_map[file_id][old_ref_id]);
+             if (new_ref_id != old_ref_id)
+                 read.ref_id = new_ref_id;
+-        } 
++        }
+ 
+         auto program = read["PG"];
+         if (!program.is_nothing) {
+@@ -216,7 +216,7 @@ auto adjustTagsInRange(R)(R read_with_aux_info) if (!isInputRange!R) {
+ 
+ ///
+ class MultiBamReader {
+-  
++
+     ///
+     this(BamReader[] readers) {
+         _readers = readers;
+diff --git a/bio/bam/read.d b/bio/bam/read.d
+index b2f8cd1..2d8182c 100644
+--- a/bio/bam/read.d
++++ b/bio/bam/read.d
+@@ -8,10 +8,10 @@
+     the rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons to whom the
+     Software is furnished to do so, subject to the following conditions:
+-    
++
+     The above copyright notice and this permission notice shall be included in
+     all copies or substantial portions of the Software.
+-    
++
+     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+@@ -31,7 +31,7 @@
+ /// ...
+ /// assert(!read.is_unmapped);              // check flag
+ /// assert(read.ref_id != -1);              // access field
+-/// 
++///
+ /// int edit_distance = to!int(read["NM"]); // access tag
+ /// read["NM"] = 0;                         // modify tag
+ /// read["NM"] = null;                      // remove tag
+@@ -82,14 +82,14 @@ struct CigarOperation {
+     /*
+         WARNING!
+ 
+-      It is very essential that the size of 
++      It is very essential that the size of
+       this struct is EXACTLY equal to uint.sizeof!
+ 
+       The reason is to avoid copying of arrays during alignment parsing.
+ 
+       Namely, when some_pointer points to raw cigar data,
+       we can just do a cast. This allows to access those data
+-      directly, not doing any memory allocations. 
++      directly, not doing any memory allocations.
+     */
+ 
+     private uint raw; // raw data from BAM
+@@ -121,7 +121,7 @@ struct CigarOperation {
+     uint length() @property const nothrow {
+         return raw >> 4;
+     }
+-  
++
+     /// CIGAR operation as one of MIDNSHP=X.
+     /// Absent or invalid operation is represented by '?'
+     char type() @property const nothrow {
+@@ -153,7 +153,7 @@ struct CigarOperation {
+         return ((raw & 0xF) >> 1) == 2; // 4 or 5
+     }
+ 
+-    private void toSam(Sink)(auto ref Sink sink) const 
++    private void toSam(Sink)(auto ref Sink sink) const
+         if (isSomeSink!Sink)
+     {
+         sink.write(length);
+@@ -170,7 +170,7 @@ struct CigarOperation {
+ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+     static assert(isInputRange!CigarOpRange && is(Unqual!(ElementType!CigarOpRange) == CigarOperation));
+     static assert(isInputRange!MdOpRange && is(Unqual!(ElementType!MdOpRange) == MdOperation));
+-  
++
+     private {
+         CigarOpRange _cigar;
+         MdOpRange _md_ops;
+@@ -199,7 +199,7 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+             import std.stdio;
+             writeln(_front_cigar_op, " - ", _front_md_op);
+         }
+-        
++
+         if (_front_cigar_op.type != 'M')
+             return _front_cigar_op;
+ 
+@@ -208,7 +208,7 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+             uint len = min(_front_md_op.match, _front_cigar_op.length);
+             return CigarOperation(len, '=');
+         }
+-    
++
+         assert(_front_md_op.is_mismatch);
+         return CigarOperation(min(_n_mismatches, _front_cigar_op.length), 'X');
+     }
+@@ -237,7 +237,7 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+         auto len = _front_cigar_op.length;
+         if (_n_mismatches > 0) {
+             enforce(_front_md_op.is_mismatch);
+-      
++
+             if (len > _n_mismatches) {
+                 _front_cigar_op = CigarOperation(len - _n_mismatches, 'M');
+                 _n_mismatches = 0;
+@@ -252,7 +252,7 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+         } else {
+             enforce(_front_md_op.is_match);
+             auto n_matches = _front_md_op.match;
+-      
++
+             if (len > n_matches) {
+                 _front_cigar_op = CigarOperation(len - n_matches, 'M');
+                 fetchNextMdOp();
+@@ -265,14 +265,14 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+             }
+         }
+     }
+-  
++
+     private {
+         void fetchNextCigarOp() {
+             if (_cigar.empty) {
+                 _empty = true;
+                 return;
+             }
+-        
++
+             _front_cigar_op = _cigar.front;
+             _cigar.popFront();
+         }
+@@ -282,7 +282,7 @@ struct ExtendedCigarRange(CigarOpRange, MdOpRange) {
+                 return;
+ 
+             _n_mismatches = 0;
+-      
++
+             _front_md_op = _md_ops.front;
+             _md_ops.popFront();
+ 
+@@ -301,7 +301,7 @@ auto makeExtendedCigar(CigarOpRange, MdOpRange)(CigarOpRange cigar, MdOpRange md
+     return ExtendedCigarRange!(CigarOpRange, MdOpRange)(cigar, md_ops);
+ }
+ 
+-/** 
++/**
+   BAM record representation.
+ */
+ struct BamRead {
+@@ -377,42 +377,42 @@ struct BamRead {
+     /// Next segment in the template unmapped
+     @property bool mate_is_unmapped()         const nothrow { return cast(bool)(flag & 0x8); }
+     /// ditto
+-    @property void mate_is_unmapped(bool b)         { _setFlag( 3, b); } 
++    @property void mate_is_unmapped(bool b)         { _setFlag( 3, b); }
+ 
+     /// Sequence being reverse complemented
+     @property bool is_reverse_strand()        const nothrow { return cast(bool)(flag & 0x10); }
+     /// ditto
+-    @property void is_reverse_strand(bool b)        { _setFlag( 4, b); } 
++    @property void is_reverse_strand(bool b)        { _setFlag( 4, b); }
+ 
+     /// Sequence of the next segment in the template being reversed
+     @property bool mate_is_reverse_strand()   const nothrow { return cast(bool)(flag & 0x20); }
+     /// ditto
+-    @property void mate_is_reverse_strand(bool b)   { _setFlag( 5, b); } 
++    @property void mate_is_reverse_strand(bool b)   { _setFlag( 5, b); }
+ 
+     /// The first segment in the template
+     @property bool is_first_of_pair()         const nothrow { return cast(bool)(flag & 0x40); }
+     /// ditto
+-    @property void is_first_of_pair(bool b)         { _setFlag( 6, b); } 
++    @property void is_first_of_pair(bool b)         { _setFlag( 6, b); }
+ 
+     /// The last segment in the template
+     @property bool is_second_of_pair()        const nothrow { return cast(bool)(flag & 0x80); }
+     /// ditto
+-    @property void is_second_of_pair(bool b)        { _setFlag( 7, b); } 
++    @property void is_second_of_pair(bool b)        { _setFlag( 7, b); }
+ 
+     /// Secondary alignment
+     @property bool is_secondary_alignment()   const nothrow { return cast(bool)(flag & 0x100); }
+     /// ditto
+-    @property void is_secondary_alignment(bool b)   { _setFlag( 8, b); } 
++    @property void is_secondary_alignment(bool b)   { _setFlag( 8, b); }
+ 
+     /// Not passing quality controls
+     @property bool failed_quality_control()   const nothrow { return cast(bool)(flag & 0x200); }
+     /// ditto
+-    @property void failed_quality_control(bool b)   { _setFlag( 9, b); } 
++    @property void failed_quality_control(bool b)   { _setFlag( 9, b); }
+ 
+     /// PCR or optical duplicate
+     @property bool is_duplicate()             const nothrow { return cast(bool)(flag & 0x400); }
+     /// ditto
+-    @property void is_duplicate(bool b)             { _setFlag(10, b); } 
++    @property void is_duplicate(bool b)             { _setFlag(10, b); }
+ 
+     /// Supplementary alignment
+     @property bool is_supplementary()         const nothrow { return cast(bool)(flag & 0x800); }
+@@ -438,10 +438,10 @@ struct BamRead {
+ 
+     /// ditto
+     @property void name(string new_name) {
+-        enforce(new_name.length >= 1 && new_name.length <= 255, 
++        enforce(new_name.length >= 1 && new_name.length <= 255,
+                 "name length must be in 1-255 range");
+         _dup();
+-        bio.bam.utils.array.replaceSlice(_chunk, 
++        bio.bam.utils.array.replaceSlice(_chunk,
+                  _chunk[_read_name_offset .. _read_name_offset + _l_read_name - 1],
+                  cast(ubyte[])new_name);
+         _l_read_name = cast(ubyte)(new_name.length + 1);
+@@ -449,7 +449,7 @@ struct BamRead {
+ 
+     /// List of CIGAR operations
+     @property const(CigarOperation)[] cigar() const nothrow {
+-        return cast(const(CigarOperation)[])(_chunk[_cigar_offset .. _cigar_offset + 
++        return cast(const(CigarOperation)[])(_chunk[_cigar_offset .. _cigar_offset +
+                                              _n_cigar_op * CigarOperation.sizeof]);
+     }
+ 
+@@ -534,32 +534,32 @@ struct BamRead {
+             return opIndex(_len - 1);
+         }
+ 
+-        /* 
++        /*
+         I have no fucking idea why this tiny piece of code
+         does NOT get inlined by stupid DMD compiler.
+ 
+-        Therefore I use string mixin instead. 
++        Therefore I use string mixin instead.
+         (hell yeah! Back to the 90s! C macros rulez!)
+ 
+         private size_t _getActualPosition(size_t index) const
+         {
+             if (_use_first_4_bits) {
+                 // [0 1] [2 3] [4 5] [6 7] ...
+-                //            |               
+-                //            V               
+-                //   0     1     2     3      
++                //            |
++                //            V
++                //   0     1     2     3
+                 return index >> 1;
+             } else {
+                 // [. 0] [1 2] [3 4] [5 6] ...
+-                //            |               
+-                //            V               
+-                //   0     1     2     3      
++                //            |
++                //            V
++                //   0     1     2     3
+                 return (index >> 1) + (index & 1);
+             }
+-        }*/ 
++        }*/
+ 
+         private static string _getActualPosition(string index) {
+-            return "((" ~ index ~") >> 1) + " ~ 
++            return "((" ~ index ~") >> 1) + " ~
+                    "(_use_first_4_bits ? 0 : ((" ~ index ~ ") & 1))";
+         }
+ 
+@@ -574,15 +574,15 @@ struct BamRead {
+ 
+         ///
+         @property SequenceResult save() const {
+-            return SequenceResult(_data[mixin(_getActualPosition("_index")) .. $], 
+-                                  _len - _index, 
++            return SequenceResult(_data[mixin(_getActualPosition("_index")) .. $],
++                                  _len - _index,
+                                   _useFirst4Bits(_index));
+         }
+ 
+         ///
+         SequenceResult opSlice(size_t i, size_t j) const {
+-            return SequenceResult(_data[mixin(_getActualPosition("_index + i")) .. $], 
+-                                  j - i, 
++            return SequenceResult(_data[mixin(_getActualPosition("_index + i")) .. $],
++                                  j - i,
+                                   _useFirst4Bits(_index + i));
+         }
+ 
+@@ -668,7 +668,7 @@ struct BamRead {
+     static assert(isRandomAccessRange!(ReturnType!sequence));
+ 
+     /// Sets query sequence. Sets all base qualities to 255 (i.e. unknown).
+-    @property void sequence(string seq) 
++    @property void sequence(string seq)
+     {
+         _dup();
+ 
+@@ -683,8 +683,8 @@ struct BamRead {
+                 replacement[i] |= cast(ubyte)(Base(seq[2 * i + 1]).internal_code);
+         }
+ 
+-        bio.bam.utils.array.replaceSlice(_chunk, 
+-                     _chunk[_seq_offset .. _tags_offset], 
++        bio.bam.utils.array.replaceSlice(_chunk,
++                     _chunk[_seq_offset .. _tags_offset],
+                      replacement);
+ 
+         _l_seq = cast(int)seq.length;
+@@ -715,7 +715,7 @@ struct BamRead {
+         // 3) the code will be too complicated, whereas there're
+         //    not so many users of big-endian systems
+         //
+-        // In summa, BAM is little-endian format, so big-endian 
++        // In summa, BAM is little-endian format, so big-endian
+         // users will suffer anyway, it's unavoidable.
+ 
+         _chunk = chunk;
+@@ -727,33 +727,33 @@ struct BamRead {
+             // Dealing with tags is the responsibility of TagStorage.
+             fixTagStorageByteOrder();
+         }
+-    } 
++    }
+ 
+-    // Doesn't touch tags, only fields. 
++    // Doesn't touch tags, only fields.
+     // @@@TODO: NEEDS TESTING@@@
+     private void switchChunkEndianness() {
+-        // First 8 fields are 32-bit integers:                 
+-        //                                                     
+-        // 0) refID                int                         
+-        // 1) pos                  int                         
+-        // 2) bin_mq_nl           uint                         
+-        // 3) flag_nc             uint                         
+-        // 4) l_seq                int                         
+-        // 5) next_refID           int                         
+-        // 6) next_pos             int                         
+-        // 7) tlen                 int                         
++        // First 8 fields are 32-bit integers:
++        //
++        // 0) refID                int
++        // 1) pos                  int
++        // 2) bin_mq_nl           uint
++        // 3) flag_nc             uint
++        // 4) l_seq                int
++        // 5) next_refID           int
++        // 6) next_pos             int
++        // 7) tlen                 int
+         // ----------------------------------------------------
+-        // (after them name follows which is string)      
+-        //                                                     
++        // (after them name follows which is string)
++        //
+         switchEndianness(_chunk.ptr, 8 * uint.sizeof);
+ 
+         // Then we need to switch endianness of CIGAR data:
+-        switchEndianness(_chunk.ptr + _cigar_offset, 
++        switchEndianness(_chunk.ptr + _cigar_offset,
+                          _n_cigar_op * uint.sizeof);
+     }
+- 
+-    private size_t calculateChunkSize(string read_name, 
+-                                      string sequence, 
++
++    private size_t calculateChunkSize(string read_name,
++                                      string sequence,
+                                       in CigarOperation[] cigar)
+     {
+         return 8 * int.sizeof
+@@ -776,7 +776,7 @@ struct BamRead {
+         if (this._chunk is null) {
+             this._chunk = new ubyte[calculateChunkSize(read_name, sequence, cigar)];
+         }
+-        
++
+         this._refID      =  -1;         // set default values
+         this._pos        =  -1;         // according to SAM/BAM
+         this._mapq       = 255;         // specification
+@@ -817,7 +817,7 @@ struct BamRead {
+         return result;
+     }
+ 
+-    /// Compare two alignments, including tags 
++    /// Compare two alignments, including tags
+     /// (the tags must follow in the same order for equality).
+     bool opEquals(BamRead other) const pure nothrow {
+         // don't forget about _is_slice trick
+@@ -835,7 +835,7 @@ struct BamRead {
+     @property size_t size_in_bytes() const {
+         return int.sizeof + _chunk.length;
+     }
+-   
++
+     package void write(BamWriter writer) {
+         writer.writeInteger(cast(int)(_chunk.length));
+ 
+@@ -858,7 +858,7 @@ struct BamRead {
+     /// Packs message in the following format:
+     /// $(BR)
+     /// MsgPack array with elements
+-    ///   $(OL 
++    ///   $(OL
+     ///     $(LI name - string)
+     ///     $(LI flag - ushort)
+     ///     $(LI reference sequence id - int)
+@@ -916,9 +916,9 @@ struct BamRead {
+             throw new FormatException("unknown format specifier");
+         }
+     }
+-    
++
+     /// ditto
+-    void toSam(Sink)(auto ref Sink sink) const 
++    void toSam(Sink)(auto ref Sink sink) const
+         if (isSomeSink!Sink)
+     {
+         sink.write(name);
+@@ -1025,10 +1025,10 @@ struct BamRead {
+         } else {
+             sink.writeJson(_reader.reference_sequences[mate_ref_id].name);
+         }
+-        
++
+         sink.write(`,"pnext":`); sink.write(mate_position + 1);
+         sink.write(`,"tlen":`); sink.write(template_length);
+-     
++
+         sink.write(`,"seq":"`);
+         if (sequence_length == 0)
+             sink.write('*');
+@@ -1041,7 +1041,7 @@ struct BamRead {
+         sink.writeJson(base_qualities);
+ 
+         sink.write(`,"tags":{`);
+-   
++
+         bool not_first = false;
+         foreach (k, v; this) {
+             if (not_first)
+@@ -1087,8 +1087,8 @@ struct BamRead {
+     void raw_data(ubyte[] data) @property {
+         _chunk = data;
+     }
+-    
+-    package ubyte[] _chunk; // holds all the data, 
++
++    package ubyte[] _chunk; // holds all the data,
+                     // the access is organized via properties
+                     // (see below)
+ 
+@@ -1130,36 +1130,36 @@ private:
+ 
+     // Official field names from SAM/BAM specification.
+     // For internal use only
+-    @property  int _refID()      const nothrow { 
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 0)); 
++    @property  int _refID()      const nothrow {
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 0));
+     }
+ 
+-    @property  int _pos()        const nothrow { 
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 1)); 
++    @property  int _pos()        const nothrow {
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 1));
+     }
+ 
+-    @property uint _bin_mq_nl()  const nothrow pure @system { 
+-        return *(cast(uint*)(_chunk.ptr + int.sizeof * 2)); 
++    @property uint _bin_mq_nl()  const nothrow pure @system {
++        return *(cast(uint*)(_chunk.ptr + int.sizeof * 2));
+     }
+ 
+-    @property uint _flag_nc()    const nothrow { 
+-        return *(cast(uint*)(_chunk.ptr + int.sizeof * 3)); 
++    @property uint _flag_nc()    const nothrow {
++        return *(cast(uint*)(_chunk.ptr + int.sizeof * 3));
+     }
+ 
+-    @property  int _l_seq()      const nothrow { 
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 4)); 
++    @property  int _l_seq()      const nothrow {
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 4));
+     }
+ 
+     @property  int _next_refID() const nothrow {
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 5)); 
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 5));
+     }
+ 
+-    @property  int _next_pos()   const nothrow { 
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 6)); 
++    @property  int _next_pos()   const nothrow {
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 6));
+     }
+ 
+     @property  int _tlen()       const nothrow {
+-        return *(cast( int*)(_chunk.ptr + int.sizeof * 7)); 
++        return *(cast( int*)(_chunk.ptr + int.sizeof * 7));
+     }
+ 
+     // Setters, also only for internal use
+@@ -1176,29 +1176,29 @@ private:
+     //
+     //             The layout of bin_mq_nl and flag_nc is as follows
+     //                     (upper bits -------> lower bits):
+-    // 
++    //
+     // bin_mq_nl [ { bin (16b) }  { mapping quality (8b) } { read name length (8b) } ]
+     //
+     // flag_nc   [ { flag (16b) } { n_cigar_op (16b) } ]
+     //
+-    @property ushort _bin()         const nothrow { 
+-        return _bin_mq_nl >> 16; 
++    @property ushort _bin()         const nothrow {
++        return _bin_mq_nl >> 16;
+     }
+-    @property  ubyte _mapq()        const nothrow { 
+-        return (_bin_mq_nl >> 8) & 0xFF; 
++    @property  ubyte _mapq()        const nothrow {
++        return (_bin_mq_nl >> 8) & 0xFF;
+     }
+-    @property  ubyte _l_read_name() const nothrow pure { 
+-        return _bin_mq_nl & 0xFF; 
++    @property  ubyte _l_read_name() const nothrow pure {
++        return _bin_mq_nl & 0xFF;
+     }
+-    @property ushort _flag()        const nothrow { 
+-        return _flag_nc >> 16; 
++    @property ushort _flag()        const nothrow {
++        return _flag_nc >> 16;
+     }
+-    @property ushort _n_cigar_op()  const nothrow { 
+-        return _flag_nc & 0xFFFF; 
++    @property ushort _n_cigar_op()  const nothrow {
++        return _flag_nc & 0xFFFF;
+     }
+-  
++
+     // Setters for those properties
+-    @property void _bin(ushort n)         { _bin_mq_nl = (_bin_mq_nl &  0xFFFF) | (n << 16); } 
++    @property void _bin(ushort n)         { _bin_mq_nl = (_bin_mq_nl &  0xFFFF) | (n << 16); }
+     @property void _mapq(ubyte n)         { _bin_mq_nl = (_bin_mq_nl & ~0xFF00) | (n << 8); }
+     @property void _l_read_name(ubyte n)  { _bin_mq_nl = (_bin_mq_nl & ~0xFF  ) | n; }
+     @property void _flag(ushort n)        { _flag_nc   = (_flag_nc   &  0xFFFF) | (n << 16); }
+@@ -1207,24 +1207,24 @@ private:
+     // Offsets of various arrays in bytes.
+     // Currently, are computed each time, so if speed will be an issue,
+     // they can be made fields instead of properties.
+-    @property size_t _read_name_offset() const nothrow pure { 
+-        return 8 * int.sizeof; 
++    @property size_t _read_name_offset() const nothrow pure {
++        return 8 * int.sizeof;
+     }
+ 
+-    @property size_t _cigar_offset()     const nothrow pure { 
+-        return _read_name_offset + _l_read_name * char.sizeof; 
++    @property size_t _cigar_offset()     const nothrow pure {
++        return _read_name_offset + _l_read_name * char.sizeof;
+     }
+ 
+-    @property size_t _seq_offset()       const nothrow { 
+-        return _cigar_offset + _n_cigar_op * uint.sizeof; 
++    @property size_t _seq_offset()       const nothrow {
++        return _cigar_offset + _n_cigar_op * uint.sizeof;
+     }
+ 
+-    @property size_t _qual_offset()      const nothrow { 
++    @property size_t _qual_offset()      const nothrow {
+         return _seq_offset + (_l_seq + 1) / 2;
+     }
+ 
+     // Offset of auxiliary data
+-    @property size_t _tags_offset()      const nothrow { 
++    @property size_t _tags_offset()      const nothrow {
+         return _qual_offset + _l_seq;
+     }
+ 
+@@ -1257,7 +1257,7 @@ public:
+ }
+ 
+ 
+-/// Lazy tag storage. 
++/// Lazy tag storage.
+ ///
+ ///   Provides hash-like access and opportunity to iterate
+ ///   storage like an associative array.
+@@ -1298,7 +1298,7 @@ mixin template TagStorage() {
+         auto __tags_chunk = _tags_chunk; // _tags_chunk is evaluated lazily
+         if (__tags_chunk.length < 4)
+             return Value(null);
+-        
++
+        size_t offset = 0;
+        while (offset + 1 < __tags_chunk.length) {
+            if (__tags_chunk[offset .. offset + 2] == key) {
+@@ -1313,8 +1313,8 @@ mixin template TagStorage() {
+     }
+ 
+     /// ditto
+-    void opIndexAssign(T)(T value, string key) 
+-        if (is(T == Value) || __traits(compiles, GetTypeId!T)) 
++    void opIndexAssign(T)(T value, string key)
++        if (is(T == Value) || __traits(compiles, GetTypeId!T))
+     {
+         static if(is(T == Value)) {
+             enforce(key.length == 2, "Key length must be 2");
+@@ -1378,7 +1378,7 @@ mixin template TagStorage() {
+         auto __tags_chunk = _tags_chunk;
+         skipValue(offset, __tags_chunk); // now offset is updated and points to the end
+         auto end = offset;
+-        
++
+         prepareSlice(_chunk, __tags_chunk[begin .. end], sizeInBytes(value));
+ 
+         emplaceValue(_chunk.ptr + _tags_offset + begin, value);
+@@ -1428,9 +1428,9 @@ mixin template TagStorage() {
+         if (std.system.endian == Endian.littleEndian) {
+             writer.writeByteArray(_tags_chunk[]);
+         } else {
+-            fixTagStorageByteOrder();                                
++            fixTagStorageByteOrder();
+             writer.writeByteArray(_tags_chunk[]);
+-            fixTagStorageByteOrder();                                
++            fixTagStorageByteOrder();
+         }
+     }
+ 
+@@ -1486,7 +1486,7 @@ mixin template TagStorage() {
+                         p += size;
+                     }
+                 } else {
+-                    // skip 
++                    // skip
+                     p += length;
+                 }
+             } else {
+@@ -1509,8 +1509,8 @@ unittest {
+     import std.math;
+ 
+     writeln("Testing BamRead behaviour...");
+-    auto read = BamRead("readname", 
+-                        "AGCTGACTACGTAATAGCCCTA", 
++    auto read = BamRead("readname",
++                        "AGCTGACTACGTAATAGCCCTA",
+                         [CigarOperation(22, 'M')]);
+     assert(read.sequence_length == 22);
+     assert(read.cigar.length == 1);
+@@ -1522,7 +1522,7 @@ unittest {
+     assert(read.name == "anothername");
+     assert(read.cigarString() == "22M");
+ 
+-    read.base_qualities = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
++    read.base_qualities = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+                            13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
+     assert(reduce!"a+b"(0, read.base_qualities) == 253);
+ 
+@@ -1602,7 +1602,7 @@ unittest {
+ /// $(P The idea is that this should be a drop-in replacement for BamRead in algorithms,
+ /// as the struct uses 'alias this' construction for the wrapped read.)
+ struct EagerBamRead(R=BamRead) {
+-    /// 
++    ///
+     this(R read) {
+         this.read = read;
+         this.end_position = read.position + read.basesCovered();
+@@ -1612,7 +1612,7 @@ struct EagerBamRead(R=BamRead) {
+     R read;
+     ///
+     alias read this;
+- 
++
+     /// End position on the reference, computed as position + basesCovered().
+     int end_position;
+ 
+@@ -1629,11 +1629,11 @@ template isBamRead(T)
+ {
+     static if (is(Unqual!T : BamRead))
+         enum isBamRead = true;
+-    else 
+-        enum isBamRead = __traits(compiles, 
++    else
++        enum isBamRead = __traits(compiles,
+         {
+             T t; bool p;
+-            p = t.ref_id == 1;          p = t.position == 2;          p = t.bin.id == 3;  
++            p = t.ref_id == 1;          p = t.position == 2;          p = t.bin.id == 3;
+             p = t.mapping_quality == 4; p = t.flag == 5;              p = t.sequence_length == 6;
+             p = t.mate_ref_id == 7;     p = t.mate_position == 8;     p = t.template_length == 9;
+             p = t.is_paired;            p = t.proper_pair;            p = t.is_unmapped;
+@@ -1649,22 +1649,22 @@ template isBamRead(T)
+ /// (return whether first read is 'less' than second))
+ ///
+ /// $(P This function can be called on:
+-///   $(UL 
++///   $(UL
+ ///     $(LI two reads)
+ ///     $(LI read and string in any order)))
+-bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2) 
++bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+     if (isBamRead!R1 && isBamRead!R2)
+ {
+     return a1.name < a2.name;
+ }
+ 
+-bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2) 
++bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+     if (isBamRead!R1 && isSomeString!R2)
+ {
+     return a1.name < a2;
+ }
+ 
+-bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2) 
++bool compareReadNames(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+     if (isSomeString!R1 && isBamRead!R2)
+ {
+     return a1 < a2.name;
+@@ -1747,10 +1747,12 @@ unittest {
+ /// (returns whether first read is 'less' than second))
+ ///
+ /// $(P This function can be called on:
+-///   $(UL 
++///   $(UL
+ ///     $(LI two reads (in this case, reference IDs are also taken into account))
+ ///     $(LI read and integer in any order)))
+-bool compareCoordinates(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
++
++/// This function takes read direction into account (used for original samtools style sorting)
++bool compareCoordinatesAndStrand(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+     if (isBamRead!R1 && isBamRead!R2)
+ {
+     if (a1.ref_id == -1) return false; // unmapped reads should be last
+@@ -1763,6 +1765,16 @@ bool compareCoordinates(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+ }
+ 
+ bool compareCoordinates(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
++    if (isBamRead!R1 && isBamRead!R2)
++{
++    if (a1.ref_id == -1) return false; // unmapped reads should be last
++    if (a2.ref_id == -1) return true;
++    if (a1.ref_id < a2.ref_id) return true;
++    if (a1.ref_id > a2.ref_id) return false;
++    return (a1.position < a2.position);
++}
++
++bool compareCoordinates(R1, R2)(const auto ref R1 a1, const auto ref R2 a2)
+     if (isBamRead!R1 && isIntegral!R2)
+ {
+     return a1.position < a2;
+-- 
+2.11.0
+
diff --git a/debian/patches/0015-Add-Meson-build-definition.patch b/debian/patches/0015-Add-Meson-build-definition.patch
new file mode 100644
index 0000000..63510d5
--- /dev/null
+++ b/debian/patches/0015-Add-Meson-build-definition.patch
@@ -0,0 +1,140 @@
+From 815047a6f2ddbf2ae4aec9fcb32d624b543fd1d6 Mon Sep 17 00:00:00 2001
+From: Matthias Klumpp <matthias at tenstral.net>
+Date: Tue, 28 Feb 2017 14:44:30 +0100
+Subject: [PATCH] Add Meson build definition
+
+---
+ meson.build | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 127 insertions(+)
+ create mode 100644 meson.build
+
+--- /dev/null
++++ b/meson.build
+@@ -0,0 +1,127 @@
++project('BioD', 'd')
++
++project_version   = '0.1.0'
++project_soversion = '0'
++
++src_dir = include_directories('.')
++pkgc = import('pkgconfig')
++
++#
++# Dependencies
++#
++undead_dep = dependency('undead', version : '>=1.0.6')
++zlib_dep = dependency('zlib')
++
++#
++# Sources
++#
++biod_src = [
++    'bio/bam/utils/value.d',
++    'bio/bam/utils/samheadermerger.d',
++    'bio/bam/utils/array.d',
++    'bio/bam/utils/graph.d',
++    'bio/bam/pileup.d',
++    'bio/bam/readrange.d',
++    'bio/bam/reader.d',
++    'bio/bam/thirdparty/msgpack.d',
++    'bio/bam/baifile.d',
++    'bio/bam/iontorrent/flowcall.d',
++    'bio/bam/iontorrent/flowindex.d',
++    'bio/bam/splitter.d',
++    'bio/bam/abstractreader.d',
++    'bio/bam/bai/indexing.d',
++    'bio/bam/bai/bin.d',
++    'bio/bam/multireader.d',
++    'bio/bam/reference.d',
++    'bio/bam/md/operation.d',
++    'bio/bam/md/core.d',
++    'bio/bam/md/parse.d',
++    'bio/bam/md/reconstruct.d',
++    'bio/bam/tagvalue.d',
++    'bio/bam/validation/alignment.d',
++    'bio/bam/validation/samheader.d',
++    'bio/bam/region.d',
++    'bio/bam/randomaccessmanager.d',
++    'bio/bam/referenceinfo.d',
++    'bio/bam/constants.d',
++    'bio/bam/snpcallers/maq.d',
++    'bio/bam/snpcallers/simple.d',
++    'bio/bam/read.d',
++    'bio/bam/writer.d',
++    'bio/bam/baseinfo.d',
++    'bio/maf/reader.d',
++    'bio/maf/parser.d',
++    'bio/maf/block.d',
++    'bio/core/utils/memoize.d',
++    'bio/core/utils/algo.d',
++    'bio/core/utils/stream.d',
++    'bio/core/utils/zlib.d',
++    'bio/core/utils/tmpfile.d',
++    'bio/core/utils/roundbuf.d',
++    'bio/core/utils/format.d',
++    'bio/core/utils/bylinefast.d',
++    'bio/core/utils/range.d',
++    'bio/core/utils/switchendianness.d',
++    'bio/core/utils/outbuffer.d',
++    'bio/core/genotype.d',
++    'bio/core/fasta.d',
++    'bio/core/base.d',
++    'bio/core/kmer.d',
++    'bio/core/region.d',
++    'bio/core/tinymap.d',
++    'bio/core/sequence.d',
++    'bio/core/bgzf/outputstream.d',
++    'bio/core/bgzf/chunk.d',
++    'bio/core/bgzf/inputstream.d',
++    'bio/core/bgzf/constants.d',
++    'bio/core/bgzf/block.d',
++    'bio/core/bgzf/virtualoffset.d',
++    'bio/core/bgzf/compress.d',
++    'bio/core/call.d',
++    'bio/sff/utils/roundup.d',
++    'bio/sff/index.d',
++    'bio/sff/readrange.d',
++    'bio/sff/reader.d',
++    'bio/sff/constants.d',
++    'bio/sff/read.d',
++    'bio/sff/writer.d',
++    'bio/sam/utils/fastrecordparser.d',
++    'bio/sam/utils/recordparser.d',
++    'bio/sam/reader.d',
++    'bio/sam/header.d'
++]
++
++#
++# Includes
++#
++install_subdir('bio/', install_dir: 'include/d/')
++
++#
++# Library and pkg-config
++#
++biod_lib = library('biod',
++        [biod_src],
++        include_directories: [src_dir],
++        dependencies: [undead_dep, zlib_dep],
++        install: true,
++        version: project_version,
++        soversion: project_soversion
++)
++pkgc.generate(name: 'biod',
++              libraries: biod_lib,
++              subdirs: 'd/',
++              version: project_version,
++              description: 'Bioinformatics library in D (utils for working with SAM, BAM, SFF formats).'
++)
++
++#
++# Tests
++#
++biod_test_exe = executable('biod_test',
++    ['test/unittests.d',
++    biod_src],
++    include_directories: [src_dir],
++    dependencies: [undead_dep, zlib_dep],
++    d_args: meson.get_compiler('d').unittest_args()
++)
++test('biod_tests', biod_test_exe)
diff --git a/debian/patches/series b/debian/patches/series
index 65d85ea..39a52ce 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +1,13 @@
-fix_deprecated_imports.patch
+# fix_deprecated_imports.patch
+0002-improved-big-endian-support.patch
+0003-include-the-AH-header-tag-to-SQ-lines.patch
+0004-use-consistent-naming-21.patch
+0005-fixes-lomereiter-sambamba-244.patch
+0006-switch-to-undead.stream.patch
+0007-std.c-core.stdc.patch
+0008-fix-deprecations-and-some-warnings.patch
+0009-fix-toHash-signature.patch
+0011-better-.travis.yml-uses-dub-test-and-tests-ldc.patch
+0013-fix-toJSON-usage-for-new-and-old-compilers.patch
+0014-Add-compareCoordinatesAndStrand-to-fix-sorting-test-.patch
+0015-Add-Meson-build-definition.patch

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



More information about the debian-med-commit mailing list